diff options
1423 files changed, 54430 insertions, 37406 deletions
@@ -3709,6 +3709,13 @@ N: Dirk Verworner D: Co-author of German book ``Linux-Kernel-Programmierung'' D: Co-founder of Berlin Linux User Group +N: Andrew Victor +E: linux@maxim.org.za +W: http://maxim.org.za/at91_26.html +D: First maintainer of Atmel ARM-based SoC, aka AT91 +D: Introduced support for at91rm9200, the first chip of AT91 family +S: South Africa + N: Riku Voipio E: riku.voipio@iki.fi D: Author of PCA9532 LED and Fintek f75375s hwmon driver diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 99983e67c13c..da95513571ea 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -162,7 +162,7 @@ Description: Discover CPUs in the same CPU frequency coordination domain What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1} Date: August 2008 KernelVersion: 2.6.27 -Contact: discuss@x86-64.org +Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> Description: Disable L3 cache indices These files exist in every CPU's cache/index3 directory. Each diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index 653d5d739d7f..31d1d658827f 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt @@ -505,7 +505,10 @@ at module load time (for a module) with: The addresses are normal I2C addresses. The adapter is the string name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. -It is *NOT* i2c-<n> itself. +It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring +spaces, so if the name is "This is an I2C chip" you can say +adapter_name=ThisisanI2cchip. This is because it's hard to pass in +spaces in kernel parameters. The debug flags are bit flags for each BMC found, they are: IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8 diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index 750401f91341..15dfce708ebf 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt @@ -253,7 +253,7 @@ input driver: GPIO support ~~~~~~~~~~~~ ACPI 5 introduced two new resources to describe GPIO connections: GpioIo -and GpioInt. These resources are used be used to pass GPIO numbers used by +and GpioInt. These resources can be used to pass GPIO numbers used by the device to the driver. ACPI 5.1 extended this with _DSD (Device Specific Data) which made it possible to name the GPIOs among other things. diff --git a/Documentation/acpi/gpio-properties.txt b/Documentation/acpi/gpio-properties.txt index ae36fcf86dc7..f35dad11f0de 100644 --- a/Documentation/acpi/gpio-properties.txt +++ b/Documentation/acpi/gpio-properties.txt @@ -1,9 +1,9 @@ _DSD Device Properties Related to GPIO -------------------------------------- -With the release of ACPI 5.1 and the _DSD configuration objecte names -can finally be given to GPIOs (and other things as well) returned by -_CRS. Previously, we were only able to use an integer index to find +With the release of ACPI 5.1, the _DSD configuration object finally +allows names to be given to GPIOs (and other things as well) returned +by _CRS. Previously, we were only able to use an integer index to find the corresponding GPIO, which is pretty error prone (it depends on the _CRS output ordering, for example). diff --git a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt index 974624ea68f6..161448da959d 100644 --- a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt +++ b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt @@ -6,6 +6,7 @@ provided by Arteris. Required properties: - compatible : Should be "ti,omap3-l3-smx" for OMAP3 family Should be "ti,omap4-l3-noc" for OMAP4 family + Should be "ti,omap5-l3-noc" for OMAP5 family Should be "ti,dra7-l3-noc" for DRA7 family Should be "ti,am4372-l3-noc" for AM43 family - reg: Contains L3 register address range for each noc domain. diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt index c40711e8e8f7..28b28309f535 100644 --- a/Documentation/devicetree/bindings/clock/silabs,si5351.txt +++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt @@ -17,7 +17,8 @@ Required properties: - #clock-cells: from common clock binding; shall be set to 1. - clocks: from common clock binding; list of parent clock handles, shall be xtal reference clock or xtal and clkin for - si5351c only. + si5351c only. Corresponding clock input names are "xtal" and + "clkin" respectively. - #address-cells: shall be set to 1. - #size-cells: shall be set to 0. @@ -71,6 +72,7 @@ i2c-master-node { /* connect xtal input to 25MHz reference */ clocks = <&ref25>; + clock-names = "xtal"; /* connect xtal input as source of pll0 and pll1 */ silabs,pll-source = <0 0>, <1 0>; diff --git a/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt b/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt index a4873e5e3e36..e30e184f50c7 100644 --- a/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt @@ -38,7 +38,7 @@ dma_apbx: dma-apbx@80024000 { 80 81 68 69 70 71 72 73 74 75 76 77>; - interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty", + interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty", "saif0", "saif1", "i2c0", "i2c1", "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx", "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx"; diff --git a/Documentation/devicetree/bindings/mtd/m25p80.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt index f20b111b502a..2bee68103b01 100644 --- a/Documentation/devicetree/bindings/mtd/m25p80.txt +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt @@ -8,8 +8,8 @@ Required properties: is not Linux-only, but in case of Linux, see the "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of supported chips. - Must also include "nor-jedec" for any SPI NOR flash that can be - identified by the JEDEC READ ID opcode (0x9F). + Must also include "jedec,spi-nor" for any SPI NOR flash that can + be identified by the JEDEC READ ID opcode (0x9F). - reg : Chip-Select number - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at @@ -25,7 +25,7 @@ Example: flash: m25p80@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80", "nor-jedec"; + compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; m25p,fast-read; diff --git a/Documentation/devicetree/bindings/net/cdns-emac.txt b/Documentation/devicetree/bindings/net/cdns-emac.txt index abd67c13d344..4451ee973223 100644 --- a/Documentation/devicetree/bindings/net/cdns-emac.txt +++ b/Documentation/devicetree/bindings/net/cdns-emac.txt @@ -3,7 +3,8 @@ Required properties: - compatible: Should be "cdns,[<chip>-]{emac}" Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. - or the generic form: "cdns,emac". + Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC. + Or the generic form: "cdns,emac". - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt - phy-mode: see ethernet.txt file in the same directory. diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt new file mode 100644 index 000000000000..be789685a1c2 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt @@ -0,0 +1,30 @@ +Abracon ABX80X I2C ultra low power RTC/Alarm chip + +The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801, +ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805 +is the superset of ab180x. + +Required properties: + + - "compatible": should one of: + "abracon,abx80x" + "abracon,ab0801" + "abracon,ab0803" + "abracon,ab0804" + "abracon,ab0805" + "abracon,ab1801" + "abracon,ab1803" + "abracon,ab1804" + "abracon,ab1805" + Using "abracon,abx80x" will enable chip autodetection. + - "reg": I2C bus address of the device + +Optional properties: + +The abx804 and abx805 have a trickle charger that is able to charge the +connected battery or supercap. Both the following properties have to be defined +and valid to enable charging: + + - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V) + - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output + resistor, the other values are in ohm. diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index dc2a18f0b3a1..ddbe304beb21 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -15,10 +15,8 @@ Optional properties: - phys: phandle + phy specifier pair - phy-names: must be "usb" - dmas: Must contain a list of references to DMA specifiers. - - dma-names : Must contain a list of DMA names: - - tx0 ... tx<n> - - rx0 ... rx<n> - - This <n> means DnFIFO in USBHS module. + - dma-names : named "ch%d", where %d is the channel number ranging from zero + to the number of channels (DnFIFOs) minus one. Example: usbhs: usb@e6590000 { diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 index 8eb88e974055..711f75e189eb 100644 --- a/Documentation/hwmon/tmp401 +++ b/Documentation/hwmon/tmp401 @@ -20,7 +20,7 @@ Supported chips: Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html * Texas Instruments TMP435 Prefix: 'tmp435' - Addresses scanned: I2C 0x37, 0x48 - 0x4f + Addresses scanned: I2C 0x48 - 0x4f Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html Authors: diff --git a/Documentation/kasan.txt b/Documentation/kasan.txt index 092fc10961fe..4692241789b1 100644 --- a/Documentation/kasan.txt +++ b/Documentation/kasan.txt @@ -9,7 +9,9 @@ a fast and comprehensive solution for finding use-after-free and out-of-bounds bugs. KASan uses compile-time instrumentation for checking every memory access, -therefore you will need a certain version of GCC > 4.9.2 +therefore you will need a gcc version of 4.9.2 or later. KASan could detect out +of bounds accesses to stack or global variables, but only if gcc 5.0 or later was +used to built the kernel. Currently KASan is supported only for x86_64 architecture and requires that the kernel be built with the SLUB allocator. @@ -23,8 +25,8 @@ To enable KASAN configure kernel with: and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline/inline is compiler instrumentation types. The former produces smaller binary the -latter is 1.1 - 2 times faster. Inline instrumentation requires GCC 5.0 or -latter. +latter is 1.1 - 2 times faster. Inline instrumentation requires a gcc version +of 5.0 or later. Currently KASAN works only with the SLUB memory allocator. For better bug detection and nicer report, enable CONFIG_STACKTRACE and put diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt index 1e52d67d0abf..dbe6623fed1c 100644 --- a/Documentation/serial/tty.txt +++ b/Documentation/serial/tty.txt @@ -198,6 +198,9 @@ TTY_IO_ERROR If set, causes all subsequent userspace read/write TTY_OTHER_CLOSED Device is a pty and the other side has closed. +TTY_OTHER_DONE Device is a pty and the other side has closed and + all pending input processing has been completed. + TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into smaller chunks. diff --git a/Documentation/target/tcmu-design.txt b/Documentation/target/tcmu-design.txt index 43e94ea6d2ca..263b907517ac 100644 --- a/Documentation/target/tcmu-design.txt +++ b/Documentation/target/tcmu-design.txt @@ -15,8 +15,7 @@ Contents: a) Discovering and configuring TCMU uio devices b) Waiting for events on the device(s) c) Managing the command ring -3) Command filtering and pass_level -4) A final note +3) A final note TCM Userspace Design @@ -324,7 +323,7 @@ int handle_device_events(int fd, void *map) /* Process events from cmd ring until we catch up with cmd_head */ while (ent != (void *)mb + mb->cmdr_off + mb->cmd_head) { - if (tcmu_hdr_get_op(&ent->hdr) == TCMU_OP_CMD) { + if (tcmu_hdr_get_op(ent->hdr.len_op) == TCMU_OP_CMD) { uint8_t *cdb = (void *)mb + ent->req.cdb_off; bool success = true; @@ -339,8 +338,12 @@ int handle_device_events(int fd, void *map) ent->rsp.scsi_status = SCSI_CHECK_CONDITION; } } + else if (tcmu_hdr_get_op(ent->hdr.len_op) != TCMU_OP_PAD) { + /* Tell the kernel we didn't handle unknown opcodes */ + ent->hdr.uflags |= TCMU_UFLAG_UNKNOWN_OP; + } else { - /* Do nothing for PAD entries */ + /* Do nothing for PAD entries except update cmd_tail */ } /* update cmd_tail */ @@ -360,28 +363,6 @@ int handle_device_events(int fd, void *map) } -Command filtering and pass_level --------------------------------- - -TCMU supports a "pass_level" option with valid values of 0 or 1. When -the value is 0 (the default), nearly all SCSI commands received for -the device are passed through to the handler. This allows maximum -flexibility but increases the amount of code required by the handler, -to support all mandatory SCSI commands. If pass_level is set to 1, -then only IO-related commands are presented, and the rest are handled -by LIO's in-kernel command emulation. The commands presented at level -1 include all versions of: - -READ -WRITE -WRITE_VERIFY -XDWRITEREAD -WRITE_SAME -COMPARE_AND_WRITE -SYNCHRONIZE_CACHE -UNMAP - - A final note ------------ diff --git a/Documentation/virtual/kvm/mmu.txt b/Documentation/virtual/kvm/mmu.txt index 53838d9c6295..c59bd9bc41ef 100644 --- a/Documentation/virtual/kvm/mmu.txt +++ b/Documentation/virtual/kvm/mmu.txt @@ -169,6 +169,10 @@ Shadow pages contain the following information: Contains the value of cr4.smep && !cr0.wp for which the page is valid (pages for which this is true are different from other pages; see the treatment of cr0.wp=0 below). + role.smap_andnot_wp: + Contains the value of cr4.smap && !cr0.wp for which the page is valid + (pages for which this is true are different from other pages; see the + treatment of cr0.wp=0 below). gfn: Either the guest page table containing the translations shadowed by this page, or the base page frame for linear translations. See role.direct. @@ -344,10 +348,16 @@ on fault type: (user write faults generate a #PF) -In the first case there is an additional complication if CR4.SMEP is -enabled: since we've turned the page into a kernel page, the kernel may now -execute it. We handle this by also setting spte.nx. If we get a user -fetch or read fault, we'll change spte.u=1 and spte.nx=gpte.nx back. +In the first case there are two additional complications: +- if CR4.SMEP is enabled: since we've turned the page into a kernel page, + the kernel may now execute it. We handle this by also setting spte.nx. + If we get a user fetch or read fault, we'll change spte.u=1 and + spte.nx=gpte.nx back. +- if CR4.SMAP is disabled: since the page has been changed to a kernel + page, it can not be reused when CR4.SMAP is enabled. We set + CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note, + here we do not care the case that CR4.SMAP is enabled since KVM will + directly inject #PF to guest due to failed permission check. To prevent an spte that was converted into a kernel page with cr0.wp=0 from being written by the kernel after cr0.wp has changed to 1, we make diff --git a/MAINTAINERS b/MAINTAINERS index 781e099495d3..ad98c7ffa4b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -51,9 +51,9 @@ trivial patch so apply some common sense. or does something very odd once a month document it. PLEASE remember that submissions must be made under the terms - of the OSDL certificate of contribution and should include a - Signed-off-by: line. The current version of this "Developer's - Certificate of Origin" (DCO) is listed in the file + of the Linux Foundation certificate of contribution and should + include a Signed-off-by: line. The current version of this + "Developer's Certificate of Origin" (DCO) is listed in the file Documentation/SubmittingPatches. 6. Make sure you have the right to send any changes you make. If you @@ -892,11 +892,10 @@ S: Maintained F: arch/arm/mach-alpine/ ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES -M: Andrew Victor <linux@maxim.org.za> M: Nicolas Ferre <nicolas.ferre@atmel.com> +M: Alexandre Belloni <alexandre.belloni@free-electrons.com> M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://maxim.org.za/at91_26.html W: http://www.linux4sam.org S: Supported F: arch/arm/mach-at91/ @@ -975,7 +974,7 @@ S: Maintained ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll <ulli.kroll@googlemail.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -T: git git://git.berlios.de/gemini-board +T: git git://github.com/ulli-kroll/linux.git S: Maintained F: arch/arm/mach-gemini/ @@ -990,6 +989,12 @@ F: drivers/clocksource/timer-prima2.c F: drivers/clocksource/timer-atlas7.c N: [^a-z]sirf +ARM/CONEXANT DIGICOLOR MACHINE SUPPORT +M: Baruch Siach <baruch@tkos.co.il> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +N: digicolor + ARM/EBSA110 MACHINE SUPPORT M: Russell King <linux@arm.linux.org.uk> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1188,7 +1193,7 @@ ARM/MAGICIAN MACHINE SUPPORT M: Philipp Zabel <philipp.zabel@gmail.com> S: Maintained -ARM/Marvell Armada 370 and Armada XP SOC support +ARM/Marvell Kirkwood and Armada 370, 375, 38x, XP SOC support M: Jason Cooper <jason@lakedaemon.net> M: Andrew Lunn <andrew@lunn.ch> M: Gregory Clement <gregory.clement@free-electrons.com> @@ -1197,12 +1202,17 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-mvebu/ F: drivers/rtc/rtc-armada38x.c +F: arch/arm/boot/dts/armada* +F: arch/arm/boot/dts/kirkwood* + ARM/Marvell Berlin SoC support M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-berlin/ +F: arch/arm/boot/dts/berlin* + ARM/Marvell Dove/MV78xx0/Orion SOC support M: Jason Cooper <jason@lakedaemon.net> @@ -1215,6 +1225,9 @@ F: arch/arm/mach-dove/ F: arch/arm/mach-mv78xx0/ F: arch/arm/mach-orion5x/ F: arch/arm/plat-orion/ +F: arch/arm/boot/dts/dove* +F: arch/arm/boot/dts/orion5x* + ARM/Orion SoC/Technologic Systems TS-78xx platform support M: Alexander Clouter <alex@digriz.org.uk> @@ -1366,6 +1379,7 @@ N: rockchip ARM/SAMSUNG EXYNOS ARM ARCHITECTURES M: Kukjin Kim <kgene@kernel.org> +M: Krzysztof Kozlowski <k.kozlowski@samsung.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained @@ -1439,9 +1453,10 @@ ARM/SOCFPGA ARCHITECTURE M: Dinh Nguyen <dinguyen@opensource.altera.com> S: Maintained F: arch/arm/mach-socfpga/ +F: arch/arm/boot/dts/socfpga* +F: arch/arm/configs/socfpga_defconfig W: http://www.rocketboards.org -T: git://git.rocketboards.org/linux-socfpga.git -T: git://git.rocketboards.org/linux-socfpga-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT M: Dinh Nguyen <dinguyen@opensource.altera.com> @@ -1929,7 +1944,7 @@ S: Maintained F: drivers/net/wireless/b43legacy/ BACKLIGHT CLASS/SUBSYSTEM -M: Jingoo Han <jg1.han@samsung.com> +M: Jingoo Han <jingoohan1@gmail.com> M: Lee Jones <lee.jones@linaro.org> S: Maintained F: drivers/video/backlight/ @@ -2116,8 +2131,9 @@ S: Supported F: drivers/net/ethernet/broadcom/bnx2x/ BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE -M: Christian Daudt <bcm@fixthebug.org> M: Florian Fainelli <f.fainelli@gmail.com> +M: Ray Jui <rjui@broadcom.com> +M: Scott Branden <sbranden@broadcom.com> L: bcm-kernel-feedback-list@broadcom.com T: git git://github.com/broadcom/mach-bcm S: Maintained @@ -2168,7 +2184,6 @@ S: Maintained F: drivers/usb/gadget/udc/bcm63xx_udc.* BROADCOM BCM7XXX ARM ARCHITECTURE -M: Marc Carino <marc.ceeeee@gmail.com> M: Brian Norris <computersforpeace@gmail.com> M: Gregory Fong <gregory.0xf0@gmail.com> M: Florian Fainelli <f.fainelli@gmail.com> @@ -2412,7 +2427,6 @@ L: linux-security-module@vger.kernel.org S: Supported F: include/linux/capability.h F: include/uapi/linux/capability.h -F: security/capability.c F: security/commoncap.c F: kernel/capability.c @@ -3810,10 +3824,11 @@ M: David Woodhouse <dwmw2@infradead.org> L: linux-embedded@vger.kernel.org S: Maintained -EMULEX LPFC FC SCSI DRIVER -M: James Smart <james.smart@emulex.com> +EMULEX/AVAGO LPFC FC/FCOE SCSI DRIVER +M: James Smart <james.smart@avagotech.com> +M: Dick Kennedy <dick.kennedy@avagotech.com> L: linux-scsi@vger.kernel.org -W: http://sourceforge.net/projects/lpfcxxxx +W: http://www.avagotech.com S: Supported F: drivers/scsi/lpfc/ @@ -3912,7 +3927,7 @@ F: drivers/extcon/ F: Documentation/extcon/ EXYNOS DP DRIVER -M: Jingoo Han <jg1.han@samsung.com> +M: Jingoo Han <jingoohan1@gmail.com> L: dri-devel@lists.freedesktop.org S: Maintained F: drivers/gpu/drm/exynos/exynos_dp* @@ -4371,11 +4386,10 @@ F: fs/gfs2/ F: include/uapi/linux/gfs2_ondisk.h GIGASET ISDN DRIVERS -M: Hansjoerg Lipp <hjlipp@web.de> -M: Tilman Schmidt <tilman@imap.cc> +M: Paul Bolle <pebolle@tiscali.nl> L: gigaset307x-common@lists.sourceforge.net W: http://gigaset307x.sourceforge.net/ -S: Maintained +S: Odd Fixes F: Documentation/isdn/README.gigaset F: drivers/isdn/gigaset/ F: include/uapi/linux/gigaset_dev.h @@ -4522,7 +4536,7 @@ M: Jean Delvare <jdelvare@suse.de> M: Guenter Roeck <linux@roeck-us.net> L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ -T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ +T: quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git S: Maintained F: Documentation/hwmon/ @@ -5042,17 +5056,19 @@ S: Orphan F: drivers/video/fbdev/imsttfb.c INFINIBAND SUBSYSTEM -M: Roland Dreier <roland@kernel.org> +M: Doug Ledford <dledford@redhat.com> M: Sean Hefty <sean.hefty@intel.com> M: Hal Rosenstock <hal.rosenstock@gmail.com> L: linux-rdma@vger.kernel.org W: http://www.openfabrics.org/ Q: http://patchwork.kernel.org/project/linux-rdma/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma.git S: Supported F: Documentation/infiniband/ F: drivers/infiniband/ F: include/uapi/linux/if_infiniband.h +F: include/uapi/rdma/ +F: include/rdma/ INOTIFY M: John McCutchan <john@johnmccutchan.com> @@ -5805,6 +5821,7 @@ F: drivers/scsi/53c700* LED SUBSYSTEM M: Bryan Wu <cooloney@gmail.com> M: Richard Purdie <rpurdie@rpsys.net> +M: Jacek Anaszewski <j.anaszewski@samsung.com> L: linux-leds@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git S: Maintained @@ -6950,6 +6967,17 @@ T: git git://git.rocketboards.org/linux-socfpga-next.git S: Maintained F: arch/nios2/ +NOKIA N900 POWER SUPPLY DRIVERS +M: Pali Rohár <pali.rohar@gmail.com> +S: Maintained +F: include/linux/power/bq2415x_charger.h +F: include/linux/power/bq27x00_battery.h +F: include/linux/power/isp1704_charger.h +F: drivers/power/bq2415x_charger.c +F: drivers/power/bq27x00_battery.c +F: drivers/power/isp1704_charger.c +F: drivers/power/rx51_battery.c + NTB DRIVER M: Jon Mason <jdmason@kudzu.us> M: Dave Jiang <dave.jiang@intel.com> @@ -7538,7 +7566,7 @@ S: Maintained F: drivers/pci/host/*rcar* PCI DRIVER FOR SAMSUNG EXYNOS -M: Jingoo Han <jg1.han@samsung.com> +M: Jingoo Han <jingoohan1@gmail.com> L: linux-pci@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) @@ -7546,7 +7574,8 @@ S: Maintained F: drivers/pci/host/pci-exynos.c PCI DRIVER FOR SYNOPSIS DESIGNWARE -M: Jingoo Han <jg1.han@samsung.com> +M: Jingoo Han <jingoohan1@gmail.com> +M: Pratyush Anand <pratyush.anand@gmail.com> L: linux-pci@vger.kernel.org S: Maintained F: drivers/pci/host/*designware* @@ -7560,8 +7589,9 @@ F: Documentation/devicetree/bindings/pci/host-generic-pci.txt F: drivers/pci/host/pci-host-generic.c PCIE DRIVER FOR ST SPEAR13XX +M: Pratyush Anand <pratyush.anand@gmail.com> L: linux-pci@vger.kernel.org -S: Orphan +S: Maintained F: drivers/pci/host/*spear* PCMCIA SUBSYSTEM @@ -8502,7 +8532,7 @@ S: Supported F: sound/soc/samsung/ SAMSUNG FRAMEBUFFER DRIVER -M: Jingoo Han <jg1.han@samsung.com> +M: Jingoo Han <jingoohan1@gmail.com> L: linux-fbdev@vger.kernel.org S: Maintained F: drivers/video/fbdev/s3c-fb.c @@ -8801,16 +8831,19 @@ F: drivers/misc/phantom.c F: include/uapi/linux/phantom.h SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER -M: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> +M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com> +M: Minh Tran <minh.tran@avagotech.com> +M: John Soni Jose <sony.john-n@avagotech.com> L: linux-scsi@vger.kernel.org -W: http://www.emulex.com +W: http://www.avagotech.com S: Supported F: drivers/scsi/be2iscsi/ -SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER -M: Sathya Perla <sathya.perla@emulex.com> -M: Subbu Seetharaman <subbu.seetharaman@emulex.com> -M: Ajit Khaparde <ajit.khaparde@emulex.com> +Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER +M: Sathya Perla <sathya.perla@avagotech.com> +M: Ajit Khaparde <ajit.khaparde@avagotech.com> +M: Padmanabh Ratnakar <padmanabh.ratnakar@avagotech.com> +M: Sriharsha Basavapatna <sriharsha.basavapatna@avagotech.com> L: netdev@vger.kernel.org W: http://www.emulex.com S: Supported @@ -9467,6 +9500,15 @@ M: Forest Bond <forest@alittletooquiet.net> S: Odd Fixes F: drivers/staging/vt665?/ +STAGING - WILC1000 WIFI DRIVER +M: Johnny Kim <johnny.kim@atmel.com> +M: Rachel Kim <rachel.kim@atmel.com> +M: Dean Lee <dean.lee@atmel.com> +M: Chris Park <chris.park@atmel.com> +L: linux-wireless@vger.kernel.org +S: Supported +F: drivers/staging/wilc1000/ + STAGING - XGI Z7,Z9,Z11 PCI DISPLAY DRIVER M: Arnaud Patard <arnaud.patard@rtp-net.org> S: Odd Fixes @@ -10556,8 +10598,7 @@ F: drivers/virtio/virtio_input.c F: include/uapi/linux/virtio_input.h VIA RHINE NETWORK DRIVER -M: Roger Luethi <rl@hellgate.ch> -S: Maintained +S: Orphan F: drivers/net/ethernet/via/via-rhine.c VIA SD/MMC CARD CONTROLLER DRIVER @@ -11037,6 +11078,7 @@ F: drivers/media/pci/zoran/ ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER M: Minchan Kim <minchan@kernel.org> M: Nitin Gupta <ngupta@vflare.org> +R: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> L: linux-kernel@vger.kernel.org S: Maintained F: drivers/block/zram/ @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 1 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc7 NAME = Hurr durr I'ma sheep # *DOCUMENTATION* diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index cd143887380a..8399bd0e68e8 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -14,6 +14,9 @@ targets := vmlinux.gz vmlinux \ tools/bootpzh bootloader bootpheader bootpzheader OBJSTRIP := $(obj)/tools/objstrip +HOSTCFLAGS := -Wall -I$(objtree)/usr/include +BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) + # SRM bootable image. Copy to offset 512 of a partition. $(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh ( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@ @@ -96,13 +99,14 @@ $(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE $(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE $(call if_changed,objstrip) -LDFLAGS_bootloader := -static -uvsprintf -T #-N -relax -LDFLAGS_bootpheader := -static -uvsprintf -T #-N -relax -LDFLAGS_bootpzheader := -static -uvsprintf -T #-N -relax +LDFLAGS_bootloader := -static -T # -N -relax +LDFLAGS_bootloader := -static -T # -N -relax +LDFLAGS_bootpheader := -static -T # -N -relax +LDFLAGS_bootpzheader := -static -T # -N -relax -OBJ_bootlx := $(obj)/head.o $(obj)/main.o -OBJ_bootph := $(obj)/head.o $(obj)/bootp.o -OBJ_bootpzh := $(obj)/head.o $(obj)/bootpz.o $(obj)/misc.o +OBJ_bootlx := $(obj)/head.o $(obj)/stdio.o $(obj)/main.o +OBJ_bootph := $(obj)/head.o $(obj)/stdio.o $(obj)/bootp.o +OBJ_bootpzh := $(obj)/head.o $(obj)/stdio.o $(obj)/bootpz.o $(obj)/misc.o $(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE $(call if_changed,ld) diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c index 3baf2d1e908d..dd6eb4a33582 100644 --- a/arch/alpha/boot/main.c +++ b/arch/alpha/boot/main.c @@ -19,7 +19,6 @@ #include "ksize.h" -extern int vsprintf(char *, const char *, va_list); extern unsigned long switch_to_osf_pal(unsigned long nr, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, unsigned long *vptb); diff --git a/arch/alpha/boot/stdio.c b/arch/alpha/boot/stdio.c new file mode 100644 index 000000000000..f844dae8a54a --- /dev/null +++ b/arch/alpha/boot/stdio.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <stdarg.h> +#include <stddef.h> + +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + +# define do_div(n, base) ({ \ + unsigned int __base = (base); \ + unsigned int __rem; \ + __rem = ((unsigned long long)(n)) % __base; \ + (n) = ((unsigned long long)(n)) / __base; \ + __rem; \ +}) + + +static int skip_atoi(const char **s) +{ + int i, c; + + for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) + i = i*10 + c - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) +{ + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if ((signed long long)num < 0) { + sign = '-'; + num = - (signed long long)num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) { + tmp[i++] = digits[do_div(num, base)]; + } + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long long num; + int i, base; + char * str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ + + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if ('0' <= *fmt && *fmt <= '9') + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if ('0' <= *fmt && *fmt <= '9') + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'l' && *(fmt + 1) == 'l') { + qualifier = 'q'; + fmt += 2; + } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' + || *fmt == 'Z') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = "<NULL>"; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z') { + size_t * ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') { + num = va_arg(args, unsigned long); + if (flags & SIGN) + num = (signed long) num; + } else if (qualifier == 'q') { + num = va_arg(args, unsigned long long); + if (flags & SIGN) + num = (signed long long) num; + } else if (qualifier == 'Z') { + num = va_arg(args, size_t); + } else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (signed short) num; + } else { + num = va_arg(args, unsigned int); + if (flags & SIGN) + num = (signed int) num; + } + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + return i; +} diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c index 367d53d031fc..dee82695f48b 100644 --- a/arch/alpha/boot/tools/objstrip.c +++ b/arch/alpha/boot/tools/objstrip.c @@ -27,6 +27,9 @@ #include <linux/param.h> #ifdef __ELF__ # include <linux/elf.h> +# define elfhdr elf64_hdr +# define elf_phdr elf64_phdr +# define elf_check_arch(x) ((x)->e_machine == EM_ALPHA) #endif /* bootfile size must be multiple of BLOCK_SIZE: */ diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h index f61e1a56c378..4cb4b6d3452c 100644 --- a/arch/alpha/include/asm/types.h +++ b/arch/alpha/include/asm/types.h @@ -2,6 +2,5 @@ #define _ALPHA_TYPES_H #include <asm-generic/int-ll64.h> -#include <uapi/asm/types.h> #endif /* _ALPHA_TYPES_H */ diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index c509d306db45..a56e608db2f9 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -3,7 +3,7 @@ #include <uapi/asm/unistd.h> -#define NR_SYSCALLS 511 +#define NR_SYSCALLS 514 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/arch/alpha/include/uapi/asm/unistd.h b/arch/alpha/include/uapi/asm/unistd.h index d214a0358100..aa33bf5aacb6 100644 --- a/arch/alpha/include/uapi/asm/unistd.h +++ b/arch/alpha/include/uapi/asm/unistd.h @@ -472,5 +472,8 @@ #define __NR_sched_setattr 508 #define __NR_sched_getattr 509 #define __NR_renameat2 510 +#define __NR_getrandom 511 +#define __NR_memfd_create 512 +#define __NR_execveat 513 #endif /* _UAPI_ALPHA_UNISTD_H */ diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 253cf1a87481..51267ac5729b 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c @@ -6,7 +6,6 @@ * Error handling code supporting Alpha systems */ -#include <linux/init.h> #include <linux/sched.h> #include <asm/io.h> diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 7b2be251c30f..51f2c8654253 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -19,7 +19,6 @@ #include <linux/ptrace.h> #include <linux/interrupt.h> #include <linux/random.h> -#include <linux/init.h> #include <linux/irq.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index e51f578636a5..36dc91ace83a 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1019,14 +1019,13 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, if (tv) { if (get_tv32((struct timeval *)&kts, tv)) return -EFAULT; + kts.tv_nsec *= 1000; } if (tz) { if (copy_from_user(&ktz, tz, sizeof(*tz))) return -EFAULT; } - kts.tv_nsec *= 1000; - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 1941a07b5811..84d13263ce46 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -236,12 +236,11 @@ release_thread(struct task_struct *dead_task) } /* - * Copy an alpha thread.. + * Copy architecture-specific thread state */ - int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, + unsigned long kthread_arg, struct task_struct *p) { extern void ret_from_fork(void); @@ -262,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, sizeof(struct switch_stack) + sizeof(struct pt_regs)); childstack->r26 = (unsigned long) ret_from_kernel_thread; childstack->r9 = usp; /* function */ - childstack->r10 = arg; + childstack->r10 = kthread_arg; childregs->hae = alpha_mv.hae_cache, childti->pcb.usp = 0; return 0; diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 99ac36d5de4e..2f24447fef92 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -63,7 +63,6 @@ static struct { enum ipi_message_type { IPI_RESCHEDULE, IPI_CALL_FUNC, - IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, }; @@ -506,7 +505,6 @@ setup_profiling_timer(unsigned int multiplier) return -EINVAL; } - static void send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) { @@ -552,10 +550,6 @@ handle_ipi(struct pt_regs *regs) generic_smp_call_function_interrupt(); break; - case IPI_CALL_FUNC_SINGLE: - generic_smp_call_function_single_interrupt(); - break; - case IPI_CPU_STOP: halt(); @@ -606,7 +600,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) void arch_send_call_function_single_ipi(int cpu) { - send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); + send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC); } static void diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 6f01d9ad7b81..72b59511e59a 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -237,8 +237,7 @@ srmcons_init(void) return -ENODEV; } - -module_init(srmcons_init); +device_initcall(srmcons_init); /* diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index f21d61fab678..24e41bd7d3c9 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -331,7 +331,7 @@ marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin) pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline); irq = intline; - msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI); + msi_loc = dev->msi_cap; msg_ctl = 0; if (msi_loc) pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl); diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 24789713f1ea..9b62e3fd4f03 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -529,6 +529,9 @@ sys_call_table: .quad sys_sched_setattr .quad sys_sched_getattr .quad sys_renameat2 /* 510 */ + .quad sys_getrandom + .quad sys_memfd_create + .quad sys_execveat .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 9c4c189eb22f..74aceead06e9 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -14,7 +14,6 @@ #include <linux/tty.h> #include <linux/delay.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/kallsyms.h> #include <linux/ratelimit.h> diff --git a/arch/alpha/oprofile/op_model_ev4.c b/arch/alpha/oprofile/op_model_ev4.c index 18aa9b4f94f1..086a0d5445c5 100644 --- a/arch/alpha/oprofile/op_model_ev4.c +++ b/arch/alpha/oprofile/op_model_ev4.c @@ -8,7 +8,6 @@ */ #include <linux/oprofile.h> -#include <linux/init.h> #include <linux/smp.h> #include <asm/ptrace.h> diff --git a/arch/alpha/oprofile/op_model_ev5.c b/arch/alpha/oprofile/op_model_ev5.c index c32f8a0ad925..c300f5ef3482 100644 --- a/arch/alpha/oprofile/op_model_ev5.c +++ b/arch/alpha/oprofile/op_model_ev5.c @@ -8,7 +8,6 @@ */ #include <linux/oprofile.h> -#include <linux/init.h> #include <linux/smp.h> #include <asm/ptrace.h> diff --git a/arch/alpha/oprofile/op_model_ev6.c b/arch/alpha/oprofile/op_model_ev6.c index 1c84cc257fc7..02edf5971614 100644 --- a/arch/alpha/oprofile/op_model_ev6.c +++ b/arch/alpha/oprofile/op_model_ev6.c @@ -8,7 +8,6 @@ */ #include <linux/oprofile.h> -#include <linux/init.h> #include <linux/smp.h> #include <asm/ptrace.h> diff --git a/arch/alpha/oprofile/op_model_ev67.c b/arch/alpha/oprofile/op_model_ev67.c index 34a57a126553..adb1744d20f3 100644 --- a/arch/alpha/oprofile/op_model_ev67.c +++ b/arch/alpha/oprofile/op_model_ev67.c @@ -9,7 +9,6 @@ */ #include <linux/oprofile.h> -#include <linux/init.h> #include <linux/smp.h> #include <asm/ptrace.h> diff --git a/arch/arc/Kconfig.debug b/arch/arc/Kconfig.debug index a7fc0da25650..ff6a4b5ce927 100644 --- a/arch/arc/Kconfig.debug +++ b/arch/arc/Kconfig.debug @@ -2,19 +2,6 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config EARLY_PRINTK - bool "Early printk" if EMBEDDED - default y - help - Write kernel log output directly into the VGA buffer or to a serial - port. - - This is useful for kernel debugging when your machine crashes very - early before the console code is initialized. For normal operation - it is not recommended because it looks ugly and doesn't cooperate - with klogd/syslogd or the X server. You should normally N here, - unless you want to debug such a crash. - config 16KSTACKS bool "Use 16Kb for kernel stacks instead of 8Kb" help diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 067551b6920a..9917a45fc430 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -99,7 +99,7 @@ static inline void atomic_##op(int i, atomic_t *v) \ atomic_ops_unlock(flags); \ } -#define ATOMIC_OP_RETURN(op, c_op) \ +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ static inline int atomic_##op##_return(int i, atomic_t *v) \ { \ unsigned long flags; \ diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 8c3a3e02ba92..12b2100db073 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -266,7 +266,7 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr, * Machine specific helpers for Entire D-Cache or Per Line ops */ -static unsigned int __before_dc_op(const int op) +static inline unsigned int __before_dc_op(const int op) { unsigned int reg = reg; @@ -284,7 +284,7 @@ static unsigned int __before_dc_op(const int op) return reg; } -static void __after_dc_op(const int op, unsigned int reg) +static inline void __after_dc_op(const int op, unsigned int reg) { if (op & OP_FLUSH) /* flush / flush-n-inv both wait */ while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS); diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 86217db2937a..992736b5229b 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -223,7 +223,7 @@ dtb-$(CONFIG_SOC_IMX25) += \ imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \ imx25-karo-tx25.dtb \ imx25-pdk.dtb -dtb-$(CONFIG_SOC_IMX31) += \ +dtb-$(CONFIG_SOC_IMX27) += \ imx27-apf27.dtb \ imx27-apf27dev.dtb \ imx27-eukrea-mbimxsd27-baseboard.dtb \ diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts index 5c42d259fa68..901739fcb85a 100644 --- a/arch/arm/boot/dts/am335x-boneblack.dts +++ b/arch/arm/boot/dts/am335x-boneblack.dts @@ -80,7 +80,3 @@ status = "okay"; }; }; - -&rtc { - system-power-controller; -}; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 87fc7a35e802..156d05efcb70 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -654,7 +654,7 @@ wlcore: wlcore@2 { compatible = "ti,wl1271"; reg = <2>; - interrupt-parent = <&gpio1>; + interrupt-parent = <&gpio0>; interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */ ref-clock-frequency = <38400000>; }; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 8ae29c955c11..c17097d2c167 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -49,7 +49,7 @@ pinctrl-0 = <&matrix_keypad_pins>; debounce-delay-ms = <5>; - col-scan-delay-us = <1500>; + col-scan-delay-us = <5>; row-gpios = <&gpio5 5 GPIO_ACTIVE_HIGH /* Bank5, pin5 */ &gpio5 6 GPIO_ACTIVE_HIGH>; /* Bank5, pin6 */ @@ -473,7 +473,7 @@ interrupt-parent = <&gpio0>; interrupts = <31 0>; - wake-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; touchscreen-size-x = <480>; touchscreen-size-y = <272>; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 15f198e4864d..7128fad991ac 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -18,6 +18,7 @@ aliases { rtc0 = &mcp_rtc; rtc1 = &tps659038_rtc; + rtc2 = &rtc; }; memory { @@ -83,7 +84,7 @@ gpio_fan: gpio_fan { /* Based on 5v 500mA AFB02505HHB */ compatible = "gpio-fan"; - gpios = <&tps659038_gpio 1 GPIO_ACTIVE_HIGH>; + gpios = <&tps659038_gpio 2 GPIO_ACTIVE_HIGH>; gpio-fan,speed-map = <0 0>, <13000 1>; #cooling-cells = <2>; @@ -130,8 +131,8 @@ uart3_pins_default: uart3_pins_default { pinctrl-single,pins = < - 0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd.rxd */ - 0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd.txd */ + 0x3f8 (PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */ + 0x3fc (PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */ >; }; @@ -455,7 +456,7 @@ mcp_rtc: rtc@6f { compatible = "microchip,mcp7941x"; reg = <0x6f>; - interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_LOW>; /* IRQ_SYS_1N */ + interrupts = <GIC_SPI 2 IRQ_TYPE_EDGE_RISING>; /* IRQ_SYS_1N */ pinctrl-names = "default"; pinctrl-0 = <&mcp79410_pins_default>; @@ -478,7 +479,7 @@ &uart3 { status = "okay"; interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, - <&dra7_pmx_core 0x248>; + <&dra7_pmx_core 0x3f8>; pinctrl-names = "default"; pinctrl-0 = <&uart3_pins_default>; diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index c675257f2377..f076ff856d8b 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -69,7 +69,7 @@ mainpll: mainpll { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <2000000000>; + clock-frequency = <1000000000>; }; /* 25 MHz reference crystal */ refclk: oscillator { diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index ed2dd8ba4080..218a2acd36e5 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -585,7 +585,7 @@ mainpll: mainpll { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <2000000000>; + clock-frequency = <1000000000>; }; /* 25 MHz reference crystal */ diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi index 0e85fc15ceda..ecd1318109ba 100644 --- a/arch/arm/boot/dts/armada-39x.dtsi +++ b/arch/arm/boot/dts/armada-39x.dtsi @@ -502,7 +502,7 @@ mainpll: mainpll { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <2000000000>; + clock-frequency = <1000000000>; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index e3b08fb959e5..990e8a2100f0 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -105,6 +105,10 @@ }; internal-regs { + rtc@10300 { + /* No crystal connected to the internal RTC */ + status = "disabled"; + }; serial@12000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts index aae7efc09b0b..e6fa251e17b9 100644 --- a/arch/arm/boot/dts/dove-cubox.dts +++ b/arch/arm/boot/dts/dove-cubox.dts @@ -87,6 +87,7 @@ /* connect xtal input to 25MHz reference */ clocks = <&ref25>; + clock-names = "xtal"; /* connect xtal input as source of pll0 and pll1 */ silabs,pll-source = <0 0>, <1 0>; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 5332b57b4950..f03a091cd076 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -911,7 +911,7 @@ ti,clock-cycles = <16>; reg = <0x4ae07ddc 0x4>, <0x4ae07de0 0x4>, - <0x4ae06014 0x4>, <0x4a003b20 0x8>, + <0x4ae06014 0x4>, <0x4a003b20 0xc>, <0x4ae0c158 0x4>; reg-names = "setup-address", "control-address", "int-address", "efuse-address", @@ -944,7 +944,7 @@ ti,clock-cycles = <16>; reg = <0x4ae07e34 0x4>, <0x4ae07e24 0x4>, - <0x4ae06010 0x4>, <0x4a0025cc 0x8>, + <0x4ae06010 0x4>, <0x4a0025cc 0xc>, <0x4a002470 0x4>; reg-names = "setup-address", "control-address", "int-address", "efuse-address", @@ -977,7 +977,7 @@ ti,clock-cycles = <16>; reg = <0x4ae07e30 0x4>, <0x4ae07e20 0x4>, - <0x4ae06010 0x4>, <0x4a0025e0 0x8>, + <0x4ae06010 0x4>, <0x4a0025e0 0xc>, <0x4a00246c 0x4>; reg-names = "setup-address", "control-address", "int-address", "efuse-address", @@ -1010,7 +1010,7 @@ ti,clock-cycles = <16>; reg = <0x4ae07de4 0x4>, <0x4ae07de8 0x4>, - <0x4ae06010 0x4>, <0x4a003b08 0x8>, + <0x4ae06010 0x4>, <0x4a003b08 0xc>, <0x4ae0c154 0x4>; reg-names = "setup-address", "control-address", "int-address", "efuse-address", @@ -1203,7 +1203,7 @@ status = "disabled"; }; - rtc@48838000 { + rtc: rtc@48838000 { compatible = "ti,am3352-rtc"; reg = <0x48838000 0x100>; interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 8de12af7c276..d6b49e5b32e9 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/sound/samsung-i2s.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/clock/maxim,max77686.h> #include "exynos4412.dtsi" / { @@ -105,6 +106,8 @@ rtc@10070000 { status = "okay"; + clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>; + clock-names = "rtc", "rtc_src"; }; g2d@10800000 { diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 173ffa479ad3..792394dd0f2a 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -736,7 +736,7 @@ display-timings { timing-0 { - clock-frequency = <0>; + clock-frequency = <57153600>; hactive = <720>; vactive = <1280>; hfront-porch = <5>; diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index 2657e842e5a5..1eca97ee4bd6 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -567,6 +567,7 @@ num-slots = <1>; broken-cd; cap-sdio-irq; + keep-power-in-suspend; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 0788d08fb43e..146e71118a72 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -711,6 +711,7 @@ num-slots = <1>; broken-cd; cap-sdio-irq; + keep-power-in-suspend; card-detect-delay = <200>; clock-frequency = <400000000>; samsung,dw-mshc-ciu-div = <1>; diff --git a/arch/arm/boot/dts/exynos5420-trip-points.dtsi b/arch/arm/boot/dts/exynos5420-trip-points.dtsi index 5d31fc140823..2180a0152c9b 100644 --- a/arch/arm/boot/dts/exynos5420-trip-points.dtsi +++ b/arch/arm/boot/dts/exynos5420-trip-points.dtsi @@ -28,7 +28,7 @@ trips { type = "active"; }; cpu-crit-0 { - temperature = <1200000>; /* millicelsius */ + temperature = <120000>; /* millicelsius */ hysteresis = <0>; /* millicelsius */ type = "critical"; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index f67b23f303c3..45317538bbae 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -536,6 +536,7 @@ clock-names = "dp"; phys = <&dp_phy>; phy-names = "dp"; + power-domains = <&disp_pd>; }; mipi_phy: video-phy@10040714 { diff --git a/arch/arm/boot/dts/exynos5440-trip-points.dtsi b/arch/arm/boot/dts/exynos5440-trip-points.dtsi index 48adfa8f4300..356e963edf11 100644 --- a/arch/arm/boot/dts/exynos5440-trip-points.dtsi +++ b/arch/arm/boot/dts/exynos5440-trip-points.dtsi @@ -18,7 +18,7 @@ trips { type = "active"; }; cpu-crit-0 { - temperature = <1050000>; /* millicelsius */ + temperature = <105000>; /* millicelsius */ hysteresis = <0>; /* millicelsius */ type = "critical"; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 412f41d62686..02eb8b15374f 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -674,6 +674,7 @@ num-slots = <1>; broken-cd; cap-sdio-irq; + keep-power-in-suspend; card-detect-delay = <200>; clock-frequency = <400000000>; samsung,dw-mshc-ciu-div = <1>; diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts index 7e6eef2488e8..82045398bf1f 100644 --- a/arch/arm/boot/dts/imx23-olinuxino.dts +++ b/arch/arm/boot/dts/imx23-olinuxino.dts @@ -12,6 +12,7 @@ */ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> #include "imx23.dtsi" / { @@ -93,6 +94,7 @@ ahb@80080000 { usb0: usb@80080000 { + dr_mode = "host"; vbus-supply = <®_usb0_vbus>; status = "okay"; }; @@ -122,7 +124,7 @@ user { label = "green"; - gpios = <&gpio2 1 1>; + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; }; }; }; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index e4d3aecc4ed2..677f81d9dcd5 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -428,6 +428,7 @@ pwm4: pwm@53fc8000 { compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; + #pwm-cells = <2>; reg = <0x53fc8000 0x4000>; clocks = <&clks 108>, <&clks 52>; clock-names = "ipg", "per"; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 6951b66d1ab7..bc215e4b75fd 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -533,7 +533,7 @@ fec: ethernet@1002b000 { compatible = "fsl,imx27-fec"; - reg = <0x1002b000 0x4000>; + reg = <0x1002b000 0x1000>; interrupts = <50>; clocks = <&clks IMX27_CLK_FEC_IPG_GATE>, <&clks IMX27_CLK_FEC_AHB_GATE>; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 25e25f82fbae..4e073e854742 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -913,7 +913,7 @@ 80 81 68 69 70 71 72 73 74 75 76 77>; - interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty", + interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty", "saif0", "saif1", "i2c0", "i2c1", "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx", "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx"; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 19cc269a08d4..1ce6133b67f5 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -31,6 +31,7 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio4 15 0>; + enable-active-high; }; reg_usb_h1_vbus: regulator@1 { @@ -40,6 +41,7 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio1 0 0>; + enable-active-high; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi index 46b2fed7c319..3b24b12651b2 100644 --- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi @@ -185,7 +185,6 @@ &i2c3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; - pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>; status = "okay"; max7310_a: gpio@30 { diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts index 134d3f27a8ec..921de6605f07 100644 --- a/arch/arm/boot/dts/omap3-devkit8000.dts +++ b/arch/arm/boot/dts/omap3-devkit8000.dts @@ -110,6 +110,8 @@ nand@0,0 { reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <16>; + gpmc,device-width = <2>; + ti,nand-ecc-opt = "sw"; gpmc,sync-clk-ps = <0>; gpmc,cs-on-ns = <0>; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index a29315833ecd..5c16145920ea 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -498,6 +498,8 @@ DRVDD-supply = <&vmmc2>; IOVDD-supply = <&vio>; DVDD-supply = <&vio>; + + ai3x-micbias-vg = <1>; }; tlv320aic3x_aux: tlv320aic3x@19 { @@ -509,6 +511,8 @@ DRVDD-supply = <&vmmc2>; IOVDD-supply = <&vio>; DVDD-supply = <&vio>; + + ai3x-micbias-vg = <2>; }; tsl2563: tsl2563@29 { diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index d18a90f5eca3..69a40cfc1f29 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -456,6 +456,7 @@ }; mmu_isp: mmu@480bd400 { + #iommu-cells = <0>; compatible = "ti,omap2-iommu"; reg = <0x480bd400 0x80>; interrupts = <24>; @@ -464,6 +465,7 @@ }; mmu_iva: mmu@5d000000 { + #iommu-cells = <0>; compatible = "ti,omap2-iommu"; reg = <0x5d000000 0x80>; interrupts = <28>; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index efe5f737f39b..7d24ae0306b5 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -128,7 +128,7 @@ * hierarchy. */ ocp { - compatible = "ti,omap4-l3-noc", "simple-bus"; + compatible = "ti,omap5-l3-noc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 74c3212f1f11..824ddab9c3ad 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -545,7 +545,7 @@ compatible = "adi,adv7511w"; reg = <0x39>; interrupt-parent = <&gpio3>; - interrupts = <29 IRQ_TYPE_EDGE_FALLING>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; adi,input-depth = <8>; adi,input-colorspace = "rgb"; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index bfd3f1c734b8..2201cd5da3bb 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -1017,23 +1017,6 @@ status = "disabled"; }; - vmmci: regulator-gpio { - compatible = "regulator-gpio"; - - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2900000>; - regulator-name = "mmci-reg"; - regulator-type = "voltage"; - - startup-delay-us = <100>; - enable-active-high; - - states = <1800000 0x1 - 2900000 0x0>; - - status = "disabled"; - }; - mcde@a0350000 { compatible = "stericsson,mcde"; reg = <0xa0350000 0x1000>, /* MCDE */ diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index bf8f0eddc2c0..744c1e3a744d 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -111,6 +111,21 @@ pinctrl-1 = <&i2c3_sleep_mode>; }; + vmmci: regulator-gpio { + compatible = "regulator-gpio"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-name = "mmci-reg"; + regulator-type = "voltage"; + + startup-delay-us = <100>; + enable-active-high; + + states = <1800000 0x1 + 2900000 0x0>; + }; + // External Micro SD slot sdi0_per1@80126000 { arm,primecell-periphid = <0x10480180>; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index 206826a855c0..1bc84ebdccaa 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -146,8 +146,21 @@ }; vmmci: regulator-gpio { + compatible = "regulator-gpio"; + gpios = <&gpio7 4 0x4>; enable-gpio = <&gpio6 25 0x4>; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-name = "mmci-reg"; + regulator-type = "voltage"; + + startup-delay-us = <100>; + enable-active-high; + + states = <1800000 0x1 + 2900000 0x0>; }; // External Micro SD slot diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index cf01c818b8ea..13cc7ca5e031 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -826,7 +826,7 @@ <&tegra_car TEGRA124_CLK_PLL_U>, <&tegra_car TEGRA124_CLK_USBD>; clock-names = "reg", "pll_u", "utmi-pads"; - resets = <&tegra_car 59>, <&tegra_car 22>; + resets = <&tegra_car 22>, <&tegra_car 22>; reset-names = "usb", "utmi-pads"; nvidia,hssync-start-delay = <0>; nvidia,idle-wait-delay = <17>; @@ -838,6 +838,7 @@ nvidia,hssquelch-level = <2>; nvidia,hsdiscon-level = <5>; nvidia,xcvr-hsslew = <12>; + nvidia,has-utmi-pad-registers; status = "disabled"; }; @@ -862,7 +863,7 @@ <&tegra_car TEGRA124_CLK_PLL_U>, <&tegra_car TEGRA124_CLK_USBD>; clock-names = "reg", "pll_u", "utmi-pads"; - resets = <&tegra_car 22>, <&tegra_car 22>; + resets = <&tegra_car 58>, <&tegra_car 22>; reset-names = "usb", "utmi-pads"; nvidia,hssync-start-delay = <0>; nvidia,idle-wait-delay = <17>; @@ -874,7 +875,6 @@ nvidia,hssquelch-level = <2>; nvidia,hsdiscon-level = <5>; nvidia,xcvr-hsslew = <12>; - nvidia,has-utmi-pad-registers; status = "disabled"; }; @@ -899,7 +899,7 @@ <&tegra_car TEGRA124_CLK_PLL_U>, <&tegra_car TEGRA124_CLK_USBD>; clock-names = "reg", "pll_u", "utmi-pads"; - resets = <&tegra_car 58>, <&tegra_car 22>; + resets = <&tegra_car 59>, <&tegra_car 22>; reset-names = "usb", "utmi-pads"; nvidia,hssync-start-delay = <0>; nvidia,idle-wait-delay = <17>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 7a2aeacd62c0..107395c32d82 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -191,6 +191,7 @@ compatible = "arm,cortex-a15-pmu"; interrupts = <0 68 4>, <0 69 4>; + interrupt-affinity = <&cpu0>, <&cpu1>; }; oscclk6a: oscclk6a { diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts index 23662b5a5e9d..d949facba376 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -33,28 +33,28 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + A9_0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <0>; next-level-cache = <&L2>; }; - cpu@1 { + A9_1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <1>; next-level-cache = <&L2>; }; - cpu@2 { + A9_2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <2>; next-level-cache = <&L2>; }; - cpu@3 { + A9_3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <3>; @@ -170,6 +170,7 @@ compatible = "arm,pl310-cache"; reg = <0x1e00a000 0x1000>; interrupts = <0 43 4>; + cache-unified; cache-level = <2>; arm,data-latency = <1 1 1>; arm,tag-latency = <1 1 1>; @@ -181,6 +182,8 @@ <0 61 4>, <0 62 4>, <0 63 4>; + interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>; + }; dcc { diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index a5cd2eda3edf..9ea54b3dba09 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -193,7 +193,7 @@ }; gem0: ethernet@e000b000 { - compatible = "cdns,gem"; + compatible = "cdns,zynq-gem"; reg = <0xe000b000 0x1000>; status = "disabled"; interrupts = <0 22 4>; @@ -204,7 +204,7 @@ }; gem1: ethernet@e000c000 { - compatible = "cdns,gem"; + compatible = "cdns,zynq-gem"; reg = <0xe000c000 0x1000>; status = "disabled"; interrupts = <0 45 4>; diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index ab86655c1f4b..fbbb1915c6a9 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -39,11 +39,14 @@ CONFIG_ARCH_HIP04=y CONFIG_ARCH_KEYSTONE=y CONFIG_ARCH_MESON=y CONFIG_ARCH_MXC=y +CONFIG_SOC_IMX50=y CONFIG_SOC_IMX51=y CONFIG_SOC_IMX53=y CONFIG_SOC_IMX6Q=y CONFIG_SOC_IMX6SL=y +CONFIG_SOC_IMX6SX=y CONFIG_SOC_VF610=y +CONFIG_SOC_LS1021A=y CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y CONFIG_SOC_OMAP5=y @@ -426,7 +429,7 @@ CONFIG_USB_EHCI_EXYNOS=y CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_EHCI_HCD_STI=y CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_ISP1760=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_STI=y CONFIG_USB_OHCI_HCD_PLATFORM=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 9ff7b54b2a83..3743ca221d40 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -393,7 +393,7 @@ CONFIG_TI_EDMA=y CONFIG_DMA_OMAP=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXTCON=m -CONFIG_EXTCON_GPIO=m +CONFIG_EXTCON_USB_GPIO=m CONFIG_EXTCON_PALMAS=m CONFIG_TI_EMIF=m CONFIG_PWM=y diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index 8e3fcb924db6..2ef282f96651 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -25,7 +25,7 @@ struct dma_iommu_mapping { }; struct dma_iommu_mapping * -arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size); +arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size); void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index 2f7e6ff67d51..0b579b2f4e0e 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h @@ -110,5 +110,6 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) bool xen_arch_need_swiotlb(struct device *dev, unsigned long pfn, unsigned long mfn); +unsigned long xen_get_swiotlb_free_pages(unsigned int order); #endif /* _ASM_ARM_XEN_PAGE_H */ diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f8ccc21fa032..4e7f40c577e6 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -33,7 +33,9 @@ ret_fast_syscall: UNWIND(.fnstart ) UNWIND(.cantunwind ) disable_irq @ disable interrupts - ldr r1, [tsk, #TI_FLAGS] + ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing + tst r1, #_TIF_SYSCALL_WORK + bne __sys_trace_return tst r1, #_TIF_WORK_MASK bne fast_work_pending asm_trace_hardirqs_on diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index 91c7ba182dcd..3b8c2833c537 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -303,9 +303,15 @@ static int probe_current_pmu(struct arm_pmu *pmu) static int of_pmu_irq_cfg(struct platform_device *pdev) { - int i; - int *irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); + int i, irq; + int *irqs; + /* Don't bother with PPIs; they're already affine */ + irq = platform_get_irq(pdev, 0); + if (irq >= 0 && irq_is_percpu(irq)) + return 0; + + irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); if (!irqs) return -ENOMEM; @@ -317,7 +323,7 @@ static int of_pmu_irq_cfg(struct platform_device *pdev) i); if (!dn) { pr_warn("Failed to parse %s/interrupt-affinity[%d]\n", - of_node_full_name(dn), i); + of_node_full_name(pdev->dev.of_node), i); break; } diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index acd5b560b728..5f5cd562c593 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -159,6 +159,8 @@ extern void exynos_enter_aftr(void); extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data; +extern void exynos_set_delayed_reset_assertion(bool enable); + extern void s5p_init_cpu(void __iomem *cpuid_addr); extern unsigned int samsung_rev(void); extern void __iomem *cpu_boot_reg_base(void); diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index bcde0dd668df..5917a30eee33 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -167,6 +167,33 @@ static void __init exynos_init_io(void) } /* + * Set or clear the USE_DELAYED_RESET_ASSERTION option. Used by smp code + * and suspend. + * + * This is necessary only on Exynos4 SoCs. When system is running + * USE_DELAYED_RESET_ASSERTION should be set so the ARM CLK clock down + * feature could properly detect global idle state when secondary CPU is + * powered down. + * + * However this should not be set when such system is going into suspend. + */ +void exynos_set_delayed_reset_assertion(bool enable) +{ + if (of_machine_is_compatible("samsung,exynos4")) { + unsigned int tmp, core_id; + + for (core_id = 0; core_id < num_possible_cpus(); core_id++) { + tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id)); + if (enable) + tmp |= S5P_USE_DELAYED_RESET_ASSERTION; + else + tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION); + pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id)); + } + } +} + +/* * Apparently, these SoCs are not able to wake-up from suspend using * the PMU. Too bad. Should they suddenly become capable of such a * feat, the matches below should be moved to suspend.c. diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index ebd135bb0995..a825bca2a2b6 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -34,30 +34,6 @@ extern void exynos4_secondary_startup(void); -/* - * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs - * during hot-(un)plugging CPUx. - * - * The feature can be cleared safely during first boot of secondary CPU. - * - * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering - * down a CPU so the CPU idle clock down feature could properly detect global - * idle state when CPUx is off. - */ -static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable) -{ - if (soc_is_exynos4()) { - unsigned int tmp; - - tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id)); - if (enable) - tmp |= S5P_USE_DELAYED_RESET_ASSERTION; - else - tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION); - pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id)); - } -} - #ifdef CONFIG_HOTPLUG_CPU static inline void cpu_leave_lowpower(u32 core_id) { @@ -73,8 +49,6 @@ static inline void cpu_leave_lowpower(u32 core_id) : "=&r" (v) : "Ir" (CR_C), "Ir" (0x40) : "cc"); - - exynos_set_delayed_reset_assertion(core_id, false); } static inline void platform_do_lowpower(unsigned int cpu, int *spurious) @@ -87,14 +61,6 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) /* Turn the CPU off on next WFI instruction. */ exynos_cpu_power_down(core_id); - /* - * Exynos4 SoCs require setting - * USE_DELAYED_RESET_ASSERTION so the CPU idle - * clock down feature could properly detect - * global idle state when CPUx is off. - */ - exynos_set_delayed_reset_assertion(core_id, true); - wfi(); if (pen_release == core_id) { @@ -371,9 +337,6 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) udelay(10); } - /* No harm if this is called during first boot of secondary CPU */ - exynos_set_delayed_reset_assertion(core_id, false); - /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish @@ -420,6 +383,8 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) exynos_sysram_init(); + exynos_set_delayed_reset_assertion(true); + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) scu_enable(scu_base_addr()); diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index cbe56b35aea0..a9686535f9ed 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -188,7 +188,7 @@ no_clk: args.np = np; args.args_count = 0; child_domain = of_genpd_get_from_provider(&args); - if (!child_domain) + if (IS_ERR(child_domain)) continue; if (of_parse_phandle_with_args(np, "power-domains", @@ -196,7 +196,7 @@ no_clk: continue; parent_domain = of_genpd_get_from_provider(&args); - if (!parent_domain) + if (IS_ERR(parent_domain)) continue; if (pm_genpd_add_subdomain(parent_domain, child_domain)) diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 3e6aea7f83af..c0b6dccbf7bd 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -342,6 +342,8 @@ static void exynos_pm_enter_sleep_mode(void) static void exynos_pm_prepare(void) { + exynos_set_delayed_reset_assertion(false); + /* Set wake-up mask registers */ exynos_pm_set_wakeup_mask(); @@ -482,6 +484,7 @@ early_wakeup: /* Clear SLEEP mode set in INFORM1 */ pmu_raw_writel(0x0, S5P_INFORM1); + exynos_set_delayed_reset_assertion(true); } static void exynos3250_pm_resume(void) @@ -723,8 +726,10 @@ void __init exynos_pm_init(void) return; } - if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) + if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) { pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); + return; + } pm_data = (const struct exynos_pm_data *) match->data; diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h index 38a45260a7c8..dd883698ff7e 100644 --- a/arch/arm/mach-gemini/common.h +++ b/arch/arm/mach-gemini/common.h @@ -12,6 +12,8 @@ #ifndef __GEMINI_COMMON_H__ #define __GEMINI_COMMON_H__ +#include <linux/reboot.h> + struct mtd_partition; extern void gemini_map_io(void); @@ -26,6 +28,6 @@ extern int platform_register_pflash(unsigned int size, struct mtd_partition *parts, unsigned int nr_parts); -extern void gemini_restart(char mode, const char *cmd); +extern void gemini_restart(enum reboot_mode mode, const char *cmd); #endif /* __GEMINI_COMMON_H__ */ diff --git a/arch/arm/mach-gemini/reset.c b/arch/arm/mach-gemini/reset.c index b26659759e27..21a6d6d4f9c4 100644 --- a/arch/arm/mach-gemini/reset.c +++ b/arch/arm/mach-gemini/reset.c @@ -14,7 +14,9 @@ #include <mach/hardware.h> #include <mach/global_reg.h> -void gemini_restart(char mode, const char *cmd) +#include "common.h" + +void gemini_restart(enum reboot_mode mode, const char *cmd) { __raw_writel(RESET_GLOBAL | RESET_CPU1, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET); diff --git a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c index fb8d4a2ad48c..a5edd7d60266 100644 --- a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c +++ b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de> + * Copyright (C) 2010 Pengutronix, Wolfram Sang <kernel@pengutronix.de> * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 4d60005e9277..6d0893a3828e 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -280,9 +280,15 @@ void __init imx_gpc_check_dt(void) struct device_node *np; np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); - if (WARN_ON(!np || - !of_find_property(np, "interrupt-controller", NULL))) - pr_warn("Outdated DT detected, system is about to crash!!!\n"); + if (WARN_ON(!np)) + return; + + if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) { + pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); + + /* map GPC, so that at least CPUidle and WARs keep working */ + gpc_base = of_iomap(np, 0); + } } #ifdef CONFIG_PM_GENERIC_DOMAINS @@ -443,6 +449,10 @@ static int imx_gpc_probe(struct platform_device *pdev) struct regulator *pu_reg; int ret; + /* bail out if DT too old and doesn't provide the necessary info */ + if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells")) + return 0; + pu_reg = devm_regulator_get_optional(&pdev->dev, "pu"); if (PTR_ERR(pu_reg) == -ENODEV) pu_reg = NULL; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 355b08936871..752969ff9de0 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -171,6 +171,12 @@ */ #define LINKS_PER_OCP_IF 2 +/* + * Address offset (in bytes) between the reset control and the reset + * status registers: 4 bytes on OMAP4 + */ +#define OMAP4_RST_CTRL_ST_OFFSET 4 + /** * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations * @enable_module: function to enable a module (via MODULEMODE) @@ -3016,10 +3022,12 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh, if (ohri->st_shift) pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", oh->name, ohri->name); - return omap_prm_deassert_hardreset(ohri->rst_shift, 0, + return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift, oh->clkdm->pwrdm.ptr->prcm_partition, oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs, 0); + oh->prcm.omap4.rstctrl_offs, + oh->prcm.omap4.rstctrl_offs + + OMAP4_RST_CTRL_ST_OFFSET); } /** @@ -3048,27 +3056,6 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, } /** - * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args - * @oh: struct omap_hwmod * to assert hardreset - * @ohri: hardreset line data - * - * Call am33xx_prminst_assert_hardreset() with parameters extracted - * from the hwmod @oh and the hardreset line data @ohri. Only - * intended for use as an soc_ops function pointer. Passes along the - * return value from am33xx_prminst_assert_hardreset(). XXX This - * function is scheduled for removal when the PRM code is moved into - * drivers/. - */ -static int _am33xx_assert_hardreset(struct omap_hwmod *oh, - struct omap_hwmod_rst_info *ohri) - -{ - return omap_prm_assert_hardreset(ohri->rst_shift, 0, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); -} - -/** * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args * @oh: struct omap_hwmod * to deassert hardreset * @ohri: hardreset line data @@ -3083,32 +3070,13 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0, + return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, oh->clkdm->pwrdm.ptr->prcm_offs, oh->prcm.omap4.rstctrl_offs, oh->prcm.omap4.rstst_offs); } -/** - * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args - * @oh: struct omap_hwmod * to test hardreset - * @ohri: hardreset line data - * - * Call am33xx_prminst_is_hardreset_asserted() with parameters - * extracted from the hwmod @oh and the hardreset line data @ohri. - * Only intended for use as an soc_ops function pointer. Passes along - * the return value from am33xx_prminst_is_hardreset_asserted(). XXX - * This function is scheduled for removal when the PRM code is moved - * into drivers/. - */ -static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, - struct omap_hwmod_rst_info *ohri) -{ - return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); -} - /* Public functions */ u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) @@ -3908,21 +3876,13 @@ void __init omap_hwmod_init(void) soc_ops.init_clkdm = _init_clkdm; soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; - } else if (soc_is_am43xx()) { + } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) { soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module; soc_ops.wait_target_ready = _omap4_wait_target_ready; soc_ops.assert_hardreset = _omap4_assert_hardreset; - soc_ops.deassert_hardreset = _omap4_deassert_hardreset; - soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; - soc_ops.init_clkdm = _init_clkdm; - } else if (cpu_is_ti816x() || soc_is_am33xx()) { - soc_ops.enable_module = _omap4_enable_module; - soc_ops.disable_module = _omap4_disable_module; - soc_ops.wait_target_ready = _omap4_wait_target_ready; - soc_ops.assert_hardreset = _am33xx_assert_hardreset; soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; - soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; + soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; soc_ops.init_clkdm = _init_clkdm; } else { WARN(1, "omap_hwmod: unknown SoC type\n"); diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index e2223148ba4d..17e8004fc20f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -544,6 +544,44 @@ static struct omap_hwmod am43xx_hdq1w_hwmod = { }, }; +static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x104, + .sysc_flags = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_vpfe_hwmod_class = { + .name = "vpfe", + .sysc = &am43xx_vpfe_sysc, +}; + +static struct omap_hwmod am43xx_vpfe0_hwmod = { + .name = "vpfe0", + .class = &am43xx_vpfe_hwmod_class, + .clkdm_name = "l3s_clkdm", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + .clkctrl_offs = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET, + }, + }, +}; + +static struct omap_hwmod am43xx_vpfe1_hwmod = { + .name = "vpfe1", + .class = &am43xx_vpfe_hwmod_class, + .clkdm_name = "l3s_clkdm", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + .clkctrl_offs = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET, + }, + }, +}; + /* Interfaces */ static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { .master = &am33xx_l3_main_hwmod, @@ -825,6 +863,34 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = { + .master = &am43xx_vpfe0_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = { + .master = &am43xx_vpfe1_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_vpfe0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_vpfe1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_wkup__synctimer, &am43xx_l4_ls__timer8, @@ -925,6 +991,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am43xx_l4_ls__dss_dispc, &am43xx_l4_ls__dss_rfbi, &am43xx_l4_ls__hdq1w, + &am43xx_l3__vpfe0, + &am43xx_l3__vpfe1, + &am43xx_l4_ls__vpfe0, + &am43xx_l4_ls__vpfe1, NULL, }; diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h index 48df3b55057e..d0261996db6d 100644 --- a/arch/arm/mach-omap2/prcm43xx.h +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -144,5 +144,6 @@ #define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0 #define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET 0x0a20 #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0 - +#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068 +#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070 #endif diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index cbefbd7cfdb5..661d753df584 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -112,6 +112,7 @@ #define OMAP3430_VC_CMD_ONLP_SHIFT 16 #define OMAP3430_VC_CMD_RET_SHIFT 8 #define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4) #define OMAP3430_HSEN_MASK (1 << 3) #define OMAP3430_MCODE_MASK (0x7 << 0) #define OMAP3430_VALID_MASK (1 << 24) diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h index b1c7a33e00e7..e794828dee55 100644 --- a/arch/arm/mach-omap2/prm-regbits-44xx.h +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -35,6 +35,7 @@ #define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1 #define OMAP4430_GLOBAL_WUEN_MASK (1 << 16) #define OMAP4430_HSMCODE_MASK (0x7 << 0) +#define OMAP4430_SRMODEEN_MASK (1 << 4) #define OMAP4430_HSMODEEN_MASK (1 << 3) #define OMAP4430_HSSCLL_SHIFT 24 #define OMAP4430_ICEPICK_RST_SHIFT 9 diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index c4859c4d3646..d0b15dbafa2e 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -87,12 +87,6 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, return v; } -/* - * Address offset (in bytes) between the reset control and the reset - * status registers: 4 bytes on OMAP4 - */ -#define OMAP4_RST_CTRL_ST_OFFSET 4 - /** * omap4_prminst_is_hardreset_asserted - read the HW reset line state of * submodules contained in the hwmod module @@ -141,11 +135,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and * wait * @shift: register bit shift corresponding to the reset line to deassert - * @st_shift: status bit offset, not used for OMAP4+ + * @st_shift: status bit offset corresponding to the reset line * @part: PRM partition * @inst: PRM instance offset * @rstctrl_offs: reset register offset - * @st_offs: reset status register offset, not used for OMAP4+ + * @rstst_offs: reset status register offset * * Some IPs like dsp, ipu or iva contain processors that require an HW * reset line to be asserted / deasserted in order to fully enable the @@ -157,11 +151,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, * of reset, or -EBUSY if the submodule did not exit reset promptly. */ int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst, - u16 rstctrl_offs, u16 st_offs) + u16 rstctrl_offs, u16 rstst_offs) { int c; u32 mask = 1 << shift; - u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET; + u32 st_mask = 1 << st_shift; /* Check the current status to avoid de-asserting the line twice */ if (omap4_prminst_is_hardreset_asserted(shift, part, inst, @@ -169,13 +163,13 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst, return -EEXIST; /* Clear the reset status by writing 1 to the status bit */ - omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst, + omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst, rstst_offs); /* de-assert the reset control line */ omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs); /* wait the status to be set */ - omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst, - rstst_offs), + omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part, + inst, rstst_offs), MAX_MODULE_HARDRESET_WAIT, c); return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index cef67af9e9b8..cac46d852da1 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -298,14 +298,11 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (IS_ERR(src)) return PTR_ERR(src); - if (clk_get_parent(timer->fclk) != src) { - r = clk_set_parent(timer->fclk, src); - if (r < 0) { - pr_warn("%s: %s cannot set source\n", __func__, - oh->name); - clk_put(src); - return r; - } + r = clk_set_parent(timer->fclk, src); + if (r < 0) { + pr_warn("%s: %s cannot set source\n", __func__, oh->name); + clk_put(src); + return r; } clk_put(src); diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index be9ef834fa81..076fd20d7e5a 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm) * idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are - * loaded. + * loaded. See also omap_vc_i2c_init for comments regarding + * erratum i531. */ val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) { @@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) return; } + /* + * Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around + * erratum i531 "Extra Power Consumed When Repeated Start Operation + * Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". + * Otherwise I2C4 eventually leads into about 23mW extra power being + * consumed even during off idle using VMODE. + */ i2c_high_speed = voltdm->pmic->i2c_high_speed; if (i2c_high_speed) - voltdm->rmw(vc->common->i2c_cfg_hsen_mask, + voltdm->rmw(vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg); diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h index cdbdd78e755e..89b83b7ff3ec 100644 --- a/arch/arm/mach-omap2/vc.h +++ b/arch/arm/mach-omap2/vc.h @@ -34,6 +34,7 @@ struct voltagedomain; * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset + * @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register * @@ -52,6 +53,7 @@ struct omap_vc_common { u8 cmd_ret_shift; u8 cmd_off_shift; u8 i2c_cfg_reg; + u8 i2c_cfg_clear_mask; u8 i2c_cfg_hsen_mask; u8 i2c_mcode_mask; }; diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c index 75bc4aa22b3a..71d74c9172c1 100644 --- a/arch/arm/mach-omap2/vc3xxx_data.c +++ b/arch/arm/mach-omap2/vc3xxx_data.c @@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK, .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK, diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c index 085e5d6a04fd..2abd5fa8a697 100644 --- a/arch/arm/mach-omap2/vc44xx_data.c +++ b/arch/arm/mach-omap2/vc44xx_data.c @@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK | OMAP4430_HSMODEEN_MASK, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, }; diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 8896e71586f5..f09683687963 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -691,4 +691,13 @@ config SHARPSL_PM_MAX1111 config PXA310_ULPI bool +config PXA_SYSTEMS_CPLDS + tristate "Motherboard cplds" + default ARCH_LUBBOCK || MACH_MAINSTONE + help + This driver supports the Lubbock and Mainstone multifunction chip + found on the pxa25x development platform system (Lubbock) and pxa27x + development platform system (Mainstone). This IO board supports the + interrupts handling, ethernet controller, flash chips, etc ... + endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index eb0bf7678a99..4087d334ecdf 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -90,4 +90,5 @@ obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o obj-$(CONFIG_MACH_ZIPIT2) += z2.o +obj-$(CONFIG_PXA_SYSTEMS_CPLDS) += pxa_cplds_irqs.o obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h index 958cd6af9384..1eecf794acd2 100644 --- a/arch/arm/mach-pxa/include/mach/lubbock.h +++ b/arch/arm/mach-pxa/include/mach/lubbock.h @@ -37,7 +37,9 @@ #define LUB_GP __LUB_REG(LUBBOCK_FPGA_PHYS + 0x100) /* Board specific IRQs */ -#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x)) +#define LUBBOCK_NR_IRQS IRQ_BOARD_START + +#define LUBBOCK_IRQ(x) (LUBBOCK_NR_IRQS + (x)) #define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0) #define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1) #define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */ @@ -47,8 +49,7 @@ #define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */ #define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6) -#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16) -#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55) +#define LUBBOCK_SA1111_IRQ_BASE (LUBBOCK_NR_IRQS + 32) #ifndef __ASSEMBLY__ extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set); diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 1bfc4e822a41..e82a7d31104e 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -120,7 +120,9 @@ #define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */ /* board specific IRQs */ -#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x)) +#define MAINSTONE_NR_IRQS IRQ_BOARD_START + +#define MAINSTONE_IRQ(x) (MAINSTONE_NR_IRQS + (x)) #define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0) #define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1) #define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2) @@ -136,6 +138,4 @@ #define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14) #define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15) -#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16) - #endif diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index d8a1be619f21..4ac9ab80d24b 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -123,84 +124,6 @@ void lubbock_set_misc_wr(unsigned int mask, unsigned int set) } EXPORT_SYMBOL(lubbock_set_misc_wr); -static unsigned long lubbock_irq_enabled; - -static void lubbock_mask_irq(struct irq_data *d) -{ - int lubbock_irq = (d->irq - LUBBOCK_IRQ(0)); - LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq)); -} - -static void lubbock_unmask_irq(struct irq_data *d) -{ - int lubbock_irq = (d->irq - LUBBOCK_IRQ(0)); - /* the irq can be acknowledged only if deasserted, so it's done here */ - LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq); - LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq)); -} - -static struct irq_chip lubbock_irq_chip = { - .name = "FPGA", - .irq_ack = lubbock_mask_irq, - .irq_mask = lubbock_mask_irq, - .irq_unmask = lubbock_unmask_irq, -}; - -static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; - do { - /* clear our parent irq */ - desc->irq_data.chip->irq_ack(&desc->irq_data); - if (likely(pending)) { - irq = LUBBOCK_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); - } - pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; - } while (pending); -} - -static void __init lubbock_init_irq(void) -{ - int irq; - - pxa25x_init_irq(); - - /* setup extra lubbock irqs */ - for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { - irq_set_chip_and_handler(irq, &lubbock_irq_chip, - handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lubbock_irq_handler); - irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); -} - -#ifdef CONFIG_PM - -static void lubbock_irq_resume(void) -{ - LUB_IRQ_MASK_EN = lubbock_irq_enabled; -} - -static struct syscore_ops lubbock_irq_syscore_ops = { - .resume = lubbock_irq_resume, -}; - -static int __init lubbock_irq_device_init(void) -{ - if (machine_is_lubbock()) { - register_syscore_ops(&lubbock_irq_syscore_ops); - return 0; - } - return -ENODEV; -} - -device_initcall(lubbock_irq_device_init); - -#endif - static int lubbock_udc_is_connected(void) { return (LUB_MISC_RD & (1 << 9)) == 0; @@ -383,11 +306,38 @@ static struct platform_device lubbock_flash_device[2] = { }, }; +static struct resource lubbock_cplds_resources[] = { + [0] = { + .start = LUBBOCK_FPGA_PHYS + 0xc0, + .end = LUBBOCK_FPGA_PHYS + 0xe0 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(0), + .end = PXA_GPIO_TO_IRQ(0), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, + [2] = { + .start = LUBBOCK_IRQ(0), + .end = LUBBOCK_IRQ(6), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device lubbock_cplds_device = { + .name = "pxa_cplds_irqs", + .id = -1, + .resource = &lubbock_cplds_resources[0], + .num_resources = 3, +}; + + static struct platform_device *devices[] __initdata = { &sa1111_device, &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], + &lubbock_cplds_device, }; static struct pxafb_mode_info sharp_lm8v31_mode = { @@ -648,7 +598,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") /* Maintainer: MontaVista Software Inc. */ .map_io = lubbock_map_io, .nr_irqs = LUBBOCK_NR_IRQS, - .init_irq = lubbock_init_irq, + .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_time = pxa_timer_init, .init_machine = lubbock_init, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 78b84c0dfc79..2c0658cf6be2 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -13,6 +13,7 @@ * published by the Free Software Foundation. */ #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/syscore_ops.h> @@ -122,92 +123,6 @@ static unsigned long mainstone_pin_config[] = { GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, }; -static unsigned long mainstone_irq_enabled; - -static void mainstone_mask_irq(struct irq_data *d) -{ - int mainstone_irq = (d->irq - MAINSTONE_IRQ(0)); - MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq)); -} - -static void mainstone_unmask_irq(struct irq_data *d) -{ - int mainstone_irq = (d->irq - MAINSTONE_IRQ(0)); - /* the irq can be acknowledged only if deasserted, so it's done here */ - MST_INTSETCLR &= ~(1 << mainstone_irq); - MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq)); -} - -static struct irq_chip mainstone_irq_chip = { - .name = "FPGA", - .irq_ack = mainstone_mask_irq, - .irq_mask = mainstone_mask_irq, - .irq_unmask = mainstone_unmask_irq, -}; - -static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; - do { - /* clear useless edge notification */ - desc->irq_data.chip->irq_ack(&desc->irq_data); - if (likely(pending)) { - irq = MAINSTONE_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); - } - pending = MST_INTSETCLR & mainstone_irq_enabled; - } while (pending); -} - -static void __init mainstone_init_irq(void) -{ - int irq; - - pxa27x_init_irq(); - - /* setup extra Mainstone irqs */ - for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { - irq_set_chip_and_handler(irq, &mainstone_irq_chip, - handle_level_irq); - if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); - else - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - set_irq_flags(MAINSTONE_IRQ(8), 0); - set_irq_flags(MAINSTONE_IRQ(12), 0); - - MST_INTMSKENA = 0; - MST_INTSETCLR = 0; - - irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), mainstone_irq_handler); - irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING); -} - -#ifdef CONFIG_PM - -static void mainstone_irq_resume(void) -{ - MST_INTMSKENA = mainstone_irq_enabled; -} - -static struct syscore_ops mainstone_irq_syscore_ops = { - .resume = mainstone_irq_resume, -}; - -static int __init mainstone_irq_device_init(void) -{ - if (machine_is_mainstone()) - register_syscore_ops(&mainstone_irq_syscore_ops); - - return 0; -} - -device_initcall(mainstone_irq_device_init); - -#endif - - static struct resource smc91x_resources[] = { [0] = { .start = (MST_ETH_PHYS + 0x300), @@ -487,11 +402,37 @@ static struct platform_device mst_gpio_keys_device = { }, }; +static struct resource mst_cplds_resources[] = { + [0] = { + .start = MST_FPGA_PHYS + 0xc0, + .end = MST_FPGA_PHYS + 0xe0 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_GPIO_TO_IRQ(0), + .end = PXA_GPIO_TO_IRQ(0), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, + [2] = { + .start = MAINSTONE_IRQ(0), + .end = MAINSTONE_IRQ(15), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mst_cplds_device = { + .name = "pxa_cplds_irqs", + .id = -1, + .resource = &mst_cplds_resources[0], + .num_resources = 3, +}; + static struct platform_device *platform_devices[] __initdata = { &smc91x_device, &mst_flash_device[0], &mst_flash_device[1], &mst_gpio_keys_device, + &mst_cplds_device, }; static struct pxaohci_platform_data mainstone_ohci_platform_data = { @@ -718,7 +659,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") .atag_offset = 0x100, /* BLOB boot parameter setting */ .map_io = mainstone_map_io, .nr_irqs = MAINSTONE_NR_IRQS, - .init_irq = mainstone_init_irq, + .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_time = pxa_timer_init, .init_machine = mainstone_init, diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c new file mode 100644 index 000000000000..2385052b0ce1 --- /dev/null +++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c @@ -0,0 +1,200 @@ +/* + * Intel Reference Systems cplds + * + * Copyright (C) 2014 Robert Jarzmik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Cplds motherboard driver, supporting lubbock and mainstone SoC board. + */ + +#include <linux/bitops.h> +#include <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/mfd/core.h> +#include <linux/module.h> +#include <linux/of_platform.h> + +#define FPGA_IRQ_MASK_EN 0x0 +#define FPGA_IRQ_SET_CLR 0x10 + +#define CPLDS_NB_IRQ 32 + +struct cplds { + void __iomem *base; + int irq; + unsigned int irq_mask; + struct gpio_desc *gpio0; + struct irq_domain *irqdomain; +}; + +static irqreturn_t cplds_irq_handler(int in_irq, void *d) +{ + struct cplds *fpga = d; + unsigned long pending; + unsigned int bit; + + pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask; + for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) + generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit)); + + return IRQ_HANDLED; +} + +static void cplds_irq_mask_ack(struct irq_data *d) +{ + struct cplds *fpga = irq_data_get_irq_chip_data(d); + unsigned int cplds_irq = irqd_to_hwirq(d); + unsigned int set, bit = BIT(cplds_irq); + + fpga->irq_mask &= ~bit; + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); + set = readl(fpga->base + FPGA_IRQ_SET_CLR); + writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR); +} + +static void cplds_irq_unmask(struct irq_data *d) +{ + struct cplds *fpga = irq_data_get_irq_chip_data(d); + unsigned int cplds_irq = irqd_to_hwirq(d); + unsigned int bit = BIT(cplds_irq); + + fpga->irq_mask |= bit; + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); +} + +static struct irq_chip cplds_irq_chip = { + .name = "pxa_cplds", + .irq_mask_ack = cplds_irq_mask_ack, + .irq_unmask = cplds_irq_unmask, + .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, +}; + +static int cplds_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + struct cplds *fpga = d->host_data; + + irq_set_chip_and_handler(irq, &cplds_irq_chip, handle_level_irq); + irq_set_chip_data(irq, fpga); + + return 0; +} + +static const struct irq_domain_ops cplds_irq_domain_ops = { + .xlate = irq_domain_xlate_twocell, + .map = cplds_irq_domain_map, +}; + +static int cplds_resume(struct platform_device *pdev) +{ + struct cplds *fpga = platform_get_drvdata(pdev); + + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); + + return 0; +} + +static int cplds_probe(struct platform_device *pdev) +{ + struct resource *res; + struct cplds *fpga; + int ret; + int base_irq; + unsigned long irqflags = 0; + + fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL); + if (!fpga) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res) { + fpga->irq = (unsigned int)res->start; + irqflags = res->flags; + } + if (!fpga->irq) + return -ENODEV; + + base_irq = platform_get_irq(pdev, 1); + if (base_irq < 0) + base_irq = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + fpga->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(fpga->base)) + return PTR_ERR(fpga->base); + + platform_set_drvdata(pdev, fpga); + + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); + writel(0, fpga->base + FPGA_IRQ_SET_CLR); + + ret = devm_request_irq(&pdev->dev, fpga->irq, cplds_irq_handler, + irqflags, dev_name(&pdev->dev), fpga); + if (ret == -ENOSYS) + return -EPROBE_DEFER; + + if (ret) { + dev_err(&pdev->dev, "couldn't request main irq%d: %d\n", + fpga->irq, ret); + return ret; + } + + irq_set_irq_wake(fpga->irq, 1); + fpga->irqdomain = irq_domain_add_linear(pdev->dev.of_node, + CPLDS_NB_IRQ, + &cplds_irq_domain_ops, fpga); + if (!fpga->irqdomain) + return -ENODEV; + + if (base_irq) { + ret = irq_create_strict_mappings(fpga->irqdomain, base_irq, 0, + CPLDS_NB_IRQ); + if (ret) { + dev_err(&pdev->dev, "couldn't create the irq mapping %d..%d\n", + base_irq, base_irq + CPLDS_NB_IRQ); + return ret; + } + } + + return 0; +} + +static int cplds_remove(struct platform_device *pdev) +{ + struct cplds *fpga = platform_get_drvdata(pdev); + + irq_set_chip_and_handler(fpga->irq, NULL, NULL); + + return 0; +} + +static const struct of_device_id cplds_id_table[] = { + { .compatible = "intel,lubbock-cplds-irqs", }, + { .compatible = "intel,mainstone-cplds-irqs", }, + { } +}; +MODULE_DEVICE_TABLE(of, cplds_id_table); + +static struct platform_driver cplds_driver = { + .driver = { + .name = "pxa_cplds_irqs", + .of_match_table = of_match_ptr(cplds_id_table), + }, + .probe = cplds_probe, + .remove = cplds_remove, + .resume = cplds_resume, +}; + +module_platform_driver(cplds_driver); + +MODULE_DESCRIPTION("PXA Cplds interrupts driver"); +MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index b07d88602073..b0dcbe28f78c 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -83,6 +83,13 @@ static void rk3288_slp_mode_set(int level) SGRF_PCLK_WDT_GATE | SGRF_FAST_BOOT_EN | SGRF_PCLK_WDT_GATE_WRITE | SGRF_FAST_BOOT_EN_WRITE); + /* + * The dapswjdp can not auto reset before resume, that cause it may + * access some illegal address during resume. Let's disable it before + * suspend, and the MASKROM will enable it back. + */ + regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, SGRF_DAPDEVICEEN_WRITE); + /* booting address of resuming system is from this register value */ regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR, rk3288_bootram_phy); diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h index 03ff31d8282d..3e8d39c0c3d5 100644 --- a/arch/arm/mach-rockchip/pm.h +++ b/arch/arm/mach-rockchip/pm.h @@ -55,6 +55,10 @@ static inline void rockchip_suspend_init(void) #define SGRF_FAST_BOOT_EN BIT(8) #define SGRF_FAST_BOOT_EN_WRITE BIT(24) +#define RK3288_SGRF_CPU_CON0 (0x40) +#define SGRF_DAPDEVICEEN BIT(0) +#define SGRF_DAPDEVICEEN_WRITE BIT(16) + #define RK3288_CRU_MODE_CON 0x50 #define RK3288_CRU_SEL0_CON 0x60 #define RK3288_CRU_SEL1_CON 0x64 diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index d360ec044b66..b6cf3b449428 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -30,11 +30,30 @@ #include "pm.h" #define RK3288_GRF_SOC_CON0 0x244 +#define RK3288_TIMER6_7_PHYS 0xff810000 static void __init rockchip_timer_init(void) { if (of_machine_is_compatible("rockchip,rk3288")) { struct regmap *grf; + void __iomem *reg_base; + + /* + * Most/all uboot versions for rk3288 don't enable timer7 + * which is needed for the architected timer to work. + * So make sure it is running during early boot. + */ + reg_base = ioremap(RK3288_TIMER6_7_PHYS, SZ_16K); + if (reg_base) { + writel(0, reg_base + 0x30); + writel(0xffffffff, reg_base + 0x20); + writel(0xffffffff, reg_base + 0x24); + writel(1, reg_base + 0x30); + dsb(); + iounmap(reg_base); + } else { + pr_err("rockchip: could not map timer7 registers\n"); + } /* * Disable auto jtag/sdmmc switching that causes issues diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 09c5fe3d30c2..7e7583ddd607 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1878,7 +1878,7 @@ struct dma_map_ops iommu_coherent_ops = { * arm_iommu_attach_device function. */ struct dma_iommu_mapping * -arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size) +arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size) { unsigned int bits = size >> PAGE_SHIFT; unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long); @@ -1886,6 +1886,10 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size) int extensions = 1; int err = -ENOMEM; + /* currently only 32-bit DMA address space is supported */ + if (size > DMA_BIT_MASK(32) + 1) + return ERR_PTR(-ERANGE); + if (!bitmap_size) return ERR_PTR(-EINVAL); @@ -2057,13 +2061,6 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, if (!iommu) return false; - /* - * currently arm_iommu_create_mapping() takes a max of size_t - * for size param. So check this limit for now. - */ - if (size > SIZE_MAX) - return false; - mapping = arm_iommu_create_mapping(dev->bus, dma_base, size); if (IS_ERR(mapping)) { pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n", diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4e6ef896c619..7186382672b5 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1112,22 +1112,22 @@ void __init sanity_check_meminfo(void) } /* - * Find the first non-section-aligned page, and point + * Find the first non-pmd-aligned page, and point * memblock_limit at it. This relies on rounding the - * limit down to be section-aligned, which happens at - * the end of this function. + * limit down to be pmd-aligned, which happens at the + * end of this function. * * With this algorithm, the start or end of almost any - * bank can be non-section-aligned. The only exception - * is that the start of the bank 0 must be section- + * bank can be non-pmd-aligned. The only exception is + * that the start of the bank 0 must be section- * aligned, since otherwise memory would need to be * allocated when mapping the start of bank 0, which * occurs before any free memory is mapped. */ if (!memblock_limit) { - if (!IS_ALIGNED(block_start, SECTION_SIZE)) + if (!IS_ALIGNED(block_start, PMD_SIZE)) memblock_limit = block_start; - else if (!IS_ALIGNED(block_end, SECTION_SIZE)) + else if (!IS_ALIGNED(block_end, PMD_SIZE)) memblock_limit = arm_lowmem_limit; } @@ -1137,12 +1137,12 @@ void __init sanity_check_meminfo(void) high_memory = __va(arm_lowmem_limit - 1) + 1; /* - * Round the memblock limit down to a section size. This + * Round the memblock limit down to a pmd size. This * helps to ensure that we will allocate memory from the - * last full section, which should be mapped. + * last full pmd, which should be mapped. */ if (memblock_limit) - memblock_limit = round_down(memblock_limit, SECTION_SIZE); + memblock_limit = round_down(memblock_limit, PMD_SIZE); if (!memblock_limit) memblock_limit = arm_lowmem_limit; diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index aa0519eed698..774ef1323554 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -22,8 +22,6 @@ * * These are the low level assembler for performing cache and TLB * functions on the arm1020. - * - * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt */ #include <linux/linkage.h> #include <linux/init.h> diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index bff4c7f70fd6..ae3c27b71594 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -22,8 +22,6 @@ * * These are the low level assembler for performing cache and TLB * functions on the arm1020e. - * - * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt */ #include <linux/linkage.h> #include <linux/init.h> diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index ede8c54ab4aa..32a47cc19076 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -441,9 +441,6 @@ ENTRY(cpu_arm925_set_pte_ext) .type __arm925_setup, #function __arm925_setup: mov r0, #0 -#if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE) - orr r0,r0,#1 << 7 -#endif /* Transparent on, D-cache clean & flush mode. See NOTE2 above */ orr r0,r0,#1 << 1 @ transparent mode on diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index e494d6d6acbe..92e08bf37aad 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -602,7 +602,6 @@ __\name\()_proc_info: PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ initfn __feroceon_setup, __\name\()_proc_info - .long __feroceon_setup .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index e1268f905026..e0e23582c8b4 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -54,6 +54,7 @@ #define SEEN_DATA (1 << (BPF_MEMWORDS + 3)) #define FLAG_NEED_X_RESET (1 << 0) +#define FLAG_IMM_OVERFLOW (1 << 1) struct jit_ctx { const struct bpf_prog *skf; @@ -293,6 +294,15 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx) /* PC in ARM mode == address of the instruction + 8 */ imm = offset - (8 + ctx->idx * 4); + if (imm & ~0xfff) { + /* + * literal pool is too far, signal it into flags. we + * can only detect it on the second pass unfortunately. + */ + ctx->flags |= FLAG_IMM_OVERFLOW; + return 0; + } + return imm; } @@ -449,10 +459,21 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx) return; } #endif - if (rm != ARM_R0) - emit(ARM_MOV_R(ARM_R0, rm), ctx); + + /* + * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4 + * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into + * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm + * before using it as a source for ARM_R1. + * + * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is + * ARM_R5 (r_X) so there is no particular register overlap + * issues. + */ if (rn != ARM_R1) emit(ARM_MOV_R(ARM_R1, rn), ctx); + if (rm != ARM_R0) + emit(ARM_MOV_R(ARM_R0, rm), ctx); ctx->seen |= SEEN_CALL; emit_mov_i(ARM_R3, (u32)jit_udiv, ctx); @@ -855,6 +876,14 @@ b_epilogue: default: return -1; } + + if (ctx->flags & FLAG_IMM_OVERFLOW) + /* + * this instruction generated an overflow when + * trying to access the literal pool, so + * delegate this filter to the kernel interpreter. + */ + return -1; } /* compute offsets only during the first pass */ @@ -917,7 +946,14 @@ void bpf_jit_compile(struct bpf_prog *fp) ctx.idx = 0; build_prologue(&ctx); - build_body(&ctx); + if (build_body(&ctx) < 0) { +#if __LINUX_ARM_ARCH__ < 7 + if (ctx.imm_count) + kfree(ctx.imms); +#endif + bpf_jit_binary_free(header); + goto out; + } build_epilogue(&ctx); flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx)); diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 224081ccc92f..7d0f07020c80 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -272,6 +272,7 @@ void xen_arch_pre_suspend(void) { } void xen_arch_post_suspend(int suspend_cancelled) { } void xen_timer_resume(void) { } void xen_arch_resume(void) { } +void xen_arch_suspend(void) { } /* In the hypervisor.S file. */ diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index 793551d15f1d..498325074a06 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -4,6 +4,7 @@ #include <linux/gfp.h> #include <linux/highmem.h> #include <linux/export.h> +#include <linux/memblock.h> #include <linux/of_address.h> #include <linux/slab.h> #include <linux/types.h> @@ -21,6 +22,20 @@ #include <asm/xen/hypercall.h> #include <asm/xen/interface.h> +unsigned long xen_get_swiotlb_free_pages(unsigned int order) +{ + struct memblock_region *reg; + gfp_t flags = __GFP_NOWARN; + + for_each_memblock(memory, reg) { + if (reg->base < (phys_addr_t)0xffffffff) { + flags |= __GFP_DMA; + break; + } + } + return __get_free_pages(flags, order); +} + enum dma_cache_op { DMA_UNMAP, DMA_MAP, diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi index c138b95a8356..351c95bda89e 100644 --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -21,6 +21,20 @@ clock-output-names = "juno_mb:clk25mhz"; }; + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "juno_mb:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "juno_mb:refclk32khz"; + }; + motherboard { compatible = "arm,vexpress,v2p-p1", "simple-bus"; #address-cells = <2>; /* SMB chipselect number and offset */ @@ -66,6 +80,15 @@ #size-cells = <1>; ranges = <0 3 0 0x200000>; + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&mb_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + mmci@050000 { compatible = "arm,pl180", "arm,primecell"; reg = <0x050000 0x1000>; @@ -106,16 +129,16 @@ compatible = "arm,sp804", "arm,primecell"; reg = <0x110000 0x10000>; interrupts = <9>; - clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; - clock-names = "timclken1", "apb_pclk"; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&mb_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; }; v2m_timer23: timer@120000 { compatible = "arm,sp804", "arm,primecell"; reg = <0x120000 0x10000>; interrupts = <9>; - clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; - clock-names = "timclken1", "apb_pclk"; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&mb_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; }; rtc@170000 { diff --git a/arch/arm64/crypto/crc32-arm64.c b/arch/arm64/crypto/crc32-arm64.c index 9499199924ae..6a37c3c6b11d 100644 --- a/arch/arm64/crypto/crc32-arm64.c +++ b/arch/arm64/crypto/crc32-arm64.c @@ -147,13 +147,21 @@ static int chksum_final(struct shash_desc *desc, u8 *out) { struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + put_unaligned_le32(ctx->crc, out); + return 0; +} + +static int chksumc_final(struct shash_desc *desc, u8 *out) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + put_unaligned_le32(~ctx->crc, out); return 0; } static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out) { - put_unaligned_le32(~crc32_arm64_le_hw(crc, data, len), out); + put_unaligned_le32(crc32_arm64_le_hw(crc, data, len), out); return 0; } @@ -199,6 +207,14 @@ static int crc32_cra_init(struct crypto_tfm *tfm) { struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + mctx->key = 0; + return 0; +} + +static int crc32c_cra_init(struct crypto_tfm *tfm) +{ + struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + mctx->key = ~0; return 0; } @@ -229,7 +245,7 @@ static struct shash_alg crc32c_alg = { .setkey = chksum_setkey, .init = chksum_init, .update = chksumc_update, - .final = chksum_final, + .final = chksumc_final, .finup = chksumc_finup, .digest = chksumc_digest, .descsize = sizeof(struct chksum_desc_ctx), @@ -241,7 +257,7 @@ static struct shash_alg crc32c_alg = { .cra_alignmask = 0, .cra_ctxsize = sizeof(struct chksum_ctx), .cra_module = THIS_MODULE, - .cra_init = crc32_cra_init, + .cra_init = crc32c_cra_init, } }; diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c index 114e7cc5de8c..aefda9868627 100644 --- a/arch/arm64/crypto/sha1-ce-glue.c +++ b/arch/arm64/crypto/sha1-ce-glue.c @@ -74,6 +74,9 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data, static int sha1_ce_final(struct shash_desc *desc, u8 *out) { + struct sha1_ce_state *sctx = shash_desc_ctx(desc); + + sctx->finalize = 0; kernel_neon_begin_partial(16); sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform); kernel_neon_end(); diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index 1340e44c048b..7cd587564a41 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -75,6 +75,9 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data, static int sha256_ce_final(struct shash_desc *desc, u8 *out) { + struct sha256_ce_state *sctx = shash_desc_ctx(desc); + + sctx->finalize = 0; kernel_neon_begin_partial(28); sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform); kernel_neon_end(); diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index 21033bba9390..28f8365edc4c 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -24,7 +24,6 @@ #include <asm/cacheflush.h> #include <asm/alternative.h> #include <asm/cpufeature.h> -#include <asm/insn.h> #include <linux/stop_machine.h> extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; @@ -34,48 +33,6 @@ struct alt_region { struct alt_instr *end; }; -/* - * Decode the imm field of a b/bl instruction, and return the byte - * offset as a signed value (so it can be used when computing a new - * branch target). - */ -static s32 get_branch_offset(u32 insn) -{ - s32 imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn); - - /* sign-extend the immediate before turning it into a byte offset */ - return (imm << 6) >> 4; -} - -static u32 get_alt_insn(u8 *insnptr, u8 *altinsnptr) -{ - u32 insn; - - aarch64_insn_read(altinsnptr, &insn); - - /* Stop the world on instructions we don't support... */ - BUG_ON(aarch64_insn_is_cbz(insn)); - BUG_ON(aarch64_insn_is_cbnz(insn)); - BUG_ON(aarch64_insn_is_bcond(insn)); - /* ... and there is probably more. */ - - if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) { - enum aarch64_insn_branch_type type; - unsigned long target; - - if (aarch64_insn_is_b(insn)) - type = AARCH64_INSN_BRANCH_NOLINK; - else - type = AARCH64_INSN_BRANCH_LINK; - - target = (unsigned long)altinsnptr + get_branch_offset(insn); - insn = aarch64_insn_gen_branch_imm((unsigned long)insnptr, - target, type); - } - - return insn; -} - static int __apply_alternatives(void *alt_region) { struct alt_instr *alt; @@ -83,9 +40,6 @@ static int __apply_alternatives(void *alt_region) u8 *origptr, *replptr; for (alt = region->begin; alt < region->end; alt++) { - u32 insn; - int i; - if (!cpus_have_cap(alt->cpufeature)) continue; @@ -95,12 +49,7 @@ static int __apply_alternatives(void *alt_region) origptr = (u8 *)&alt->orig_offset + alt->orig_offset; replptr = (u8 *)&alt->alt_offset + alt->alt_offset; - - for (i = 0; i < alt->alt_len; i += sizeof(insn)) { - insn = get_alt_insn(origptr + i, replptr + i); - aarch64_insn_write(origptr + i, insn); - } - + memcpy(origptr, replptr, alt->alt_len); flush_icache_range((uintptr_t)origptr, (uintptr_t)(origptr + alt->alt_len)); } diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 23f25acf43a9..cce18c85d2e8 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1315,15 +1315,15 @@ static int armpmu_device_probe(struct platform_device *pdev) if (!cpu_pmu) return -ENODEV; - irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); - if (!irqs) - return -ENOMEM; - /* Don't bother with PPIs; they're already affine */ irq = platform_get_irq(pdev, 0); if (irq >= 0 && irq_is_percpu(irq)) return 0; + irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); + if (!irqs) + return -ENOMEM; + for (i = 0; i < pdev->num_resources; ++i) { struct device_node *dn; int cpu; diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index 74c256744b25..f3d6221cd5bd 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c @@ -328,10 +328,12 @@ static int ptdump_init(void) for (j = 0; j < pg_level[i].num; j++) pg_level[i].mask |= pg_level[i].bits[j].mask; +#ifdef CONFIG_SPARSEMEM_VMEMMAP address_markers[VMEMMAP_START_NR].start_address = (unsigned long)virt_to_page(PAGE_OFFSET); address_markers[VMEMMAP_END_NR].start_address = (unsigned long)virt_to_page(high_memory); +#endif pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops); diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index edba042b2325..dc6a4842683a 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -487,7 +487,7 @@ emit_cond_jmp: return -EINVAL; } - imm64 = (u64)insn1.imm << 32 | imm; + imm64 = (u64)insn1.imm << 32 | (u32)imm; emit_a64_mov_i64(dst, imm64, ctx); return 1; diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 15051e9c2c6f..b054c5c6e713 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -127,7 +127,7 @@ int smp_num_siblings = 1; volatile int ia64_cpu_to_sapicid[NR_CPUS]; EXPORT_SYMBOL(ia64_cpu_to_sapicid); -static volatile cpumask_t cpu_callin_map; +static cpumask_t cpu_callin_map; struct smp_boot_data smp_boot_data __initdata; @@ -477,6 +477,7 @@ do_boot_cpu (int sapicid, int cpu, struct task_struct *idle) for (timeout = 0; timeout < 100000; timeout++) { if (cpumask_test_cpu(cpu, &cpu_callin_map)) break; /* It has booted */ + barrier(); /* Make sure we re-read cpu_callin_map */ udelay(100); } Dprintk("\n"); diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index d4e162d35b34..7cc3be9fa7c6 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -478,9 +478,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) { - struct pci_controller *controller = bridge->bus->sysdata; - - ACPI_COMPANION_SET(&bridge->dev, controller->companion); + /* + * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL + * here, pci_create_root_bus() has been called by someone else and + * sysdata is likely to be different from what we expect. Let it go in + * that case. + */ + if (!bridge->dev.parent) { + struct pci_controller *controller = bridge->bus->sysdata; + ACPI_COMPANION_SET(&bridge->dev, controller->companion); + } return 0; } diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index ce7aea34fdf4..c18ddc74ef9a 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c @@ -45,7 +45,7 @@ static volatile unsigned long flushcache_cpumask = 0; /* * For flush_tlb_others() */ -static volatile cpumask_t flush_cpumask; +static cpumask_t flush_cpumask; static struct mm_struct *flush_mm; static struct vm_area_struct *flush_vma; static volatile unsigned long flush_va; @@ -415,7 +415,7 @@ static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, */ send_IPI_mask(&cpumask, INVALIDATE_TLB_IPI, 0); - while (!cpumask_empty((cpumask_t*)&flush_cpumask)) { + while (!cpumask_empty(&flush_cpumask)) { /* nothing. lockup detection does not belong here */ mb(); } @@ -468,7 +468,7 @@ void smp_invalidate_interrupt(void) __flush_tlb_page(va); } } - cpumask_clear_cpu(cpu_id, (cpumask_t*)&flush_cpumask); + cpumask_clear_cpu(cpu_id, &flush_cpumask); } /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 5200f649dd4e..ae2dd59050f7 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -277,7 +277,7 @@ LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ - sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/") + sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') ifdef CONFIG_64BIT CHECKFLAGS += -m64 endif diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c index e1fe63051136..597899ad5438 100644 --- a/arch/mips/ath79/prom.c +++ b/arch/mips/ath79/prom.c @@ -1,6 +1,7 @@ /* * Atheros AR71XX/AR724X/AR913X specific prom routines * + * Copyright (C) 2015 Laurent Fasnacht <l@libres.ch> * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> * @@ -25,12 +26,14 @@ void __init prom_init(void) { fw_init_cmdline(); +#ifdef CONFIG_BLK_DEV_INITRD /* Read the initrd address from the firmware environment */ initrd_start = fw_getenvl("initrd_start"); if (initrd_start) { initrd_start = KSEG0ADDR(initrd_start); initrd_end = initrd_start + fw_getenvl("initrd_size"); } +#endif } void __init prom_free_prom_memory(void) diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index a73c93c3d44a..7fc8397d16f2 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -225,7 +225,7 @@ void __init plat_time_init(void) ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); ref_clk_rate = ath79_get_sys_clk_rate("ref"); - pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz", + pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n", cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000, ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000, ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000, diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index 002680648dcb..b2a577ebce0b 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -194,7 +194,7 @@ CONFIG_USB_WUSB_CBAF=m CONFIG_USB_C67X00_HCD=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_ISP1760=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_UHCI_HCD=m CONFIG_USB_R8A66597_HCD=m diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index a594d8ed9698..f19e890b99d2 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -304,7 +304,7 @@ do { \ \ current->thread.abi = &mips_abi; \ \ - current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \ + current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \ } while (0) #endif /* CONFIG_32BIT */ @@ -366,7 +366,7 @@ do { \ else \ current->thread.abi = &mips_abi; \ \ - current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \ + current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \ \ p = personality(current->personality); \ if (p != PER_LINUX32 && p != PER_LINUX) \ diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index bb02fac9b4fa..2b25d1ba1ea0 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -45,7 +45,7 @@ extern int __cpu_logical_map[NR_CPUS]; #define SMP_DUMP 0x8 #define SMP_ASK_C0COUNT 0x10 -extern volatile cpumask_t cpu_callin_map; +extern cpumask_t cpu_callin_map; /* Mask of CPUs which are currently definitely operating coherently */ extern cpumask_t cpu_coherent_mask; diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e36515dcd3b2..209e5b76c1bc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -74,13 +74,12 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) { unsigned long sr, mask, fcsr, fcsr0, fcsr1; + fcsr = c->fpu_csr31; mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; sr = read_c0_status(); __enable_fpu(FPU_AS_IS); - fcsr = read_32bit_cp1_register(CP1_STATUS); - fcsr0 = fcsr & mask; write_32bit_cp1_register(CP1_STATUS, fcsr0); fcsr0 = read_32bit_cp1_register(CP1_STATUS); diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index be4899f3c393..4a4d9e067c89 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -76,14 +76,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, /* Lets see if this is an O32 ELF */ if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) { - /* FR = 1 for N32 */ - if (ehdr32->e_flags & EF_MIPS_ABI2) - state->overall_fp_mode = FP_FR1; - else - /* Set a good default FPU mode for O32 */ - state->overall_fp_mode = cpu_has_mips_r6 ? - FP_FRE : FP_FR0; - if (ehdr32->e_flags & EF_MIPS_FP64) { /* * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it @@ -104,9 +96,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, (char *)&abiflags, sizeof(abiflags)); } else { - /* FR=1 is really the only option for 64-bit */ - state->overall_fp_mode = FP_FR1; - if (phdr64->p_type != PT_MIPS_ABIFLAGS) return 0; if (phdr64->p_filesz < sizeof(abiflags)) @@ -137,6 +126,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, struct elf32_hdr *ehdr = _ehdr; struct mode_req prog_req, interp_req; int fp_abi, interp_fp_abi, abi0, abi1, max_abi; + bool is_mips64; if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) return 0; @@ -152,10 +142,22 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, abi0 = abi1 = fp_abi; } - /* ABI limits. O32 = FP_64A, N32/N64 = FP_SOFT */ - max_abi = ((ehdr->e_ident[EI_CLASS] == ELFCLASS32) && - (!(ehdr->e_flags & EF_MIPS_ABI2))) ? - MIPS_ABI_FP_64A : MIPS_ABI_FP_SOFT; + is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) || + (ehdr->e_flags & EF_MIPS_ABI2); + + if (is_mips64) { + /* MIPS64 code always uses FR=1, thus the default is easy */ + state->overall_fp_mode = FP_FR1; + + /* Disallow access to the various FPXX & FP64 ABIs */ + max_abi = MIPS_ABI_FP_SOFT; + } else { + /* Default to a mode capable of running code expecting FR=0 */ + state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0; + + /* Allow all ABIs we know about */ + max_abi = MIPS_ABI_FP_64A; + } if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) || (abi1 > max_abi && abi1 != MIPS_ABI_FP_UNKNOWN)) diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index d2bfbc2e8995..3c8a18a00a65 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -29,7 +29,7 @@ int kgdb_early_setup; #endif -static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; +static DECLARE_BITMAP(irq_map, NR_IRQS); int allocate_irqno(void) { @@ -109,7 +109,7 @@ void __init init_IRQ(void) #endif } -#ifdef DEBUG_STACKOVERFLOW +#ifdef CONFIG_DEBUG_STACKOVERFLOW static inline void check_stack_overflow(void) { unsigned long sp; diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index d544e774eea6..e933a309f2ea 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -176,7 +176,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) __get_user(value, data + 64); fcr31 = child->thread.fpu.fcr31; - mask = current_cpu_data.fpu_msk31; + mask = boot_cpu_data.fpu_msk31; child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); /* FIR may not be written. */ diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index fd528d7ea278..336708ae5c5b 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -444,7 +444,7 @@ struct plat_smp_ops bmips5000_smp_ops = { static void bmips_wr_vec(unsigned long dst, char *start, char *end) { memcpy((void *)dst, start, end - start); - dma_cache_wback((unsigned long)start, end - start); + dma_cache_wback(dst, end - start); local_flush_icache_range(dst, dst + (end - start)); instruction_hazard(); } diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 7e011f95bb8e..4251d390b5b6 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -92,7 +92,7 @@ static void __init cps_smp_setup(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(0, mt_fpu_cpumask); + cpumask_set_cpu(0, &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 193ace7955fb..faa46ebd9dda 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -43,7 +43,7 @@ #include <asm/time.h> #include <asm/setup.h> -volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ +cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ EXPORT_SYMBOL(__cpu_number_map); @@ -218,8 +218,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) /* * Trust is futile. We should really have timeouts ... */ - while (!cpumask_test_cpu(cpu, &cpu_callin_map)) + while (!cpumask_test_cpu(cpu, &cpu_callin_map)) { udelay(100); + schedule(); + } synchronise_count_master(cpu); return 0; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index ba32e48d4697..d2d1c1933bc9 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -269,7 +269,6 @@ static void __show_regs(const struct pt_regs *regs) */ printk("epc : %0*lx %pS\n", field, regs->cp0_epc, (void *) regs->cp0_epc); - printk(" %s\n", print_tainted()); printk("ra : %0*lx %pS\n", field, regs->regs[31], (void *) regs->regs[31]); diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 6230f376a44e..d5fa3eaf39a1 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -2389,7 +2389,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, { unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr]; enum emulation_result er = EMULATE_DONE; - unsigned long curr_pc; if (run->mmio.len > sizeof(*gpr)) { kvm_err("Bad MMIO length: %d", run->mmio.len); @@ -2397,11 +2396,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, goto done; } - /* - * Update PC and hold onto current PC in case there is - * an error and we want to rollback the PC - */ - curr_pc = vcpu->arch.pc; er = update_pc(vcpu, vcpu->arch.pending_load_cause); if (er == EMULATE_FAIL) return er; @@ -2415,7 +2409,7 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, if (vcpu->mmio_needed == 2) *gpr = *(int16_t *) run->mmio.data; else - *gpr = *(int16_t *) run->mmio.data; + *gpr = *(uint16_t *)run->mmio.data; break; case 1: diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S index 7d12c0dded3d..77e64942f004 100644 --- a/arch/mips/lib/strnlen_user.S +++ b/arch/mips/lib/strnlen_user.S @@ -34,7 +34,12 @@ LEAF(__strnlen_\func\()_asm) FEXPORT(__strnlen_\func\()_nocheck_asm) move v0, a0 PTR_ADDU a1, a0 # stop pointer -1: beq v0, a1, 1f # limit reached? +1: +#ifdef CONFIG_CPU_DADDI_WORKAROUNDS + .set noat + li AT, 1 +#endif + beq v0, a1, 1f # limit reached? .ifeqs "\func", "kernel" EX(lb, t0, (v0), .Lfault\@) .else @@ -42,7 +47,13 @@ FEXPORT(__strnlen_\func\()_nocheck_asm) .endif .set noreorder bnez t0, 1b -1: PTR_ADDIU v0, 1 +1: +#ifndef CONFIG_CPU_DADDI_WORKAROUNDS + PTR_ADDIU v0, 1 +#else + PTR_ADDU v0, AT + .set at +#endif .set reorder PTR_SUBU v0, a0 jr ra diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index e3c68b5da18d..509877c6e9d9 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c @@ -272,7 +272,7 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) if (action & SMP_ASK_C0COUNT) { BUG_ON(cpu != 0); c0count = read_c0_count(); - for (i = 1; i < loongson_sysconf.nr_cpus; i++) + for (i = 1; i < num_possible_cpus(); i++) per_cpu(core0_c0count, i) = c0count; } } diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index d31c537ace1d..22b9b2cb9219 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -889,7 +889,7 @@ static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; case FPCREG_RID: - value = current_cpu_data.fpu_id; + value = boot_cpu_data.fpu_id; break; default: @@ -921,7 +921,7 @@ static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx, (void *)xcp->cp0_epc, MIPSInst_RT(ir), value); /* Preserve read-only bits. */ - mask = current_cpu_data.fpu_msk31; + mask = boot_cpu_data.fpu_msk31; fcr31 = (value & ~mask) | (fcr31 & mask); break; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 0dbb65a51ce5..2e03ab173591 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1372,7 +1372,7 @@ static int probe_scache(void) scache_size = addr; c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); c->scache.ways = 1; - c->dcache.waybit = 0; /* does not matter */ + c->scache.waybit = 0; /* does not matter */ return 1; } diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index a27a088e6f9f..08318ecb803a 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -495,7 +495,7 @@ static void r4k_tlb_configure(void) if (cpu_has_rixi) { /* - * Enable the no read, no exec bits, and enable large virtual + * Enable the no read, no exec bits, and enable large physical * address. */ #ifdef CONFIG_64BIT diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 5d6139390bf8..e23fdf2a9c80 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c @@ -681,11 +681,7 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx) sp_off += config_enabled(CONFIG_64BIT) ? (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE; - /* - * Subtract the bytes for the last registers since we only care about - * the location on the stack pointer. - */ - return sp_off - RSIZE; + return sp_off; } static void build_prologue(struct jit_ctx *ctx) diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c index e20b02e3ae28..e10d10b9e82a 100644 --- a/arch/mips/ralink/ill_acc.c +++ b/arch/mips/ralink/ill_acc.c @@ -41,7 +41,7 @@ static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, type & ILL_ACC_LEN_M); - rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); + rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); return IRQ_HANDLED; } diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 0134db2ad0a8..5a2a82148d8d 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -130,9 +130,9 @@ struct platform_device ip32_rtc_device = { .resource = ip32_rtc_resources, }; -+static int __init sgio2_rtc_devinit(void) +static __init int sgio2_rtc_devinit(void) { return platform_device_register(&ip32_rtc_device); } -device_initcall(sgio2_cmos_devinit); +device_initcall(sgio2_rtc_devinit); diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h index 3391d061eccc..78c9fd32c554 100644 --- a/arch/parisc/include/asm/elf.h +++ b/arch/parisc/include/asm/elf.h @@ -348,6 +348,10 @@ struct pt_regs; /* forward declaration... */ #define ELF_HWCAP 0 +#define STACK_RND_MASK (is_32bit_task() ? \ + 0x7ff >> (PAGE_SHIFT - 12) : \ + 0x3ffff >> (PAGE_SHIFT - 12)) + struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *); #define arch_randomize_brk arch_randomize_brk diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 8a488c22a99f..809905a811ed 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -181,9 +181,12 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) return 1; } +/* + * Copy architecture-specific thread state + */ int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, struct task_struct *p) + unsigned long kthread_arg, struct task_struct *p) { struct pt_regs *cregs = &(p->thread.regs); void *stack = task_stack_page(p); @@ -195,11 +198,10 @@ copy_thread(unsigned long clone_flags, unsigned long usp, extern void * const child_return; if (unlikely(p->flags & PF_KTHREAD)) { + /* kernel thread */ memset(cregs, 0, sizeof(struct pt_regs)); if (!usp) /* idle thread */ return 0; - - /* kernel thread */ /* Must exit via ret_from_kernel_thread in order * to call schedule_tail() */ @@ -215,7 +217,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, #else cregs->gr[26] = usp; #endif - cregs->gr[25] = arg; + cregs->gr[25] = kthread_arg; } else { /* user thread */ /* usp must be word aligned. This also prevents users from diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index e1ffea2f9a0b..5aba01ac457f 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -77,6 +77,9 @@ static unsigned long mmap_upper_limit(void) if (stack_base > STACK_SIZE_MAX) stack_base = STACK_SIZE_MAX; + /* Add space for stack randomization. */ + stack_base += (STACK_RND_MASK << PAGE_SHIFT); + return PAGE_ALIGN(STACK_TOP - stack_base); } diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index 15c99b649b04..b2eb4686bd8f 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -73,7 +73,7 @@ void save_mce_event(struct pt_regs *regs, long handled, uint64_t nip, uint64_t addr) { uint64_t srr1; - int index = __this_cpu_inc_return(mce_nest_count); + int index = __this_cpu_inc_return(mce_nest_count) - 1; struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]); /* @@ -184,7 +184,7 @@ void machine_check_queue_event(void) if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) return; - index = __this_cpu_inc_return(mce_queue_count); + index = __this_cpu_inc_return(mce_queue_count) - 1; /* If queue is full, just return for now. */ if (index >= MAX_MC_EVT) { __this_cpu_dec(mce_queue_count); diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index f096e72262f4..1db685104ffc 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -213,6 +213,7 @@ SECTIONS *(.opd) } + . = ALIGN(256); .got : AT(ADDR(.got) - LOAD_OFFSET) { __toc_start = .; #ifndef CONFIG_RELOCATABLE diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 48d3c5d2ecc9..df81caab7383 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1952,7 +1952,7 @@ static void post_guest_process(struct kvmppc_vcore *vc) */ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) { - struct kvm_vcpu *vcpu; + struct kvm_vcpu *vcpu, *vnext; int i; int srcu_idx; @@ -1982,7 +1982,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) */ if ((threads_per_core > 1) && ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) { - list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { + list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads, + arch.run_list) { vcpu->arch.ret = -EBUSY; kvmppc_remove_runnable(vc, vcpu); wake_up(&vcpu->arch.cpu_run); diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 0ce968b00b7c..3385e3d0506e 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -689,27 +689,34 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, struct page * follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { - pte_t *ptep; - struct page *page; + pte_t *ptep, pte; unsigned shift; unsigned long mask, flags; + struct page *page = ERR_PTR(-EINVAL); + + local_irq_save(flags); + ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift); + if (!ptep) + goto no_page; + pte = READ_ONCE(*ptep); /* + * Verify it is a huge page else bail. * Transparent hugepages are handled by generic code. We can skip them * here. */ - local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift); + if (!shift || pmd_trans_huge(__pmd(pte_val(pte)))) + goto no_page; - /* Verify it is a huge page else bail. */ - if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) { - local_irq_restore(flags); - return ERR_PTR(-EINVAL); + if (!pte_present(pte)) { + page = NULL; + goto no_page; } mask = (1UL << shift) - 1; - page = pte_page(*ptep); + page = pte_page(pte); if (page) page += (address & mask) / PAGE_SIZE; +no_page: local_irq_restore(flags); return page; } diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 59daa5eeec25..6bfadf1aa5cb 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -839,6 +839,17 @@ pmd_t pmdp_get_and_clear(struct mm_struct *mm, * hash fault look at them. */ memset(pgtable, 0, PTE_FRAG_SIZE); + /* + * Serialize against find_linux_pte_or_hugepte which does lock-less + * lookup in page tables with local interrupts disabled. For huge pages + * it casts pmd_t to pte_t. Since format of pte_t is different from + * pmd_t we want to prevent transit from pmd pointing to page table + * to pmd pointing to huge page (and back) while interrupts are disabled. + * We clear pmd to possibly replace it with page table pointer in + * different code paths. So make sure we wait for the parallel + * find_linux_pte_or_hugepage to finish. + */ + kick_all_cpus_sync(); return old_pmd; } diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c index 7940dc90e80b..b258110da952 100644 --- a/arch/s390/crypto/ghash_s390.c +++ b/arch/s390/crypto/ghash_s390.c @@ -16,11 +16,12 @@ #define GHASH_DIGEST_SIZE 16 struct ghash_ctx { - u8 icv[16]; - u8 key[16]; + u8 key[GHASH_BLOCK_SIZE]; }; struct ghash_desc_ctx { + u8 icv[GHASH_BLOCK_SIZE]; + u8 key[GHASH_BLOCK_SIZE]; u8 buffer[GHASH_BLOCK_SIZE]; u32 bytes; }; @@ -28,8 +29,10 @@ struct ghash_desc_ctx { static int ghash_init(struct shash_desc *desc) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); memset(dctx, 0, sizeof(*dctx)); + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); return 0; } @@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm, } memcpy(ctx->key, key, GHASH_BLOCK_SIZE); - memset(ctx->icv, 0, GHASH_BLOCK_SIZE); return 0; } @@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); unsigned int n; u8 *buf = dctx->buffer; int ret; @@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc, src += n; if (!dctx->bytes) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); if (ret != GHASH_BLOCK_SIZE) return -EIO; @@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc, n = srclen & ~(GHASH_BLOCK_SIZE - 1); if (n) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); + ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n); if (ret != n) return -EIO; src += n; @@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc, return 0; } -static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) +static int ghash_flush(struct ghash_desc_ctx *dctx) { u8 *buf = dctx->buffer; int ret; @@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) memset(pos, 0, dctx->bytes); - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); if (ret != GHASH_BLOCK_SIZE) return -EIO; + + dctx->bytes = 0; } - dctx->bytes = 0; return 0; } static int ghash_final(struct shash_desc *desc, u8 *dst) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); int ret; - ret = ghash_flush(ctx, dctx); + ret = ghash_flush(dctx); if (!ret) - memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); + memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE); return ret; } diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 1f374b39a4ec..9d5192c94963 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -125,7 +125,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes) /* fill page with urandom bytes */ get_random_bytes(pg, PAGE_SIZE); /* exor page with stckf values */ - for (n = 0; n < sizeof(PAGE_SIZE/sizeof(u64)); n++) { + for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) { u64 *p = ((u64 *)pg) + n; *p ^= get_tod_clock_fast(); } diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index fc642399b489..ef24a212eeb7 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -494,7 +494,7 @@ static inline int pmd_large(pmd_t pmd) return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; } -static inline int pmd_pfn(pmd_t pmd) +static inline unsigned long pmd_pfn(pmd_t pmd) { unsigned long origin_mask; diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 7690dc8e1ab5..20c146d1251a 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -443,8 +443,11 @@ static void bpf_jit_epilogue(struct bpf_jit *jit) /* * Compile one eBPF instruction into s390x code + * + * NOTE: Use noinline because for gcov (-fprofile-arcs) gcc allocates a lot of + * stack space for the large switch statement. */ -static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) +static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) { struct bpf_insn *insn = &fp->insnsi[i]; int jmp_off, last, insn_count = 1; @@ -588,8 +591,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) EMIT4(0xb9160000, dst_reg, rc_reg); break; } - case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / (u32) src */ - case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % (u32) src */ + case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */ + case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % src */ { int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; @@ -602,10 +605,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) EMIT4_IMM(0xa7090000, REG_W0, 0); /* lgr %w1,%dst */ EMIT4(0xb9040000, REG_W1, dst_reg); - /* llgfr %dst,%src (u32 cast) */ - EMIT4(0xb9160000, dst_reg, src_reg); /* dlgr %w0,%dst */ - EMIT4(0xb9870000, REG_W0, dst_reg); + EMIT4(0xb9870000, REG_W0, src_reg); /* lgr %dst,%rc */ EMIT4(0xb9040000, dst_reg, rc_reg); break; @@ -632,8 +633,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) EMIT4(0xb9160000, dst_reg, rc_reg); break; } - case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / (u32) imm */ - case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % (u32) imm */ + case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */ + case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % imm */ { int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; @@ -649,7 +650,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) EMIT4(0xb9040000, REG_W1, dst_reg); /* dlg %w0,<d(imm)>(%l) */ EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L, - EMIT_CONST_U64((u32) imm)); + EMIT_CONST_U64(imm)); /* lgr %dst,%rc */ EMIT4(0xb9040000, dst_reg, rc_reg); break; diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index a6e424d185d0..a6cfdabb6054 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h @@ -24,7 +24,8 @@ typedef struct { unsigned int icache_line_size; unsigned int ecache_size; unsigned int ecache_line_size; - int core_id; + unsigned short sock_id; + unsigned short core_id; int proc_id; } cpuinfo_sparc; diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index dc165ebdf05a..2a52c91d2c8a 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) " sllx %1, 32, %1\n" " or %0, %1, %0\n" " .previous\n" + " .section .sun_m7_2insn_patch, \"ax\"\n" + " .word 661b\n" + " sethi %%uhi(%4), %1\n" + " sethi %%hi(%4), %0\n" + " .word 662b\n" + " or %1, %%ulo(%4), %1\n" + " or %0, %%lo(%4), %0\n" + " .word 663b\n" + " sllx %1, 32, %1\n" + " or %0, %1, %0\n" + " .previous\n" : "=r" (mask), "=r" (tmp) : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | + _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V), + "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | + _PAGE_CP_4V | _PAGE_E_4V | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); @@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) " andn %0, %4, %0\n" " or %0, %5, %0\n" " .previous\n" + " .section .sun_m7_2insn_patch, \"ax\"\n" + " .word 661b\n" + " andn %0, %6, %0\n" + " or %0, %5, %0\n" + " .previous\n" : "=r" (val) : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), - "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V)); + "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V), + "i" (_PAGE_CP_4V)); return __pgprot(val); } diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index ed8f071132e4..d1761df5cca6 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h @@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus) #ifdef CONFIG_SMP #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) #define topology_core_id(cpu) (cpu_data(cpu).core_id) -#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) +#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu]) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) #endif /* CONFIG_SMP */ extern cpumask_t cpu_core_map[NR_CPUS]; +extern cpumask_t cpu_core_sib_map[NR_CPUS]; static inline const struct cpumask *cpu_coregroup_mask(int cpu) { return &cpu_core_map[cpu]; diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h index 6fd4436d32f0..ec9c04de3664 100644 --- a/arch/sparc/include/asm/trap_block.h +++ b/arch/sparc/include/asm/trap_block.h @@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry { }; extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, __sun4v_2insn_patch_end; +extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch, + __sun_m7_2insn_patch_end; #endif /* !(__ASSEMBLY__) */ diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 07cc49e541f4..0f679421b468 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, struct sun4v_1insn_patch_entry *); void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, struct sun4v_2insn_patch_entry *); +void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *, + struct sun4v_2insn_patch_entry *); extern unsigned int dcache_parity_tl1_occurred; extern unsigned int icache_parity_tl1_occurred; diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 94e392bdee7d..814fb1729b12 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev) err = -ENOMEM; goto err1; } - memset(grpci2priv, 0, sizeof(*grpci2priv)); priv->regs = regs; priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */ priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT; diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 26c80e18d7b1..6f80936e0eea 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp) } } -static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) +static void find_back_node_value(struct mdesc_handle *hp, u64 node, + char *srch_val, + void (*func)(struct mdesc_handle *, u64, int), + u64 val, int depth) { - u64 a; - - mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { - u64 t = mdesc_arc_target(hp, a); - const char *name; - const u64 *id; + u64 arc; - name = mdesc_node_name(hp, t); - if (!strcmp(name, "cpu")) { - id = mdesc_get_property(hp, t, "id", NULL); - if (*id < NR_CPUS) - cpu_data(*id).core_id = core_id; - } else { - u64 j; + /* Since we have an estimate of recursion depth, do a sanity check. */ + if (depth == 0) + return; - mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { - u64 n = mdesc_arc_target(hp, j); - const char *n_name; + mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) { + u64 n = mdesc_arc_target(hp, arc); + const char *name = mdesc_node_name(hp, n); - n_name = mdesc_node_name(hp, n); - if (strcmp(n_name, "cpu")) - continue; + if (!strcmp(srch_val, name)) + (*func)(hp, n, val); - id = mdesc_get_property(hp, n, "id", NULL); - if (*id < NR_CPUS) - cpu_data(*id).core_id = core_id; - } - } + find_back_node_value(hp, n, srch_val, func, val, depth-1); } } +static void __mark_core_id(struct mdesc_handle *hp, u64 node, + int core_id) +{ + const u64 *id = mdesc_get_property(hp, node, "id", NULL); + + if (*id < num_possible_cpus()) + cpu_data(*id).core_id = core_id; +} + +static void __mark_sock_id(struct mdesc_handle *hp, u64 node, + int sock_id) +{ + const u64 *id = mdesc_get_property(hp, node, "id", NULL); + + if (*id < num_possible_cpus()) + cpu_data(*id).sock_id = sock_id; +} + +static void mark_core_ids(struct mdesc_handle *hp, u64 mp, + int core_id) +{ + find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10); +} + +static void mark_sock_ids(struct mdesc_handle *hp, u64 mp, + int sock_id) +{ + find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10); +} + static void set_core_ids(struct mdesc_handle *hp) { int idx; u64 mp; idx = 1; + + /* Identify unique cores by looking for cpus backpointed to by + * level 1 instruction caches. + */ mdesc_for_each_node_by_name(hp, mp, "cache") { const u64 *level; const char *type; @@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp) continue; mark_core_ids(hp, mp, idx); + idx++; + } +} + +static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level) +{ + u64 mp; + int idx = 1; + int fnd = 0; + + /* Identify unique sockets by looking for cpus backpointed to by + * shared level n caches. + */ + mdesc_for_each_node_by_name(hp, mp, "cache") { + const u64 *cur_lvl; + + cur_lvl = mdesc_get_property(hp, mp, "level", NULL); + if (*cur_lvl != level) + continue; + + mark_sock_ids(hp, mp, idx); + idx++; + fnd = 1; + } + return fnd; +} + +static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp) +{ + int idx = 1; + mdesc_for_each_node_by_name(hp, mp, "socket") { + u64 a; + + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 t = mdesc_arc_target(hp, a); + const char *name; + const u64 *id; + + name = mdesc_node_name(hp, t); + if (strcmp(name, "cpu")) + continue; + + id = mdesc_get_property(hp, t, "id", NULL); + if (*id < num_possible_cpus()) + cpu_data(*id).sock_id = idx; + } idx++; } } +static void set_sock_ids(struct mdesc_handle *hp) +{ + u64 mp; + + /* If machine description exposes sockets data use it. + * Otherwise fallback to use shared L3 or L2 caches. + */ + mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets"); + if (mp != MDESC_NODE_NULL) + return set_sock_ids_by_socket(hp, mp); + + if (!set_sock_ids_by_cache(hp, 3)) + set_sock_ids_by_cache(hp, 2); +} + static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) { u64 a; @@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name) continue; mark_proc_ids(hp, mp, idx); - idx++; } } @@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) set_core_ids(hp); set_proc_ids(hp); + set_sock_ids(hp); mdesc_release(hp); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 6f7251fd2eab..c928bc64b4ba 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -1002,6 +1002,38 @@ static int __init pcibios_init(void) subsys_initcall(pcibios_init); #ifdef CONFIG_SYSFS + +#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */ + +static void pcie_bus_slot_names(struct pci_bus *pbus) +{ + struct pci_dev *pdev; + struct pci_bus *bus; + + list_for_each_entry(pdev, &pbus->devices, bus_list) { + char name[SLOT_NAME_SIZE]; + struct pci_slot *pci_slot; + const u32 *slot_num; + int len; + + slot_num = of_get_property(pdev->dev.of_node, + "physical-slot#", &len); + + if (slot_num == NULL || len != 4) + continue; + + snprintf(name, sizeof(name), "%u", slot_num[0]); + pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL); + + if (IS_ERR(pci_slot)) + pr_err("PCI: pci_create_slot returned %ld.\n", + PTR_ERR(pci_slot)); + } + + list_for_each_entry(bus, &pbus->children, node) + pcie_bus_slot_names(bus); +} + static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) { const struct pci_slot_names { @@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void) while ((pbus = pci_find_next_bus(pbus)) != NULL) { struct device_node *node; + struct pci_dev *pdev; + + pdev = list_first_entry(&pbus->devices, struct pci_dev, + bus_list); - if (pbus->self) { - /* PCI->PCI bridge */ - node = pbus->self->dev.of_node; + if (pdev && pci_is_pcie(pdev)) { + pcie_bus_slot_names(pbus); } else { - struct pci_pbm_info *pbm = pbus->sysdata; - /* Host PCI controller */ - node = pbm->op->dev.of_node; - } + if (pbus->self) { + + /* PCI->PCI bridge */ + node = pbus->self->dev.of_node; + + } else { + struct pci_pbm_info *pbm = pbus->sysdata; - pci_bus_slot_names(node, pbus); + /* Host PCI controller */ + node = pbm->op->dev.of_node; + } + + pci_bus_slot_names(node, pbus); + } } return 0; diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index c38d19fc27ba..f7b261749383 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start, } } +void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start, + struct sun4v_2insn_patch_entry *end) +{ + while (start < end) { + unsigned long addr = start->addr; + + *(unsigned int *) (addr + 0) = start->insns[0]; + wmb(); + __asm__ __volatile__("flush %0" : : "r" (addr + 0)); + + *(unsigned int *) (addr + 4) = start->insns[1]; + wmb(); + __asm__ __volatile__("flush %0" : : "r" (addr + 4)); + + start++; + } +} + static void __init sun4v_patch(void) { extern void sun4v_hvapi_init(void); @@ -267,6 +285,9 @@ static void __init sun4v_patch(void) sun4v_patch_2insn_range(&__sun4v_2insn_patch, &__sun4v_2insn_patch_end); + if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7) + sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, + &__sun_m7_2insn_patch_end); sun4v_hvapi_init(); } diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 61139d9924ca..19cd08d18672 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; cpumask_t cpu_core_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; +cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = { + [0 ... NR_CPUS-1] = CPU_MASK_NONE }; + EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_SYMBOL(cpu_core_map); +EXPORT_SYMBOL(cpu_core_sib_map); static cpumask_t smp_commenced_mask; @@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void) } } + for_each_present_cpu(i) { + unsigned int j; + + for_each_present_cpu(j) { + if (cpu_data(i).sock_id == cpu_data(j).sock_id) + cpumask_set_cpu(j, &cpu_core_sib_map[i]); + } + } + for_each_present_cpu(i) { unsigned int j; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 09243057cb0b..f1a2f688b28a 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -138,6 +138,11 @@ SECTIONS *(.pause_3insn_patch) __pause_3insn_patch_end = .; } + .sun_m7_2insn_patch : { + __sun_m7_2insn_patch = .; + *(.sun_m7_2insn_patch) + __sun_m7_2insn_patch_end = .; + } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 4ca0d6ba5ec8..559cb744112c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -54,6 +54,7 @@ #include "init_64.h" unsigned long kern_linear_pte_xor[4] __read_mostly; +static unsigned long page_cache4v_flag; /* A bitmap, two bits for every 256MB of physical memory. These two * bits determine what page size we use for kernel linear @@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void) static void __init sun4v_linear_pte_xor_finalize(void) { + unsigned long pagecv_flag; + + /* Bit 9 of TTE is no longer CV bit on M7 processor and it instead + * enables MCD error. Do not set bit 9 on M7 processor. + */ + switch (sun4v_chip_type) { + case SUN4V_CHIP_SPARC_M7: + pagecv_flag = 0x00; + break; + default: + pagecv_flag = _PAGE_CV_4V; + break; + } #ifndef CONFIG_DEBUG_PAGEALLOC if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ PAGE_OFFSET; - kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | + kern_linear_pte_xor[1] |= (_PAGE_CP_4V | pagecv_flag | _PAGE_P_4V | _PAGE_W_4V); } else { kern_linear_pte_xor[1] = kern_linear_pte_xor[0]; @@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ PAGE_OFFSET; - kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V | + kern_linear_pte_xor[2] |= (_PAGE_CP_4V | pagecv_flag | _PAGE_P_4V | _PAGE_W_4V); } else { kern_linear_pte_xor[2] = kern_linear_pte_xor[1]; @@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ PAGE_OFFSET; - kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V | + kern_linear_pte_xor[3] |= (_PAGE_CP_4V | pagecv_flag | _PAGE_P_4V | _PAGE_W_4V); } else { kern_linear_pte_xor[3] = kern_linear_pte_xor[2]; @@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void) return available; } +#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U) +#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V) +#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U) +#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V) +#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R) +#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R) + /* We need to exclude reserved regions. This exclusion will include * vmlinux and initrd. To be more precise the initrd size could be used to * compute a new lower limit because it is freed later during initialization. @@ -2034,6 +2055,25 @@ void __init paging_init(void) memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); #endif + /* TTE.cv bit on sparc v9 occupies the same position as TTE.mcde + * bit on M7 processor. This is a conflicting usage of the same + * bit. Enabling TTE.cv on M7 would turn on Memory Corruption + * Detection error on all pages and this will lead to problems + * later. Kernel does not run with MCD enabled and hence rest + * of the required steps to fully configure memory corruption + * detection are not taken. We need to ensure TTE.mcde is not + * set on M7 processor. Compute the value of cacheability + * flag for use later taking this into consideration. + */ + switch (sun4v_chip_type) { + case SUN4V_CHIP_SPARC_M7: + page_cache4v_flag = _PAGE_CP_4V; + break; + default: + page_cache4v_flag = _PAGE_CACHE_4V; + break; + } + if (tlb_type == hypervisor) sun4v_pgprot_init(); else @@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U) -#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V) -#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U) -#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V) -#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R) -#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R) - pgprot_t PAGE_KERNEL __read_mostly; EXPORT_SYMBOL(PAGE_KERNEL); @@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, _PAGE_P_4U | _PAGE_W_4U); if (tlb_type == hypervisor) pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | - _PAGE_CP_4V | _PAGE_CV_4V | - _PAGE_P_4V | _PAGE_W_4V); + page_cache4v_flag | _PAGE_P_4V | _PAGE_W_4V); pte_base |= _PAGE_PMD_HUGE; @@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void) int i; PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID | - _PAGE_CACHE_4V | _PAGE_P_4V | + page_cache4v_flag | _PAGE_P_4V | __ACCESS_BITS_4V | __DIRTY_BITS_4V | _PAGE_EXEC_4V); PAGE_KERNEL_LOCKED = PAGE_KERNEL; _PAGE_IE = _PAGE_IE_4V; _PAGE_E = _PAGE_E_4V; - _PAGE_CACHE = _PAGE_CACHE_4V; + _PAGE_CACHE = page_cache4v_flag; #ifdef CONFIG_DEBUG_PAGEALLOC kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; @@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void) kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ PAGE_OFFSET; #endif - kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | - _PAGE_P_4V | _PAGE_W_4V); + kern_linear_pte_xor[0] |= (page_cache4v_flag | _PAGE_P_4V | + _PAGE_W_4V); for (i = 1; i < 4; i++) kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; @@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void) _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V | _PAGE_SZ64K_4V | _PAGE_SZ8K_4V); - page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | _PAGE_CACHE_4V; - page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | + page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | page_cache4v_flag; + page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | __ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V); - page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | + page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | __ACCESS_BITS_4V | _PAGE_EXEC_4V); - page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | + page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | __ACCESS_BITS_4V | _PAGE_EXEC_4V); page_exec_bit = _PAGE_EXEC_4V; @@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr) _PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U); if (tlb_type == hypervisor) val = (_PAGE_VALID | _PAGE_SZ4MB_4V | - _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | + page_cache4v_flag | _PAGE_P_4V | _PAGE_EXEC_4V | _PAGE_W_4V); return val | paddr; diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index ef17683484e9..48304b89b601 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -1109,6 +1109,8 @@ struct boot_params *make_boot_params(struct efi_config *c) if (!cmdline_ptr) goto fail; hdr->cmd_line_ptr = (unsigned long)cmdline_ptr; + /* Fill in upper bits of command line address, NOP on 32 bit */ + boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32; hdr->ramdisk_image = 0; hdr->ramdisk_size = 0; diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 89dd0d78013a..805d25ca5f1d 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -2,15 +2,14 @@ #define BOOT_COMPRESSED_MISC_H /* - * we have to be careful, because no indirections are allowed here, and - * paravirt_ops is a kind of one. As it will only run in baremetal anyway, - * we just keep it from happening + * Special hack: we have to be careful, because no indirections are allowed here, + * and paravirt_ops is a kind of one. As it will only run in baremetal anyway, + * we just keep it from happening. (This list needs to be extended when new + * paravirt and debugging variants are added.) */ #undef CONFIG_PARAVIRT +#undef CONFIG_PARAVIRT_SPINLOCKS #undef CONFIG_KASAN -#ifdef CONFIG_X86_32 -#define _ASM_X86_DESC_H 1 -#endif #include <linux/linkage.h> #include <linux/screen_info.h> diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index e42f758a0fbd..055ea9941dd5 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -50,7 +50,7 @@ extern const struct hypervisor_x86 *x86_hyper; /* Recognized hypervisors */ extern const struct hypervisor_x86 x86_hyper_vmware; extern const struct hypervisor_x86 x86_hyper_ms_hyperv; -extern const struct hypervisor_x86 x86_hyper_xen_hvm; +extern const struct hypervisor_x86 x86_hyper_xen; extern const struct hypervisor_x86 x86_hyper_kvm; extern void init_hypervisor(struct cpuinfo_x86 *c); diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index dea2e7e962e3..f4a555beef19 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -207,6 +207,7 @@ union kvm_mmu_page_role { unsigned nxe:1; unsigned cr0_wp:1; unsigned smep_andnot_wp:1; + unsigned smap_andnot_wp:1; }; }; @@ -400,6 +401,7 @@ struct kvm_vcpu_arch { struct kvm_mmu_memory_cache mmu_page_header_cache; struct fpu guest_fpu; + bool eager_fpu; u64 xcr0; u64 guest_supported_xcr0; u32 guest_xstate_size; @@ -743,6 +745,7 @@ struct kvm_x86_ops { void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); + void (*fpu_activate)(struct kvm_vcpu *vcpu); void (*fpu_deactivate)(struct kvm_vcpu *vcpu); void (*tlb_flush)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 19507ffa5d28..5fabf1362942 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -107,7 +107,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) static inline int user_mode(struct pt_regs *regs) { #ifdef CONFIG_X86_32 - return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL; #else return !!(regs->cs & 3); #endif diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 5a9856eb12ba..7d5a1929d76b 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -231,11 +231,21 @@ #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) #ifdef __KERNEL__ + +/* + * early_idt_handler_array is an array of entry points referenced in the + * early IDT. For simplicity, it's a real array with one entry point + * every nine bytes. That leaves room for an optional 'push $0' if the + * vector has no error code (two bytes), a 'push $vector_number' (two + * bytes), and a jump to the common entry code (up to five bytes). + */ +#define EARLY_IDT_HANDLER_SIZE 9 + #ifndef __ASSEMBLY__ -extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; +extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; #ifdef CONFIG_TRACING -# define trace_early_idt_handlers early_idt_handlers +# define trace_early_idt_handler_array early_idt_handler_array #endif /* diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index cf87de3fc390..64b611782ef0 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -169,7 +169,7 @@ static inline int arch_spin_is_contended(arch_spinlock_t *lock) struct __raw_tickets tmp = READ_ONCE(lock->tickets); tmp.head &= ~TICKET_SLOWPATH_FLAG; - return (tmp.tail - tmp.head) > TICKET_LOCK_INC; + return (__ticket_t)(tmp.tail - tmp.head) > TICKET_LOCK_INC; } #define arch_spin_is_contended arch_spin_is_contended diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 358dcd338915..c44a5d53e464 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -269,4 +269,9 @@ static inline bool xen_arch_need_swiotlb(struct device *dev, return false; } +static inline unsigned long xen_get_swiotlb_free_pages(unsigned int order) +{ + return __get_free_pages(__GFP_NOWARN, order); +} + #endif /* _ASM_X86_XEN_PAGE_H */ diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index c469490db4a8..3c6bb342a48f 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -140,6 +140,7 @@ #define MSR_CORE_C3_RESIDENCY 0x000003fc #define MSR_CORE_C6_RESIDENCY 0x000003fd #define MSR_CORE_C7_RESIDENCY 0x000003fe +#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff #define MSR_PKG_C2_RESIDENCY 0x0000060d #define MSR_PKG_C8_RESIDENCY 0x00000630 #define MSR_PKG_C9_RESIDENCY 0x00000631 diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 36ce402a3fa5..d820d8eae96b 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -27,8 +27,8 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = { -#ifdef CONFIG_XEN_PVHVM - &x86_hyper_xen_hvm, +#ifdef CONFIG_XEN + &x86_hyper_xen, #endif &x86_hyper_vmware, &x86_hyper_ms_hyperv, diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index e535533d5ab8..20190bdac9d5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -708,6 +708,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, struct pt_regs *regs) { int i, ret = 0; + char *tmp; for (i = 0; i < mca_cfg.banks; i++) { m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); @@ -716,9 +717,11 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, if (quirk_no_way_out) quirk_no_way_out(i, m, regs); } - if (mce_severity(m, mca_cfg.tolerant, msg, true) >= - MCE_PANIC_SEVERITY) + + if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) { + *msg = tmp; ret = 1; + } } return ret; } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 87848ebe2bb7..4f7001f28936 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -190,6 +190,7 @@ static bool check_hw_exists(void) u64 val, val_fail, val_new= ~0; int i, reg, reg_fail, ret = 0; int bios_fail = 0; + int reg_safe = -1; /* * Check to see if the BIOS enabled any of the counters, if so @@ -204,6 +205,8 @@ static bool check_hw_exists(void) bios_fail = 1; val_fail = val; reg_fail = reg; + } else { + reg_safe = i; } } @@ -222,11 +225,22 @@ static bool check_hw_exists(void) } /* + * If all the counters are enabled, the below test will always + * fail. The tools will also become useless in this scenario. + * Just fail and disable the hardware counters. + */ + + if (reg_safe == -1) { + reg = reg_safe; + goto msr_fail; + } + + /* * Read the current value, change it and read it back to see if it * matches, this is needed to detect certain hardware emulators * (qemu/kvm) that don't trap on the MSR access and always return 0s. */ - reg = x86_pmu_event_addr(0); + reg = x86_pmu_event_addr(reg_safe); if (rdmsrl_safe(reg, &val)) goto msr_fail; val ^= 0xffffUL; @@ -611,6 +625,7 @@ struct sched_state { int event; /* event index */ int counter; /* counter index */ int unassigned; /* number of events to be assigned left */ + int nr_gp; /* number of GP counters used */ unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; }; @@ -620,27 +635,29 @@ struct sched_state { struct perf_sched { int max_weight; int max_events; - struct perf_event **events; - struct sched_state state; + int max_gp; int saved_states; + struct event_constraint **constraints; + struct sched_state state; struct sched_state saved[SCHED_STATES_MAX]; }; /* * Initialize interator that runs through all events and counters. */ -static void perf_sched_init(struct perf_sched *sched, struct perf_event **events, - int num, int wmin, int wmax) +static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints, + int num, int wmin, int wmax, int gpmax) { int idx; memset(sched, 0, sizeof(*sched)); sched->max_events = num; sched->max_weight = wmax; - sched->events = events; + sched->max_gp = gpmax; + sched->constraints = constraints; for (idx = 0; idx < num; idx++) { - if (events[idx]->hw.constraint->weight == wmin) + if (constraints[idx]->weight == wmin) break; } @@ -687,7 +704,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) if (sched->state.event >= sched->max_events) return false; - c = sched->events[sched->state.event]->hw.constraint; + c = sched->constraints[sched->state.event]; /* Prefer fixed purpose counters */ if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { idx = INTEL_PMC_IDX_FIXED; @@ -696,11 +713,16 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) goto done; } } + /* Grab the first unused counter starting with idx */ idx = sched->state.counter; for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { - if (!__test_and_set_bit(idx, sched->state.used)) + if (!__test_and_set_bit(idx, sched->state.used)) { + if (sched->state.nr_gp++ >= sched->max_gp) + return false; + goto done; + } } return false; @@ -745,7 +767,7 @@ static bool perf_sched_next_event(struct perf_sched *sched) if (sched->state.weight > sched->max_weight) return false; } - c = sched->events[sched->state.event]->hw.constraint; + c = sched->constraints[sched->state.event]; } while (c->weight != sched->state.weight); sched->state.counter = 0; /* start with first counter */ @@ -756,12 +778,12 @@ static bool perf_sched_next_event(struct perf_sched *sched) /* * Assign a counter for each event. */ -int perf_assign_events(struct perf_event **events, int n, - int wmin, int wmax, int *assign) +int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int gpmax, int *assign) { struct perf_sched sched; - perf_sched_init(&sched, events, n, wmin, wmax); + perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax); do { if (!perf_sched_find_counter(&sched)) @@ -788,9 +810,9 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) x86_pmu.start_scheduling(cpuc); for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { - hwc = &cpuc->event_list[i]->hw; + cpuc->event_constraint[i] = NULL; c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); - hwc->constraint = c; + cpuc->event_constraint[i] = c; wmin = min(wmin, c->weight); wmax = max(wmax, c->weight); @@ -801,7 +823,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) */ for (i = 0; i < n; i++) { hwc = &cpuc->event_list[i]->hw; - c = hwc->constraint; + c = cpuc->event_constraint[i]; /* never assigned */ if (hwc->idx == -1) @@ -821,9 +843,26 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) } /* slow path */ - if (i != n) - unsched = perf_assign_events(cpuc->event_list, n, wmin, - wmax, assign); + if (i != n) { + int gpmax = x86_pmu.num_counters; + + /* + * Do not allow scheduling of more than half the available + * generic counters. + * + * This helps avoid counter starvation of sibling thread by + * ensuring at most half the counters cannot be in exclusive + * mode. There is no designated counters for the limits. Any + * N/2 counters can be used. This helps with events with + * specific counter constraints. + */ + if (is_ht_workaround_enabled() && !cpuc->is_fake && + READ_ONCE(cpuc->excl_cntrs->exclusive_present)) + gpmax /= 2; + + unsched = perf_assign_events(cpuc->event_constraint, n, wmin, + wmax, gpmax, assign); + } /* * In case of success (unsched = 0), mark events as committed, @@ -840,7 +879,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) e = cpuc->event_list[i]; e->hw.flags |= PERF_X86_EVENT_COMMITTED; if (x86_pmu.commit_scheduling) - x86_pmu.commit_scheduling(cpuc, e, assign[i]); + x86_pmu.commit_scheduling(cpuc, i, assign[i]); } } @@ -1292,8 +1331,10 @@ static void x86_pmu_del(struct perf_event *event, int flags) x86_pmu.put_event_constraints(cpuc, event); /* Delete the array entry. */ - while (++i < cpuc->n_events) + while (++i < cpuc->n_events) { cpuc->event_list[i-1] = cpuc->event_list[i]; + cpuc->event_constraint[i-1] = cpuc->event_constraint[i]; + } --cpuc->n_events; perf_event_update_userpage(event); diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 6ac5cb7a9e14..ef78516850fb 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -74,6 +74,7 @@ struct event_constraint { #define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */ #define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */ #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ +#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */ struct amd_nb { @@ -134,8 +135,6 @@ enum intel_excl_state_type { struct intel_excl_states { enum intel_excl_state_type init_state[X86_PMC_IDX_MAX]; enum intel_excl_state_type state[X86_PMC_IDX_MAX]; - int num_alloc_cntrs;/* #counters allocated */ - int max_alloc_cntrs;/* max #counters allowed */ bool sched_started; /* true if scheduling has started */ }; @@ -144,6 +143,11 @@ struct intel_excl_cntrs { struct intel_excl_states states[2]; + union { + u16 has_exclusive[2]; + u32 exclusive_present; + }; + int refcnt; /* per-core: #HT threads */ unsigned core_id; /* per-core: core id */ }; @@ -172,7 +176,11 @@ struct cpu_hw_events { added in the current transaction */ int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ u64 tags[X86_PMC_IDX_MAX]; + struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ + struct event_constraint *event_constraint[X86_PMC_IDX_MAX]; + + int n_excl; /* the number of exclusive events */ unsigned int group_flag; int is_fake; @@ -519,9 +527,7 @@ struct x86_pmu { void (*put_event_constraints)(struct cpu_hw_events *cpuc, struct perf_event *event); - void (*commit_scheduling)(struct cpu_hw_events *cpuc, - struct perf_event *event, - int cntr); + void (*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr); void (*start_scheduling)(struct cpu_hw_events *cpuc); @@ -717,8 +723,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, void x86_pmu_enable_all(int added); -int perf_assign_events(struct perf_event **events, int n, - int wmin, int wmax, int *assign); +int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int gpmax, int *assign); int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); void x86_pmu_stop(struct perf_event *event, int flags); @@ -929,4 +935,8 @@ static inline struct intel_shared_regs *allocate_shared_regs(int cpu) return NULL; } +static inline int is_ht_workaround_enabled(void) +{ + return 0; +} #endif /* CONFIG_CPU_SUP_INTEL */ diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 219d3fb423a1..a1e35c9f06b9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1134,7 +1134,7 @@ static __initconst const u64 slm_hw_cache_extra_regs [ C(LL ) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS, - [ C(RESULT_MISS) ] = SLM_DMND_READ|SLM_LLC_MISS, + [ C(RESULT_MISS) ] = 0, }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS, @@ -1184,8 +1184,7 @@ static __initconst const u64 slm_hw_cache_event_ids [ C(OP_READ) ] = { /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ [ C(RESULT_ACCESS) ] = 0x01b7, - /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ - [ C(RESULT_MISS) ] = 0x01b7, + [ C(RESULT_MISS) ] = 0, }, [ C(OP_WRITE) ] = { /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ @@ -1217,7 +1216,7 @@ static __initconst const u64 slm_hw_cache_event_ids [ C(ITLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */ - [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */ + [ C(RESULT_MISS) ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */ }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = -1, @@ -1924,7 +1923,6 @@ intel_start_scheduling(struct cpu_hw_events *cpuc) xl = &excl_cntrs->states[tid]; xl->sched_started = true; - xl->num_alloc_cntrs = 0; /* * lock shared state until we are done scheduling * in stop_event_scheduling() @@ -2001,6 +1999,11 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, * across HT threads */ is_excl = c->flags & PERF_X86_EVENT_EXCL; + if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) { + event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT; + if (!cpuc->n_excl++) + WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1); + } /* * xl = state of current HT @@ -2009,18 +2012,6 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, xl = &excl_cntrs->states[tid]; xlo = &excl_cntrs->states[o_tid]; - /* - * do not allow scheduling of more than max_alloc_cntrs - * which is set to half the available generic counters. - * this helps avoid counter starvation of sibling thread - * by ensuring at most half the counters cannot be in - * exclusive mode. There is not designated counters for the - * limits. Any N/2 counters can be used. This helps with - * events with specifix counter constraints - */ - if (xl->num_alloc_cntrs++ == xl->max_alloc_cntrs) - return &emptyconstraint; - cx = c; /* @@ -2107,7 +2098,7 @@ static struct event_constraint * intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, struct perf_event *event) { - struct event_constraint *c1 = event->hw.constraint; + struct event_constraint *c1 = cpuc->event_constraint[idx]; struct event_constraint *c2; /* @@ -2151,6 +2142,11 @@ static void intel_put_excl_constraints(struct cpu_hw_events *cpuc, xl = &excl_cntrs->states[tid]; xlo = &excl_cntrs->states[o_tid]; + if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) { + hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT; + if (!--cpuc->n_excl) + WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0); + } /* * put_constraint may be called from x86_schedule_events() @@ -2189,8 +2185,6 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc, static void intel_put_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) { - struct event_constraint *c = event->hw.constraint; - intel_put_shared_regs_event_constraints(cpuc, event); /* @@ -2198,19 +2192,14 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, * all events are subject to and must call the * put_excl_constraints() routine */ - if (c && cpuc->excl_cntrs) + if (cpuc->excl_cntrs) intel_put_excl_constraints(cpuc, event); - - /* cleanup dynamic constraint */ - if (c && (c->flags & PERF_X86_EVENT_DYNAMIC)) - event->hw.constraint = NULL; } -static void intel_commit_scheduling(struct cpu_hw_events *cpuc, - struct perf_event *event, int cntr) +static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr) { struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs; - struct event_constraint *c = event->hw.constraint; + struct event_constraint *c = cpuc->event_constraint[idx]; struct intel_excl_states *xlo, *xl; int tid = cpuc->excl_thread_id; int o_tid = 1 - tid; @@ -2533,34 +2522,6 @@ ssize_t intel_event_sysfs_show(char *page, u64 config) return x86_event_sysfs_show(page, config, event); } -static __initconst const struct x86_pmu core_pmu = { - .name = "core", - .handle_irq = x86_pmu_handle_irq, - .disable_all = x86_pmu_disable_all, - .enable_all = core_pmu_enable_all, - .enable = core_pmu_enable_event, - .disable = x86_pmu_disable_event, - .hw_config = x86_pmu_hw_config, - .schedule_events = x86_schedule_events, - .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, - .perfctr = MSR_ARCH_PERFMON_PERFCTR0, - .event_map = intel_pmu_event_map, - .max_events = ARRAY_SIZE(intel_perfmon_event_map), - .apic = 1, - /* - * Intel PMCs cannot be accessed sanely above 32 bit width, - * so we install an artificial 1<<31 period regardless of - * the generic event period: - */ - .max_period = (1ULL << 31) - 1, - .get_event_constraints = intel_get_event_constraints, - .put_event_constraints = intel_put_event_constraints, - .event_constraints = intel_core_event_constraints, - .guest_get_msrs = core_guest_get_msrs, - .format_attrs = intel_arch_formats_attr, - .events_sysfs_show = intel_event_sysfs_show, -}; - struct intel_shared_regs *allocate_shared_regs(int cpu) { struct intel_shared_regs *regs; @@ -2668,8 +2629,6 @@ static void intel_pmu_cpu_starting(int cpu) cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR]; if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { - int h = x86_pmu.num_counters >> 1; - for_each_cpu(i, topology_thread_cpumask(cpu)) { struct intel_excl_cntrs *c; @@ -2683,11 +2642,6 @@ static void intel_pmu_cpu_starting(int cpu) } cpuc->excl_cntrs->core_id = core_id; cpuc->excl_cntrs->refcnt++; - /* - * set hard limit to half the number of generic counters - */ - cpuc->excl_cntrs->states[0].max_alloc_cntrs = h; - cpuc->excl_cntrs->states[1].max_alloc_cntrs = h; } } @@ -2743,6 +2697,44 @@ static struct attribute *intel_arch3_formats_attr[] = { NULL, }; +static __initconst const struct x86_pmu core_pmu = { + .name = "core", + .handle_irq = x86_pmu_handle_irq, + .disable_all = x86_pmu_disable_all, + .enable_all = core_pmu_enable_all, + .enable = core_pmu_enable_event, + .disable = x86_pmu_disable_event, + .hw_config = x86_pmu_hw_config, + .schedule_events = x86_schedule_events, + .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, + .perfctr = MSR_ARCH_PERFMON_PERFCTR0, + .event_map = intel_pmu_event_map, + .max_events = ARRAY_SIZE(intel_perfmon_event_map), + .apic = 1, + /* + * Intel PMCs cannot be accessed sanely above 32-bit width, + * so we install an artificial 1<<31 period regardless of + * the generic event period: + */ + .max_period = (1ULL<<31) - 1, + .get_event_constraints = intel_get_event_constraints, + .put_event_constraints = intel_put_event_constraints, + .event_constraints = intel_core_event_constraints, + .guest_get_msrs = core_guest_get_msrs, + .format_attrs = intel_arch_formats_attr, + .events_sysfs_show = intel_event_sysfs_show, + + /* + * Virtual (or funny metal) CPU can define x86_pmu.extra_regs + * together with PMU version 1 and thus be using core_pmu with + * shared_regs. We need following callbacks here to allocate + * it properly. + */ + .cpu_prepare = intel_pmu_cpu_prepare, + .cpu_starting = intel_pmu_cpu_starting, + .cpu_dying = intel_pmu_cpu_dying, +}; + static __initconst const struct x86_pmu intel_pmu = { .name = "Intel", .handle_irq = intel_pmu_handle_irq, diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 813f75d71175..7f73b3553e2e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -706,9 +706,9 @@ void intel_pmu_pebs_disable(struct perf_event *event) cpuc->pebs_enabled &= ~(1ULL << hwc->idx); - if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_LDLAT) + if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32)); - else if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_ST) + else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) cpuc->pebs_enabled &= ~(1ULL << 63); if (cpuc->enabled) diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c index ffe666c2c6b5..123ff1bb2f60 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_pt.c +++ b/arch/x86/kernel/cpu/perf_event_intel_pt.c @@ -151,7 +151,7 @@ static int __init pt_pmu_hw_init(void) de_attr->attr.attr.name = pt_caps[i].name; - sysfs_attr_init(&de_attrs->attr.attr); + sysfs_attr_init(&de_attr->attr.attr); de_attr->attr.attr.mode = S_IRUGO; de_attr->attr.show = pt_cap_show; @@ -615,7 +615,8 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, struct perf_output_handle *handle) { - unsigned long idx, npages, end; + unsigned long head = local64_read(&buf->head); + unsigned long idx, npages, wakeup; if (buf->snapshot) return 0; @@ -634,17 +635,26 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, buf->topa_index[buf->stop_pos]->stop = 0; buf->topa_index[buf->intr_pos]->intr = 0; - if (pt_cap_get(PT_CAP_topa_multiple_entries)) { - npages = (handle->size + 1) >> PAGE_SHIFT; - end = (local64_read(&buf->head) >> PAGE_SHIFT) + npages; - /*if (end > handle->wakeup >> PAGE_SHIFT) - end = handle->wakeup >> PAGE_SHIFT;*/ - idx = end & (buf->nr_pages - 1); - buf->stop_pos = idx; - idx = (local64_read(&buf->head) >> PAGE_SHIFT) + npages - 1; - idx &= buf->nr_pages - 1; - buf->intr_pos = idx; - } + /* how many pages till the STOP marker */ + npages = handle->size >> PAGE_SHIFT; + + /* if it's on a page boundary, fill up one more page */ + if (!offset_in_page(head + handle->size + 1)) + npages++; + + idx = (head >> PAGE_SHIFT) + npages; + idx &= buf->nr_pages - 1; + buf->stop_pos = idx; + + wakeup = handle->wakeup >> PAGE_SHIFT; + + /* in the worst case, wake up the consumer one page before hard stop */ + idx = (head >> PAGE_SHIFT) + npages - 1; + if (idx > wakeup) + idx = wakeup; + + idx &= buf->nr_pages - 1; + buf->intr_pos = idx; buf->topa_index[buf->stop_pos]->stop = 1; buf->topa_index[buf->intr_pos]->intr = 1; diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 999289b94025..358c54ad20d4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -722,6 +722,7 @@ static int __init rapl_pmu_init(void) break; case 60: /* Haswell */ case 69: /* Haswell-Celeron */ + case 61: /* Broadwell */ rapl_cntr_mask = RAPL_IDX_HSW; rapl_pmu_events_group.attrs = rapl_events_hsw_attr; break; diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index c635b8b49e93..dd319e59246b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -365,9 +365,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { - hwc = &box->event_list[i]->hw; c = uncore_get_event_constraint(box, box->event_list[i]); - hwc->constraint = c; + box->event_constraint[i] = c; wmin = min(wmin, c->weight); wmax = max(wmax, c->weight); } @@ -375,7 +374,7 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int /* fastpath, try to reuse previous register */ for (i = 0; i < n; i++) { hwc = &box->event_list[i]->hw; - c = hwc->constraint; + c = box->event_constraint[i]; /* never assigned */ if (hwc->idx == -1) @@ -395,8 +394,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int } /* slow path */ if (i != n) - ret = perf_assign_events(box->event_list, n, - wmin, wmax, assign); + ret = perf_assign_events(box->event_constraint, n, + wmin, wmax, n, assign); if (!assign || ret) { for (i = 0; i < n; i++) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 6c8c1e7e69d8..f789ec9a0133 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -97,6 +97,7 @@ struct intel_uncore_box { atomic_t refcnt; struct perf_event *events[UNCORE_PMC_IDX_MAX]; struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; + struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX]; unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; u64 tags[UNCORE_PMC_IDX_MAX]; struct pci_dev *pci_dev; diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c index 3001015b755c..4562e9e22c60 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c @@ -1,6 +1,13 @@ /* Nehalem/SandBridge/Haswell uncore support */ #include "perf_event_intel_uncore.h" +/* Uncore IMC PCI IDs */ +#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 +#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154 +#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150 +#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 +#define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04 + /* SNB event control */ #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff #define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 @@ -472,6 +479,10 @@ static const struct pci_device_id hsw_uncore_pci_ids[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, { /* end: all zeroes */ }, }; @@ -502,6 +513,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */ IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */ IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ + IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ { /* end marker */ } }; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 2b55ee6db053..5a4668136e98 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) clear_bss(); for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) - set_intr_gate(i, early_idt_handlers[i]); + set_intr_gate(i, early_idt_handler_array[i]); load_idt((const struct desc_ptr *)&idt_descr); copy_bootdata(__va(real_mode_data)); diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index d031bad9e07e..53eeb226657c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -478,21 +478,22 @@ is486: __INIT setup_once: /* - * Set up a idt with 256 entries pointing to ignore_int, - * interrupt gates. It doesn't actually load idt - that needs - * to be done on each CPU. Interrupts are enabled elsewhere, - * when we can be relatively sure everything is ok. + * Set up a idt with 256 interrupt gates that push zero if there + * is no error code and then jump to early_idt_handler_common. + * It doesn't actually load the idt - that needs to be done on + * each CPU. Interrupts are enabled elsewhere, when we can be + * relatively sure everything is ok. */ movl $idt_table,%edi - movl $early_idt_handlers,%eax + movl $early_idt_handler_array,%eax movl $NUM_EXCEPTION_VECTORS,%ecx 1: movl %eax,(%edi) movl %eax,4(%edi) /* interrupt gate, dpl=0, present */ movl $(0x8E000000 + __KERNEL_CS),2(%edi) - addl $9,%eax + addl $EARLY_IDT_HANDLER_SIZE,%eax addl $8,%edi loop 1b @@ -524,26 +525,28 @@ setup_once: andl $0,setup_once_ref /* Once is enough, thanks */ ret -ENTRY(early_idt_handlers) +ENTRY(early_idt_handler_array) # 36(%esp) %eflags # 32(%esp) %cs # 28(%esp) %eip # 24(%rsp) error code i = 0 .rept NUM_EXCEPTION_VECTORS - .if (EXCEPTION_ERRCODE_MASK >> i) & 1 - ASM_NOP2 - .else + .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 pushl $0 # Dummy error code, to make stack frame uniform .endif pushl $i # 20(%esp) Vector number - jmp early_idt_handler + jmp early_idt_handler_common i = i + 1 + .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc .endr -ENDPROC(early_idt_handlers) +ENDPROC(early_idt_handler_array) - /* This is global to keep gas from relaxing the jumps */ -ENTRY(early_idt_handler) +early_idt_handler_common: + /* + * The stack is the hardware frame, an error code or zero, and the + * vector number. + */ cld cmpl $2,(%esp) # X86_TRAP_NMI @@ -603,7 +606,7 @@ ex_entry: is_nmi: addl $8,%esp /* drop vector number and error code */ iret -ENDPROC(early_idt_handler) +ENDPROC(early_idt_handler_common) /* This is the default interrupt "handler" :-) */ ALIGN diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ae6588b301c2..df7e78057ae0 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -321,26 +321,28 @@ bad_address: jmp bad_address __INIT - .globl early_idt_handlers -early_idt_handlers: +ENTRY(early_idt_handler_array) # 104(%rsp) %rflags # 96(%rsp) %cs # 88(%rsp) %rip # 80(%rsp) error code i = 0 .rept NUM_EXCEPTION_VECTORS - .if (EXCEPTION_ERRCODE_MASK >> i) & 1 - ASM_NOP2 - .else + .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 pushq $0 # Dummy error code, to make stack frame uniform .endif pushq $i # 72(%rsp) Vector number - jmp early_idt_handler + jmp early_idt_handler_common i = i + 1 + .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc .endr +ENDPROC(early_idt_handler_array) -/* This is global to keep gas from relaxing the jumps */ -ENTRY(early_idt_handler) +early_idt_handler_common: + /* + * The stack is the hardware frame, an error code or zero, and the + * vector number. + */ cld cmpl $2,(%rsp) # X86_TRAP_NMI @@ -412,7 +414,7 @@ ENTRY(early_idt_handler) is_nmi: addq $16,%rsp # drop vector number and error code INTERRUPT_RETURN -ENDPROC(early_idt_handler) +ENDPROC(early_idt_handler_common) __INITDATA diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 009183276bb7..6185d3141219 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -173,6 +173,21 @@ static void init_thread_xstate(void) xstate_size = sizeof(struct i387_fxsave_struct); else xstate_size = sizeof(struct i387_fsave_struct); + + /* + * Quirk: we don't yet handle the XSAVES* instructions + * correctly, as we don't correctly convert between + * standard and compacted format when interfacing + * with user-space - so disable it for now. + * + * The difference is small: with recent CPUs the + * compacted format is only marginally smaller than + * the standard FPU state format. + * + * ( This is easy to backport while we are fixing + * XSAVES* support. ) + */ + setup_clear_cpu_cap(X86_FEATURE_XSAVES); } /* diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 8213da62b1b7..6e338e3b1dc0 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -57,7 +57,7 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, #endif }; -EXPORT_PER_CPU_SYMBOL_GPL(cpu_tss); +EXPORT_PER_CPU_SYMBOL(cpu_tss); #ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle); @@ -156,11 +156,13 @@ void flush_thread(void) /* FPU state will be reallocated lazily at the first use. */ drop_fpu(tsk); free_thread_xstate(tsk); - } else if (!used_math()) { - /* kthread execs. TODO: cleanup this horror. */ - if (WARN_ON(init_fpu(tsk))) - force_sig(SIGKILL, tsk); - user_fpu_begin(); + } else { + if (!tsk_used_math(tsk)) { + /* kthread execs. TODO: cleanup this horror. */ + if (WARN_ON(init_fpu(tsk))) + force_sig(SIGKILL, tsk); + user_fpu_begin(); + } restore_init_xstate(); } } diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 59b69f6a2844..1d08ad3582d0 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -16,6 +16,8 @@ #include <linux/module.h> #include <linux/vmalloc.h> #include <linux/uaccess.h> +#include <asm/i387.h> /* For use_eager_fpu. Ugh! */ +#include <asm/fpu-internal.h> /* For use_eager_fpu. Ugh! */ #include <asm/user.h> #include <asm/xsave.h> #include "cpuid.h" @@ -95,6 +97,8 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) best->ebx = xstate_required_size(vcpu->arch.xcr0, true); + vcpu->arch.eager_fpu = guest_cpuid_has_mpx(vcpu); + /* * The existing code assumes virtual address is 48-bit in the canonical * address checks; exit if it is ever changed. diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index c3b1ad9fca81..496b3695d3d3 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu) best = kvm_find_cpuid_entry(vcpu, 7, 0); return best && (best->ebx & bit(X86_FEATURE_RTM)); } + +static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + + best = kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->ebx & bit(X86_FEATURE_MPX)); +} #endif diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index d43867c33bc4..44a7d2515497 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3736,8 +3736,8 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, } } -void update_permission_bitmask(struct kvm_vcpu *vcpu, - struct kvm_mmu *mmu, bool ept) +static void update_permission_bitmask(struct kvm_vcpu *vcpu, + struct kvm_mmu *mmu, bool ept) { unsigned bit, byte, pfec; u8 map; @@ -3918,6 +3918,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu) { bool smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); + bool smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); struct kvm_mmu *context = &vcpu->arch.mmu; MMU_WARN_ON(VALID_PAGE(context->root_hpa)); @@ -3936,6 +3937,8 @@ void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu) context->base_role.cr0_wp = is_write_protection(vcpu); context->base_role.smep_andnot_wp = smep && !is_write_protection(vcpu); + context->base_role.smap_andnot_wp + = smap && !is_write_protection(vcpu); } EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu); @@ -4207,12 +4210,18 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, int bytes) { gfn_t gfn = gpa >> PAGE_SHIFT; - union kvm_mmu_page_role mask = { .word = 0 }; struct kvm_mmu_page *sp; LIST_HEAD(invalid_list); u64 entry, gentry, *spte; int npte; bool remote_flush, local_flush, zap_page; + union kvm_mmu_page_role mask = (union kvm_mmu_page_role) { + .cr0_wp = 1, + .cr4_pae = 1, + .nxe = 1, + .smep_andnot_wp = 1, + .smap_andnot_wp = 1, + }; /* * If we don't have indirect shadow pages, it means no page is @@ -4238,7 +4247,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, ++vcpu->kvm->stat.mmu_pte_write; kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE); - mask.cr0_wp = mask.cr4_pae = mask.nxe = 1; for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) { if (detect_write_misaligned(sp, gpa, bytes) || detect_write_flooding(sp)) { diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index c7d65637c851..0ada65ecddcf 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -71,8 +71,6 @@ enum { int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu); void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly); -void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - bool ept); static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) { @@ -166,6 +164,8 @@ static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, int index = (pfec >> 1) + (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); + WARN_ON(pfec & PFERR_RSVD_MASK); + return (mmu->permissions[index] >> pte_access) & 1; } diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index fd49c867b25a..6e6d115fe9b5 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -718,6 +718,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code, mmu_is_nested(vcpu)); if (likely(r != RET_MMIO_PF_INVALID)) return r; + + /* + * page fault with PFEC.RSVD = 1 is caused by shadow + * page fault, should not be used to walk guest page + * table. + */ + error_code &= ~PFERR_RSVD_MASK; }; r = mmu_topup_memory_caches(vcpu); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ce741b8650f6..9afa233b5482 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4381,6 +4381,7 @@ static struct kvm_x86_ops svm_x86_ops = { .cache_reg = svm_cache_reg, .get_rflags = svm_get_rflags, .set_rflags = svm_set_rflags, + .fpu_activate = svm_fpu_activate, .fpu_deactivate = svm_fpu_deactivate, .tlb_flush = svm_flush_tlb, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f7b61687bd79..2d73807f0d31 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10185,6 +10185,7 @@ static struct kvm_x86_ops vmx_x86_ops = { .cache_reg = vmx_cache_reg, .get_rflags = vmx_get_rflags, .set_rflags = vmx_set_rflags, + .fpu_activate = vmx_fpu_activate, .fpu_deactivate = vmx_fpu_deactivate, .tlb_flush = vmx_flush_tlb, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c73efcd03e29..ea306adbbc13 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -702,8 +702,9 @@ EXPORT_SYMBOL_GPL(kvm_set_xcr); int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { unsigned long old_cr4 = kvm_read_cr4(vcpu); - unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | - X86_CR4_PAE | X86_CR4_SMEP; + unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | + X86_CR4_SMEP | X86_CR4_SMAP; + if (cr4 & CR4_RESERVED_BITS) return 1; @@ -744,9 +745,6 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) kvm_mmu_reset_context(vcpu); - if ((cr4 ^ old_cr4) & X86_CR4_SMAP) - update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false); - if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) kvm_update_cpuid(vcpu); @@ -6197,6 +6195,8 @@ void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu) return; page = gfn_to_page(vcpu->kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT); + if (is_error_page(page)) + return; kvm_x86_ops->set_apic_access_page_addr(vcpu, page_to_phys(page)); /* @@ -7060,7 +7060,9 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) fpu_save_init(&vcpu->arch.guest_fpu); __kernel_fpu_end(); ++vcpu->stat.fpu_reload; - kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); + if (!vcpu->arch.eager_fpu) + kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu); + trace_kvm_fpu(0); } @@ -7076,11 +7078,21 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { + struct kvm_vcpu *vcpu; + if (check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0) printk_once(KERN_WARNING "kvm: SMP vm created on host with unstable TSC; " "guest TSC will not be reliable\n"); - return kvm_x86_ops->vcpu_create(kvm, id); + + vcpu = kvm_x86_ops->vcpu_create(kvm, id); + + /* + * Activate fpu unconditionally in case the guest needs eager FPU. It will be + * deactivated soon if it doesn't. + */ + kvm_x86_ops->fpu_activate(vcpu); + return vcpu; } int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 5ead4d6cf3a7..70e7444c6835 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -351,18 +351,20 @@ int arch_ioremap_pmd_supported(void) */ void *xlate_dev_mem_ptr(phys_addr_t phys) { - void *addr; - unsigned long start = phys & PAGE_MASK; + unsigned long start = phys & PAGE_MASK; + unsigned long offset = phys & ~PAGE_MASK; + unsigned long vaddr; /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */ if (page_is_ram(start >> PAGE_SHIFT)) return __va(phys); - addr = (void __force *)ioremap_cache(start, PAGE_SIZE); - if (addr) - addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK)); + vaddr = (unsigned long)ioremap_cache(start, PAGE_SIZE); + /* Only add the offset on success and return NULL if the ioremap() failed: */ + if (vaddr) + vaddr += offset; - return addr; + return (void *)vaddr; } void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr) diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 987514396c1e..ddeff4844a10 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, if (is_ereg(dst_reg)) EMIT1(0x41); EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8); + + /* emit 'movzwl eax, ax' */ + if (is_ereg(dst_reg)) + EMIT3(0x45, 0x0F, 0xB7); + else + EMIT2(0x0F, 0xB7); + EMIT1(add_2reg(0xC0, dst_reg, dst_reg)); break; case 32: /* emit 'bswap eax' to swap lower 4 bytes */ @@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, break; case BPF_ALU | BPF_END | BPF_FROM_LE: + switch (imm32) { + case 16: + /* emit 'movzwl eax, ax' to zero extend 16-bit + * into 64 bit + */ + if (is_ereg(dst_reg)) + EMIT3(0x45, 0x0F, 0xB7); + else + EMIT2(0x0F, 0xB7); + EMIT1(add_2reg(0xC0, dst_reg, dst_reg)); + break; + case 32: + /* emit 'mov eax, eax' to clear upper 32-bits */ + if (is_ereg(dst_reg)) + EMIT1(0x45); + EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg)); + break; + case 64: + /* nop */ + break; + } break; /* ST: *(u8*)(dst_reg + off) = imm */ @@ -938,7 +966,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog) } ctx.cleanup_addr = proglen; - for (pass = 0; pass < 10; pass++) { + /* JITed image shrinks with every pass and the loop iterates + * until the image stops shrinking. Very large bpf programs + * may converge on the last pass. In such case do one more + * pass to emit the final image + */ + for (pass = 0; pass < 10 || image; pass++) { proglen = do_jit(prog, addrs, image, oldproglen, &ctx); if (proglen <= 0) { image = NULL; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index e4695985f9de..14a63ed6fe09 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -325,6 +325,26 @@ static void release_pci_root_info(struct pci_host_bridge *bridge) kfree(info); } +/* + * An IO port or MMIO resource assigned to a PCI host bridge may be + * consumed by the host bridge itself or available to its child + * bus/devices. The ACPI specification defines a bit (Producer/Consumer) + * to tell whether the resource is consumed by the host bridge itself, + * but firmware hasn't used that bit consistently, so we can't rely on it. + * + * On x86 and IA64 platforms, all IO port and MMIO resources are assumed + * to be available to child bus/devices except one special case: + * IO port [0xCF8-0xCFF] is consumed by the host bridge itself + * to access PCI configuration space. + * + * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF]. + */ +static bool resource_is_pcicfg_ioport(struct resource *res) +{ + return (res->flags & IORESOURCE_IO) && + res->start == 0xCF8 && res->end == 0xCFF; +} + static void probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, int busnum, int domain, @@ -346,8 +366,8 @@ static void probe_pci_root_info(struct pci_root_info *info, "no IO and memory resources present in _CRS\n"); else resource_list_for_each_entry_safe(entry, tmp, list) { - if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || - (entry->res->flags & IORESOURCE_DISABLED)) + if ((entry->res->flags & IORESOURCE_DISABLED) || + resource_is_pcicfg_ioport(entry->res)) resource_list_destroy_entry(entry); else entry->res->name = info->name; @@ -462,9 +482,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) { - struct pci_sysdata *sd = bridge->bus->sysdata; - - ACPI_COMPANION_SET(&bridge->dev, sd->companion); + /* + * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL + * here, pci_create_root_bus() has been called by someone else and + * sysdata is likely to be different from what we expect. Let it go in + * that case. + */ + if (!bridge->dev.parent) { + struct pci_sysdata *sd = bridge->bus->sysdata; + ACPI_COMPANION_SET(&bridge->dev, sd->companion); + } return 0; } diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 275a3a8b78af..e97032069f88 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -51,7 +51,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE $(call if_changed,vdso) -HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi +HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/x86/include/uapi hostprogs-y += vdso2c quiet_cmd_vdso2c = VDSO2C $@ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 94578efd3067..46957ead3060 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1760,6 +1760,9 @@ static struct notifier_block xen_hvm_cpu_notifier = { static void __init xen_hvm_guest_init(void) { + if (xen_pv_domain()) + return; + init_hvm_pv_info(); xen_hvm_init_shared_info(); @@ -1775,6 +1778,7 @@ static void __init xen_hvm_guest_init(void) xen_hvm_init_time_ops(); xen_hvm_init_mmu_ops(); } +#endif static bool xen_nopv = false; static __init int xen_parse_nopv(char *arg) @@ -1784,14 +1788,11 @@ static __init int xen_parse_nopv(char *arg) } early_param("xen_nopv", xen_parse_nopv); -static uint32_t __init xen_hvm_platform(void) +static uint32_t __init xen_platform(void) { if (xen_nopv) return 0; - if (xen_pv_domain()) - return 0; - return xen_cpuid_base(); } @@ -1809,11 +1810,19 @@ bool xen_hvm_need_lapic(void) } EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); -const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = { - .name = "Xen HVM", - .detect = xen_hvm_platform, +static void xen_set_cpu_features(struct cpuinfo_x86 *c) +{ + if (xen_pv_domain()) + clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); +} + +const struct hypervisor_x86 x86_hyper_xen = { + .name = "Xen", + .detect = xen_platform, +#ifdef CONFIG_XEN_PVHVM .init_platform = xen_hvm_guest_init, +#endif .x2apic_available = xen_x2apic_para_available, + .set_cpu_features = xen_set_cpu_features, }; -EXPORT_SYMBOL(x86_hyper_xen_hvm); -#endif +EXPORT_SYMBOL(x86_hyper_xen); diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index d9497698645a..53b4c0811f4f 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -88,7 +88,17 @@ static void xen_vcpu_notify_restore(void *data) tick_resume_local(); } +static void xen_vcpu_notify_suspend(void *data) +{ + tick_suspend_local(); +} + void xen_arch_resume(void) { on_each_cpu(xen_vcpu_notify_restore, NULL, 1); } + +void xen_arch_suspend(void) +{ + on_each_cpu(xen_vcpu_notify_suspend, NULL, 1); +} diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 172a02a6ad14..ba78ccf651e7 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -185,4 +185,17 @@ static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, return -EINVAL; } +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) +{ + return NULL; +} + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ +} + #endif /* _XTENSA_DMA_MAPPING_H */ diff --git a/block/blk-core.c b/block/blk-core.c index fd154b94447a..03b5f8d77f37 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -552,6 +552,8 @@ void blk_cleanup_queue(struct request_queue *q) q->queue_lock = &q->__queue_lock; spin_unlock_irq(lock); + bdi_destroy(&q->backing_dev_info); + /* @q is and will stay empty, shutdown and put */ blk_put_queue(q); } @@ -732,6 +734,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) } EXPORT_SYMBOL(blk_init_queue_node); +static void blk_queue_bio(struct request_queue *q, struct bio *bio); + struct request_queue * blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, spinlock_t *lock) @@ -1576,7 +1580,7 @@ void init_request_from_bio(struct request *req, struct bio *bio) blk_rq_bio_prep(req->q, req, bio); } -void blk_queue_bio(struct request_queue *q, struct bio *bio) +static void blk_queue_bio(struct request_queue *q, struct bio *bio) { const bool sync = !!(bio->bi_rw & REQ_SYNC); struct blk_plug *plug; @@ -1684,7 +1688,6 @@ out_unlock: spin_unlock_irq(q->queue_lock); } } -EXPORT_SYMBOL_GPL(blk_queue_bio); /* for device mapper only */ /* * If bio->bi_dev is a partition, remap the location diff --git a/block/blk-mq.c b/block/blk-mq.c index ade8a2d1b0aa..e68b71b85a7e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -677,8 +677,11 @@ static void blk_mq_rq_timer(unsigned long priv) data.next = blk_rq_timeout(round_jiffies_up(data.next)); mod_timer(&q->timeout, data.next); } else { - queue_for_each_hw_ctx(q, hctx, i) - blk_mq_tag_idle(hctx); + queue_for_each_hw_ctx(q, hctx, i) { + /* the hctx may be unmapped, so check it here */ + if (blk_mq_hw_queue_mapped(hctx)) + blk_mq_tag_idle(hctx); + } } } @@ -855,6 +858,16 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) spin_lock(&hctx->lock); list_splice(&rq_list, &hctx->dispatch); spin_unlock(&hctx->lock); + /* + * the queue is expected stopped with BLK_MQ_RQ_QUEUE_BUSY, but + * it's possible the queue is stopped and restarted again + * before this. Queue restart will dispatch requests. And since + * requests in rq_list aren't added into hctx->dispatch yet, + * the requests in rq_list might get lost. + * + * blk_mq_run_hw_queue() already checks the STOPPED bit + **/ + blk_mq_run_hw_queue(hctx, true); } } @@ -1571,22 +1584,6 @@ static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu) return NOTIFY_OK; } -static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu) -{ - struct request_queue *q = hctx->queue; - struct blk_mq_tag_set *set = q->tag_set; - - if (set->tags[hctx->queue_num]) - return NOTIFY_OK; - - set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num); - if (!set->tags[hctx->queue_num]) - return NOTIFY_STOP; - - hctx->tags = set->tags[hctx->queue_num]; - return NOTIFY_OK; -} - static int blk_mq_hctx_notify(void *data, unsigned long action, unsigned int cpu) { @@ -1594,8 +1591,11 @@ static int blk_mq_hctx_notify(void *data, unsigned long action, if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) return blk_mq_hctx_cpu_offline(hctx, cpu); - else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) - return blk_mq_hctx_cpu_online(hctx, cpu); + + /* + * In case of CPU online, tags may be reallocated + * in blk_mq_map_swqueue() after mapping is updated. + */ return NOTIFY_OK; } @@ -1775,6 +1775,7 @@ static void blk_mq_map_swqueue(struct request_queue *q) unsigned int i; struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; + struct blk_mq_tag_set *set = q->tag_set; queue_for_each_hw_ctx(q, hctx, i) { cpumask_clear(hctx->cpumask); @@ -1803,16 +1804,20 @@ static void blk_mq_map_swqueue(struct request_queue *q) * disable it and free the request entries. */ if (!hctx->nr_ctx) { - struct blk_mq_tag_set *set = q->tag_set; - if (set->tags[i]) { blk_mq_free_rq_map(set, set->tags[i], i); set->tags[i] = NULL; - hctx->tags = NULL; } + hctx->tags = NULL; continue; } + /* unmapped hw queue can be remapped after CPU topo changed */ + if (!set->tags[i]) + set->tags[i] = blk_mq_init_rq_map(set, i); + hctx->tags = set->tags[i]; + WARN_ON(!hctx->tags); + /* * Set the map size to the number of mapped software queues. * This is more accurate and more efficient than looping @@ -2090,9 +2095,16 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb, */ list_for_each_entry(q, &all_q_list, all_q_node) blk_mq_freeze_queue_start(q); - list_for_each_entry(q, &all_q_list, all_q_node) + list_for_each_entry(q, &all_q_list, all_q_node) { blk_mq_freeze_queue_wait(q); + /* + * timeout handler can't touch hw queue during the + * reinitialization + */ + del_timer_sync(&q->timeout); + } + list_for_each_entry(q, &all_q_list, all_q_node) blk_mq_queue_reinit(q); diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index faaf36ade7eb..2b8fd302f677 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -522,8 +522,6 @@ static void blk_release_queue(struct kobject *kobj) blk_trace_shutdown(q); - bdi_destroy(&q->backing_dev_info); - ida_simple_remove(&blk_queue_ida, q->id); call_rcu(&q->rcu_head, blk_free_queue_rcu); } diff --git a/block/bounce.c b/block/bounce.c index ab21ba203d5c..ed9dd8067120 100644 --- a/block/bounce.c +++ b/block/bounce.c @@ -221,8 +221,8 @@ bounce: if (page_to_pfn(page) <= queue_bounce_pfn(q) && !force) continue; - inc_zone_page_state(to->bv_page, NR_BOUNCE); to->bv_page = mempool_alloc(pool, q->bounce_gfp); + inc_zone_page_state(to->bv_page, NR_BOUNCE); if (rw == WRITE) { char *vto, *vfrom; diff --git a/block/elevator.c b/block/elevator.c index 59794d0d38e3..8985038f398c 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -157,7 +157,7 @@ struct elevator_queue *elevator_alloc(struct request_queue *q, eq = kzalloc_node(sizeof(*eq), GFP_KERNEL, q->node); if (unlikely(!eq)) - goto err; + return NULL; eq->type = e; kobject_init(&eq->kobj, &elv_ktype); @@ -165,10 +165,6 @@ struct elevator_queue *elevator_alloc(struct request_queue *q, hash_init(eq->hash); return eq; -err: - kfree(eq); - elevator_put(e); - return NULL; } EXPORT_SYMBOL(elevator_alloc); diff --git a/block/genhd.c b/block/genhd.c index 0a536dc05f3b..666e11b83983 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -653,7 +653,6 @@ void del_gendisk(struct gendisk *disk) disk->flags &= ~GENHD_FL_UP; sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); - bdi_unregister(&disk->queue->backing_dev_info); blk_unregister_queue(disk); blk_unregister_region(disk_devt(disk), disk->minors); diff --git a/crypto/Kconfig b/crypto/Kconfig index 8aaf298a80e1..362905e7c841 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1512,15 +1512,6 @@ config CRYPTO_USER_API_RNG This option enables the user-spaces interface for random number generator algorithms. -config CRYPTO_USER_API_AEAD - tristate "User-space interface for AEAD cipher algorithms" - depends on NET - select CRYPTO_AEAD - select CRYPTO_USER_API - help - This option enables the user-spaces interface for AEAD - cipher algorithms. - config CRYPTO_HASH_INFO bool diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 00a6fe166fed..69abada22373 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -33,7 +33,7 @@ struct aead_ctx { /* * RSGL_MAX_ENTRIES is an artificial limit where user space at maximum * can cause the kernel to allocate RSGL_MAX_ENTRIES * ALG_MAX_PAGES - * bytes + * pages */ #define RSGL_MAX_ENTRIES ALG_MAX_PAGES struct af_alg_sgl rsgl[RSGL_MAX_ENTRIES]; @@ -435,11 +435,10 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, if (err < 0) goto unlock; usedpages += err; - /* chain the new scatterlist with initial list */ + /* chain the new scatterlist with previous one */ if (cnt) - scatterwalk_crypto_chain(ctx->rsgl[0].sg, - ctx->rsgl[cnt].sg, 1, - sg_nents(ctx->rsgl[cnt-1].sg)); + af_alg_link_sg(&ctx->rsgl[cnt-1], &ctx->rsgl[cnt]); + /* we do not need more iovecs as we have sufficient memory */ if (outlen <= usedpages) break; diff --git a/drivers/Makefile b/drivers/Makefile index 46d2554be404..9a02fb7c5106 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -98,7 +98,6 @@ obj-$(CONFIG_USB_GADGET) += usb/ obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ -obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ obj-y += i2c/ media/ obj-$(CONFIG_PPS) += pps/ diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index b193f8425999..ff6d8adc9cda 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { {"PNPb006"}, /* cs423x-pnpbios */ {"CSC0100"}, + {"CSC0103"}, + {"CSC0110"}, {"CSC0000"}, {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ /* es18xx-pnpbios */ diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a72685c1e819..5e8df9177da4 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_TZ_", ACPI_TYPE_DEVICE, NULL}, - /* - * March, 2015: - * The _REV object is in the process of being deprecated, because - * other ACPI implementations permanently return 2. Thus, it - * has little or no value. Return 2 for compatibility with - * other ACPI implementations. - */ - {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)}, + {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, - {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)}, + {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) - {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)}, + {"_OSI", ACPI_TYPE_METHOD, (char *)1}, #endif /* Table terminator */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 39748bb3a543..7ccba395c9dd 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas, request_mem_region(addr, length, desc); } -static int __init acpi_reserve_resources(void) +static void __init acpi_reserve_resources(void) { acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK"); @@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void) if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) acpi_request_region(&acpi_gbl_FADT.xgpe1_block, acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); - - return 0; } -device_initcall(acpi_reserve_resources); void acpi_os_printf(const char *fmt, ...) { @@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void) acpi_status __init acpi_os_initialize1(void) { + acpi_reserve_resources(); kacpid_wq = alloc_workqueue("kacpid", 0, 1); kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 5589a6e2a023..8244f013f210 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources); * @ares: Input ACPI resource object. * @types: Valid resource types of IORESOURCE_XXX * - * This is a hepler function to support acpi_dev_get_resources(), which filters + * This is a helper function to support acpi_dev_get_resources(), which filters * ACPI resource objects according to resource types. */ int acpi_dev_filter_resource_type(struct acpi_resource *ares, diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 26e5b5060523..bf034f8b7c1a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -14,6 +14,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/interrupt.h> +#include <linux/dmi.h> #include "sbshc.h" #define PREFIX "ACPI: " @@ -87,6 +88,8 @@ enum acpi_smb_offset { ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ }; +static bool macbook; + static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) { return ec_read(hc->offset + address, data); @@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, } mutex_lock(&hc->lock); + if (macbook) + udelay(5); if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) goto end; if (temp) { @@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, acpi_handle handle, acpi_ec_query_func func, void *data); +static int macbook_dmi_match(const struct dmi_system_id *d) +{ + pr_debug("Detected MacBook, enabling workaround\n"); + macbook = true; + return 0; +} + +static struct dmi_system_id acpi_smbus_dmi_table[] = { + { macbook_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, + }, + { }, +}; + static int acpi_smbus_hc_add(struct acpi_device *device) { int status; unsigned long long val; struct acpi_smb_hc *hc; + dmi_check_system(acpi_smbus_dmi_table); + if (!device) return -EINVAL; diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5f601553b9b0..9dca4b995be0 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -270,6 +270,7 @@ config ATA_PIIX config SATA_DWC tristate "DesignWare Cores SATA support" depends on 460EX + select DW_DMAC help This option enables support for the on-chip SATA controller of the AppliedMicro processor 460EX. @@ -729,15 +730,6 @@ config PATA_SC1200 If unsure, say N. -config PATA_SCC - tristate "Toshiba's Cell Reference Set IDE support" - depends on PCI && PPC_CELLEB - help - This option enables support for the built-in IDE controller on - Toshiba Cell Reference Board. - - If unsure, say N. - config PATA_SCH tristate "Intel SCH PATA support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b67e995179a9..40f7865f20a1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -75,7 +75,6 @@ obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o obj-$(CONFIG_PATA_RDC) += pata_rdc.o obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o -obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o obj-$(CONFIG_PATA_SIL680) += pata_sil680.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c7a92a743ed0..65ee94454bbd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -66,6 +66,7 @@ enum board_ids { board_ahci_yes_fbs, /* board IDs for specific chipsets in alphabetical order */ + board_ahci_avn, board_ahci_mcp65, board_ahci_mcp77, board_ahci_mcp89, @@ -84,6 +85,8 @@ enum board_ids { static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); +static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); static void ahci_mcp89_apple_enable(struct pci_dev *pdev); static bool is_mcp89_apple(struct pci_dev *pdev); static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, @@ -107,6 +110,11 @@ static struct ata_port_operations ahci_p5wdh_ops = { .hardreset = ahci_p5wdh_hardreset, }; +static struct ata_port_operations ahci_avn_ops = { + .inherits = &ahci_ops, + .hardreset = ahci_avn_hardreset, +}; + static const struct ata_port_info ahci_port_info[] = { /* by features */ [board_ahci] = { @@ -151,6 +159,12 @@ static const struct ata_port_info ahci_port_info[] = { .port_ops = &ahci_ops, }, /* by chipsets */ + [board_ahci_avn] = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_avn_ops, + }, [board_ahci_mcp65] = { AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ), @@ -290,14 +304,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */ - { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */ - { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */ + { PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */ + { PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ @@ -670,6 +684,79 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, return rc; } +/* + * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports. + * + * It has been observed with some SSDs that the timing of events in the + * link synchronization phase can leave the port in a state that can not + * be recovered by a SATA-hard-reset alone. The failing signature is + * SStatus.DET stuck at 1 ("Device presence detected but Phy + * communication not established"). It was found that unloading and + * reloading the driver when this problem occurs allows the drive + * connection to be recovered (DET advanced to 0x3). The critical + * component of reloading the driver is that the port state machines are + * reset by bouncing "port enable" in the AHCI PCS configuration + * register. So, reproduce that effect by bouncing a port whenever we + * see DET==1 after a reset. + */ +static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_host_priv *hpriv = ap->host->private_data; + u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; + unsigned long tmo = deadline - jiffies; + struct ata_taskfile tf; + bool online; + int rc, i; + + DPRINTK("ENTER\n"); + + ahci_stop_engine(ap); + + for (i = 0; i < 2; i++) { + u16 val; + u32 sstatus; + int port = ap->port_no; + struct ata_host *host = ap->host; + struct pci_dev *pdev = to_pci_dev(host->dev); + + /* clear D2H reception area to properly wait for D2H FIS */ + ata_tf_init(link->device, &tf); + tf.command = ATA_BUSY; + ata_tf_to_fis(&tf, 0, 0, d2h_fis); + + rc = sata_link_hardreset(link, timing, deadline, &online, + ahci_check_ready); + + if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 || + (sstatus & 0xf) != 1) + break; + + ata_link_printk(link, KERN_INFO, "avn bounce port%d\n", + port); + + pci_read_config_word(pdev, 0x92, &val); + val &= ~(1 << port); + pci_write_config_word(pdev, 0x92, val); + ata_msleep(ap, 1000); + val |= 1 << port; + pci_write_config_word(pdev, 0x92, val); + deadline += tmo; + } + + hpriv->start_engine(ap); + + if (online) + *class = ahci_dev_classify(ap); + + DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); + return rc; +} + + #ifdef CONFIG_PM static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index ea0ff005b86c..8ff428fe8e0f 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c @@ -37,7 +37,6 @@ struct st_ahci_drv_data { struct reset_control *pwr; struct reset_control *sw_rst; struct reset_control *pwr_rst; - struct ahci_host_priv *hpriv; }; static void st_ahci_configure_oob(void __iomem *mmio) @@ -55,9 +54,10 @@ static void st_ahci_configure_oob(void __iomem *mmio) writel(new_val, mmio + ST_AHCI_OOBR); } -static int st_ahci_deassert_resets(struct device *dev) +static int st_ahci_deassert_resets(struct ahci_host_priv *hpriv, + struct device *dev) { - struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); + struct st_ahci_drv_data *drv_data = hpriv->plat_data; int err; if (drv_data->pwr) { @@ -90,8 +90,8 @@ static int st_ahci_deassert_resets(struct device *dev) static void st_ahci_host_stop(struct ata_host *host) { struct ahci_host_priv *hpriv = host->private_data; + struct st_ahci_drv_data *drv_data = hpriv->plat_data; struct device *dev = host->dev; - struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); int err; if (drv_data->pwr) { @@ -103,29 +103,30 @@ static void st_ahci_host_stop(struct ata_host *host) ahci_platform_disable_resources(hpriv); } -static int st_ahci_probe_resets(struct platform_device *pdev) +static int st_ahci_probe_resets(struct ahci_host_priv *hpriv, + struct device *dev) { - struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev); + struct st_ahci_drv_data *drv_data = hpriv->plat_data; - drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn"); + drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn"); if (IS_ERR(drv_data->pwr)) { - dev_info(&pdev->dev, "power reset control not defined\n"); + dev_info(dev, "power reset control not defined\n"); drv_data->pwr = NULL; } - drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst"); + drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst"); if (IS_ERR(drv_data->sw_rst)) { - dev_info(&pdev->dev, "soft reset control not defined\n"); + dev_info(dev, "soft reset control not defined\n"); drv_data->sw_rst = NULL; } - drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst"); + drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst"); if (IS_ERR(drv_data->pwr_rst)) { - dev_dbg(&pdev->dev, "power soft reset control not defined\n"); + dev_dbg(dev, "power soft reset control not defined\n"); drv_data->pwr_rst = NULL; } - return st_ahci_deassert_resets(&pdev->dev); + return st_ahci_deassert_resets(hpriv, dev); } static struct ata_port_operations st_ahci_port_ops = { @@ -154,15 +155,12 @@ static int st_ahci_probe(struct platform_device *pdev) if (!drv_data) return -ENOMEM; - platform_set_drvdata(pdev, drv_data); - hpriv = ahci_platform_get_resources(pdev); if (IS_ERR(hpriv)) return PTR_ERR(hpriv); + hpriv->plat_data = drv_data; - drv_data->hpriv = hpriv; - - err = st_ahci_probe_resets(pdev); + err = st_ahci_probe_resets(hpriv, &pdev->dev); if (err) return err; @@ -170,7 +168,7 @@ static int st_ahci_probe(struct platform_device *pdev) if (err) return err; - st_ahci_configure_oob(drv_data->hpriv->mmio); + st_ahci_configure_oob(hpriv->mmio); err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, &ahci_platform_sht); @@ -185,8 +183,9 @@ static int st_ahci_probe(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int st_ahci_suspend(struct device *dev) { - struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = drv_data->hpriv; + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct st_ahci_drv_data *drv_data = hpriv->plat_data; int err; err = ahci_platform_suspend_host(dev); @@ -208,21 +207,21 @@ static int st_ahci_suspend(struct device *dev) static int st_ahci_resume(struct device *dev) { - struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = drv_data->hpriv; + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; int err; err = ahci_platform_enable_resources(hpriv); if (err) return err; - err = st_ahci_deassert_resets(dev); + err = st_ahci_deassert_resets(hpriv, dev); if (err) { ahci_platform_disable_resources(hpriv); return err; } - st_ahci_configure_oob(drv_data->hpriv->mmio); + st_ahci_configure_oob(hpriv->mmio); return ahci_platform_resume_host(dev); } diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 61a9c07e0dff..287c4ba0219f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1707,8 +1707,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, if (unlikely(resetting)) status &= ~PORT_IRQ_BAD_PMP; - /* if LPM is enabled, PHYRDY doesn't mean anything */ - if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + if (sata_lpm_ignore_phy_events(&ap->link)) { status &= ~PORT_IRQ_PHYRDY; ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f6cb1f1b30b7..577849c6611a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4235,7 +4235,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, - { "Samsung SSD 850 PRO*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + { "Samsung SSD 8*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, /* @@ -6752,6 +6752,38 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, return tmp; } +/** + * sata_lpm_ignore_phy_events - test if PHY event should be ignored + * @link: Link receiving the event + * + * Test whether the received PHY event has to be ignored or not. + * + * LOCKING: + * None: + * + * RETURNS: + * True if the event has to be ignored. + */ +bool sata_lpm_ignore_phy_events(struct ata_link *link) +{ + unsigned long lpm_timeout = link->last_lpm_change + + msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); + + /* if LPM is enabled, PHYRDY doesn't mean anything */ + if (link->lpm_policy > ATA_LPM_MAX_POWER) + return true; + + /* ignore the first PHY event after the LPM policy changed + * as it is might be spurious + */ + if ((link->flags & ATA_LFLAG_CHANGED) && + time_before(jiffies, lpm_timeout)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); + /* * Dummy port_ops */ diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 07f41be38fbe..cf0022ec07f2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3597,6 +3597,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, } } + link->last_lpm_change = jiffies; + link->flags |= ATA_LFLAG_CHANGED; + return 0; fail: diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c deleted file mode 100644 index 5cd60d6388ec..000000000000 --- a/drivers/ata/pata_scc.c +++ /dev/null @@ -1,1110 +0,0 @@ -/* - * Support for IDE interfaces on Celleb platform - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This code is based on drivers/ata/ata_piix.c: - * Copyright 2003-2005 Red Hat Inc - * Copyright 2003-2005 Jeff Garzik - * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat Inc - * - * and drivers/ata/ahci.c: - * Copyright 2004-2005 Red Hat, Inc. - * - * and drivers/ata/libata-core.c: - * Copyright 2003-2004 Red Hat, Inc. All rights reserved. - * Copyright 2003-2004 Jeff Garzik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/blkdev.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <scsi/scsi_host.h> -#include <linux/libata.h> - -#define DRV_NAME "pata_scc" -#define DRV_VERSION "0.3" - -#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 - -/* PCI BARs */ -#define SCC_CTRL_BAR 0 -#define SCC_BMID_BAR 1 - -/* offset of CTRL registers */ -#define SCC_CTL_PIOSHT 0x000 -#define SCC_CTL_PIOCT 0x004 -#define SCC_CTL_MDMACT 0x008 -#define SCC_CTL_MCRCST 0x00C -#define SCC_CTL_SDMACT 0x010 -#define SCC_CTL_SCRCST 0x014 -#define SCC_CTL_UDENVT 0x018 -#define SCC_CTL_TDVHSEL 0x020 -#define SCC_CTL_MODEREG 0x024 -#define SCC_CTL_ECMODE 0xF00 -#define SCC_CTL_MAEA0 0xF50 -#define SCC_CTL_MAEC0 0xF54 -#define SCC_CTL_CCKCTRL 0xFF0 - -/* offset of BMID registers */ -#define SCC_DMA_CMD 0x000 -#define SCC_DMA_STATUS 0x004 -#define SCC_DMA_TABLE_OFS 0x008 -#define SCC_DMA_INTMASK 0x010 -#define SCC_DMA_INTST 0x014 -#define SCC_DMA_PTERADD 0x018 -#define SCC_REG_CMD_ADDR 0x020 -#define SCC_REG_DATA 0x000 -#define SCC_REG_ERR 0x004 -#define SCC_REG_FEATURE 0x004 -#define SCC_REG_NSECT 0x008 -#define SCC_REG_LBAL 0x00C -#define SCC_REG_LBAM 0x010 -#define SCC_REG_LBAH 0x014 -#define SCC_REG_DEVICE 0x018 -#define SCC_REG_STATUS 0x01C -#define SCC_REG_CMD 0x01C -#define SCC_REG_ALTSTATUS 0x020 - -/* register value */ -#define TDVHSEL_MASTER 0x00000001 -#define TDVHSEL_SLAVE 0x00000004 - -#define MODE_JCUSFEN 0x00000080 - -#define ECMODE_VALUE 0x01 - -#define CCKCTRL_ATARESET 0x00040000 -#define CCKCTRL_BUFCNT 0x00020000 -#define CCKCTRL_CRST 0x00010000 -#define CCKCTRL_OCLKEN 0x00000100 -#define CCKCTRL_ATACLKOEN 0x00000002 -#define CCKCTRL_LCLKEN 0x00000001 - -#define QCHCD_IOS_SS 0x00000001 - -#define QCHSD_STPDIAG 0x00020000 - -#define INTMASK_MSK 0xD1000012 -#define INTSTS_SERROR 0x80000000 -#define INTSTS_PRERR 0x40000000 -#define INTSTS_RERR 0x10000000 -#define INTSTS_ICERR 0x01000000 -#define INTSTS_BMSINT 0x00000010 -#define INTSTS_BMHE 0x00000008 -#define INTSTS_IOIRQS 0x00000004 -#define INTSTS_INTRQ 0x00000002 -#define INTSTS_ACTEINT 0x00000001 - - -/* PIO transfer mode table */ -/* JCHST */ -static const unsigned long JCHSTtbl[2][7] = { - {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHHT */ -static const unsigned long JCHHTtbl[2][7] = { - {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHCT */ -static const unsigned long JCHCTtbl[2][7] = { - {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ - {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ -}; - -/* DMA transfer mode table */ -/* JCHDCTM/JCHDCTS */ -static const unsigned long JCHDCTxtbl[2][7] = { - {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ - {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ -}; - -/* JCSTWTM/JCSTWTS */ -static const unsigned long JCSTWTxtbl[2][7] = { - {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ - {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCTSS */ -static const unsigned long JCTSStbl[2][7] = { - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ -}; - -/* JCENVT */ -static const unsigned long JCENVTtbl[2][7] = { - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCACTSELS/JCACTSELM */ -static const unsigned long JCACTSELtbl[2][7] = { - {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ -}; - -static const struct pci_device_id scc_pci_tbl[] = { - { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0}, - { } /* terminate list */ -}; - -/** - * scc_set_piomode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring - * @adev: um - * - * Set PIO mode for device. - * - * LOCKING: - * None (inherited from caller). - */ - -static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev) -{ - unsigned int pio = adev->pio_mode - XFER_PIO_0; - void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; - void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; - void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT; - void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT; - unsigned long reg; - int offset; - - reg = in_be32(cckctrl_port); - if (reg & CCKCTRL_ATACLKOEN) - offset = 1; /* 133MHz */ - else - offset = 0; /* 100MHz */ - - reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; - out_be32(piosht_port, reg); - reg = JCHCTtbl[offset][pio]; - out_be32(pioct_port, reg); -} - -/** - * scc_set_dmamode - Initialize host controller PATA DMA timings - * @ap: Port whose timings we are configuring - * @adev: um - * - * Set UDMA mode for device. - * - * LOCKING: - * None (inherited from caller). - */ - -static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) -{ - unsigned int udma = adev->dma_mode; - unsigned int is_slave = (adev->devno != 0); - u8 speed = udma; - void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; - void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; - void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT; - void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST; - void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT; - void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST; - void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT; - void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL; - int offset, idx; - - if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN) - offset = 1; /* 133MHz */ - else - offset = 0; /* 100MHz */ - - if (speed >= XFER_UDMA_0) - idx = speed - XFER_UDMA_0; - else - return; - - if (is_slave) { - out_be32(sdmact_port, JCHDCTxtbl[offset][idx]); - out_be32(scrcst_port, JCSTWTxtbl[offset][idx]); - out_be32(tdvhsel_port, - (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2)); - } else { - out_be32(mdmact_port, JCHDCTxtbl[offset][idx]); - out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]); - out_be32(tdvhsel_port, - (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]); - } - out_be32(udenvt_port, - JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); -} - -unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) -{ - /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ - if (adev->class == ATA_DEV_ATAPI && - (mask & (0xE0 << ATA_SHIFT_UDMA))) { - printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); - mask &= ~(0xE0 << ATA_SHIFT_UDMA); - } - return mask; -} - -/** - * scc_tf_load - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Note: Original code is ata_sff_tf_load(). - */ - -static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - - if (tf->ctl != ap->last_ctl) { - out_be32(ioaddr->ctl_addr, tf->ctl); - ap->last_ctl = tf->ctl; - ata_wait_idle(ap); - } - - if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - out_be32(ioaddr->feature_addr, tf->hob_feature); - out_be32(ioaddr->nsect_addr, tf->hob_nsect); - out_be32(ioaddr->lbal_addr, tf->hob_lbal); - out_be32(ioaddr->lbam_addr, tf->hob_lbam); - out_be32(ioaddr->lbah_addr, tf->hob_lbah); - VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", - tf->hob_feature, - tf->hob_nsect, - tf->hob_lbal, - tf->hob_lbam, - tf->hob_lbah); - } - - if (is_addr) { - out_be32(ioaddr->feature_addr, tf->feature); - out_be32(ioaddr->nsect_addr, tf->nsect); - out_be32(ioaddr->lbal_addr, tf->lbal); - out_be32(ioaddr->lbam_addr, tf->lbam); - out_be32(ioaddr->lbah_addr, tf->lbah); - VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", - tf->feature, - tf->nsect, - tf->lbal, - tf->lbam, - tf->lbah); - } - - if (tf->flags & ATA_TFLAG_DEVICE) { - out_be32(ioaddr->device_addr, tf->device); - VPRINTK("device 0x%X\n", tf->device); - } - - ata_wait_idle(ap); -} - -/** - * scc_check_status - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Note: Original code is ata_check_status(). - */ - -static u8 scc_check_status (struct ata_port *ap) -{ - return in_be32(ap->ioaddr.status_addr); -} - -/** - * scc_tf_read - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Note: Original code is ata_sff_tf_read(). - */ - -static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - - tf->command = scc_check_status(ap); - tf->feature = in_be32(ioaddr->error_addr); - tf->nsect = in_be32(ioaddr->nsect_addr); - tf->lbal = in_be32(ioaddr->lbal_addr); - tf->lbam = in_be32(ioaddr->lbam_addr); - tf->lbah = in_be32(ioaddr->lbah_addr); - tf->device = in_be32(ioaddr->device_addr); - - if (tf->flags & ATA_TFLAG_LBA48) { - out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB); - tf->hob_feature = in_be32(ioaddr->error_addr); - tf->hob_nsect = in_be32(ioaddr->nsect_addr); - tf->hob_lbal = in_be32(ioaddr->lbal_addr); - tf->hob_lbam = in_be32(ioaddr->lbam_addr); - tf->hob_lbah = in_be32(ioaddr->lbah_addr); - out_be32(ioaddr->ctl_addr, tf->ctl); - ap->last_ctl = tf->ctl; - } -} - -/** - * scc_exec_command - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Note: Original code is ata_sff_exec_command(). - */ - -static void scc_exec_command (struct ata_port *ap, - const struct ata_taskfile *tf) -{ - DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); - - out_be32(ap->ioaddr.command_addr, tf->command); - ata_sff_pause(ap); -} - -/** - * scc_check_altstatus - Read device alternate status reg - * @ap: port where the device is - */ - -static u8 scc_check_altstatus (struct ata_port *ap) -{ - return in_be32(ap->ioaddr.altstatus_addr); -} - -/** - * scc_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * Note: Original code is ata_sff_dev_select(). - */ - -static void scc_dev_select (struct ata_port *ap, unsigned int device) -{ - u8 tmp; - - if (device == 0) - tmp = ATA_DEVICE_OBS; - else - tmp = ATA_DEVICE_OBS | ATA_DEV1; - - out_be32(ap->ioaddr.device_addr, tmp); - ata_sff_pause(ap); -} - -/** - * scc_set_devctl - Write device control reg - * @ap: port where the device is - * @ctl: value to write - */ - -static void scc_set_devctl(struct ata_port *ap, u8 ctl) -{ - out_be32(ap->ioaddr.ctl_addr, ctl); -} - -/** - * scc_bmdma_setup - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Note: Original code is ata_bmdma_setup(). - */ - -static void scc_bmdma_setup (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 dmactl; - void __iomem *mmio = ap->ioaddr.bmdma_addr; - - /* load PRD table addr */ - out_be32(mmio + SCC_DMA_TABLE_OFS, ap->bmdma_prd_dma); - - /* specify data direction, triple-check start bit is clear */ - dmactl = in_be32(mmio + SCC_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - out_be32(mmio + SCC_DMA_CMD, dmactl); - - /* issue r/w command */ - ap->ops->sff_exec_command(ap, &qc->tf); -} - -/** - * scc_bmdma_start - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Note: Original code is ata_bmdma_start(). - */ - -static void scc_bmdma_start (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - u8 dmactl; - void __iomem *mmio = ap->ioaddr.bmdma_addr; - - /* start host DMA transaction */ - dmactl = in_be32(mmio + SCC_DMA_CMD); - out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START); -} - -/** - * scc_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * Note: Original code is ata_devchk(). - */ - -static unsigned int scc_devchk (struct ata_port *ap, - unsigned int device) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - u8 nsect, lbal; - - ap->ops->sff_dev_select(ap, device); - - out_be32(ioaddr->nsect_addr, 0x55); - out_be32(ioaddr->lbal_addr, 0xaa); - - out_be32(ioaddr->nsect_addr, 0xaa); - out_be32(ioaddr->lbal_addr, 0x55); - - out_be32(ioaddr->nsect_addr, 0x55); - out_be32(ioaddr->lbal_addr, 0xaa); - - nsect = in_be32(ioaddr->nsect_addr); - lbal = in_be32(ioaddr->lbal_addr); - - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ - - return 0; /* nothing found */ -} - -/** - * scc_wait_after_reset - wait for devices to become ready after reset - * - * Note: Original code is ata_sff_wait_after_reset - */ - -static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, - unsigned long deadline) -{ - struct ata_port *ap = link->ap; - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int dev0 = devmask & (1 << 0); - unsigned int dev1 = devmask & (1 << 1); - int rc, ret = 0; - - /* Spec mandates ">= 2ms" before checking status. We wait - * 150ms, because that was the magic delay used for ATAPI - * devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - * - * Old drivers/ide uses the 2mS rule and then waits for ready. - */ - ata_msleep(ap, 150); - - /* always check readiness of the master device */ - rc = ata_sff_wait_ready(link, deadline); - /* -ENODEV means the odd clown forgot the D7 pulldown resistor - * and TF status is 0xff, bail out on it too. - */ - if (rc) - return rc; - - /* if device 1 was found in ata_devchk, wait for register - * access briefly, then wait for BSY to clear. - */ - if (dev1) { - int i; - - ap->ops->sff_dev_select(ap, 1); - - /* Wait for register access. Some ATAPI devices fail - * to set nsect/lbal after reset, so don't waste too - * much time on it. We're gonna wait for !BSY anyway. - */ - for (i = 0; i < 2; i++) { - u8 nsect, lbal; - - nsect = in_be32(ioaddr->nsect_addr); - lbal = in_be32(ioaddr->lbal_addr); - if ((nsect == 1) && (lbal == 1)) - break; - ata_msleep(ap, 50); /* give drive a breather */ - } - - rc = ata_sff_wait_ready(link, deadline); - if (rc) { - if (rc != -ENODEV) - return rc; - ret = rc; - } - } - - /* is all this really necessary? */ - ap->ops->sff_dev_select(ap, 0); - if (dev1) - ap->ops->sff_dev_select(ap, 1); - if (dev0) - ap->ops->sff_dev_select(ap, 0); - - return ret; -} - -/** - * scc_bus_softreset - PATA device software reset - * - * Note: Original code is ata_bus_softreset(). - */ - -static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, - unsigned long deadline) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - - DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); - - /* software reset. causes dev0 to be selected */ - out_be32(ioaddr->ctl_addr, ap->ctl); - udelay(20); - out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST); - udelay(20); - out_be32(ioaddr->ctl_addr, ap->ctl); - - return scc_wait_after_reset(&ap->link, devmask, deadline); -} - -/** - * scc_softreset - reset host port via ATA SRST - * @ap: port to reset - * @classes: resulting classes of attached devices - * @deadline: deadline jiffies for the operation - * - * Note: Original code is ata_sff_softreset(). - */ - -static int scc_softreset(struct ata_link *link, unsigned int *classes, - unsigned long deadline) -{ - struct ata_port *ap = link->ap; - unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; - unsigned int devmask = 0; - int rc; - u8 err; - - DPRINTK("ENTER\n"); - - /* determine if device 0/1 are present */ - if (scc_devchk(ap, 0)) - devmask |= (1 << 0); - if (slave_possible && scc_devchk(ap, 1)) - devmask |= (1 << 1); - - /* select device 0 again */ - ap->ops->sff_dev_select(ap, 0); - - /* issue bus reset */ - DPRINTK("about to softreset, devmask=%x\n", devmask); - rc = scc_bus_softreset(ap, devmask, deadline); - if (rc) { - ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc); - return -EIO; - } - - /* determine by signature whether we have ATA or ATAPI devices */ - classes[0] = ata_sff_dev_classify(&ap->link.device[0], - devmask & (1 << 0), &err); - if (slave_possible && err != 0x81) - classes[1] = ata_sff_dev_classify(&ap->link.device[1], - devmask & (1 << 1), &err); - - DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); - return 0; -} - -/** - * scc_bmdma_stop - Stop PCI IDE BMDMA transfer - * @qc: Command we are ending DMA for - */ - -static void scc_bmdma_stop (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; - void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR]; - u32 reg; - - while (1) { - reg = in_be32(bmid_base + SCC_DMA_INTST); - - if (reg & INTSTS_SERROR) { - printk(KERN_WARNING "%s: SERROR\n", DRV_NAME); - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT); - out_be32(bmid_base + SCC_DMA_CMD, - in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); - continue; - } - - if (reg & INTSTS_PRERR) { - u32 maea0, maec0; - maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0); - maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0); - printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0); - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT); - out_be32(bmid_base + SCC_DMA_CMD, - in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); - continue; - } - - if (reg & INTSTS_RERR) { - printk(KERN_WARNING "%s: Response Error\n", DRV_NAME); - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT); - out_be32(bmid_base + SCC_DMA_CMD, - in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); - continue; - } - - if (reg & INTSTS_ICERR) { - out_be32(bmid_base + SCC_DMA_CMD, - in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); - printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME); - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT); - continue; - } - - if (reg & INTSTS_BMSINT) { - unsigned int classes; - unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT); - printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); - /* TBD: SW reset */ - scc_softreset(&ap->link, &classes, deadline); - continue; - } - - if (reg & INTSTS_BMHE) { - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE); - continue; - } - - if (reg & INTSTS_ACTEINT) { - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT); - continue; - } - - if (reg & INTSTS_IOIRQS) { - out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS); - continue; - } - break; - } - - /* clear start/stop bit */ - out_be32(bmid_base + SCC_DMA_CMD, - in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); - - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_sff_dma_pause(ap); /* dummy read */ -} - -/** - * scc_bmdma_status - Read PCI IDE BMDMA status - * @ap: Port associated with this ATA transaction. - */ - -static u8 scc_bmdma_status (struct ata_port *ap) -{ - void __iomem *mmio = ap->ioaddr.bmdma_addr; - u8 host_stat = in_be32(mmio + SCC_DMA_STATUS); - u32 int_status = in_be32(mmio + SCC_DMA_INTST); - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); - static int retry = 0; - - /* return if IOS_SS is cleared */ - if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START)) - return host_stat; - - /* errata A252,A308 workaround: Step4 */ - if ((scc_check_altstatus(ap) & ATA_ERR) - && (int_status & INTSTS_INTRQ)) - return (host_stat | ATA_DMA_INTR); - - /* errata A308 workaround Step5 */ - if (int_status & INTSTS_IOIRQS) { - host_stat |= ATA_DMA_INTR; - - /* We don't check ATAPI DMA because it is limited to UDMA4 */ - if ((qc->tf.protocol == ATA_PROT_DMA && - qc->dev->xfer_mode > XFER_UDMA_4)) { - if (!(int_status & INTSTS_ACTEINT)) { - printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n", - ap->print_id); - host_stat |= ATA_DMA_ERR; - if (retry++) - ap->udma_mask &= ~(1 << qc->dev->xfer_mode); - } else - retry = 0; - } - } - - return host_stat; -} - -/** - * scc_data_xfer - Transfer data by PIO - * @dev: device for this I/O - * @buf: data buffer - * @buflen: buffer length - * @rw: read/write - * - * Note: Original code is ata_sff_data_xfer(). - */ - -static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, - unsigned int buflen, int rw) -{ - struct ata_port *ap = dev->link->ap; - unsigned int words = buflen >> 1; - unsigned int i; - __le16 *buf16 = (__le16 *) buf; - void __iomem *mmio = ap->ioaddr.data_addr; - - /* Transfer multiple of 2 bytes */ - if (rw == READ) - for (i = 0; i < words; i++) - buf16[i] = cpu_to_le16(in_be32(mmio)); - else - for (i = 0; i < words; i++) - out_be32(mmio, le16_to_cpu(buf16[i])); - - /* Transfer trailing 1 byte, if any. */ - if (unlikely(buflen & 0x01)) { - __le16 align_buf[1] = { 0 }; - unsigned char *trailing_buf = buf + buflen - 1; - - if (rw == READ) { - align_buf[0] = cpu_to_le16(in_be32(mmio)); - memcpy(trailing_buf, align_buf, 1); - } else { - memcpy(align_buf, trailing_buf, 1); - out_be32(mmio, le16_to_cpu(align_buf[0])); - } - words++; - } - - return words << 1; -} - -/** - * scc_postreset - standard postreset callback - * @ap: the target ata_port - * @classes: classes of attached devices - * - * Note: Original code is ata_sff_postreset(). - */ - -static void scc_postreset(struct ata_link *link, unsigned int *classes) -{ - struct ata_port *ap = link->ap; - - DPRINTK("ENTER\n"); - - /* is double-select really necessary? */ - if (classes[0] != ATA_DEV_NONE) - ap->ops->sff_dev_select(ap, 1); - if (classes[1] != ATA_DEV_NONE) - ap->ops->sff_dev_select(ap, 0); - - /* bail out if no device is present */ - if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { - DPRINTK("EXIT, no device\n"); - return; - } - - /* set up device control */ - out_be32(ap->ioaddr.ctl_addr, ap->ctl); - - DPRINTK("EXIT\n"); -} - -/** - * scc_irq_clear - Clear PCI IDE BMDMA interrupt. - * @ap: Port associated with this ATA transaction. - * - * Note: Original code is ata_bmdma_irq_clear(). - */ - -static void scc_irq_clear (struct ata_port *ap) -{ - void __iomem *mmio = ap->ioaddr.bmdma_addr; - - if (!mmio) - return; - - out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS)); -} - -/** - * scc_port_start - Set port up for dma. - * @ap: Port to initialize - * - * Allocate space for PRD table using ata_bmdma_port_start(). - * Set PRD table address for PTERADD. (PRD Transfer End Read) - */ - -static int scc_port_start (struct ata_port *ap) -{ - void __iomem *mmio = ap->ioaddr.bmdma_addr; - int rc; - - rc = ata_bmdma_port_start(ap); - if (rc) - return rc; - - out_be32(mmio + SCC_DMA_PTERADD, ap->bmdma_prd_dma); - return 0; -} - -/** - * scc_port_stop - Undo scc_port_start() - * @ap: Port to shut down - * - * Reset PTERADD. - */ - -static void scc_port_stop (struct ata_port *ap) -{ - void __iomem *mmio = ap->ioaddr.bmdma_addr; - - out_be32(mmio + SCC_DMA_PTERADD, 0); -} - -static struct scsi_host_template scc_sht = { - ATA_BMDMA_SHT(DRV_NAME), -}; - -static struct ata_port_operations scc_pata_ops = { - .inherits = &ata_bmdma_port_ops, - - .set_piomode = scc_set_piomode, - .set_dmamode = scc_set_dmamode, - .mode_filter = scc_mode_filter, - - .sff_tf_load = scc_tf_load, - .sff_tf_read = scc_tf_read, - .sff_exec_command = scc_exec_command, - .sff_check_status = scc_check_status, - .sff_check_altstatus = scc_check_altstatus, - .sff_dev_select = scc_dev_select, - .sff_set_devctl = scc_set_devctl, - - .bmdma_setup = scc_bmdma_setup, - .bmdma_start = scc_bmdma_start, - .bmdma_stop = scc_bmdma_stop, - .bmdma_status = scc_bmdma_status, - .sff_data_xfer = scc_data_xfer, - - .cable_detect = ata_cable_80wire, - .softreset = scc_softreset, - .postreset = scc_postreset, - - .sff_irq_clear = scc_irq_clear, - - .port_start = scc_port_start, - .port_stop = scc_port_stop, -}; - -static struct ata_port_info scc_port_info[] = { - { - .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = ATA_PIO4, - /* No MWDMA */ - .udma_mask = ATA_UDMA6, - .port_ops = &scc_pata_ops, - }, -}; - -/** - * scc_reset_controller - initialize SCC PATA controller. - */ - -static int scc_reset_controller(struct ata_host *host) -{ - void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR]; - void __iomem *bmid_base = host->iomap[SCC_BMID_BAR]; - void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; - void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG; - void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE; - void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK; - void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS; - u32 reg = 0; - - out_be32(cckctrl_port, reg); - reg |= CCKCTRL_ATACLKOEN; - out_be32(cckctrl_port, reg); - reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; - out_be32(cckctrl_port, reg); - reg |= CCKCTRL_CRST; - out_be32(cckctrl_port, reg); - - for (;;) { - reg = in_be32(cckctrl_port); - if (reg & CCKCTRL_CRST) - break; - udelay(5000); - } - - reg |= CCKCTRL_ATARESET; - out_be32(cckctrl_port, reg); - out_be32(ecmode_port, ECMODE_VALUE); - out_be32(mode_port, MODE_JCUSFEN); - out_be32(intmask_port, INTMASK_MSK); - - if (in_be32(dmastatus_port) & QCHSD_STPDIAG) { - printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME); - return -EIO; - } - - return 0; -} - -/** - * scc_setup_ports - initialize ioaddr with SCC PATA port offsets. - * @ioaddr: IO address structure to be initialized - * @base: base address of BMID region - */ - -static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base) -{ - ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR; - ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; - ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; - ioaddr->bmdma_addr = base; - ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA; - ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR; - ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE; - ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT; - ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL; - ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM; - ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH; - ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE; - ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS; - ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD; -} - -static int scc_host_init(struct ata_host *host) -{ - struct pci_dev *pdev = to_pci_dev(host->dev); - int rc; - - rc = scc_reset_controller(host); - if (rc) - return rc; - - rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK); - if (rc) - return rc; - rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK); - if (rc) - return rc; - - scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]); - - pci_set_master(pdev); - - return 0; -} - -/** - * scc_init_one - Register SCC PATA device with kernel services - * @pdev: PCI device to register - * @ent: Entry in scc_pci_tbl matching with @pdev - * - * LOCKING: - * Inherited from PCI layer (may sleep). - * - * RETURNS: - * Zero on success, or -ERRNO value. - */ - -static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -{ - unsigned int board_idx = (unsigned int) ent->driver_data; - const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL }; - struct ata_host *host; - int rc; - - ata_print_version_once(&pdev->dev, DRV_VERSION); - - host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1); - if (!host) - return -ENOMEM; - - rc = pcim_enable_device(pdev); - if (rc) - return rc; - - rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME); - if (rc == -EBUSY) - pcim_pin_device(pdev); - if (rc) - return rc; - host->iomap = pcim_iomap_table(pdev); - - ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl"); - ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid"); - - rc = scc_host_init(host); - if (rc) - return rc; - - return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, - IRQF_SHARED, &scc_sht); -} - -static struct pci_driver scc_pci_driver = { - .name = DRV_NAME, - .id_table = scc_pci_tbl, - .probe = scc_init_one, - .remove = ata_pci_remove_one, -#ifdef CONFIG_PM_SLEEP - .suspend = ata_pci_device_suspend, - .resume = ata_pci_device_resume, -#endif -}; - -module_pci_driver(scc_pci_driver); - -MODULE_AUTHOR("Toshiba corp"); -MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller"); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(pci, scc_pci_tbl); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 9c2ba1c97c42..df0c66cb7ad3 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -179,7 +179,7 @@ static int detect_cache_attributes(unsigned int cpu) { int ret; - if (init_cache_level(cpu)) + if (init_cache_level(cpu) || !cache_leaves(cpu)) return -ENOENT; per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), diff --git a/drivers/base/init.c b/drivers/base/init.c index da033d3bab3c..48c0e220acc0 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c @@ -8,6 +8,7 @@ #include <linux/device.h> #include <linux/init.h> #include <linux/memory.h> +#include <linux/of.h> #include "base.h" @@ -34,4 +35,5 @@ void __init driver_init(void) cpu_dev_init(); memory_dev_init(); container_dev_init(); + of_core_init(); } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ae3fcb4199e9..d7173cb1ea76 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1620,8 +1620,8 @@ out: static void loop_remove(struct loop_device *lo) { - del_gendisk(lo->lo_disk); blk_cleanup_queue(lo->lo_queue); + del_gendisk(lo->lo_disk); blk_mq_free_tag_set(&lo->tag_set); put_disk(lo->lo_disk); kfree(lo); diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 85b8036deaa3..683dff272562 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1750,6 +1750,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) struct nvme_iod *iod; dma_addr_t meta_dma = 0; void *meta = NULL; + void __user *metadata; if (copy_from_user(&io, uio, sizeof(io))) return -EFAULT; @@ -1763,6 +1764,8 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) meta_len = 0; } + metadata = (void __user *)(unsigned long)io.metadata; + write = io.opcode & 1; switch (io.opcode) { @@ -1786,13 +1789,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) if (meta_len) { meta = dma_alloc_coherent(&dev->pci_dev->dev, meta_len, &meta_dma, GFP_KERNEL); + if (!meta) { status = -ENOMEM; goto unmap; } if (write) { - if (copy_from_user(meta, (void __user *)io.metadata, - meta_len)) { + if (copy_from_user(meta, metadata, meta_len)) { status = -EFAULT; goto unmap; } @@ -1819,8 +1822,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) nvme_free_iod(dev, iod); if (meta) { if (status == NVME_SC_SUCCESS && !write) { - if (copy_to_user((void __user *)io.metadata, meta, - meta_len)) + if (copy_to_user(metadata, meta, meta_len)) status = -EFAULT; } dma_free_coherent(&dev->pci_dev->dev, meta_len, meta, meta_dma); diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index 6b736b00f63e..44f2514fb775 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -944,7 +944,8 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len) { - __be32 max_sectors = cpu_to_be32(queue_max_hw_sectors(ns->queue)); + __be32 max_sectors = cpu_to_be32( + nvme_block_nr(ns, queue_max_hw_sectors(ns->queue))); __be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors); __be32 discard_desc_count = cpu_to_be32(0x100); @@ -2256,7 +2257,8 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr, page_code = GET_INQ_PAGE_CODE(cmd); alloc_len = GET_INQ_ALLOC_LENGTH(cmd); - inq_response = kmalloc(alloc_len, GFP_KERNEL); + inq_response = kmalloc(max(alloc_len, STANDARD_INQUIRY_LENGTH), + GFP_KERNEL); if (inq_response == NULL) { res = -ENOMEM; goto out_mem; diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index bd2b3bbbb22c..713fc9ff1149 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -265,17 +265,6 @@ static void put_persistent_gnt(struct xen_blkif *blkif, atomic_dec(&blkif->persistent_gnt_in_use); } -static void free_persistent_gnts_unmap_callback(int result, - struct gntab_unmap_queue_data *data) -{ - struct completion *c = data->data; - - /* BUG_ON used to reproduce existing behaviour, - but is this the best way to deal with this? */ - BUG_ON(result); - complete(c); -} - static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, unsigned int num) { @@ -285,12 +274,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, struct rb_node *n; int segs_to_unmap = 0; struct gntab_unmap_queue_data unmap_data; - struct completion unmap_completion; - init_completion(&unmap_completion); - - unmap_data.data = &unmap_completion; - unmap_data.done = &free_persistent_gnts_unmap_callback; unmap_data.pages = pages; unmap_data.unmap_ops = unmap; unmap_data.kunmap_ops = NULL; @@ -310,8 +294,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, !rb_next(&persistent_gnt->node)) { unmap_data.count = segs_to_unmap; - gnttab_unmap_refs_async(&unmap_data); - wait_for_completion(&unmap_completion); + BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); put_free_pages(blkif, pages, segs_to_unmap); segs_to_unmap = 0; @@ -329,8 +312,13 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct persistent_gnt *persistent_gnt; - int ret, segs_to_unmap = 0; + int segs_to_unmap = 0; struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); + struct gntab_unmap_queue_data unmap_data; + + unmap_data.pages = pages; + unmap_data.unmap_ops = unmap; + unmap_data.kunmap_ops = NULL; while(!list_empty(&blkif->persistent_purge_list)) { persistent_gnt = list_first_entry(&blkif->persistent_purge_list, @@ -346,17 +334,16 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) pages[segs_to_unmap] = persistent_gnt->page; if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { - ret = gnttab_unmap_refs(unmap, NULL, pages, - segs_to_unmap); - BUG_ON(ret); + unmap_data.count = segs_to_unmap; + BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); put_free_pages(blkif, pages, segs_to_unmap); segs_to_unmap = 0; } kfree(persistent_gnt); } if (segs_to_unmap > 0) { - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); - BUG_ON(ret); + unmap_data.count = segs_to_unmap; + BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); put_free_pages(blkif, pages, segs_to_unmap); } } diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index c94386aa563d..8dcbced0eafd 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -74,6 +74,27 @@ static inline struct zram *dev_to_zram(struct device *dev) return (struct zram *)dev_to_disk(dev)->private_data; } +static ssize_t compact_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + unsigned long nr_migrated; + struct zram *zram = dev_to_zram(dev); + struct zram_meta *meta; + + down_read(&zram->init_lock); + if (!init_done(zram)) { + up_read(&zram->init_lock); + return -EINVAL; + } + + meta = zram->meta; + nr_migrated = zs_compact(meta->mem_pool); + atomic64_add(nr_migrated, &zram->stats.num_migrated); + up_read(&zram->init_lock); + + return len; +} + static ssize_t disksize_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1038,6 +1059,7 @@ static const struct block_device_operations zram_devops = { .owner = THIS_MODULE }; +static DEVICE_ATTR_WO(compact); static DEVICE_ATTR_RW(disksize); static DEVICE_ATTR_RO(initstate); static DEVICE_ATTR_WO(reset); @@ -1114,6 +1136,7 @@ static struct attribute *zram_disk_attrs[] = { &dev_attr_num_writes.attr, &dev_attr_failed_reads.attr, &dev_attr_failed_writes.attr, + &dev_attr_compact.attr, &dev_attr_invalid_io.attr, &dev_attr_notify_free.attr, &dev_attr_zero_pages.attr, diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 288547a3c566..8c81af6dbe06 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3007) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x300b) }, + { USB_DEVICE(0x04CA, 0x300f) }, { USB_DEVICE(0x04CA, 0x3010) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x0220) }, @@ -104,6 +105,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE005) }, + { USB_DEVICE(0x0CF3, 0xE006) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x13d3, 0x3393) }, @@ -143,6 +145,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, @@ -158,6 +161,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 4f7e8d400bc0..6de97b3871b0 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -227,7 +227,6 @@ static void bt3c_receive(struct bt3c_info *info) iobase = info->p_dev->resource[0]->start; avail = bt3c_read(iobase, 0x7006); - //printk("bt3c_cs: receiving %d bytes\n", avail); bt3c_address(iobase, 0x7480); while (size < avail) { @@ -250,7 +249,6 @@ static void bt3c_receive(struct bt3c_info *info) bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L); inb(iobase + DATA_H); - //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type); switch (bt_cb(info->rx_skb)->pkt_type) { @@ -364,7 +362,6 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) if (stat & 0x0001) bt3c_receive(info); if (stat & 0x0002) { - //BT_ERR("Ack (stat=0x%04x)", stat); clear_bit(XMIT_SENDING, &(info->tx_state)); bt3c_write_wakeup(info); } diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index d0741f3ed7ec..4bba86677adc 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -95,6 +95,78 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) } EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); +int btbcm_patchram(struct hci_dev *hdev, const char *firmware) +{ + const struct hci_command_hdr *cmd; + const struct firmware *fw; + const u8 *fw_ptr; + size_t fw_size; + struct sk_buff *skb; + u16 opcode; + int err; + + err = request_firmware(&fw, firmware, &hdev->dev); + if (err < 0) { + BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware); + return err; + } + + /* Start Download */ + skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: BCM: Download Minidrv command failed (%d)", + hdev->name, err); + goto done; + } + kfree_skb(skb); + + /* 50 msec delay after Download Minidrv completes */ + msleep(50); + + fw_ptr = fw->data; + fw_size = fw->size; + + while (fw_size >= sizeof(*cmd)) { + const u8 *cmd_param; + + cmd = (struct hci_command_hdr *)fw_ptr; + fw_ptr += sizeof(*cmd); + fw_size -= sizeof(*cmd); + + if (fw_size < cmd->plen) { + BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name, + firmware); + err = -EINVAL; + goto done; + } + + cmd_param = fw_ptr; + fw_ptr += cmd->plen; + fw_size -= cmd->plen; + + opcode = le16_to_cpu(cmd->opcode); + + skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: BCM: Patch command %04x failed (%d)", + hdev->name, opcode, err); + goto done; + } + kfree_skb(skb); + } + + /* 250 msec delay after Launch Ram completes */ + msleep(250); + +done: + release_firmware(fw); + return err; +} +EXPORT_SYMBOL(btbcm_patchram); + static int btbcm_reset(struct hci_dev *hdev) { struct sk_buff *skb; @@ -198,12 +270,8 @@ static const struct { int btbcm_setup_patchram(struct hci_dev *hdev) { - const struct hci_command_hdr *cmd; - const struct firmware *fw; - const u8 *fw_ptr; - size_t fw_size; char fw_name[64]; - u16 opcode, subver, rev, pid, vid; + u16 subver, rev, pid, vid; const char *hw_name = NULL; struct sk_buff *skb; struct hci_rp_read_local_version *ver; @@ -273,74 +341,19 @@ int btbcm_setup_patchram(struct hci_dev *hdev) hw_name ? : "BCM", (subver & 0x7000) >> 13, (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); - err = request_firmware(&fw, fw_name, &hdev->dev); - if (err < 0) { - BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name); + err = btbcm_patchram(hdev, fw_name); + if (err == -ENOENT) return 0; - } - - /* Start Download */ - skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - BT_ERR("%s: BCM: Download Minidrv command failed (%d)", - hdev->name, err); - goto reset; - } - kfree_skb(skb); - - /* 50 msec delay after Download Minidrv completes */ - msleep(50); - - fw_ptr = fw->data; - fw_size = fw->size; - - while (fw_size >= sizeof(*cmd)) { - const u8 *cmd_param; - - cmd = (struct hci_command_hdr *)fw_ptr; - fw_ptr += sizeof(*cmd); - fw_size -= sizeof(*cmd); - - if (fw_size < cmd->plen) { - BT_ERR("%s: BCM: patch %s is corrupted", hdev->name, - fw_name); - err = -EINVAL; - goto reset; - } - cmd_param = fw_ptr; - fw_ptr += cmd->plen; - fw_size -= cmd->plen; - - opcode = le16_to_cpu(cmd->opcode); - - skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param, - HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - BT_ERR("%s: BCM: patch command %04x failed (%d)", - hdev->name, opcode, err); - goto reset; - } - kfree_skb(skb); - } - - /* 250 msec delay after Launch Ram completes */ - msleep(250); - -reset: /* Reset */ err = btbcm_reset(hdev); if (err) - goto done; + return err; /* Read Local Version Info */ skb = btbcm_read_local_version(hdev); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - goto done; - } + if (IS_ERR(skb)) + return PTR_ERR(skb); ver = (struct hci_rp_read_local_version *)skb->data; rev = le16_to_cpu(ver->hci_rev); @@ -355,10 +368,7 @@ reset: set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); -done: - release_firmware(fw); - - return err; + return 0; } EXPORT_SYMBOL_GPL(btbcm_setup_patchram); diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index 34268ae3eb46..eb6ab5f9483d 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -25,6 +25,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev); int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); +int btbcm_patchram(struct hci_dev *hdev, const char *firmware); int btbcm_setup_patchram(struct hci_dev *hdev); int btbcm_setup_apple(struct hci_dev *hdev); @@ -41,6 +42,11 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) return -EOPNOTSUPP; } +static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware) +{ + return -EOPNOTSUPP; +} + static inline int btbcm_setup_patchram(struct hci_dev *hdev) { return 0; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index de7b236eeae7..3c10d4dfe9a7 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/usb.h> #include <linux/firmware.h> +#include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -57,6 +58,7 @@ static struct usb_driver btusb_driver; #define BTUSB_AMP 0x4000 #define BTUSB_QCA_ROME 0x8000 #define BTUSB_BCM_APPLE 0x10000 +#define BTUSB_REALTEK 0x20000 static const struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ @@ -184,6 +186,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, @@ -200,6 +203,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, @@ -216,6 +220,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, /* QCA ROME chipset */ + { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME }, @@ -288,6 +293,28 @@ static const struct usb_device_id blacklist_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), .driver_info = BTUSB_IGNORE }, + /* Realtek Bluetooth devices */ + { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), + .driver_info = BTUSB_REALTEK }, + + /* Additional Realtek 8723AE Bluetooth devices */ + { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, + + /* Additional Realtek 8723BE Bluetooth devices */ + { USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK }, + + /* Additional Realtek 8821AE Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK }, + { } /* Terminating entry */ }; @@ -892,7 +919,7 @@ static int btusb_open(struct hci_dev *hdev) */ if (data->setup_on_usb) { err = data->setup_on_usb(hdev); - if (err <0) + if (err < 0) return err; } @@ -1345,6 +1372,378 @@ static int btusb_setup_csr(struct hci_dev *hdev) return ret; } +#define RTL_FRAG_LEN 252 + +struct rtl_download_cmd { + __u8 index; + __u8 data[RTL_FRAG_LEN]; +} __packed; + +struct rtl_download_response { + __u8 status; + __u8 index; +} __packed; + +struct rtl_rom_version_evt { + __u8 status; + __u8 version; +} __packed; + +struct rtl_epatch_header { + __u8 signature[8]; + __le32 fw_version; + __le16 num_patches; +} __packed; + +#define RTL_EPATCH_SIGNATURE "Realtech" +#define RTL_ROM_LMP_3499 0x3499 +#define RTL_ROM_LMP_8723A 0x1200 +#define RTL_ROM_LMP_8723B 0x8723 +#define RTL_ROM_LMP_8821A 0x8821 +#define RTL_ROM_LMP_8761A 0x8761 + +static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) +{ + struct rtl_rom_version_evt *rom_version; + struct sk_buff *skb; + int ret; + + /* Read RTL ROM version command */ + skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + BT_ERR("%s: Read ROM version failed (%ld)", + hdev->name, PTR_ERR(skb)); + return PTR_ERR(skb); + } + + if (skb->len != sizeof(*rom_version)) { + BT_ERR("%s: RTL version event length mismatch", hdev->name); + kfree_skb(skb); + return -EIO; + } + + rom_version = (struct rtl_rom_version_evt *)skb->data; + BT_INFO("%s: rom_version status=%x version=%x", + hdev->name, rom_version->status, rom_version->version); + + ret = rom_version->status; + if (ret == 0) + *version = rom_version->version; + + kfree_skb(skb); + return ret; +} + +static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, + const struct firmware *fw, + unsigned char **_buf) +{ + const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; + struct rtl_epatch_header *epatch_info; + unsigned char *buf; + int i, ret, len; + size_t min_size; + u8 opcode, length, data, rom_version = 0; + int project_id = -1; + const unsigned char *fwptr, *chip_id_base; + const unsigned char *patch_length_base, *patch_offset_base; + u32 patch_offset = 0; + u16 patch_length, num_patches; + const u16 project_id_to_lmp_subver[] = { + RTL_ROM_LMP_8723A, + RTL_ROM_LMP_8723B, + RTL_ROM_LMP_8821A, + RTL_ROM_LMP_8761A + }; + + ret = rtl_read_rom_version(hdev, &rom_version); + if (ret) + return -bt_to_errno(ret); + + min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; + if (fw->size < min_size) + return -EINVAL; + + fwptr = fw->data + fw->size - sizeof(extension_sig); + if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { + BT_ERR("%s: extension section signature mismatch", hdev->name); + return -EINVAL; + } + + /* Loop from the end of the firmware parsing instructions, until + * we find an instruction that identifies the "project ID" for the + * hardware supported by this firwmare file. + * Once we have that, we double-check that that project_id is suitable + * for the hardware we are working with. + */ + while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) { + opcode = *--fwptr; + length = *--fwptr; + data = *--fwptr; + + BT_DBG("check op=%x len=%x data=%x", opcode, length, data); + + if (opcode == 0xff) /* EOF */ + break; + + if (length == 0) { + BT_ERR("%s: found instruction with length 0", + hdev->name); + return -EINVAL; + } + + if (opcode == 0 && length == 1) { + project_id = data; + break; + } + + fwptr -= length; + } + + if (project_id < 0) { + BT_ERR("%s: failed to find version instruction", hdev->name); + return -EINVAL; + } + + if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) { + BT_ERR("%s: unknown project id %d", hdev->name, project_id); + return -EINVAL; + } + + if (lmp_subver != project_id_to_lmp_subver[project_id]) { + BT_ERR("%s: firmware is for %x but this is a %x", hdev->name, + project_id_to_lmp_subver[project_id], lmp_subver); + return -EINVAL; + } + + epatch_info = (struct rtl_epatch_header *)fw->data; + if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { + BT_ERR("%s: bad EPATCH signature", hdev->name); + return -EINVAL; + } + + num_patches = le16_to_cpu(epatch_info->num_patches); + BT_DBG("fw_version=%x, num_patches=%d", + le32_to_cpu(epatch_info->fw_version), num_patches); + + /* After the rtl_epatch_header there is a funky patch metadata section. + * Assuming 2 patches, the layout is: + * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2 + * + * Find the right patch for this chip. + */ + min_size += 8 * num_patches; + if (fw->size < min_size) + return -EINVAL; + + chip_id_base = fw->data + sizeof(struct rtl_epatch_header); + patch_length_base = chip_id_base + (sizeof(u16) * num_patches); + patch_offset_base = patch_length_base + (sizeof(u16) * num_patches); + for (i = 0; i < num_patches; i++) { + u16 chip_id = get_unaligned_le16(chip_id_base + + (i * sizeof(u16))); + if (chip_id == rom_version + 1) { + patch_length = get_unaligned_le16(patch_length_base + + (i * sizeof(u16))); + patch_offset = get_unaligned_le32(patch_offset_base + + (i * sizeof(u32))); + break; + } + } + + if (!patch_offset) { + BT_ERR("%s: didn't find patch for chip id %d", + hdev->name, rom_version); + return -EINVAL; + } + + BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i); + min_size = patch_offset + patch_length; + if (fw->size < min_size) + return -EINVAL; + + /* Copy the firmware into a new buffer and write the version at + * the end. + */ + len = patch_length; + buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); + + *_buf = buf; + return len; +} + +static int rtl_download_firmware(struct hci_dev *hdev, + const unsigned char *data, int fw_len) +{ + struct rtl_download_cmd *dl_cmd; + int frag_num = fw_len / RTL_FRAG_LEN + 1; + int frag_len = RTL_FRAG_LEN; + int ret = 0; + int i; + + dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); + if (!dl_cmd) + return -ENOMEM; + + for (i = 0; i < frag_num; i++) { + struct rtl_download_response *dl_resp; + struct sk_buff *skb; + + BT_DBG("download fw (%d/%d)", i, frag_num); + + dl_cmd->index = i; + if (i == (frag_num - 1)) { + dl_cmd->index |= 0x80; /* data end */ + frag_len = fw_len % RTL_FRAG_LEN; + } + memcpy(dl_cmd->data, data, frag_len); + + /* Send download command */ + skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + BT_ERR("%s: download fw command failed (%ld)", + hdev->name, PTR_ERR(skb)); + ret = -PTR_ERR(skb); + goto out; + } + + if (skb->len != sizeof(*dl_resp)) { + BT_ERR("%s: download fw event length mismatch", + hdev->name); + kfree_skb(skb); + ret = -EIO; + goto out; + } + + dl_resp = (struct rtl_download_response *)skb->data; + if (dl_resp->status != 0) { + kfree_skb(skb); + ret = bt_to_errno(dl_resp->status); + goto out; + } + + kfree_skb(skb); + data += RTL_FRAG_LEN; + } + +out: + kfree(dl_cmd); + return ret; +} + +static int btusb_setup_rtl8723a(struct hci_dev *hdev) +{ + struct btusb_data *data = dev_get_drvdata(&hdev->dev); + struct usb_device *udev = interface_to_usbdev(data->intf); + const struct firmware *fw; + int ret; + + BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); + ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev); + if (ret < 0) { + BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); + return ret; + } + + if (fw->size < 8) { + ret = -EINVAL; + goto out; + } + + /* Check that the firmware doesn't have the epatch signature + * (which is only for RTL8723B and newer). + */ + if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) { + BT_ERR("%s: unexpected EPATCH signature!", hdev->name); + ret = -EINVAL; + goto out; + } + + ret = rtl_download_firmware(hdev, fw->data, fw->size); + +out: + release_firmware(fw); + return ret; +} + +static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, + const char *fw_name) +{ + struct btusb_data *data = dev_get_drvdata(&hdev->dev); + struct usb_device *udev = interface_to_usbdev(data->intf); + unsigned char *fw_data = NULL; + const struct firmware *fw; + int ret; + + BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); + ret = request_firmware(&fw, fw_name, &udev->dev); + if (ret < 0) { + BT_ERR("%s: Failed to load %s", hdev->name, fw_name); + return ret; + } + + ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); + if (ret < 0) + goto out; + + ret = rtl_download_firmware(hdev, fw_data, ret); + kfree(fw_data); + if (ret < 0) + goto out; + +out: + release_firmware(fw); + return ret; +} + +static int btusb_setup_realtek(struct hci_dev *hdev) +{ + struct sk_buff *skb; + struct hci_rp_read_local_version *resp; + u16 lmp_subver; + + skb = btusb_read_local_version(hdev); + if (IS_ERR(skb)) + return -PTR_ERR(skb); + + resp = (struct hci_rp_read_local_version *)skb->data; + BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " + "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, + resp->lmp_ver, resp->lmp_subver); + + lmp_subver = le16_to_cpu(resp->lmp_subver); + kfree_skb(skb); + + /* Match a set of subver values that correspond to stock firmware, + * which is not compatible with standard btusb. + * If matched, upload an alternative firmware that does conform to + * standard btusb. Once that firmware is uploaded, the subver changes + * to a different value. + */ + switch (lmp_subver) { + case RTL_ROM_LMP_8723A: + case RTL_ROM_LMP_3499: + return btusb_setup_rtl8723a(hdev); + case RTL_ROM_LMP_8723B: + return btusb_setup_rtl8723b(hdev, lmp_subver, + "rtl_bt/rtl8723b_fw.bin"); + case RTL_ROM_LMP_8821A: + return btusb_setup_rtl8723b(hdev, lmp_subver, + "rtl_bt/rtl8821a_fw.bin"); + case RTL_ROM_LMP_8761A: + return btusb_setup_rtl8723b(hdev, lmp_subver, + "rtl_bt/rtl8761a_fw.bin"); + default: + BT_INFO("rtl: assuming no firmware upload needed."); + return 0; + } +} + static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, struct intel_version *ver) { @@ -2577,7 +2976,7 @@ static int btusb_setup_qca(struct hci_dev *hdev) int i, err; err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver, - sizeof(ver)); + sizeof(ver)); if (err < 0) return err; @@ -2776,6 +3175,9 @@ static int btusb_probe(struct usb_interface *intf, hdev->set_bdaddr = btusb_set_bdaddr_ath3012; } + if (id->driver_info & BTUSB_REALTEK) + hdev->setup = btusb_setup_realtek; + if (id->driver_info & BTUSB_AMP) { /* AMP controllers do not support SCO packets */ data->isoc = NULL; diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 1b3f8647ea2f..ec8fa0e0f036 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -95,7 +95,6 @@ static void ath_hci_uart_work(struct work_struct *work) hci_uart_tx_wakeup(hu); } -/* Initialize protocol */ static int ath_open(struct hci_uart *hu) { struct ath_struct *ath; @@ -116,8 +115,7 @@ static int ath_open(struct hci_uart *hu) return 0; } -/* Flush protocol data */ -static int ath_flush(struct hci_uart *hu) +static int ath_close(struct hci_uart *hu) { struct ath_struct *ath = hu->priv; @@ -125,11 +123,17 @@ static int ath_flush(struct hci_uart *hu) skb_queue_purge(&ath->txq); + kfree_skb(ath->rx_skb); + + cancel_work_sync(&ath->ctxtsw); + + hu->priv = NULL; + kfree(ath); + return 0; } -/* Close protocol */ -static int ath_close(struct hci_uart *hu) +static int ath_flush(struct hci_uart *hu) { struct ath_struct *ath = hu->priv; @@ -137,19 +141,65 @@ static int ath_close(struct hci_uart *hu) skb_queue_purge(&ath->txq); - kfree_skb(ath->rx_skb); + return 0; +} - cancel_work_sync(&ath->ctxtsw); +static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) +{ + struct sk_buff *skb; + u8 buf[10]; + int err; + + buf[0] = 0x01; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = sizeof(bdaddr_t); + memcpy(buf + 4, bdaddr, sizeof(bdaddr_t)); + + skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: Change address command failed (%d)", + hdev->name, err); + return err; + } + kfree_skb(skb); - hu->priv = NULL; - kfree(ath); + return 0; +} + +static int ath_setup(struct hci_uart *hu) +{ + BT_DBG("hu %p", hu); + + hu->hdev->set_bdaddr = ath_set_bdaddr; return 0; } +static const struct h4_recv_pkt ath_recv_pkts[] = { + { H4_RECV_ACL, .recv = hci_recv_frame }, + { H4_RECV_SCO, .recv = hci_recv_frame }, + { H4_RECV_EVENT, .recv = hci_recv_frame }, +}; + +static int ath_recv(struct hci_uart *hu, const void *data, int count) +{ + struct ath_struct *ath = hu->priv; + + ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, + ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); + if (IS_ERR(ath->rx_skb)) { + int err = PTR_ERR(ath->rx_skb); + BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); + return err; + } + + return count; +} + #define HCI_OP_ATH_SLEEP 0xFC04 -/* Enqueue frame for transmittion */ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct ath_struct *ath = hu->priv; @@ -159,8 +209,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) return 0; } - /* - * Update power management enable flag with parameters of + /* Update power management enable flag with parameters of * HCI sleep enable vendor specific HCI command. */ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { @@ -190,37 +239,16 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) return skb_dequeue(&ath->txq); } -static const struct h4_recv_pkt ath_recv_pkts[] = { - { H4_RECV_ACL, .recv = hci_recv_frame }, - { H4_RECV_SCO, .recv = hci_recv_frame }, - { H4_RECV_EVENT, .recv = hci_recv_frame }, -}; - -/* Recv data */ -static int ath_recv(struct hci_uart *hu, const void *data, int count) -{ - struct ath_struct *ath = hu->priv; - - ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, - ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); - if (IS_ERR(ath->rx_skb)) { - int err = PTR_ERR(ath->rx_skb); - BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); - return err; - } - - return count; -} - static const struct hci_uart_proto athp = { .id = HCI_UART_ATH3K, .name = "ATH3K", .open = ath_open, .close = ath_close, + .flush = ath_flush, + .setup = ath_setup, .recv = ath_recv, .enqueue = ath_enqueue, .dequeue = ath_dequeue, - .flush = ath_flush, }; int __init ath_init(void) diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index b854125e4831..5340604b23a4 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -660,7 +660,7 @@ validate_group(struct perf_event *event) * Initialise the fake PMU. We only need to populate the * used_mask for the purposes of validation. */ - .used_mask = CPU_BITS_NONE, + .used_mask = { 0 }, }; if (!validate_event(event->pmu, &fake_pmu, leader)) diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c index 5bd792c68f9b..ab3bde16ecb4 100644 --- a/drivers/bus/mips_cdmm.c +++ b/drivers/bus/mips_cdmm.c @@ -453,7 +453,7 @@ void __iomem *mips_cdmm_early_probe(unsigned int dev_type) /* Look for a specific device type */ for (; drb < bus->drbs; drb += size + 1) { - acsr = readl(cdmm + drb * CDMM_DRB_SIZE); + acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE); type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT; if (type == dev_type) return cdmm + drb * CDMM_DRB_SIZE; @@ -500,7 +500,7 @@ static void mips_cdmm_bus_discover(struct mips_cdmm_bus *bus) bus->discovered = true; pr_info("cdmm%u discovery (%u blocks)\n", cpu, bus->drbs); for (; drb < bus->drbs; drb += size + 1) { - acsr = readl(cdmm + drb * CDMM_DRB_SIZE); + acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE); type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT; size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT; rev = (acsr & CDMM_ACSR_DEVREV) >> CDMM_ACSR_DEVREV_SHIFT; diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index 11f7982cbdb3..ebee57d715d2 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -1,7 +1,7 @@ /* * OMAP L3 Interconnect error handling driver * - * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/ * Santosh Shilimkar <santosh.shilimkar@ti.com> * Sricharan <r.sricharan@ti.com> * @@ -233,7 +233,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) } static const struct of_device_id l3_noc_match[] = { - {.compatible = "ti,omap4-l3-noc", .data = &omap_l3_data}, + {.compatible = "ti,omap4-l3-noc", .data = &omap4_l3_data}, + {.compatible = "ti,omap5-l3-noc", .data = &omap5_l3_data}, {.compatible = "ti,dra7-l3-noc", .data = &dra_l3_data}, {.compatible = "ti,am4372-l3-noc", .data = &am4372_l3_data}, {}, diff --git a/drivers/bus/omap_l3_noc.h b/drivers/bus/omap_l3_noc.h index 95254585db86..73431f81da28 100644 --- a/drivers/bus/omap_l3_noc.h +++ b/drivers/bus/omap_l3_noc.h @@ -1,7 +1,7 @@ /* * OMAP L3 Interconnect error handling driver header * - * Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/ * Santosh Shilimkar <santosh.shilimkar@ti.com> * sricharan <r.sricharan@ti.com> * @@ -175,16 +175,14 @@ static struct l3_flagmux_data omap_l3_flagmux_clk2 = { }; -static struct l3_target_data omap_l3_target_data_clk3[] = { - {0x0100, "EMUSS",}, - {0x0300, "DEBUG SOURCE",}, - {0x0, "HOST CLK3",}, +static struct l3_target_data omap4_l3_target_data_clk3[] = { + {0x0100, "DEBUGSS",}, }; -static struct l3_flagmux_data omap_l3_flagmux_clk3 = { +static struct l3_flagmux_data omap4_l3_flagmux_clk3 = { .offset = 0x0200, - .l3_targ = omap_l3_target_data_clk3, - .num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk3), + .l3_targ = omap4_l3_target_data_clk3, + .num_targ_data = ARRAY_SIZE(omap4_l3_target_data_clk3), }; static struct l3_masters_data omap_l3_masters[] = { @@ -215,21 +213,49 @@ static struct l3_masters_data omap_l3_masters[] = { { 0x32, "USBHOSTFS"} }; -static struct l3_flagmux_data *omap_l3_flagmux[] = { +static struct l3_flagmux_data *omap4_l3_flagmux[] = { &omap_l3_flagmux_clk1, &omap_l3_flagmux_clk2, - &omap_l3_flagmux_clk3, + &omap4_l3_flagmux_clk3, }; -static const struct omap_l3 omap_l3_data = { - .l3_flagmux = omap_l3_flagmux, - .num_modules = ARRAY_SIZE(omap_l3_flagmux), +static const struct omap_l3 omap4_l3_data = { + .l3_flagmux = omap4_l3_flagmux, + .num_modules = ARRAY_SIZE(omap4_l3_flagmux), .l3_masters = omap_l3_masters, .num_masters = ARRAY_SIZE(omap_l3_masters), /* The 6 MSBs of register field used to distinguish initiator */ .mst_addr_mask = 0xFC, }; +/* OMAP5 data */ +static struct l3_target_data omap5_l3_target_data_clk3[] = { + {0x0100, "L3INSTR",}, + {0x0300, "DEBUGSS",}, + {0x0, "HOSTCLK3",}, +}; + +static struct l3_flagmux_data omap5_l3_flagmux_clk3 = { + .offset = 0x0200, + .l3_targ = omap5_l3_target_data_clk3, + .num_targ_data = ARRAY_SIZE(omap5_l3_target_data_clk3), +}; + +static struct l3_flagmux_data *omap5_l3_flagmux[] = { + &omap_l3_flagmux_clk1, + &omap_l3_flagmux_clk2, + &omap5_l3_flagmux_clk3, +}; + +static const struct omap_l3 omap5_l3_data = { + .l3_flagmux = omap5_l3_flagmux, + .num_modules = ARRAY_SIZE(omap5_l3_flagmux), + .l3_masters = omap_l3_masters, + .num_masters = ARRAY_SIZE(omap_l3_masters), + /* The 6 MSBs of register field used to distinguish initiator */ + .mst_addr_mask = 0x7E0, +}; + /* DRA7 data */ static struct l3_target_data dra_l3_target_data_clk1[] = { {0x2a00, "AES1",}, @@ -274,7 +300,7 @@ static struct l3_flagmux_data dra_l3_flagmux_clk1 = { static struct l3_target_data dra_l3_target_data_clk2[] = { {0x0, "HOST CLK1",}, - {0x0, "HOST CLK2",}, + {0x800000, "HOST CLK2",}, {0xdead, L3_TARGET_NOT_SUPPORTED,}, {0x3400, "SHA2_2",}, {0x0900, "BB2D",}, diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index d1494ecd9e11..4b31f1387f37 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -57,7 +57,7 @@ static void bcm63xx_rng_cleanup(struct hwrng *rng) val &= ~RNG_EN; __raw_writel(val, priv->regs + RNG_CTRL); - clk_didsable_unprepare(prov->clk); + clk_disable_unprepare(priv->clk); } static int bcm63xx_rng_data_present(struct hwrng *rng, int wait) @@ -97,14 +97,14 @@ static int bcm63xx_rng_probe(struct platform_device *pdev) priv->rng.name = pdev->name; priv->rng.init = bcm63xx_rng_init; priv->rng.cleanup = bcm63xx_rng_cleanup; - prov->rng.data_present = bcm63xx_rng_data_present; + priv->rng.data_present = bcm63xx_rng_data_present; priv->rng.data_read = bcm63xx_rng_data_read; priv->clk = devm_clk_get(&pdev->dev, "ipsec"); if (IS_ERR(priv->clk)) { - error = PTR_ERR(priv->clk); - dev_err(&pdev->dev, "no clock for device: %d\n", error); - return error; + ret = PTR_ERR(priv->clk); + dev_err(&pdev->dev, "no clock for device: %d\n", ret); + return ret; } if (!devm_request_mem_region(&pdev->dev, r->start, @@ -120,11 +120,11 @@ static int bcm63xx_rng_probe(struct platform_device *pdev) return -ENOMEM; } - error = devm_hwrng_register(&pdev->dev, &priv->rng); - if (error) { + ret = devm_hwrng_register(&pdev->dev, &priv->rng); + if (ret) { dev_err(&pdev->dev, "failed to register rng device: %d\n", - error); - return error; + ret); + return ret; } dev_info(&pdev->dev, "registered RNG driver\n"); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 9bb592872532..bf75f6361773 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2000,7 +2000,7 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v) seq_printf(m, " %x", intf->channels[i].address); seq_putc(m, '\n'); - return seq_has_overflowed(m); + return 0; } static int smi_ipmb_proc_open(struct inode *inode, struct file *file) @@ -2023,7 +2023,7 @@ static int smi_version_proc_show(struct seq_file *m, void *v) ipmi_version_major(&intf->bmc->id), ipmi_version_minor(&intf->bmc->id)); - return seq_has_overflowed(m); + return 0; } static int smi_version_proc_open(struct inode *inode, struct file *file) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5e90a18afbaf..8a45e92ff60c 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -942,8 +942,7 @@ static void sender(void *send_info, * If we are running to completion, start it and run * transactions until everything is clear. */ - smi_info->curr_msg = msg; - smi_info->waiting_msg = NULL; + smi_info->waiting_msg = msg; /* * Run to completion means we are single-threaded, no @@ -2244,7 +2243,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, acpi_handle handle; acpi_status status; unsigned long long tmp; - int rv; + int rv = -EINVAL; acpi_dev = pnp_acpi_device(dev); if (!acpi_dev) @@ -2262,8 +2261,10 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, /* _IFT tells us the interface type: KCS, BT, etc */ status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n"); goto err_free; + } switch (tmp) { case 1: @@ -2276,6 +2277,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, info->si_type = SI_BT; break; case 4: /* SSIF, just ignore */ + rv = -ENODEV; goto err_free; default: dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); @@ -2336,7 +2338,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, err_free: kfree(info); - return -EINVAL; + return rv; } static void ipmi_pnp_remove(struct pnp_dev *dev) @@ -3080,7 +3082,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v) seq_printf(m, "%s\n", si_to_str[smi->si_type]); - return seq_has_overflowed(m); + return 0; } static int smi_type_proc_open(struct inode *inode, struct file *file) @@ -3153,7 +3155,7 @@ static int smi_params_proc_show(struct seq_file *m, void *v) smi->irq, smi->slave_addr); - return seq_has_overflowed(m); + return 0; } static int smi_params_proc_open(struct inode *inode, struct file *file) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index f40e3bd2c69c..207689c444a8 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -31,7 +31,6 @@ * interface into the I2C driver, I believe. */ -#include <linux/version.h> #if defined(MODVERSIONS) #include <linux/modversions.h> #endif @@ -166,6 +165,9 @@ enum ssif_stat_indexes { /* Number of watchdog pretimeouts. */ SSIF_STAT_watchdog_pretimeouts, + /* Number of alers received. */ + SSIF_STAT_alerts, + /* Always add statistics before this value, it must be last. */ SSIF_NUM_STATS }; @@ -214,7 +216,16 @@ struct ssif_info { #define WDT_PRE_TIMEOUT_INT 0x08 unsigned char msg_flags; + u8 global_enables; bool has_event_buffer; + bool supports_alert; + + /* + * Used to tell what we should do with alerts. If we are + * waiting on a response, read the data immediately. + */ + bool got_alert; + bool waiting_alert; /* * If set to true, this will request events the next time the @@ -478,13 +489,13 @@ static int ipmi_ssif_thread(void *data) if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) { result = i2c_smbus_write_block_data( - ssif_info->client, SSIF_IPMI_REQUEST, + ssif_info->client, ssif_info->i2c_command, ssif_info->i2c_data[0], ssif_info->i2c_data + 1); ssif_info->done_handler(ssif_info, result, NULL, 0); } else { result = i2c_smbus_read_block_data( - ssif_info->client, SSIF_IPMI_RESPONSE, + ssif_info->client, ssif_info->i2c_command, ssif_info->i2c_data); if (result < 0) ssif_info->done_handler(ssif_info, result, @@ -518,15 +529,12 @@ static int ssif_i2c_send(struct ssif_info *ssif_info, static void msg_done_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len); -static void retry_timeout(unsigned long data) +static void start_get(struct ssif_info *ssif_info) { - struct ssif_info *ssif_info = (void *) data; int rv; - if (ssif_info->stopping) - return; - ssif_info->rtc_us_timer = 0; + ssif_info->multi_pos = 0; rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, SSIF_IPMI_RESPONSE, @@ -540,6 +548,46 @@ static void retry_timeout(unsigned long data) } } +static void retry_timeout(unsigned long data) +{ + struct ssif_info *ssif_info = (void *) data; + unsigned long oflags, *flags; + bool waiting; + + if (ssif_info->stopping) + return; + + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + waiting = ssif_info->waiting_alert; + ssif_info->waiting_alert = false; + ipmi_ssif_unlock_cond(ssif_info, flags); + + if (waiting) + start_get(ssif_info); +} + + +static void ssif_alert(struct i2c_client *client, unsigned int data) +{ + struct ssif_info *ssif_info = i2c_get_clientdata(client); + unsigned long oflags, *flags; + bool do_get = false; + + ssif_inc_stat(ssif_info, alerts); + + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + if (ssif_info->waiting_alert) { + ssif_info->waiting_alert = false; + del_timer(&ssif_info->retry_timer); + do_get = true; + } else if (ssif_info->curr_msg) { + ssif_info->got_alert = true; + } + ipmi_ssif_unlock_cond(ssif_info, flags); + if (do_get) + start_get(ssif_info); +} + static int start_resend(struct ssif_info *ssif_info); static void msg_done_handler(struct ssif_info *ssif_info, int result, @@ -559,9 +607,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, if (ssif_info->retries_left > 0) { ssif_inc_stat(ssif_info, receive_retries); + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + ssif_info->waiting_alert = true; + ssif_info->rtc_us_timer = SSIF_MSG_USEC; mod_timer(&ssif_info->retry_timer, jiffies + SSIF_MSG_JIFFIES); - ssif_info->rtc_us_timer = SSIF_MSG_USEC; + ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -581,9 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, ssif_inc_stat(ssif_info, received_message_parts); /* Remove the multi-part read marker. */ - for (i = 0; i < (len-2); i++) - ssif_info->data[i] = data[i+2]; len -= 2; + for (i = 0; i < len; i++) + ssif_info->data[i] = data[i+2]; ssif_info->multi_len = len; ssif_info->multi_pos = 1; @@ -610,9 +661,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, goto continue_op; } - blocknum = data[ssif_info->multi_len]; + blocknum = data[0]; - if (ssif_info->multi_len+len-1 > IPMI_MAX_MSG_LENGTH) { + if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) { /* Received message too big, abort the operation. */ result = -E2BIG; if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) @@ -622,15 +673,15 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } /* Remove the blocknum from the data. */ - for (i = 0; i < (len-1); i++) - ssif_info->data[i+ssif_info->multi_len] = data[i+1]; len--; + for (i = 0; i < len; i++) + ssif_info->data[i + ssif_info->multi_len] = data[i + 1]; ssif_info->multi_len += len; if (blocknum == 0xff) { /* End of read */ len = ssif_info->multi_len; data = ssif_info->data; - } else if ((blocknum+1) != ssif_info->multi_pos) { + } else if (blocknum + 1 != ssif_info->multi_pos) { /* * Out of sequence block, just abort. Block * numbers start at zero for the second block, @@ -650,7 +701,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, if (rv < 0) { if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) pr_info(PFX - "Error from i2c_non_blocking_op(2)\n"); + "Error from ssif_i2c_send\n"); result = -EIO; } else @@ -830,7 +881,11 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, } if (ssif_info->multi_data) { - /* In the middle of a multi-data write. */ + /* + * In the middle of a multi-data write. See the comment + * in the SSIF_MULTI_n_PART case in the probe function + * for details on the intricacies of this. + */ int left; ssif_inc_stat(ssif_info, sent_messages_parts); @@ -864,15 +919,32 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, msg_done_handler(ssif_info, -EIO, NULL, 0); } } else { + unsigned long oflags, *flags; + bool got_alert; + ssif_inc_stat(ssif_info, sent_messages); ssif_inc_stat(ssif_info, sent_messages_parts); - /* Wait a jiffie then request the next message */ - ssif_info->retries_left = SSIF_RECV_RETRIES; - ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; - mod_timer(&ssif_info->retry_timer, - jiffies + SSIF_MSG_PART_JIFFIES); - return; + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + got_alert = ssif_info->got_alert; + if (got_alert) { + ssif_info->got_alert = false; + ssif_info->waiting_alert = false; + } + + if (got_alert) { + ipmi_ssif_unlock_cond(ssif_info, flags); + /* The alert already happened, try now. */ + retry_timeout((unsigned long) ssif_info); + } else { + /* Wait a jiffie then request the next message */ + ssif_info->waiting_alert = true; + ssif_info->retries_left = SSIF_RECV_RETRIES; + ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; + mod_timer(&ssif_info->retry_timer, + jiffies + SSIF_MSG_PART_JIFFIES); + ipmi_ssif_unlock_cond(ssif_info, flags); + } } } @@ -881,6 +953,8 @@ static int start_resend(struct ssif_info *ssif_info) int rv; int command; + ssif_info->got_alert = false; + if (ssif_info->data_len > 32) { command = SSIF_IPMI_MULTI_PART_REQUEST_START; ssif_info->multi_data = ssif_info->data; @@ -915,7 +989,7 @@ static int start_send(struct ssif_info *ssif_info, return -E2BIG; ssif_info->retries_left = SSIF_SEND_RETRIES; - memcpy(ssif_info->data+1, data, len); + memcpy(ssif_info->data + 1, data, len); ssif_info->data_len = len; return start_resend(ssif_info); } @@ -1200,7 +1274,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v) { seq_puts(m, "ssif\n"); - return seq_has_overflowed(m); + return 0; } static int smi_type_proc_open(struct inode *inode, struct file *file) @@ -1243,6 +1317,8 @@ static int smi_stats_proc_show(struct seq_file *m, void *v) ssif_get_stat(ssif_info, events)); seq_printf(m, "watchdog_pretimeouts: %u\n", ssif_get_stat(ssif_info, watchdog_pretimeouts)); + seq_printf(m, "alerts: %u\n", + ssif_get_stat(ssif_info, alerts)); return 0; } @@ -1258,6 +1334,23 @@ static const struct file_operations smi_stats_proc_ops = { .release = single_release, }; +static int strcmp_nospace(char *s1, char *s2) +{ + while (*s1 && *s2) { + while (isspace(*s1)) + s1++; + while (isspace(*s2)) + s2++; + if (*s1 > *s2) + return 1; + if (*s1 < *s2) + return -1; + s1++; + s2++; + } + return 0; +} + static struct ssif_addr_info *ssif_info_find(unsigned short addr, char *adapter_name, bool match_null_name) @@ -1272,8 +1365,10 @@ restart: /* One is NULL and one is not */ continue; } - if (strcmp(info->adapter_name, adapter_name)) - /* Names to not match */ + if (adapter_name && + strcmp_nospace(info->adapter_name, + adapter_name)) + /* Names do not match */ continue; } found = info; @@ -1306,6 +1401,12 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev) return false; } +/* + * Global enables we care about. + */ +#define GLOBAL_ENABLES_MASK (IPMI_BMC_EVT_MSG_BUFF | IPMI_BMC_RCV_MSG_INTR | \ + IPMI_BMC_EVT_MSG_INTR) + static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) { unsigned char msg[3]; @@ -1391,13 +1492,33 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) break; case SSIF_MULTI_2_PART: - if (ssif_info->max_xmit_msg_size > 64) - ssif_info->max_xmit_msg_size = 64; + if (ssif_info->max_xmit_msg_size > 63) + ssif_info->max_xmit_msg_size = 63; if (ssif_info->max_recv_msg_size > 62) ssif_info->max_recv_msg_size = 62; break; case SSIF_MULTI_n_PART: + /* + * The specification is rather confusing at + * this point, but I think I understand what + * is meant. At least I have a workable + * solution. With multi-part messages, you + * cannot send a message that is a multiple of + * 32-bytes in length, because the start and + * middle messages are 32-bytes and the end + * message must be at least one byte. You + * can't fudge on an extra byte, that would + * screw up things like fru data writes. So + * we limit the length to 63 bytes. That way + * a 32-byte message gets sent as a single + * part. A larger message will be a 32-byte + * start and the next message is always going + * to be 1-31 bytes in length. Not ideal, but + * it should work. + */ + if (ssif_info->max_xmit_msg_size > 63) + ssif_info->max_xmit_msg_size = 63; break; default: @@ -1407,7 +1528,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) } else { no_support: /* Assume no multi-part or PEC support */ - pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", + pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", rv, len, resp[2]); ssif_info->max_xmit_msg_size = 32; @@ -1436,6 +1557,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) goto found; } + ssif_info->global_enables = resp[3]; + if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) { ssif_info->has_event_buffer = true; /* buffer is already enabled, nothing to do. */ @@ -1444,18 +1567,37 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) msg[0] = IPMI_NETFN_APP_REQUEST << 2; msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; - msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF; + msg[2] = ssif_info->global_enables | IPMI_BMC_EVT_MSG_BUFF; rv = do_cmd(client, 3, msg, &len, resp); if (rv || (len < 2)) { - pr_warn(PFX "Error getting global enables: %d %d %2.2x\n", + pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", rv, len, resp[2]); rv = 0; /* Not fatal */ goto found; } - if (resp[2] == 0) + if (resp[2] == 0) { /* A successful return means the event buffer is supported. */ ssif_info->has_event_buffer = true; + ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF; + } + + msg[0] = IPMI_NETFN_APP_REQUEST << 2; + msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; + msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR; + rv = do_cmd(client, 3, msg, &len, resp); + if (rv || (len < 2)) { + pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", + rv, len, resp[2]); + rv = 0; /* Not fatal */ + goto found; + } + + if (resp[2] == 0) { + /* A successful return means the alert is supported. */ + ssif_info->supports_alert = true; + ssif_info->global_enables |= IPMI_BMC_RCV_MSG_INTR; + } found: ssif_info->intf_num = atomic_inc_return(&next_intf); @@ -1813,6 +1955,7 @@ static struct i2c_driver ssif_i2c_driver = { }, .probe = ssif_probe, .remove = ssif_remove, + .alert = ssif_alert, .id_table = ssif_id, .detect = ssif_detect }; @@ -1832,7 +1975,7 @@ static int init_ipmi_ssif(void) rv = new_ssif_client(addr[i], adapter_name[i], dbg[i], slave_addrs[i], SI_HARDCODED); - if (!rv) + if (rv) pr_err(PFX "Couldn't add hardcoded device at addr 0x%x\n", addr[i]); diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 44ea107cfc67..30335d3b99af 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1128,13 +1128,6 @@ static int si5351_dt_parse(struct i2c_client *client, if (!pdata) return -ENOMEM; - pdata->clk_xtal = of_clk_get(np, 0); - if (!IS_ERR(pdata->clk_xtal)) - clk_put(pdata->clk_xtal); - pdata->clk_clkin = of_clk_get(np, 1); - if (!IS_ERR(pdata->clk_clkin)) - clk_put(pdata->clk_clkin); - /* * property silabs,pll-source : <num src>, [<..>] * allow to selectively set pll source @@ -1328,8 +1321,22 @@ static int si5351_i2c_probe(struct i2c_client *client, i2c_set_clientdata(client, drvdata); drvdata->client = client; drvdata->variant = variant; - drvdata->pxtal = pdata->clk_xtal; - drvdata->pclkin = pdata->clk_clkin; + drvdata->pxtal = devm_clk_get(&client->dev, "xtal"); + drvdata->pclkin = devm_clk_get(&client->dev, "clkin"); + + if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER || + PTR_ERR(drvdata->pclkin) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + /* + * Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL, + * VARIANT_C can have CLKIN instead. + */ + if (IS_ERR(drvdata->pxtal) && + (drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) { + dev_err(&client->dev, "missing parent clock\n"); + return -EINVAL; + } drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config); if (IS_ERR(drvdata->regmap)) { @@ -1393,6 +1400,11 @@ static int si5351_i2c_probe(struct i2c_client *client, } } + if (!IS_ERR(drvdata->pxtal)) + clk_prepare_enable(drvdata->pxtal); + if (!IS_ERR(drvdata->pclkin)) + clk_prepare_enable(drvdata->pclkin); + /* register xtal input clock gate */ memset(&init, 0, sizeof(init)); init.name = si5351_input_names[0]; @@ -1407,7 +1419,8 @@ static int si5351_i2c_probe(struct i2c_client *client, clk = devm_clk_register(&client->dev, &drvdata->xtal); if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto err_clk; } /* register clkin input clock gate */ @@ -1425,7 +1438,8 @@ static int si5351_i2c_probe(struct i2c_client *client, if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto err_clk; } } @@ -1447,7 +1461,8 @@ static int si5351_i2c_probe(struct i2c_client *client, clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw); if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return -EINVAL; + ret = PTR_ERR(clk); + goto err_clk; } /* register PLLB or VXCO (Si5351B) */ @@ -1471,7 +1486,8 @@ static int si5351_i2c_probe(struct i2c_client *client, clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw); if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return -EINVAL; + ret = PTR_ERR(clk); + goto err_clk; } /* register clk multisync and clk out divider */ @@ -1492,8 +1508,10 @@ static int si5351_i2c_probe(struct i2c_client *client, num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL); if (WARN_ON(!drvdata->msynth || !drvdata->clkout || - !drvdata->onecell.clks)) - return -ENOMEM; + !drvdata->onecell.clks)) { + ret = -ENOMEM; + goto err_clk; + } for (n = 0; n < num_clocks; n++) { drvdata->msynth[n].num = n; @@ -1511,7 +1529,8 @@ static int si5351_i2c_probe(struct i2c_client *client, if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return -EINVAL; + ret = PTR_ERR(clk); + goto err_clk; } } @@ -1538,7 +1557,8 @@ static int si5351_i2c_probe(struct i2c_client *client, if (IS_ERR(clk)) { dev_err(&client->dev, "unable to register %s\n", init.name); - return -EINVAL; + ret = PTR_ERR(clk); + goto err_clk; } drvdata->onecell.clks[n] = clk; @@ -1557,10 +1577,17 @@ static int si5351_i2c_probe(struct i2c_client *client, &drvdata->onecell); if (ret) { dev_err(&client->dev, "unable to add clk provider\n"); - return ret; + goto err_clk; } return 0; + +err_clk: + if (!IS_ERR(drvdata->pxtal)) + clk_disable_unprepare(drvdata->pxtal); + if (!IS_ERR(drvdata->pclkin)) + clk_disable_unprepare(drvdata->pclkin); + return ret; } static const struct i2c_device_id si5351_i2c_ids[] = { diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 459ce9da13e0..5b0f41868b42 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1475,8 +1475,10 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *clk, */ if (clk->prepare_count) { clk_core_prepare(parent); + flags = clk_enable_lock(); clk_core_enable(parent); clk_core_enable(clk); + clk_enable_unlock(flags); } /* update the clk tree topology */ @@ -1491,13 +1493,17 @@ static void __clk_set_parent_after(struct clk_core *core, struct clk_core *parent, struct clk_core *old_parent) { + unsigned long flags; + /* * Finish the migration of prepare state and undo the changes done * for preventing a race with clk_enable(). */ if (core->prepare_count) { + flags = clk_enable_lock(); clk_core_disable(core); clk_core_disable(old_parent); + clk_enable_unlock(flags); clk_core_unprepare(old_parent); } } @@ -1525,8 +1531,10 @@ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent, clk_enable_unlock(flags); if (clk->prepare_count) { + flags = clk_enable_lock(); clk_core_disable(clk); clk_core_disable(parent); + clk_enable_unlock(flags); clk_core_unprepare(parent); } return ret; diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index d3458474eb3a..c66f7bc2ae87 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -71,8 +71,8 @@ static const char *gcc_xo_gpll0_bimc[] = { static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2a_map[] = { { P_XO, 0 }, { P_GPLL0_AUX, 3 }, - { P_GPLL2_AUX, 2 }, { P_GPLL1, 1 }, + { P_GPLL2_AUX, 2 }, }; static const char *gcc_xo_gpll0a_gpll1_gpll2a[] = { @@ -1115,7 +1115,7 @@ static struct clk_rcg2 usb_hs_system_clk_src = { static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = { F(100000000, P_GPLL0, 8, 0, 0), F(160000000, P_GPLL0, 5, 0, 0), - F(228570000, P_GPLL0, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), { } }; diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 17e9af7fe81f..a17683b2cf27 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o -obj-$(CONFIG_ARCH_EXYNOS5433) += clk-exynos5433.o +obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos5433.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 07d666cc6a29..bea4a173eef5 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -271,6 +271,7 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { { .offset = SRC_MASK_PERIC0, .value = 0x11111110, }, { .offset = SRC_MASK_PERIC1, .value = 0x11111100, }, { .offset = SRC_MASK_ISP, .value = 0x11111000, }, + { .offset = GATE_BUS_TOP, .value = 0xffffffff, }, { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, }; diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 387e3e39e635..9e04ae2bb4d7 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -748,7 +748,7 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = { PLL_35XX_RATE(825000000U, 275, 4, 1), PLL_35XX_RATE(800000000U, 400, 6, 1), PLL_35XX_RATE(733000000U, 733, 12, 1), - PLL_35XX_RATE(700000000U, 360, 6, 1), + PLL_35XX_RATE(700000000U, 175, 3, 1), PLL_35XX_RATE(667000000U, 222, 4, 1), PLL_35XX_RATE(633000000U, 211, 4, 1), PLL_35XX_RATE(600000000U, 500, 5, 2), @@ -760,14 +760,14 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = { PLL_35XX_RATE(444000000U, 370, 5, 2), PLL_35XX_RATE(420000000U, 350, 5, 2), PLL_35XX_RATE(400000000U, 400, 6, 2), - PLL_35XX_RATE(350000000U, 360, 6, 2), + PLL_35XX_RATE(350000000U, 350, 6, 2), PLL_35XX_RATE(333000000U, 222, 4, 2), PLL_35XX_RATE(300000000U, 500, 5, 3), PLL_35XX_RATE(266000000U, 532, 6, 3), PLL_35XX_RATE(200000000U, 400, 6, 3), PLL_35XX_RATE(166000000U, 332, 6, 3), PLL_35XX_RATE(160000000U, 320, 6, 3), - PLL_35XX_RATE(133000000U, 552, 6, 4), + PLL_35XX_RATE(133000000U, 532, 6, 4), PLL_35XX_RATE(100000000U, 400, 6, 4), { /* sentinel */ } }; @@ -1490,7 +1490,7 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = { /* ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT */ GATE(CLK_PCLK_MONOTONIC_CNT, "pclk_monotonic_cnt", "div_aclk_mif_133", - ENABLE_PCLK_MIF_SECURE_RTC, 0, 0, 0), + ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT, 0, 0, 0), /* ENABLE_PCLK_MIF_SECURE_RTC */ GATE(CLK_PCLK_RTC, "pclk_rtc", "div_aclk_mif_133", @@ -3665,7 +3665,7 @@ static struct samsung_gate_clock apollo_gate_clks[] __initdata = { ENABLE_SCLK_APOLLO, 3, CLK_IGNORE_UNUSED, 0), GATE(CLK_SCLK_HPM_APOLLO, "sclk_hpm_apollo", "div_sclk_hpm_apollo", ENABLE_SCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0), - GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo_pll", + GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo2", ENABLE_SCLK_APOLLO, 0, CLK_IGNORE_UNUSED, 0), }; @@ -3927,7 +3927,7 @@ CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas", #define ENABLE_PCLK_MSCL 0x0900 #define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0 0x0904 #define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1 0x0908 -#define ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG 0x000c +#define ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG 0x090c #define ENABLE_SCLK_MSCL 0x0a00 #define ENABLE_IP_MSCL0 0x0b00 #define ENABLE_IP_MSCL1 0x0b04 diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 9b84def7a353..f42f71e37e73 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -384,7 +384,10 @@ static int hsu_dma_terminate_all(struct dma_chan *chan) spin_lock_irqsave(&hsuc->vchan.lock, flags); hsu_dma_stop_channel(hsuc); - hsuc->desc = NULL; + if (hsuc->desc) { + hsu_dma_desc_free(&hsuc->desc->vdesc); + hsuc->desc = NULL; + } vchan_get_all_descriptors(&hsuc->vchan, &head); spin_unlock_irqrestore(&hsuc->vchan.lock, flags); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index a7d9d3029b14..340f9e607cd8 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2127,6 +2127,7 @@ static int pl330_terminate_all(struct dma_chan *chan) struct pl330_dmac *pl330 = pch->dmac; LIST_HEAD(list); + pm_runtime_get_sync(pl330->ddma.dev); spin_lock_irqsave(&pch->lock, flags); spin_lock(&pl330->lock); _stop(pch->thread); @@ -2151,6 +2152,8 @@ static int pl330_terminate_all(struct dma_chan *chan) list_splice_tail_init(&pch->work_list, &pl330->desc_pool); list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); spin_unlock_irqrestore(&pch->lock, flags); + pm_runtime_mark_last_busy(pl330->ddma.dev); + pm_runtime_put_autosuspend(pl330->ddma.dev); return 0; } diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index de67fce18984..e45d1f13f445 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c @@ -119,6 +119,18 @@ static int usb_extcon_probe(struct platform_device *pdev) return PTR_ERR(info->id_gpiod); } + info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); + if (IS_ERR(info->edev)) { + dev_err(dev, "failed to allocate extcon device\n"); + return -ENOMEM; + } + + ret = devm_extcon_dev_register(dev, info->edev); + if (ret < 0) { + dev_err(dev, "failed to register extcon device\n"); + return ret; + } + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEBOUNCE_MS * 1000); if (ret < 0) @@ -142,18 +154,6 @@ static int usb_extcon_probe(struct platform_device *pdev) return ret; } - info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); - if (IS_ERR(info->edev)) { - dev_err(dev, "failed to allocate extcon device\n"); - return -ENOMEM; - } - - ret = devm_extcon_dev_register(dev, info->edev); - if (ret < 0) { - dev_err(dev, "failed to register extcon device\n"); - return ret; - } - platform_set_drvdata(pdev, info); device_init_wakeup(dev, 1); diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 6e45a43ffe84..97b1616aa391 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -499,19 +499,19 @@ static int __init dmi_present(const u8 *buf) buf += 16; if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { + if (smbios_ver) + dmi_ver = smbios_ver; + else + dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F); dmi_num = get_unaligned_le16(buf + 12); dmi_len = get_unaligned_le16(buf + 6); dmi_base = get_unaligned_le32(buf + 8); if (dmi_walk_early(dmi_decode) == 0) { if (smbios_ver) { - dmi_ver = smbios_ver; - pr_info("SMBIOS %d.%d%s present.\n", - dmi_ver >> 8, dmi_ver & 0xFF, - (dmi_ver < 0x0300) ? "" : ".x"); + pr_info("SMBIOS %d.%d present.\n", + dmi_ver >> 8, dmi_ver & 0xFF); } else { - dmi_ver = (buf[14] & 0xF0) << 4 | - (buf[14] & 0x0F); pr_info("Legacy DMI %d.%d present.\n", dmi_ver >> 8, dmi_ver & 0xFF); } diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c index 87b8e3b900d2..5c55227a34c8 100644 --- a/drivers/firmware/efi/runtime-map.c +++ b/drivers/firmware/efi/runtime-map.c @@ -120,7 +120,8 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) { kset_unregister(map_kset); - return entry; + map_kset = NULL; + return ERR_PTR(-ENOMEM); } memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size, @@ -132,6 +133,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) if (ret) { kobject_put(&entry->kobj); kset_unregister(map_kset); + map_kset = NULL; return ERR_PTR(ret); } @@ -195,8 +197,6 @@ out_add_entry: entry = *(map_entries + j); kobject_put(&entry->kobj); } - if (map_kset) - kset_unregister(map_kset); out: return ret; } diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 071c2c969eec..72791232e46b 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -186,8 +186,20 @@ struct ibft_kobject { static struct iscsi_boot_kset *boot_kset; +/* fully null address */ static const char nulls[16]; +/* IPv4-mapped IPv6 ::ffff:0.0.0.0 */ +static const char mapped_nulls[16] = { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00 }; + +static int address_not_null(u8 *ip) +{ + return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16)); +} + /* * Helper functions to parse data properly. */ @@ -445,7 +457,7 @@ static umode_t ibft_check_nic_for(void *data, int type) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_IP_ADDR: - if (memcmp(nic->ip_addr, nulls, sizeof(nic->ip_addr))) + if (address_not_null(nic->ip_addr)) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_SUBNET_MASK: @@ -456,21 +468,19 @@ static umode_t ibft_check_nic_for(void *data, int type) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_GATEWAY: - if (memcmp(nic->gateway, nulls, sizeof(nic->gateway))) + if (address_not_null(nic->gateway)) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_PRIMARY_DNS: - if (memcmp(nic->primary_dns, nulls, - sizeof(nic->primary_dns))) + if (address_not_null(nic->primary_dns)) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_SECONDARY_DNS: - if (memcmp(nic->secondary_dns, nulls, - sizeof(nic->secondary_dns))) + if (address_not_null(nic->secondary_dns)) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_DHCP: - if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) + if (address_not_null(nic->dhcp)) rc = S_IRUGO; break; case ISCSI_BOOT_ETH_VLAN: @@ -536,23 +546,19 @@ static umode_t __init ibft_check_initiator_for(void *data, int type) rc = S_IRUGO; break; case ISCSI_BOOT_INI_ISNS_SERVER: - if (memcmp(init->isns_server, nulls, - sizeof(init->isns_server))) + if (address_not_null(init->isns_server)) rc = S_IRUGO; break; case ISCSI_BOOT_INI_SLP_SERVER: - if (memcmp(init->slp_server, nulls, - sizeof(init->slp_server))) + if (address_not_null(init->slp_server)) rc = S_IRUGO; break; case ISCSI_BOOT_INI_PRI_RADIUS_SERVER: - if (memcmp(init->pri_radius_server, nulls, - sizeof(init->pri_radius_server))) + if (address_not_null(init->pri_radius_server)) rc = S_IRUGO; break; case ISCSI_BOOT_INI_SEC_RADIUS_SERVER: - if (memcmp(init->sec_radius_server, nulls, - sizeof(init->sec_radius_server))) + if (address_not_null(init->sec_radius_server)) rc = S_IRUGO; break; case ISCSI_BOOT_INI_INITIATOR_NAME: diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index 6b8115f34208..83f281dda1e0 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -117,7 +117,7 @@ static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset) = container_of(chip, struct kempld_gpio_data, chip); struct kempld_device_data *pld = gpio->pld; - return kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset); + return !kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset); } static int kempld_gpio_pincount(struct kempld_device_data *pld) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index cd1d5bf48f36..b232397ad7ec 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1054,38 +1054,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) dev_err(bank->dev, "Could not get gpio dbck\n"); } -static void -omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, - unsigned int num) -{ - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - - gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, - handle_simple_irq); - if (!gc) { - dev_err(bank->dev, "Memory alloc failed for gc\n"); - return; - } - - ct = gc->chip_types; - - /* NOTE: No ack required, reading IRQ status clears it. */ - ct->chip.irq_mask = irq_gc_mask_set_bit; - ct->chip.irq_unmask = irq_gc_mask_clr_bit; - ct->chip.irq_set_type = omap_gpio_irq_type; - - if (bank->regs->wkup_en) - ct->chip.irq_set_wake = omap_gpio_wake_enable; - - ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; - irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, - IRQ_NOREQUEST | IRQ_NOPROBE, 0); -} - static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) { - int j; static int gpio; int irq_base = 0; int ret; @@ -1132,6 +1102,15 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) } #endif + /* MPUIO is a bit different, reading IRQ status clears it */ + if (bank->is_mpuio) { + irqc->irq_ack = dummy_irq_chip.irq_ack; + irqc->irq_mask = irq_gc_mask_set_bit; + irqc->irq_unmask = irq_gc_mask_clr_bit; + if (!bank->regs->wkup_en) + irqc->irq_set_wake = NULL; + } + ret = gpiochip_irqchip_add(&bank->chip, irqc, irq_base, omap_gpio_irq_handler, IRQ_TYPE_NONE); @@ -1145,15 +1124,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) gpiochip_set_chained_irqchip(&bank->chip, irqc, bank->irq, omap_gpio_irq_handler); - for (j = 0; j < bank->width; j++) { - int irq = irq_find_mapping(bank->chip.irqdomain, j); - if (bank->is_mpuio) { - omap_mpuio_alloc_gc(bank, irq, bank->width); - irq_set_chip_and_handler(irq, NULL, NULL); - set_irq_flags(irq, 0); - } - } - return 0; } diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d2303d50f561..725d16138b74 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -550,7 +550,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, length = min(agpio->pin_table_length, (u16)(pin_index + bits)); for (i = pin_index; i < length; ++i) { - unsigned pin = agpio->pin_table[i]; + int pin = agpio->pin_table[i]; struct acpi_gpio_connection *conn; struct gpio_desc *desc; bool found; diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 7722ed53bd65..af3bc7a8033b 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -551,6 +551,7 @@ static struct class gpio_class = { */ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) { + struct gpio_chip *chip; unsigned long flags; int status; const char *ioname = NULL; @@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) return -EINVAL; } + chip = desc->chip; + mutex_lock(&sysfs_lock); + /* check if chip is being removed */ + if (!chip || !chip->exported) { + status = -ENODEV; + goto fail_unlock; + } + spin_lock_irqsave(&gpio_lock, flags); if (!test_bit(FLAG_REQUESTED, &desc->flags) || test_bit(FLAG_EXPORT, &desc->flags)) { @@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip) { int status; struct device *dev; + struct gpio_desc *desc; + unsigned int i; mutex_lock(&sysfs_lock); dev = class_find_device(&gpio_class, NULL, chip, match_export); if (dev) { put_device(dev); device_unregister(dev); + /* prevent further gpiod exports */ chip->exported = false; status = 0; } else @@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip) if (status) chip_dbg(chip, "%s: status %d\n", __func__, status); + + /* unregister gpiod class devices owned by sysfs */ + for (i = 0; i < chip->ngpio; i++) { + desc = &chip->desc[i]; + if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) + gpiod_free(desc); + } } static int __init gpiolib_sysfs_init(void) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 59eaa23767d8..6bc612b8a49f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -53,6 +53,11 @@ static DEFINE_MUTEX(gpio_lookup_lock); static LIST_HEAD(gpio_lookup_list); LIST_HEAD(gpio_chips); + +static void gpiochip_free_hogs(struct gpio_chip *chip); +static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); + + static inline void desc_set_label(struct gpio_desc *d, const char *label) { d->label = label; @@ -297,6 +302,7 @@ int gpiochip_add(struct gpio_chip *chip) err_remove_chip: acpi_gpiochip_remove(chip); + gpiochip_free_hogs(chip); of_gpiochip_remove(chip); spin_lock_irqsave(&gpio_lock, flags); list_del(&chip->list); @@ -313,10 +319,6 @@ err_free_descs: } EXPORT_SYMBOL_GPL(gpiochip_add); -/* Forward-declaration */ -static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); -static void gpiochip_free_hogs(struct gpio_chip *chip); - /** * gpiochip_remove() - unregister a gpio_chip * @chip: the chip to unregister diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 69af73f15310..596ee5cd3b84 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -430,9 +430,10 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm, BUG_ON(!dqm || !qpd); - BUG_ON(!list_empty(&qpd->queues_list)); + pr_debug("In func %s\n", __func__); - pr_debug("kfd: In func %s\n", __func__); + pr_debug("qpd->queues_list is %s\n", + list_empty(&qpd->queues_list) ? "empty" : "not empty"); retval = 0; mutex_lock(&dqm->lock); @@ -882,6 +883,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, return -ENOMEM; } + init_sdma_vm(dqm, q, qpd); + retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, &q->gart_mqd_addr, &q->properties); if (retval != 0) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 661c6605d31b..c25728bc388a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -684,8 +684,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, dev->node_props.cpu_core_id_base); sysfs_show_32bit_prop(buffer, "simd_id_base", dev->node_props.simd_id_base); - sysfs_show_32bit_prop(buffer, "capability", - dev->node_props.capability); sysfs_show_32bit_prop(buffer, "max_waves_per_simd", dev->node_props.max_waves_per_simd); sysfs_show_32bit_prop(buffer, "lds_size_in_kb", @@ -728,14 +726,16 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz( dev->gpu->kgd)); + sysfs_show_64bit_prop(buffer, "local_mem_size", - dev->gpu->kfd2kgd->get_vmem_size( - dev->gpu->kgd)); + (unsigned long long int) 0); sysfs_show_32bit_prop(buffer, "fw_version", dev->gpu->kfd2kgd->get_fw_version( dev->gpu->kgd, KGD_ENGINE_MEC1)); + sysfs_show_32bit_prop(buffer, "capability", + dev->node_props.capability); } return sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index c8a34476570a..af9662e58272 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -131,12 +131,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) /* Reinitialize corresponding vblank timestamp if high-precision query * available. Skip this step if query unsupported or failed. Will - * reinitialize delayed at next vblank interrupt in that case. + * reinitialize delayed at next vblank interrupt in that case and + * assign 0 for now, to mark the vblanktimestamp as invalid. */ - if (rc) { - tslot = atomic_read(&vblank->count) + diff; - vblanktimestamp(dev, crtc, tslot) = t_vblank; - } + tslot = atomic_read(&vblank->count) + diff; + vblanktimestamp(dev, crtc, tslot) = rc ? t_vblank : (struct timeval) {0, 0}; smp_mb__before_atomic(); atomic_add(diff, &vblank->count); diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 40c1db9ad7c3..2f0ed11024eb 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -465,6 +465,9 @@ int drm_plane_helper_commit(struct drm_plane *plane, if (!crtc[i]) continue; + if (crtc[i]->cursor == plane) + continue; + /* There's no other way to figure out whether the crtc is running. */ ret = drm_crtc_vblank_get(crtc[i]); if (ret == 0) { diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index ffc305fc2076..eb7e61078a5b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -217,7 +217,7 @@ static ssize_t status_store(struct device *device, mutex_unlock(&dev->mode_config.mutex); - return ret; + return ret ? ret : count; } static ssize_t status_show(struct device *device, diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 1f7e33f59de6..6714e5b193ea 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -91,7 +91,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) static void decon_clear_channel(struct decon_context *ctx) { - int win, ch_enabled = 0; + unsigned int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -710,7 +710,7 @@ static void decon_dpms(struct exynos_drm_crtc *crtc, int mode) } } -static struct exynos_drm_crtc_ops decon_crtc_ops = { +static const struct exynos_drm_crtc_ops decon_crtc_ops = { .dpms = decon_dpms, .mode_fixup = decon_mode_fixup, .commit = decon_commit, diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 1dbfba58f909..30feb7d06624 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -32,7 +32,6 @@ #include <drm/bridge/ptn3460.h> #include "exynos_dp_core.h" -#include "exynos_drm_fimd.h" #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ connector) @@ -196,7 +195,7 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp) } } - dev_err(dp->dev, "EDID Read success!\n"); + dev_dbg(dp->dev, "EDID Read success!\n"); return 0; } @@ -1066,6 +1065,8 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp) static void exynos_dp_poweron(struct exynos_dp_device *dp) { + struct exynos_drm_crtc *crtc = dp_to_crtc(dp); + if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; @@ -1076,7 +1077,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp) } } - fimd_dp_clock_enable(dp_to_crtc(dp), true); + if (crtc->ops->clock_enable) + crtc->ops->clock_enable(dp_to_crtc(dp), true); clk_prepare_enable(dp->clock); exynos_dp_phy_init(dp); @@ -1087,6 +1089,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp) static void exynos_dp_poweroff(struct exynos_dp_device *dp) { + struct exynos_drm_crtc *crtc = dp_to_crtc(dp); + if (dp->dpms_mode != DRM_MODE_DPMS_ON) return; @@ -1102,7 +1106,8 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp) exynos_dp_phy_exit(dp); clk_disable_unprepare(dp->clock); - fimd_dp_clock_enable(dp_to_crtc(dp), false); + if (crtc->ops->clock_enable) + crtc->ops->clock_enable(dp_to_crtc(dp), false); if (dp->panel) { if (drm_panel_unprepare(dp->panel)) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index eb49195cec5c..9006b947e03c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -238,11 +238,11 @@ static struct drm_crtc_funcs exynos_crtc_funcs = { }; struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, - struct drm_plane *plane, - int pipe, - enum exynos_drm_output_type type, - struct exynos_drm_crtc_ops *ops, - void *ctx) + struct drm_plane *plane, + int pipe, + enum exynos_drm_output_type type, + const struct exynos_drm_crtc_ops *ops, + void *ctx) { struct exynos_drm_crtc *exynos_crtc; struct exynos_drm_private *private = drm_dev->dev_private; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 0ecd8fc45cff..0f3aa70818e3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -18,11 +18,11 @@ #include "exynos_drm_drv.h" struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, - struct drm_plane *plane, - int pipe, - enum exynos_drm_output_type type, - struct exynos_drm_crtc_ops *ops, - void *context); + struct drm_plane *plane, + int pipe, + enum exynos_drm_output_type type, + const struct exynos_drm_crtc_ops *ops, + void *context); int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe); void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index e12ecb5d5d9a..29e3fb78c615 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -71,13 +71,6 @@ enum exynos_drm_output_type { * @dma_addr: array of bus(accessed by dma) address to the memory region * allocated for a overlay. * @zpos: order of overlay layer(z position). - * @index_color: if using color key feature then this value would be used - * as index color. - * @default_win: a window to be enabled. - * @color_key: color key on or off. - * @local_path: in case of lcd type, local path mode on or off. - * @transparency: transparency on or off. - * @activated: activated or not. * @enabled: enabled or not. * @resume: to resume or not. * @@ -108,13 +101,7 @@ struct exynos_drm_plane { uint32_t pixel_format; dma_addr_t dma_addr[MAX_FB_BUFFER]; unsigned int zpos; - unsigned int index_color; - bool default_win:1; - bool color_key:1; - bool local_path:1; - bool transparency:1; - bool activated:1; bool enabled:1; bool resume:1; }; @@ -181,6 +168,10 @@ struct exynos_drm_display { * @win_disable: disable hardware specific overlay. * @te_handler: trigger to transfer video image at the tearing effect * synchronization signal if there is a page flip request. + * @clock_enable: optional function enabling/disabling display domain clock, + * called from exynos-dp driver before powering up (with + * 'enable' argument as true) and after powering down (with + * 'enable' as false). */ struct exynos_drm_crtc; struct exynos_drm_crtc_ops { @@ -195,6 +186,7 @@ struct exynos_drm_crtc_ops { void (*win_commit)(struct exynos_drm_crtc *crtc, unsigned int zpos); void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos); void (*te_handler)(struct exynos_drm_crtc *crtc); + void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); }; /* @@ -221,7 +213,7 @@ struct exynos_drm_crtc { unsigned int dpms; wait_queue_head_t pending_flip_queue; struct drm_pending_vblank_event *event; - struct exynos_drm_crtc_ops *ops; + const struct exynos_drm_crtc_ops *ops; void *ctx; }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 929cb03a8eab..142eb4e3f59e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -171,43 +171,6 @@ exynos_drm_framebuffer_init(struct drm_device *dev, return &exynos_fb->fb; } -static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd) -{ - unsigned int cnt = 0; - - if (mode_cmd->pixel_format != DRM_FORMAT_NV12) - return drm_format_num_planes(mode_cmd->pixel_format); - - while (cnt != MAX_FB_BUFFER) { - if (!mode_cmd->handles[cnt]) - break; - cnt++; - } - - /* - * check if NV12 or NV12M. - * - * NV12 - * handles[0] = base1, offsets[0] = 0 - * handles[1] = base1, offsets[1] = Y_size - * - * NV12M - * handles[0] = base1, offsets[0] = 0 - * handles[1] = base2, offsets[1] = 0 - */ - if (cnt == 2) { - /* - * in case of NV12 format, offsets[1] is not 0 and - * handles[0] is same as handles[1]. - */ - if (mode_cmd->offsets[1] && - mode_cmd->handles[0] == mode_cmd->handles[1]) - cnt = 1; - } - - return cnt; -} - static struct drm_framebuffer * exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) @@ -230,7 +193,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); - exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd); + exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format); DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 9819fa6a9e2a..a0edab833148 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -33,7 +33,6 @@ #include "exynos_drm_crtc.h" #include "exynos_drm_plane.h" #include "exynos_drm_iommu.h" -#include "exynos_drm_fimd.h" /* * FIMD stands for Fully Interactive Mobile Display and @@ -216,7 +215,7 @@ static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) DRM_DEBUG_KMS("vblank wait timed out.\n"); } -static void fimd_enable_video_output(struct fimd_context *ctx, int win, +static void fimd_enable_video_output(struct fimd_context *ctx, unsigned int win, bool enable) { u32 val = readl(ctx->regs + WINCON(win)); @@ -229,7 +228,8 @@ static void fimd_enable_video_output(struct fimd_context *ctx, int win, writel(val, ctx->regs + WINCON(win)); } -static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, +static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, + unsigned int win, bool enable) { u32 val = readl(ctx->regs + SHADOWCON); @@ -244,7 +244,7 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, static void fimd_clear_channel(struct fimd_context *ctx) { - int win, ch_enabled = 0; + unsigned int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -946,7 +946,24 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc) drm_handle_vblank(ctx->drm_dev, ctx->pipe); } -static struct exynos_drm_crtc_ops fimd_crtc_ops = { +static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) +{ + struct fimd_context *ctx = crtc->ctx; + u32 val; + + /* + * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE + * clock. On these SoCs the bootloader may enable it but any + * power domain off/on will reset it to disable state. + */ + if (ctx->driver_data != &exynos5_fimd_driver_data) + return; + + val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; + writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON); +} + +static const struct exynos_drm_crtc_ops fimd_crtc_ops = { .dpms = fimd_dpms, .mode_fixup = fimd_mode_fixup, .commit = fimd_commit, @@ -956,6 +973,7 @@ static struct exynos_drm_crtc_ops fimd_crtc_ops = { .win_commit = fimd_win_commit, .win_disable = fimd_win_disable, .te_handler = fimd_te_handler, + .clock_enable = fimd_dp_clock_enable, }; static irqreturn_t fimd_irq_handler(int irq, void *dev_id) @@ -1025,12 +1043,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) if (ctx->display) exynos_drm_create_enc_conn(drm_dev, ctx->display); - ret = fimd_iommu_attach_devices(ctx, drm_dev); - if (ret) - return ret; - - return 0; - + return fimd_iommu_attach_devices(ctx, drm_dev); } static void fimd_unbind(struct device *dev, struct device *master, @@ -1192,24 +1205,6 @@ static int fimd_remove(struct platform_device *pdev) return 0; } -void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) -{ - struct fimd_context *ctx = crtc->ctx; - u32 val; - - /* - * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE - * clock. On these SoCs the bootloader may enable it but any - * power domain off/on will reset it to disable state. - */ - if (ctx->driver_data != &exynos5_fimd_driver_data) - return; - - val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; - writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON); -} -EXPORT_SYMBOL_GPL(fimd_dp_clock_enable); - struct platform_driver fimd_driver = { .probe = fimd_probe, .remove = fimd_remove, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.h b/drivers/gpu/drm/exynos/exynos_drm_fimd.h deleted file mode 100644 index b4fcaa568456..000000000000 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef _EXYNOS_DRM_FIMD_H_ -#define _EXYNOS_DRM_FIMD_H_ - -extern void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable); - -#endif /* _EXYNOS_DRM_FIMD_H_ */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 13ea3349363b..b1180fbe7546 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -76,7 +76,7 @@ int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb) return -EFAULT; } - exynos_plane->dma_addr[i] = buffer->dma_addr; + exynos_plane->dma_addr[i] = buffer->dma_addr + fb->offsets[i]; DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", i, (unsigned long)exynos_plane->dma_addr[i]); diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 27e84ec21694..1b3479a8db5f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -217,7 +217,7 @@ static int vidi_ctx_initialize(struct vidi_context *ctx, return 0; } -static struct exynos_drm_crtc_ops vidi_crtc_ops = { +static const struct exynos_drm_crtc_ops vidi_crtc_ops = { .dpms = vidi_dpms, .enable_vblank = vidi_enable_vblank, .disable_vblank = vidi_disable_vblank, diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index fbec750574e6..8874c1fcb3ab 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -44,6 +44,12 @@ #define MIXER_WIN_NR 3 #define MIXER_DEFAULT_WIN 0 +/* The pixelformats that are natively supported by the mixer. */ +#define MXR_FORMAT_RGB565 4 +#define MXR_FORMAT_ARGB1555 5 +#define MXR_FORMAT_ARGB4444 6 +#define MXR_FORMAT_ARGB8888 7 + struct mixer_resources { int irq; void __iomem *mixer_regs; @@ -327,7 +333,8 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); } -static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable) +static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, + bool enable) { struct mixer_resources *res = &ctx->mixer_res; u32 val = enable ? ~0 : 0; @@ -359,8 +366,6 @@ static void mixer_run(struct mixer_context *ctx) struct mixer_resources *res = &ctx->mixer_res; mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); - - mixer_regs_dump(ctx); } static void mixer_stop(struct mixer_context *ctx) @@ -373,16 +378,13 @@ static void mixer_stop(struct mixer_context *ctx) while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) && --timeout) usleep_range(10000, 12000); - - mixer_regs_dump(ctx); } -static void vp_video_buffer(struct mixer_context *ctx, int win) +static void vp_video_buffer(struct mixer_context *ctx, unsigned int win) { struct mixer_resources *res = &ctx->mixer_res; unsigned long flags; struct exynos_drm_plane *plane; - unsigned int buf_num = 1; dma_addr_t luma_addr[2], chroma_addr[2]; bool tiled_mode = false; bool crcb_mode = false; @@ -393,27 +395,18 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) switch (plane->pixel_format) { case DRM_FORMAT_NV12: crcb_mode = false; - buf_num = 2; break; - /* TODO: single buffer format NV12, NV21 */ + case DRM_FORMAT_NV21: + crcb_mode = true; + break; default: - /* ignore pixel format at disable time */ - if (!plane->dma_addr[0]) - break; - DRM_ERROR("pixel format for vp is wrong [%d].\n", plane->pixel_format); return; } - if (buf_num == 2) { - luma_addr[0] = plane->dma_addr[0]; - chroma_addr[0] = plane->dma_addr[1]; - } else { - luma_addr[0] = plane->dma_addr[0]; - chroma_addr[0] = plane->dma_addr[0] - + (plane->pitch * plane->fb_height); - } + luma_addr[0] = plane->dma_addr[0]; + chroma_addr[0] = plane->dma_addr[1]; if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) { ctx->interlace = true; @@ -484,6 +477,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) mixer_vsync_set_update(ctx, true); spin_unlock_irqrestore(&res->reg_slock, flags); + mixer_regs_dump(ctx); vp_regs_dump(ctx); } @@ -518,7 +512,7 @@ fail: return -ENOTSUPP; } -static void mixer_graph_buffer(struct mixer_context *ctx, int win) +static void mixer_graph_buffer(struct mixer_context *ctx, unsigned int win) { struct mixer_resources *res = &ctx->mixer_res; unsigned long flags; @@ -531,20 +525,27 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) plane = &ctx->planes[win]; - #define RGB565 4 - #define ARGB1555 5 - #define ARGB4444 6 - #define ARGB8888 7 + switch (plane->pixel_format) { + case DRM_FORMAT_XRGB4444: + fmt = MXR_FORMAT_ARGB4444; + break; - switch (plane->bpp) { - case 16: - fmt = ARGB4444; + case DRM_FORMAT_XRGB1555: + fmt = MXR_FORMAT_ARGB1555; break; - case 32: - fmt = ARGB8888; + + case DRM_FORMAT_RGB565: + fmt = MXR_FORMAT_RGB565; + break; + + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + fmt = MXR_FORMAT_ARGB8888; break; + default: - fmt = ARGB8888; + DRM_DEBUG_KMS("pixelformat unsupported by mixer\n"); + return; } /* check if mixer supports requested scaling setup */ @@ -617,6 +618,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) mixer_vsync_set_update(ctx, true); spin_unlock_irqrestore(&res->reg_slock, flags); + + mixer_regs_dump(ctx); } static void vp_win_reset(struct mixer_context *ctx) @@ -1070,6 +1073,7 @@ static void mixer_poweroff(struct mixer_context *ctx) mutex_unlock(&ctx->mixer_mutex); mixer_stop(ctx); + mixer_regs_dump(ctx); mixer_window_suspend(ctx); ctx->int_en = mixer_reg_read(res, MXR_INT_EN); @@ -1126,7 +1130,7 @@ int mixer_check_mode(struct drm_display_mode *mode) return -EINVAL; } -static struct exynos_drm_crtc_ops mixer_crtc_ops = { +static const struct exynos_drm_crtc_ops mixer_crtc_ops = { .dpms = mixer_dpms, .enable_vblank = mixer_enable_vblank, .disable_vblank = mixer_disable_vblank, @@ -1156,7 +1160,7 @@ static struct mixer_drv_data exynos4210_mxr_drv_data = { .has_sclk = 1, }; -static struct platform_device_id mixer_driver_types[] = { +static const struct platform_device_id mixer_driver_types[] = { { .name = "s5p-mixer", .driver_data = (unsigned long)&exynos4210_mxr_drv_data, diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 007c7d7d8295..dc55c51964ab 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1667,12 +1667,15 @@ static int i915_sr_status(struct seq_file *m, void *unused) if (HAS_PCH_SPLIT(dev)) sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; - else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) + else if (IS_CRESTLINE(dev) || IS_G4X(dev) || + IS_I945G(dev) || IS_I945GM(dev)) sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; else if (IS_I915GM(dev)) sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; else if (IS_PINEVIEW(dev)) sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; + else if (IS_VALLEYVIEW(dev)) + sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; intel_runtime_pm_put(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c302ffb5a168..a19d2c71e205 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -699,6 +699,16 @@ static int i915_drm_resume(struct drm_device *dev) intel_init_pch_refclk(dev); drm_mode_config_reset(dev); + /* + * Interrupts have to be enabled before any batches are run. If not the + * GPU will hang. i915_gem_init_hw() will initiate batches to + * update/restore the context. + * + * Modeset enabling in intel_modeset_init_hw() also needs working + * interrupts. + */ + intel_runtime_pm_enable_interrupts(dev_priv); + mutex_lock(&dev->struct_mutex); if (i915_gem_init_hw(dev)) { DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); @@ -706,9 +716,6 @@ static int i915_drm_resume(struct drm_device *dev) } mutex_unlock(&dev->struct_mutex); - /* We need working interrupts for modeset enabling ... */ - intel_runtime_pm_enable_interrupts(dev_priv); - intel_modeset_init_hw(dev); spin_lock_irq(&dev_priv->irq_lock); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 53394f998a1f..851b585987f9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2656,9 +2656,6 @@ void i915_gem_reset(struct drm_device *dev) void i915_gem_retire_requests_ring(struct intel_engine_cs *ring) { - if (list_empty(&ring->request_list)) - return; - WARN_ON(i915_verify_lists(ring->dev)); /* Retire requests first as we use it above for the early return. diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d547d9c8dda2..d0f3cbc87474 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13635,9 +13635,6 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = { }; static struct intel_quirk intel_quirks[] = { - /* HP Mini needs pipe A force quirk (LP: #322104) */ - { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, - /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d0237102c27e..d714a4b5711e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -880,10 +880,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, DP_AUX_CH_CTL_RECEIVE_ERROR)) continue; if (status & DP_AUX_CH_CTL_DONE) - break; + goto done; } - if (status & DP_AUX_CH_CTL_DONE) - break; } if ((status & DP_AUX_CH_CTL_DONE) == 0) { @@ -892,6 +890,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, goto out; } +done: /* Check for timeout or receive error. * Timeouts occur when the sink is not connected */ @@ -1348,7 +1347,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_dp_encoder = true; pipe_config->has_drrs = false; - pipe_config->has_audio = intel_dp->has_audio; + pipe_config->has_audio = intel_dp->has_audio && port != PORT_A; if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { intel_fixed_panel_mode(intel_connector->panel.fixed_mode, @@ -2211,8 +2210,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder, int dotclock; tmp = I915_READ(intel_dp->output_reg); - if (tmp & DP_AUDIO_OUTPUT_ENABLE) - pipe_config->has_audio = true; + + pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; if ((port == PORT_A) || !HAS_PCH_CPT(dev)) { if (tmp & DP_SYNC_HS_HIGH) @@ -3812,7 +3811,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (val == 0) break; - intel_dp->sink_rates[i] = val * 200; + /* Value read is in kHz while drm clock is saved in deca-kHz */ + intel_dp->sink_rates[i] = (val * 200) / 10; } intel_dp->num_sink_rates = i; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 09df74b8e917..424e62197787 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1134,6 +1134,12 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); + if (ring->status_page.obj) { + I915_WRITE(RING_HWS_PGA(ring->mmio_base), + (u32)ring->status_page.gfx_addr); + POSTING_READ(RING_HWS_PGA(ring->mmio_base)); + } + I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 5abda1d2c018..fbcc7dff0d63 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -813,12 +813,28 @@ static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) static const struct dmi_system_id intel_dual_link_lvds[] = { { .callback = intel_dual_link_lvds_callback, - .ident = "Apple MacBook Pro (Core i5/i7 Series)", + .ident = "Apple MacBook Pro 15\" (2010)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"), + }, + }, + { + .callback = intel_dual_link_lvds_callback, + .ident = "Apple MacBook Pro 15\" (2011)", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), }, }, + { + .callback = intel_dual_link_lvds_callback, + .ident = "Apple MacBook Pro 15\" (2012)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"), + }, + }, { } /* terminating entry */ }; @@ -848,6 +864,11 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) if (i915.lvds_channel_mode > 0) return i915.lvds_channel_mode == 2; + /* single channel LVDS is limited to 112 MHz */ + if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock + > 112999) + return true; + if (dmi_check_system(intel_dual_link_lvds)) return true; @@ -1111,6 +1132,8 @@ void intel_lvds_init(struct drm_device *dev) out: mutex_unlock(&dev->mode_config.mutex); + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); + lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); DRM_DEBUG_KMS("detected %s-link lvds configuration\n", lvds_encoder->is_dual_link ? "dual" : "single"); @@ -1125,7 +1148,6 @@ out: } drm_connector_register(connector); - intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_panel_setup_backlight(connector, INVALID_PIPE); return; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fa4ccb346389..555b896d2bda 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2045,22 +2045,20 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc, p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); - if (crtc->primary->state->fb) { - p->pri.enabled = true; + if (crtc->primary->state->fb) p->pri.bytes_per_pixel = crtc->primary->state->fb->bits_per_pixel / 8; - } else { - p->pri.enabled = false; - p->pri.bytes_per_pixel = 0; - } + else + p->pri.bytes_per_pixel = 4; + + p->cur.bytes_per_pixel = 4; + /* + * TODO: for now, assume primary and cursor planes are always enabled. + * Setting them to false makes the screen flicker. + */ + p->pri.enabled = true; + p->cur.enabled = true; - if (crtc->cursor->state->fb) { - p->cur.enabled = true; - p->cur.bytes_per_pixel = 4; - } else { - p->cur.enabled = false; - p->cur.bytes_per_pixel = 0; - } p->pri.horiz_pixels = intel_crtc->config->pipe_src_w; p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 441e2502b889..005b5e04de4d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -901,13 +901,6 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4); - if (INTEL_REVID(dev) == SKL_REVID_C0 || - INTEL_REVID(dev) == SKL_REVID_D0) - /* WaBarrierPerformanceFixDisable:skl */ - WA_SET_BIT_MASKED(HDC_CHICKEN0, - HDC_FENCE_DEST_SLM_DISABLE | - HDC_BARRIER_PERFORMANCE_DISABLE); - return 0; } @@ -1024,6 +1017,13 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(HIZ_CHICKEN, BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); + if (INTEL_REVID(dev) == SKL_REVID_C0 || + INTEL_REVID(dev) == SKL_REVID_D0) + /* WaBarrierPerformanceFixDisable:skl */ + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FENCE_DEST_SLM_DISABLE | + HDC_BARRIER_PERFORMANCE_DISABLE); + return skl_tune_iz_hashing(ring); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 94a5bee69fe7..bbdcab0a56c1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -384,7 +384,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) if (gpu->memptrs_bo) { if (gpu->memptrs_iova) msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); - drm_gem_object_unreference(gpu->memptrs_bo); + drm_gem_object_unreference_unlocked(gpu->memptrs_bo); } release_firmware(gpu->pm4); release_firmware(gpu->pfp); diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 28d1f95a90cc..ad50b80225f5 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -177,6 +177,11 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, goto fail; } + for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { + encoders[i]->bridge = msm_dsi->bridge; + msm_dsi->encoders[i] = encoders[i]; + } + msm_dsi->connector = msm_dsi_manager_connector_init(msm_dsi->id); if (IS_ERR(msm_dsi->connector)) { ret = PTR_ERR(msm_dsi->connector); @@ -185,11 +190,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, goto fail; } - for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { - encoders[i]->bridge = msm_dsi->bridge; - msm_dsi->encoders[i] = encoders[i]; - } - priv->bridges[priv->num_bridges++] = msm_dsi->bridge; priv->connectors[priv->num_connectors++] = msm_dsi->connector; diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 956b22492c9a..649d20d29f92 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1023,7 +1023,7 @@ static int dsi_short_read1_resp(u8 *buf, const struct mipi_dsi_msg *msg) *data = buf[1]; /* strip out dcs type */ return 1; } else { - pr_err("%s: read data does not match with rx_buf len %d\n", + pr_err("%s: read data does not match with rx_buf len %zu\n", __func__, msg->rx_len); return -EINVAL; } @@ -1040,7 +1040,7 @@ static int dsi_short_read2_resp(u8 *buf, const struct mipi_dsi_msg *msg) data[1] = buf[2]; return 2; } else { - pr_err("%s: read data does not match with rx_buf len %d\n", + pr_err("%s: read data does not match with rx_buf len %zu\n", __func__, msg->rx_len); return -EINVAL; } @@ -1093,7 +1093,6 @@ static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host, { u32 *lp, *temp, data; int i, j = 0, cnt; - bool ack_error = false; u32 read_cnt; u8 reg[16]; int repeated_bytes = 0; @@ -1105,15 +1104,10 @@ static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host, if (cnt > 4) cnt = 4; /* 4 x 32 bits registers only */ - /* Calculate real read data count */ - read_cnt = dsi_read(msm_host, 0x1d4) >> 16; - - ack_error = (rx_byte == 4) ? - (read_cnt == 8) : /* short pkt + 4-byte error pkt */ - (read_cnt == (pkt_size + 6 + 4)); /* long pkt+4-byte error pkt*/ - - if (ack_error) - read_cnt -= 4; /* Remove 4 byte error pkt */ + if (rx_byte == 4) + read_cnt = 4; + else + read_cnt = pkt_size + 6; /* * In case of multiple reads from the panel, after the first read, there @@ -1215,7 +1209,7 @@ static void dsi_err_worker(struct work_struct *work) container_of(work, struct msm_dsi_host, err_work); u32 status = msm_host->err_work_state; - pr_err("%s: status=%x\n", __func__, status); + pr_err_ratelimited("%s: status=%x\n", __func__, status); if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW) dsi_sw_reset_restore(msm_host); @@ -1797,6 +1791,7 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host, case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: pr_err("%s: rx ACK_ERR_PACLAGE\n", __func__); ret = 0; + break; case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: ret = dsi_short_read1_resp(buf, msg); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index ee3ebcaa33f5..0a40f3c64e8b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -462,7 +462,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id) struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct drm_connector *connector = NULL; struct dsi_connector *dsi_connector; - int ret; + int ret, i; dsi_connector = devm_kzalloc(msm_dsi->dev->dev, sizeof(*dsi_connector), GFP_KERNEL); @@ -495,6 +495,10 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id) if (ret) goto fail; + for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) + drm_mode_connector_attach_encoder(connector, + msm_dsi->encoders[i]); + return connector; fail: diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c index 5f5a84f6074c..208f9d47f82e 100644 --- a/drivers/gpu/drm/msm/edp/edp_aux.c +++ b/drivers/gpu/drm/msm/edp/edp_aux.c @@ -132,7 +132,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg) /* msg sanity check */ if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) || (msg->size > AUX_CMD_I2C_MAX)) { - pr_err("%s: invalid msg: size(%d), request(%x)\n", + pr_err("%s: invalid msg: size(%zu), request(%x)\n", __func__, msg->size, msg->request); return -EINVAL; } @@ -155,7 +155,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg) */ edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0); msm_edp_aux_ctrl(aux, 1); - pr_err("%s: aux timeout, %d\n", __func__, ret); + pr_err("%s: aux timeout, %zd\n", __func__, ret); goto unlock_exit; } DBG("completion"); diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c index d8812e84da54..b4d1b469862a 100644 --- a/drivers/gpu/drm/msm/edp/edp_connector.c +++ b/drivers/gpu/drm/msm/edp/edp_connector.c @@ -151,6 +151,8 @@ struct drm_connector *msm_edp_connector_init(struct msm_edp *edp) if (ret) goto fail; + drm_mode_connector_attach_encoder(connector, edp->encoder); + return connector; fail: diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c index 0ec5abdba5c4..29e52d7c61c0 100644 --- a/drivers/gpu/drm/msm/edp/edp_ctrl.c +++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c @@ -1149,12 +1149,13 @@ int msm_edp_ctrl_init(struct msm_edp *edp) ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux); if (!ctrl->aux || !ctrl->drm_aux) { pr_err("%s:failed to init aux\n", __func__); - return ret; + return -ENOMEM; } ctrl->phy = msm_edp_phy_init(dev, ctrl->base); if (!ctrl->phy) { pr_err("%s:failed to init phy\n", __func__); + ret = -ENOMEM; goto err_destory_aux; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index e001e6b2296a..8b9a7931b162 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -72,14 +72,13 @@ const struct mdp5_cfg_hw msm8x74_config = { .base = { 0x12d00, 0x12e00, 0x12f00 }, }, .intf = { - .count = 4, .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, - }, - .intfs = { - [0] = INTF_eDP, - [1] = INTF_DSI, - [2] = INTF_DSI, - [3] = INTF_HDMI, + .connect = { + [0] = INTF_eDP, + [1] = INTF_DSI, + [2] = INTF_DSI, + [3] = INTF_HDMI, + }, }, .max_clk = 200000000, }; @@ -142,14 +141,13 @@ const struct mdp5_cfg_hw apq8084_config = { .base = { 0x12f00, 0x13000, 0x13100, 0x13200 }, }, .intf = { - .count = 5, .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, - }, - .intfs = { - [0] = INTF_eDP, - [1] = INTF_DSI, - [2] = INTF_DSI, - [3] = INTF_HDMI, + .connect = { + [0] = INTF_eDP, + [1] = INTF_DSI, + [2] = INTF_DSI, + [3] = INTF_HDMI, + }, }, .max_clk = 320000000, }; @@ -196,10 +194,12 @@ const struct mdp5_cfg_hw msm8x16_config = { }, .intf = { - .count = 1, /* INTF_1 */ - .base = { 0x6B800 }, + .base = { 0x00000, 0x6b800 }, + .connect = { + [0] = INTF_DISABLED, + [1] = INTF_DSI, + }, }, - /* TODO enable .intfs[] with [1] = INTF_DSI, once DSI is implemented */ .max_clk = 320000000, }; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h index 3a551b0892d8..69349abe59f2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h @@ -59,6 +59,11 @@ struct mdp5_smp_block { #define MDP5_INTF_NUM_MAX 5 +struct mdp5_intf_block { + uint32_t base[MAX_BASES]; + u32 connect[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */ +}; + struct mdp5_cfg_hw { char *name; @@ -72,9 +77,7 @@ struct mdp5_cfg_hw { struct mdp5_sub_block dspp; struct mdp5_sub_block ad; struct mdp5_sub_block pp; - struct mdp5_sub_block intf; - - u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */ + struct mdp5_intf_block intf; uint32_t max_clk; }; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index dfa8beb9343a..bbacf9d2b738 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -206,8 +206,8 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num) { - const int intf_cnt = hw_cfg->intf.count; - const u32 *intfs = hw_cfg->intfs; + const enum mdp5_intf_type *intfs = hw_cfg->intf.connect; + const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect); int id = 0, i; for (i = 0; i < intf_cnt; i++) { @@ -228,7 +228,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) struct msm_drm_private *priv = dev->dev_private; const struct mdp5_cfg_hw *hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); - enum mdp5_intf_type intf_type = hw_cfg->intfs[intf_num]; + enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num]; struct drm_encoder *encoder; int ret = 0; @@ -365,7 +365,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) /* Construct encoders and modeset initialize connector devices * for each external display interface. */ - for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) { + for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) { ret = modeset_init_intf(mdp5_kms, i); if (ret) goto fail; @@ -514,8 +514,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) */ mdp5_enable(mdp5_kms); for (i = 0; i < MDP5_INTF_NUM_MAX; i++) { - if (!config->hw->intf.base[i] || - mdp5_cfg_intf_is_virtual(config->hw->intfs[i])) + if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) || + !config->hw->intf.base[i]) continue; mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 18a3d203b174..57b8f56ae9d0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -273,7 +273,7 @@ static void set_scanout_locked(struct drm_plane *plane, mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), msm_framebuffer_iova(fb, mdp5_kms->id, 2)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 4)); + msm_framebuffer_iova(fb, mdp5_kms->id, 3)); plane->fb = fb; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 47f4dd407671..c80a6bee2b18 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -21,9 +21,11 @@ static void msm_fb_output_poll_changed(struct drm_device *dev) { +#ifdef CONFIG_DRM_MSM_FBDEV struct msm_drm_private *priv = dev->dev_private; if (priv->fbdev) drm_fb_helper_hotplug_event(priv->fbdev); +#endif } static const struct drm_mode_config_funcs mode_config_funcs = { @@ -94,7 +96,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, } if (reglog) - printk(KERN_DEBUG "IO:region %s %08x %08lx\n", dbgname, (u32)ptr, size); + printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size); return ptr; } @@ -102,7 +104,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, void msm_writel(u32 data, void __iomem *addr) { if (reglog) - printk(KERN_DEBUG "IO:W %08x %08x\n", (u32)addr, data); + printk(KERN_DEBUG "IO:W %p %08x\n", addr, data); writel(data, addr); } @@ -110,7 +112,7 @@ u32 msm_readl(const void __iomem *addr) { u32 val = readl(addr); if (reglog) - printk(KERN_ERR "IO:R %08x %08x\n", (u32)addr, val); + printk(KERN_ERR "IO:R %p %08x\n", addr, val); return val; } @@ -143,8 +145,8 @@ static int msm_unload(struct drm_device *dev) if (gpu) { mutex_lock(&dev->struct_mutex); gpu->funcs->pm_suspend(gpu); - gpu->funcs->destroy(gpu); mutex_unlock(&dev->struct_mutex); + gpu->funcs->destroy(gpu); } if (priv->vram.paddr) { @@ -177,7 +179,7 @@ static int get_mdp_ver(struct platform_device *pdev) const struct of_device_id *match; match = of_match_node(match_types, dev->of_node); if (match) - return (int)match->data; + return (int)(unsigned long)match->data; #endif return 4; } @@ -216,7 +218,7 @@ static int msm_init_vram(struct drm_device *dev) if (ret) return ret; size = r.end - r.start; - DRM_INFO("using VRAM carveout: %lx@%08x\n", size, r.start); + DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start); } else #endif @@ -283,10 +285,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags) drm_mode_config_init(dev); - ret = msm_init_vram(dev); - if (ret) - goto fail; - platform_set_drvdata(pdev, dev); /* Bind all our sub-components: */ @@ -294,6 +292,10 @@ static int msm_load(struct drm_device *dev, unsigned long flags) if (ret) return ret; + ret = msm_init_vram(dev); + if (ret) + goto fail; + switch (get_mdp_ver(pdev)) { case 4: kms = mdp4_kms_init(dev); @@ -419,9 +421,11 @@ static void msm_preclose(struct drm_device *dev, struct drm_file *file) static void msm_lastclose(struct drm_device *dev) { +#ifdef CONFIG_DRM_MSM_FBDEV struct msm_drm_private *priv = dev->dev_private; if (priv->fbdev) drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev); +#endif } static irqreturn_t msm_irq(int irq, void *arg) diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 6b573e612f27..121713281417 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -172,8 +172,8 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, { struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; - struct msm_framebuffer *msm_fb; - struct drm_framebuffer *fb = NULL; + struct msm_framebuffer *msm_fb = NULL; + struct drm_framebuffer *fb; const struct msm_format *format; int ret, i, n; unsigned int hsub, vsub; @@ -239,8 +239,7 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, return fb; fail: - if (fb) - msm_framebuffer_destroy(fb); + kfree(msm_fb); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 479d8af72bcb..52839769eb6c 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -483,7 +483,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) uint64_t off = drm_vma_node_start(&obj->vma_node); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %d\n", + seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %zu\n", msm_obj->flags, is_active(msm_obj) ? 'A' : 'I', msm_obj->read_fence, msm_obj->write_fence, obj->name, obj->refcount.refcount.counter, diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 7acdaa5688b7..7ac2f1997e4a 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -60,7 +60,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova, u32 pa = sg_phys(sg) - sg->offset; size_t bytes = sg->length + sg->offset; - VERB("map[%d]: %08x %08x(%x)", i, iova, pa, bytes); + VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes); ret = iommu_map(domain, da, pa, bytes, prot); if (ret) @@ -99,7 +99,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint32_t iova, if (unmapped < bytes) return unmapped; - VERB("unmap[%d]: %08x(%x)", i, iova, bytes); + VERB("unmap[%d]: %08x(%zx)", i, iova, bytes); BUG_ON(!PAGE_ALIGNED(bytes)); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 8171537dd7d1..1f14b908b221 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -56,6 +56,6 @@ fail: void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) { if (ring->bo) - drm_gem_object_unreference(ring->bo); + drm_gem_object_unreference_unlocked(ring->bo); kfree(ring); } diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 0b5af0fe8659..64f8b2f687d2 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -14,7 +14,7 @@ #define FERMI_TWOD_A 0x0000902d -#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x0000903d +#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x00009039 #define KEPLER_INLINE_TO_MEMORY_A 0x0000a040 #define KEPLER_INLINE_TO_MEMORY_B 0x0000a140 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c index 2f5eadd12a9b..fdb1dcf16a59 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c @@ -329,7 +329,6 @@ gm204_gr_init(struct nvkm_object *object) nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - printk(KERN_ERR "ppc %d %d\n", gpc, priv->ppc_nr[gpc]); for (ppc = 0; ppc < priv->ppc_nr[gpc]; ppc++) nv_wr32(priv, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c index e8778c67578e..c61102f70805 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c @@ -90,12 +90,14 @@ gf100_devinit_disable(struct nvkm_devinit *devinit) return disable; } -static int +int gf100_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { + struct nvkm_devinit_impl *impl = (void *)oclass; struct nv50_devinit_priv *priv; + u64 disable; int ret; ret = nvkm_devinit_create(parent, engine, oclass, &priv); @@ -103,7 +105,8 @@ gf100_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; - if (nv_rd32(priv, 0x022500) & 0x00000001) + disable = impl->disable(&priv->base); + if (disable & (1ULL << NVDEV_ENGINE_DISP)) priv->base.post = true; return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c index b345a53e881d..87ca0ece37b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c @@ -48,7 +48,7 @@ struct nvkm_oclass * gm107_devinit_oclass = &(struct nvkm_devinit_impl) { .base.handle = NV_SUBDEV(DEVINIT, 0x07), .base.ofuncs = &(struct nvkm_ofuncs) { - .ctor = nv50_devinit_ctor, + .ctor = gf100_devinit_ctor, .dtor = _nvkm_devinit_dtor, .init = nv50_devinit_init, .fini = _nvkm_devinit_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c index 535172c5f1ad..1076fcf0d716 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c @@ -161,7 +161,7 @@ struct nvkm_oclass * gm204_devinit_oclass = &(struct nvkm_devinit_impl) { .base.handle = NV_SUBDEV(DEVINIT, 0x07), .base.ofuncs = &(struct nvkm_ofuncs) { - .ctor = nv50_devinit_ctor, + .ctor = gf100_devinit_ctor, .dtor = _nvkm_devinit_dtor, .init = nv50_devinit_init, .fini = _nvkm_devinit_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h index b882b65ff3cd..9243521c80ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h @@ -15,6 +15,9 @@ int nv50_devinit_pll_set(struct nvkm_devinit *, u32, u32); int gt215_devinit_pll_set(struct nvkm_devinit *, u32, u32); +int gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *, + struct nvkm_oclass *, void *, u32, + struct nvkm_object **); int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32); u64 gm107_devinit_disable(struct nvkm_devinit *); diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 42b2ea3fdcf3..e597ffc26563 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1798,7 +1798,9 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) if ((crtc->mode.clock == test_crtc->mode.clock) && (adjusted_clock == test_adjusted_clock) && (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) && - (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)) + (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) && + (drm_detect_monitor_audio(radeon_connector_edid(test_radeon_crtc->connector)) == + drm_detect_monitor_audio(radeon_connector_edid(radeon_crtc->connector)))) return test_radeon_crtc->pll_id; } } diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 3e3290c203c6..b435c859dcbc 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -421,19 +421,21 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) { struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; u8 msg[DP_DPCD_SIZE]; - int ret; + int ret, i; - ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, - DP_DPCD_SIZE); - if (ret > 0) { - memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); + for (i = 0; i < 7; i++) { + ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, + DP_DPCD_SIZE); + if (ret == DP_DPCD_SIZE) { + memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); - DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), - dig_connector->dpcd); + DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), + dig_connector->dpcd); - radeon_dp_probe_oui(radeon_connector); + radeon_dp_probe_oui(radeon_connector); - return true; + return true; + } } dig_connector->dpcd[0] = 0; return false; diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 28faea9996f9..ba50f3c1c2e0 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5837,7 +5837,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) /* restore context1-15 */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); for (i = 1; i < 16; i++) { if (i < 8) WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f04205170b8a..cfa3a84a2af0 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -173,7 +173,7 @@ void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - WREG32(HDMI0_ACR_PACKET_CONTROL + offset, + WREG32(DCE3_HDMI0_ACR_PACKET_CONTROL + offset, HDMI0_ACR_SOURCE | /* select SW CTS value */ HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 0926739c9fa7..9953356fe263 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -400,7 +400,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) if (enable) { struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { + if (connector && drm_detect_monitor_audio(radeon_connector_edid(connector))) { WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, HDMI_AVI_INFO_SEND | /* enable AVI info frames */ HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */ @@ -438,7 +438,8 @@ void evergreen_dp_enable(struct drm_encoder *encoder, bool enable) if (!dig || !dig->afmt) return; - if (enable && drm_detect_monitor_audio(radeon_connector_edid(connector))) { + if (enable && connector && + drm_detect_monitor_audio(radeon_connector_edid(connector))) { struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *dig_connector; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index e8a496ff007e..64d3a771920d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1301,7 +1301,8 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) */ for (i = 1; i < 8; i++) { WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), + rdev->vm_manager.max_pfn - 1); WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), rdev->vm_manager.saved_table_addr[i]); } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d2abe481954f..46eb0fa75a61 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1673,7 +1673,6 @@ struct radeon_uvd { struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; - void *saved_bo; atomic_t handles[RADEON_MAX_UVD_HANDLES]; struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; unsigned img_size[RADEON_MAX_UVD_HANDLES]; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index fafd8ce4d58f..8dbf5083c4ff 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1202,7 +1202,7 @@ static struct radeon_asic rs780_asic = { static struct radeon_asic_ring rv770_uvd_ring = { .ib_execute = &uvd_v1_0_ib_execute, .emit_fence = &uvd_v2_2_fence_emit, - .emit_semaphore = &uvd_v1_0_semaphore_emit, + .emit_semaphore = &uvd_v2_2_semaphore_emit, .cs_parse = &radeon_uvd_cs_parse, .ring_test = &uvd_v1_0_ring_test, .ib_test = &uvd_v1_0_ib_test, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index cf0a90bb61ca..a3ca8cd305c5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -949,6 +949,10 @@ void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int uvd_v2_2_resume(struct radeon_device *rdev); void uvd_v2_2_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); +bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait); /* uvd v3.1 */ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 8b82abb78df1..25191f126f3b 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -460,33 +460,34 @@ void radeon_audio_detect(struct drm_connector *connector, if (!connector || !connector->encoder) return; - if (!radeon_encoder_is_digital(connector->encoder)) + rdev = connector->encoder->dev->dev_private; + + if (!radeon_audio_chipset_supported(rdev)) return; - rdev = connector->encoder->dev->dev_private; radeon_encoder = to_radeon_encoder(connector->encoder); dig = radeon_encoder->enc_priv; - if (!dig->afmt) - return; - if (status == connector_status_connected) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector *radeon_connector; + int sink_type; + + if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { + radeon_encoder->audio = NULL; + return; + } + + radeon_connector = to_radeon_connector(connector); + sink_type = radeon_dp_getsinktype(radeon_connector); if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && - radeon_dp_getsinktype(radeon_connector) == - CONNECTOR_OBJECT_ID_DISPLAYPORT) + sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) radeon_encoder->audio = rdev->audio.dp_funcs; else radeon_encoder->audio = rdev->audio.hdmi_funcs; dig->afmt->pin = radeon_audio_get_pin(connector->encoder); - if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { - radeon_audio_enable(rdev, dig->afmt->pin, 0xf); - } else { - radeon_audio_enable(rdev, dig->afmt->pin, 0); - dig->afmt->pin = NULL; - } + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); } else { radeon_audio_enable(rdev, dig->afmt->pin, 0); dig->afmt->pin = NULL; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index d17d251dbd4f..cebb65e07e1d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1379,10 +1379,8 @@ out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); - if (radeon_audio != 0) { - radeon_connector_get_edid(connector); + if (radeon_audio != 0) radeon_audio_detect(connector, ret); - } exit: pm_runtime_mark_last_busy(connector->dev->dev); @@ -1719,10 +1717,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) radeon_connector_update_scratch_regs(connector, ret); - if (radeon_audio != 0) { - radeon_connector_get_edid(connector); + if (radeon_audio != 0) radeon_audio_detect(connector, ret); - } out: pm_runtime_mark_last_busy(connector->dev->dev); diff --git a/drivers/gpu/drm/radeon/radeon_dp_auxch.c b/drivers/gpu/drm/radeon/radeon_dp_auxch.c index bf1fecc6cceb..fcbd60bb0349 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_auxch.c +++ b/drivers/gpu/drm/radeon/radeon_dp_auxch.c @@ -30,8 +30,6 @@ AUX_SW_RX_HPD_DISCON | \ AUX_SW_RX_PARTIAL_BYTE | \ AUX_SW_NON_AUX_MODE | \ - AUX_SW_RX_MIN_COUNT_VIOL | \ - AUX_SW_RX_INVALID_STOP | \ AUX_SW_RX_SYNC_INVALID_L | \ AUX_SW_RX_SYNC_INVALID_H | \ AUX_SW_RX_INVALID_START | \ diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 1017338a49d9..2b98ed3e684d 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -666,6 +666,9 @@ radeon_dp_mst_probe(struct radeon_connector *radeon_connector) int ret; u8 msg[1]; + if (!radeon_mst) + return 0; + if (dig_connector->dpcd[DP_DPCD_REV] < 0x12) return 0; diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c index 535bf404b725..eef006c48584 100644 --- a/drivers/gpu/drm/radeon/radeon_mn.c +++ b/drivers/gpu/drm/radeon/radeon_mn.c @@ -142,6 +142,9 @@ static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn, list_for_each_entry(bo, &node->bos, mn_list) { + if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound) + continue; + r = radeon_bo_reserve(bo, true); if (r) { DRM_ERROR("(%ld) failed to reserve user bo\n", r); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index b292aca0f342..edafd3c2b170 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -591,8 +591,7 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) { struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); struct radeon_ttm_tt *gtt = (void *)ttm; - struct scatterlist *sg; - int i; + struct sg_page_iter sg_iter; int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); enum dma_data_direction direction = write ? @@ -605,9 +604,8 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) /* free the sg table and pages again */ dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); - for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) { - struct page *page = sg_page(sg); - + for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) { + struct page *page = sg_page_iter_page(&sg_iter); if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) set_page_dirty(page); diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index c10b2aec6450..6edcb5485092 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -204,28 +204,32 @@ void radeon_uvd_fini(struct radeon_device *rdev) int radeon_uvd_suspend(struct radeon_device *rdev) { - unsigned size; - void *ptr; - int i; + int i, r; if (rdev->uvd.vcpu_bo == NULL) return 0; - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) - if (atomic_read(&rdev->uvd.handles[i])) - break; + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + uint32_t handle = atomic_read(&rdev->uvd.handles[i]); + if (handle != 0) { + struct radeon_fence *fence; - if (i == RADEON_MAX_UVD_HANDLES) - return 0; + radeon_uvd_note_usage(rdev); - size = radeon_bo_size(rdev->uvd.vcpu_bo); - size -= rdev->uvd_fw->size; + r = radeon_uvd_get_destroy_msg(rdev, + R600_RING_TYPE_UVD_INDEX, handle, &fence); + if (r) { + DRM_ERROR("Error destroying UVD (%d)!\n", r); + continue; + } - ptr = rdev->uvd.cpu_addr; - ptr += rdev->uvd_fw->size; + radeon_fence_wait(fence, false); + radeon_fence_unref(&fence); - rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); - memcpy(rdev->uvd.saved_bo, ptr, size); + rdev->uvd.filp[i] = NULL; + atomic_set(&rdev->uvd.handles[i], 0); + } + } return 0; } @@ -246,12 +250,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size; - if (rdev->uvd.saved_bo != NULL) { - memcpy(ptr, rdev->uvd.saved_bo, size); - kfree(rdev->uvd.saved_bo); - rdev->uvd.saved_bo = NULL; - } else - memset(ptr, 0, size); + memset(ptr, 0, size); return 0; } @@ -396,6 +395,29 @@ static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) return 0; } +static int radeon_uvd_validate_codec(struct radeon_cs_parser *p, + unsigned stream_type) +{ + switch (stream_type) { + case 0: /* H264 */ + case 1: /* VC1 */ + /* always supported */ + return 0; + + case 3: /* MPEG2 */ + case 4: /* MPEG4 */ + /* only since UVD 3 */ + if (p->rdev->family >= CHIP_PALM) + return 0; + + /* fall through */ + default: + DRM_ERROR("UVD codec not supported by hardware %d!\n", + stream_type); + return -EINVAL; + } +} + static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, unsigned offset, unsigned buf_sizes[]) { @@ -436,50 +458,70 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return -EINVAL; } - if (msg_type == 1) { - /* it's a decode msg, calc buffer sizes */ - r = radeon_uvd_cs_msg_decode(msg, buf_sizes); - /* calc image size (width * height) */ - img_size = msg[6] * msg[7]; + switch (msg_type) { + case 0: + /* it's a create msg, calc image size (width * height) */ + img_size = msg[7] * msg[8]; + + r = radeon_uvd_validate_codec(p, msg[4]); radeon_bo_kunmap(bo); if (r) return r; - } else if (msg_type == 2) { + /* try to alloc a new handle */ + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { + DRM_ERROR("Handle 0x%x already in use!\n", handle); + return -EINVAL; + } + + if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { + p->rdev->uvd.filp[i] = p->filp; + p->rdev->uvd.img_size[i] = img_size; + return 0; + } + } + + DRM_ERROR("No more free UVD handles!\n"); + return -EINVAL; + + case 1: + /* it's a decode msg, validate codec and calc buffer sizes */ + r = radeon_uvd_validate_codec(p, msg[4]); + if (!r) + r = radeon_uvd_cs_msg_decode(msg, buf_sizes); + radeon_bo_kunmap(bo); + if (r) + return r; + + /* validate the handle */ + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { + if (p->rdev->uvd.filp[i] != p->filp) { + DRM_ERROR("UVD handle collision detected!\n"); + return -EINVAL; + } + return 0; + } + } + + DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); + return -ENOENT; + + case 2: /* it's a destroy msg, free the handle */ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); radeon_bo_kunmap(bo); return 0; - } else { - /* it's a create msg, calc image size (width * height) */ - img_size = msg[7] * msg[8]; - radeon_bo_kunmap(bo); - if (msg_type != 0) { - DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); - return -EINVAL; - } - - /* it's a create msg, no special handling needed */ - } - - /* create or decode, validate the handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { - if (atomic_read(&p->rdev->uvd.handles[i]) == handle) - return 0; - } + default: - /* handle not found try to alloc a new one */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { - if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { - p->rdev->uvd.filp[i] = p->filp; - p->rdev->uvd.img_size[i] = img_size; - return 0; - } + DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); + return -EINVAL; } - DRM_ERROR("No more free UVD handles!\n"); + BUG(); return -EINVAL; } diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 24f849f888bb..0de5711ac508 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -493,18 +493,27 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, * * @p: parser context * @handle: handle to validate + * @allocated: allocated a new handle? * * Validates the handle and return the found session index or -EINVAL * we we don't have another free session index. */ -int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) +static int radeon_vce_validate_handle(struct radeon_cs_parser *p, + uint32_t handle, bool *allocated) { unsigned i; + *allocated = false; + /* validate the handle */ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { - if (atomic_read(&p->rdev->vce.handles[i]) == handle) + if (atomic_read(&p->rdev->vce.handles[i]) == handle) { + if (p->rdev->vce.filp[i] != p->filp) { + DRM_ERROR("VCE handle collision detected!\n"); + return -EINVAL; + } return i; + } } /* handle not found try to alloc a new one */ @@ -512,6 +521,7 @@ int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) { p->rdev->vce.filp[i] = p->filp; p->rdev->vce.img_size[i] = 0; + *allocated = true; return i; } } @@ -529,10 +539,10 @@ int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) int radeon_vce_cs_parse(struct radeon_cs_parser *p) { int session_idx = -1; - bool destroyed = false; + bool destroyed = false, created = false, allocated = false; uint32_t tmp, handle = 0; uint32_t *size = &tmp; - int i, r; + int i, r = 0; while (p->idx < p->chunk_ib->length_dw) { uint32_t len = radeon_get_ib_value(p, p->idx); @@ -540,18 +550,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) if ((len < 8) || (len & 3)) { DRM_ERROR("invalid VCE command length (%d)!\n", len); - return -EINVAL; + r = -EINVAL; + goto out; } if (destroyed) { DRM_ERROR("No other command allowed after destroy!\n"); - return -EINVAL; + r = -EINVAL; + goto out; } switch (cmd) { case 0x00000001: // session handle = radeon_get_ib_value(p, p->idx + 2); - session_idx = radeon_vce_validate_handle(p, handle); + session_idx = radeon_vce_validate_handle(p, handle, + &allocated); if (session_idx < 0) return session_idx; size = &p->rdev->vce.img_size[session_idx]; @@ -561,6 +574,13 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) break; case 0x01000001: // create + created = true; + if (!allocated) { + DRM_ERROR("Handle already in use!\n"); + r = -EINVAL; + goto out; + } + *size = radeon_get_ib_value(p, p->idx + 8) * radeon_get_ib_value(p, p->idx + 10) * 8 * 3 / 2; @@ -578,12 +598,12 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9, *size); if (r) - return r; + goto out; r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11, *size / 3); if (r) - return r; + goto out; break; case 0x02000001: // destroy @@ -594,7 +614,7 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, *size * 2); if (r) - return r; + goto out; break; case 0x05000004: // video bitstream buffer @@ -602,36 +622,47 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, tmp); if (r) - return r; + goto out; break; case 0x05000005: // feedback buffer r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, 4096); if (r) - return r; + goto out; break; default: DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); - return -EINVAL; + r = -EINVAL; + goto out; } if (session_idx == -1) { DRM_ERROR("no session command at start of IB\n"); - return -EINVAL; + r = -EINVAL; + goto out; } p->idx += len / 4; } - if (destroyed) { - /* IB contains a destroy msg, free the handle */ + if (allocated && !created) { + DRM_ERROR("New session without create command!\n"); + r = -ENOENT; + } + +out: + if ((!r && destroyed) || (r && allocated)) { + /* + * IB contains a destroy msg or we have allocated an + * handle and got an error, anyway free the handle + */ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); } - return 0; + return r; } /** diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 3cf1e2921545..9ef2064b1c9c 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -989,6 +989,9 @@ ((n) & 0x3FFF) << 16) /* UVD */ +#define UVD_SEMA_ADDR_LOW 0xef00 +#define UVD_SEMA_ADDR_HIGH 0xef04 +#define UVD_SEMA_CMD 0xef08 #define UVD_GPCOM_VCPU_CMD 0xef0c #define UVD_GPCOM_VCPU_DATA0 0xef10 #define UVD_GPCOM_VCPU_DATA1 0xef14 diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index b1d74bc375d8..4c679b802bc8 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4318,7 +4318,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) /* empty context1-15 */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); /* Assign the pt base to something valid for now; the pts used for * the VMs are determined by the application and setup and assigned * on the fly in the vm part of radeon_gart.c diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index e72b3cb59358..c6b1cbca47fc 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -466,18 +466,8 @@ bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, struct radeon_semaphore *semaphore, bool emit_wait) { - uint64_t addr = semaphore->gpu_addr; - - radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); - radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); - - radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); - radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); - - radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); - radeon_ring_write(ring, emit_wait ? 1 : 0); - - return true; + /* disable semaphores for UVD V1 hardware */ + return false; } /** diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 89193519f8a1..7ed778cec7c6 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -60,6 +60,35 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, } /** + * uvd_v2_2_semaphore_emit - emit semaphore command + * + * @rdev: radeon_device pointer + * @ring: radeon_ring pointer + * @semaphore: semaphore to emit commands for + * @emit_wait: true if we should emit a wait command + * + * Emit a semaphore command (either wait or signal) to the UVD ring. + */ +bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +{ + uint64_t addr = semaphore->gpu_addr; + + radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); + radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); + + radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); + radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); + + radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); + radeon_ring_write(ring, emit_wait ? 1 : 0); + + return true; +} + +/** * uvd_v2_2_resume - memory controller programming * * @rdev: radeon_device pointer diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 1833abd7d3aa..bfad15a913a0 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -173,7 +173,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) drm->irq_enabled = true; /* syncpoints are used for full 32-bit hardware VBLANK counters */ - drm->vblank_disable_immediate = true; drm->max_vblank_count = 0xffffffff; err = drm_vblank_init(drm, drm->mode_config.num_crtc); diff --git a/drivers/gpu/drm/vgem/Makefile b/drivers/gpu/drm/vgem/Makefile index 1055cb79096c..3f4c7b842028 100644 --- a/drivers/gpu/drm/vgem/Makefile +++ b/drivers/gpu/drm/vgem/Makefile @@ -1,4 +1,4 @@ ccflags-y := -Iinclude/drm -vgem-y := vgem_drv.o vgem_dma_buf.o +vgem-y := vgem_drv.o obj-$(CONFIG_DRM_VGEM) += vgem.o diff --git a/drivers/gpu/drm/vgem/vgem_dma_buf.c b/drivers/gpu/drm/vgem/vgem_dma_buf.c deleted file mode 100644 index 0254438ad1a6..000000000000 --- a/drivers/gpu/drm/vgem/vgem_dma_buf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2014 The Chromium OS Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -#include <linux/dma-buf.h> -#include "vgem_drv.h" - -struct sg_table *vgem_gem_prime_get_sg_table(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - BUG_ON(obj->pages == NULL); - - return drm_prime_pages_to_sg(obj->pages, obj->base.size / PAGE_SIZE); -} - -int vgem_gem_prime_pin(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - return vgem_gem_get_pages(obj); -} - -void vgem_gem_prime_unpin(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - vgem_gem_put_pages(obj); -} - -void *vgem_gem_prime_vmap(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - BUG_ON(obj->pages == NULL); - - return vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL); -} - -void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) -{ - vunmap(vaddr); -} - -struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf) -{ - struct drm_vgem_gem_object *obj = NULL; - int ret; - - obj = kzalloc(sizeof(*obj), GFP_KERNEL); - if (obj == NULL) { - ret = -ENOMEM; - goto fail; - } - - ret = drm_gem_object_init(dev, &obj->base, dma_buf->size); - if (ret) { - ret = -ENOMEM; - goto fail_free; - } - - get_dma_buf(dma_buf); - - obj->base.dma_buf = dma_buf; - obj->use_dma_buf = true; - - return &obj->base; - -fail_free: - kfree(obj); -fail: - return ERR_PTR(ret); -} diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index cb3b43525b2d..7a207ca547be 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -302,22 +302,13 @@ static const struct file_operations vgem_driver_fops = { }; static struct drm_driver vgem_driver = { - .driver_features = DRIVER_GEM | DRIVER_PRIME, + .driver_features = DRIVER_GEM, .gem_free_object = vgem_gem_free_object, .gem_vm_ops = &vgem_gem_vm_ops, .ioctls = vgem_ioctls, .fops = &vgem_driver_fops, .dumb_create = vgem_gem_dumb_create, .dumb_map_offset = vgem_gem_dumb_map, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = vgem_gem_prime_import, - .gem_prime_pin = vgem_gem_prime_pin, - .gem_prime_unpin = vgem_gem_prime_unpin, - .gem_prime_get_sg_table = vgem_gem_prime_get_sg_table, - .gem_prime_vmap = vgem_gem_prime_vmap, - .gem_prime_vunmap = vgem_gem_prime_vunmap, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h index 57ab4d8f41f9..e9f92f7ee275 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.h +++ b/drivers/gpu/drm/vgem/vgem_drv.h @@ -43,15 +43,4 @@ struct drm_vgem_gem_object { extern void vgem_gem_put_pages(struct drm_vgem_gem_object *obj); extern int vgem_gem_get_pages(struct drm_vgem_gem_object *obj); -/* vgem_dma_buf.c */ -extern struct sg_table *vgem_gem_prime_get_sg_table( - struct drm_gem_object *gobj); -extern int vgem_gem_prime_pin(struct drm_gem_object *gobj); -extern void vgem_gem_prime_unpin(struct drm_gem_object *gobj); -extern void *vgem_gem_prime_vmap(struct drm_gem_object *gobj); -extern void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); -extern struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf); - - #endif diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 41f167e4d75f..7ce93d927f62 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -164,6 +164,7 @@ #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 +#define USB_DEVICE_ID_ATEN_CS682 0x2213 #define USB_VENDOR_ID_ATMEL 0x03eb #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index b3cf6fd4be96..5fd530acf747 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -44,7 +44,6 @@ MODULE_PARM_DESC(disable_raw_mode, /* bits 1..20 are reserved for classes */ #define HIDPP_QUIRK_DELAYED_INIT BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) -#define HIDPP_QUIRK_MULTI_INPUT BIT(23) /* * There are two hidpp protocols in use, the first version hidpp10 is known @@ -706,12 +705,6 @@ static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { - struct hidpp_device *hidpp = hid_get_drvdata(hdev); - - if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && - (field->application == HID_GD_KEYBOARD)) - return 0; - return -1; } @@ -720,10 +713,6 @@ static void wtp_populate_input(struct hidpp_device *hidpp, { struct wtp_data *wd = hidpp->private_data; - if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core) - /* this is the generic hid-input call */ - return; - __set_bit(EV_ABS, input_dev->evbit); __set_bit(EV_KEY, input_dev->evbit); __clear_bit(EV_REL, input_dev->evbit); @@ -1245,10 +1234,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) connect_mask &= ~HID_CONNECT_HIDINPUT; - /* Re-enable hidinput for multi-input devices */ - if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) - connect_mask |= HID_CONNECT_HIDINPUT; - ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); @@ -1296,11 +1281,6 @@ static const struct hid_device_id hidpp_devices[] = { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651), .driver_data = HIDPP_QUIRK_CLASS_WTP }, - { /* Keyboard TK820 */ - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, - USB_VENDOR_ID_LOGITECH, 0x4102), - .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT | - HIDPP_QUIRK_CLASS_WTP }, { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index c3f6f1e311ea..090a1ba0abb6 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -294,7 +294,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, if (!report) return -EINVAL; - mutex_lock(&hsdev->mutex); + mutex_lock(hsdev->mutex_ptr); if (flag == SENSOR_HUB_SYNC) { memset(&hsdev->pending, 0, sizeof(hsdev->pending)); init_completion(&hsdev->pending.ready); @@ -328,7 +328,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, kfree(hsdev->pending.raw_data); hsdev->pending.status = false; } - mutex_unlock(&hsdev->mutex); + mutex_unlock(hsdev->mutex_ptr); return ret_val; } @@ -667,7 +667,14 @@ static int sensor_hub_probe(struct hid_device *hdev, hsdev->vendor_id = hdev->vendor; hsdev->product_id = hdev->product; hsdev->usage = collection->usage; - mutex_init(&hsdev->mutex); + hsdev->mutex_ptr = devm_kzalloc(&hdev->dev, + sizeof(struct mutex), + GFP_KERNEL); + if (!hsdev->mutex_ptr) { + ret = -ENOMEM; + goto err_stop_hw; + } + mutex_init(hsdev->mutex_ptr); hsdev->start_collection_index = i; if (last_hsdev) last_hsdev->end_collection_index = i; diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index ab4dd952b6ba..92d6cdf02460 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -862,6 +862,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, union acpi_object *obj; struct acpi_device *adev; acpi_handle handle; + int ret; handle = ACPI_HANDLE(&client->dev); if (!handle || acpi_bus_get_device(handle, &adev)) @@ -877,7 +878,9 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, pdata->hid_descriptor_address = obj->integer.value; ACPI_FREE(obj); - return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios); + /* GPIOs are optional */ + ret = acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios); + return ret < 0 && ret != -ENXIO ? ret : 0; } static const struct acpi_device_id i2c_hid_acpi_match[] = { diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a775143e6265..4696895eb708 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -61,6 +61,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index fa54d3290659..adf959dcfa5d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1072,6 +1072,9 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) int count = 0; int i; + if (!touch_max) + return 0; + /* non-HID_GENERIC single touch input doesn't call this routine */ if ((touch_max == 1) && (wacom->features.type == HID_GENERIC)) return wacom->hid_data.tipswitch && diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c index f3830db02d46..37f01702d081 100644 --- a/drivers/hwmon/nct6683.c +++ b/drivers/hwmon/nct6683.c @@ -439,6 +439,7 @@ nct6683_create_attr_group(struct device *dev, struct sensor_template_group *tg, (*t)->dev_attr.attr.name, tg->base + i); if ((*t)->s2) { a2 = &su->u.a2; + sysfs_attr_init(&a2->dev_attr.attr); a2->dev_attr.attr.name = su->name; a2->nr = (*t)->u.s.nr + i; a2->index = (*t)->u.s.index; @@ -449,6 +450,7 @@ nct6683_create_attr_group(struct device *dev, struct sensor_template_group *tg, *attrs = &a2->dev_attr.attr; } else { a = &su->u.a1; + sysfs_attr_init(&a->dev_attr.attr); a->dev_attr.attr.name = su->name; a->index = (*t)->u.index + i; a->dev_attr.attr.mode = diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 4fcb48103299..bd1c99deac71 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -995,6 +995,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, (*t)->dev_attr.attr.name, tg->base + i); if ((*t)->s2) { a2 = &su->u.a2; + sysfs_attr_init(&a2->dev_attr.attr); a2->dev_attr.attr.name = su->name; a2->nr = (*t)->u.s.nr + i; a2->index = (*t)->u.s.index; @@ -1005,6 +1006,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, *attrs = &a2->dev_attr.attr; } else { a = &su->u.a1; + sysfs_attr_init(&a->dev_attr.attr); a->dev_attr.attr.name = su->name; a->index = (*t)->u.index + i; a->dev_attr.attr.mode = diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 112e4d45e4a0..68800115876b 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -239,8 +239,10 @@ static struct ntc_thermistor_platform_data * ntc_thermistor_parse_dt(struct platform_device *pdev) { struct iio_channel *chan; + enum iio_chan_type type; struct device_node *np = pdev->dev.of_node; struct ntc_thermistor_platform_data *pdata; + int ret; if (!np) return NULL; @@ -253,6 +255,13 @@ ntc_thermistor_parse_dt(struct platform_device *pdev) if (IS_ERR(chan)) return ERR_CAST(chan); + ret = iio_get_channel_type(chan, &type); + if (ret < 0) + return ERR_PTR(ret); + + if (type != IIO_VOLTAGE) + return ERR_PTR(-EINVAL); + if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) return ERR_PTR(-ENODEV); if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 99664ebc738d..ccf4cffe0ee1 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -44,7 +44,7 @@ #include <linux/sysfs.h> /* Addresses to scan */ -static const unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4c, 0x4d, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c index 8fe78d08e01c..7c6966434ee7 100644 --- a/drivers/i2c/busses/i2c-hix5hd2.c +++ b/drivers/i2c/busses/i2c-hix5hd2.c @@ -554,4 +554,4 @@ module_platform_driver(hix5hd2_i2c_driver); MODULE_DESCRIPTION("Hix5hd2 I2C Bus driver"); MODULE_AUTHOR("Wei Yan <sledge.yanwei@huawei.com>"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:i2c-hix5hd2"); +MODULE_ALIAS("platform:hix5hd2-i2c"); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 958c8db4ec30..297e9c9ac943 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1143,6 +1143,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) return -ENOMEM; i2c->quirks = s3c24xx_get_device_quirks(pdev); + i2c->sysreg = ERR_PTR(-ENOENT); if (pdata) memcpy(i2c->pdata, pdata, sizeof(*pdata)); else diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index a04c49f2a011..39ea67f9b066 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -643,15 +643,6 @@ config BLK_DEV_TC86C001 help This driver adds support for Toshiba TC86C001 GOKU-S chip. -config BLK_DEV_CELLEB - tristate "Toshiba's Cell Reference Set IDE support" - depends on PPC_CELLEB - select BLK_DEV_IDEDMA_PCI - help - This driver provides support for the on-board IDE controller on - Toshiba Cell Reference Board. - If unsure, say Y. - endif # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index a04ee82f1c8f..2a8c417d4081 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o -obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c deleted file mode 100644 index 2a2d188b5d5b..000000000000 --- a/drivers/ide/scc_pata.c +++ /dev/null @@ -1,887 +0,0 @@ -/* - * Support for IDE interfaces on Celleb platform - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This code is based on drivers/ide/pci/siimage.c: - * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <linux/types.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/ide.h> -#include <linux/init.h> - -#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 - -#define SCC_PATA_NAME "scc IDE" - -#define TDVHSEL_MASTER 0x00000001 -#define TDVHSEL_SLAVE 0x00000004 - -#define MODE_JCUSFEN 0x00000080 - -#define CCKCTRL_ATARESET 0x00040000 -#define CCKCTRL_BUFCNT 0x00020000 -#define CCKCTRL_CRST 0x00010000 -#define CCKCTRL_OCLKEN 0x00000100 -#define CCKCTRL_ATACLKOEN 0x00000002 -#define CCKCTRL_LCLKEN 0x00000001 - -#define QCHCD_IOS_SS 0x00000001 - -#define QCHSD_STPDIAG 0x00020000 - -#define INTMASK_MSK 0xD1000012 -#define INTSTS_SERROR 0x80000000 -#define INTSTS_PRERR 0x40000000 -#define INTSTS_RERR 0x10000000 -#define INTSTS_ICERR 0x01000000 -#define INTSTS_BMSINT 0x00000010 -#define INTSTS_BMHE 0x00000008 -#define INTSTS_IOIRQS 0x00000004 -#define INTSTS_INTRQ 0x00000002 -#define INTSTS_ACTEINT 0x00000001 - -#define ECMODE_VALUE 0x01 - -static struct scc_ports { - unsigned long ctl, dma; - struct ide_host *host; /* for removing port from system */ -} scc_ports[MAX_HWIFS]; - -/* PIO transfer mode table */ -/* JCHST */ -static unsigned long JCHSTtbl[2][7] = { - {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHHT */ -static unsigned long JCHHTtbl[2][7] = { - {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHCT */ -static unsigned long JCHCTtbl[2][7] = { - {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ - {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ -}; - - -/* DMA transfer mode table */ -/* JCHDCTM/JCHDCTS */ -static unsigned long JCHDCTxtbl[2][7] = { - {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ - {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ -}; - -/* JCSTWTM/JCSTWTS */ -static unsigned long JCSTWTxtbl[2][7] = { - {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ - {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCTSS */ -static unsigned long JCTSStbl[2][7] = { - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ -}; - -/* JCENVT */ -static unsigned long JCENVTtbl[2][7] = { - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCACTSELS/JCACTSELM */ -static unsigned long JCACTSELtbl[2][7] = { - {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ -}; - - -static u8 scc_ide_inb(unsigned long port) -{ - u32 data = in_be32((void*)port); - return (u8)data; -} - -static void scc_exec_command(ide_hwif_t *hwif, u8 cmd) -{ - out_be32((void *)hwif->io_ports.command_addr, cmd); - eieio(); - in_be32((void *)(hwif->dma_base + 0x01c)); - eieio(); -} - -static u8 scc_read_status(ide_hwif_t *hwif) -{ - return (u8)in_be32((void *)hwif->io_ports.status_addr); -} - -static u8 scc_read_altstatus(ide_hwif_t *hwif) -{ - return (u8)in_be32((void *)hwif->io_ports.ctl_addr); -} - -static u8 scc_dma_sff_read_status(ide_hwif_t *hwif) -{ - return (u8)in_be32((void *)(hwif->dma_base + 4)); -} - -static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl) -{ - out_be32((void *)hwif->io_ports.ctl_addr, ctl); - eieio(); - in_be32((void *)(hwif->dma_base + 0x01c)); - eieio(); -} - -static void scc_ide_insw(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - *ptr++ = le16_to_cpu(in_be32((void*)port)); - } -} - -static void scc_ide_insl(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - *ptr++ = le16_to_cpu(in_be32((void*)port)); - *ptr++ = le16_to_cpu(in_be32((void*)port)); - } -} - -static void scc_ide_outb(u8 addr, unsigned long port) -{ - out_be32((void*)port, addr); -} - -static void -scc_ide_outsw(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - out_be32((void*)port, cpu_to_le16(*ptr++)); - } -} - -static void -scc_ide_outsl(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - out_be32((void*)port, cpu_to_le16(*ptr++)); - out_be32((void*)port, cpu_to_le16(*ptr++)); - } -} - -/** - * scc_set_pio_mode - set host controller for PIO mode - * @hwif: port - * @drive: drive - * - * Load the timing settings for this device mode into the - * controller. - */ - -static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) -{ - struct scc_ports *ports = ide_get_hwifdata(hwif); - unsigned long ctl_base = ports->ctl; - unsigned long cckctrl_port = ctl_base + 0xff0; - unsigned long piosht_port = ctl_base + 0x000; - unsigned long pioct_port = ctl_base + 0x004; - unsigned long reg; - int offset; - const u8 pio = drive->pio_mode - XFER_PIO_0; - - reg = in_be32((void __iomem *)cckctrl_port); - if (reg & CCKCTRL_ATACLKOEN) { - offset = 1; /* 133MHz */ - } else { - offset = 0; /* 100MHz */ - } - reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; - out_be32((void __iomem *)piosht_port, reg); - reg = JCHCTtbl[offset][pio]; - out_be32((void __iomem *)pioct_port, reg); -} - -/** - * scc_set_dma_mode - set host controller for DMA mode - * @hwif: port - * @drive: drive - * - * Load the timing settings for this device mode into the - * controller. - */ - -static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) -{ - struct scc_ports *ports = ide_get_hwifdata(hwif); - unsigned long ctl_base = ports->ctl; - unsigned long cckctrl_port = ctl_base + 0xff0; - unsigned long mdmact_port = ctl_base + 0x008; - unsigned long mcrcst_port = ctl_base + 0x00c; - unsigned long sdmact_port = ctl_base + 0x010; - unsigned long scrcst_port = ctl_base + 0x014; - unsigned long udenvt_port = ctl_base + 0x018; - unsigned long tdvhsel_port = ctl_base + 0x020; - int is_slave = drive->dn & 1; - int offset, idx; - unsigned long reg; - unsigned long jcactsel; - const u8 speed = drive->dma_mode; - - reg = in_be32((void __iomem *)cckctrl_port); - if (reg & CCKCTRL_ATACLKOEN) { - offset = 1; /* 133MHz */ - } else { - offset = 0; /* 100MHz */ - } - - idx = speed - XFER_UDMA_0; - - jcactsel = JCACTSELtbl[offset][idx]; - if (is_slave) { - out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); - out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); - jcactsel = jcactsel << 2; - out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); - } else { - out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); - out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); - out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); - } - reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; - out_be32((void __iomem *)udenvt_port, reg); -} - -static void scc_dma_host_set(ide_drive_t *drive, int on) -{ - ide_hwif_t *hwif = drive->hwif; - u8 unit = drive->dn & 1; - u8 dma_stat = scc_dma_sff_read_status(hwif); - - if (on) - dma_stat |= (1 << (5 + unit)); - else - dma_stat &= ~(1 << (5 + unit)); - - scc_ide_outb(dma_stat, hwif->dma_base + 4); -} - -/** - * scc_dma_setup - begin a DMA phase - * @drive: target device - * @cmd: command - * - * Build an IDE DMA PRD (IDE speak for scatter gather table) - * and then set up the DMA transfer registers. - * - * Returns 0 on success. If a PIO fallback is required then 1 - * is returned. - */ - -static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) -{ - ide_hwif_t *hwif = drive->hwif; - u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; - u8 dma_stat; - - /* fall back to pio! */ - if (ide_build_dmatable(drive, cmd) == 0) - return 1; - - /* PRD table */ - out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); - - /* specify r/w */ - out_be32((void __iomem *)hwif->dma_base, rw); - - /* read DMA status for INTR & ERROR flags */ - dma_stat = scc_dma_sff_read_status(hwif); - - /* clear INTR & ERROR flags */ - out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); - - return 0; -} - -static void scc_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_cmd = scc_ide_inb(hwif->dma_base); - - /* start DMA */ - scc_ide_outb(dma_cmd | 1, hwif->dma_base); -} - -static int __scc_dma_end(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_stat, dma_cmd; - - /* get DMA command mode */ - dma_cmd = scc_ide_inb(hwif->dma_base); - /* stop DMA */ - scc_ide_outb(dma_cmd & ~1, hwif->dma_base); - /* get DMA status */ - dma_stat = scc_dma_sff_read_status(hwif); - /* clear the INTR & ERROR bits */ - scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); - /* verify good DMA status */ - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; -} - -/** - * scc_dma_end - Stop DMA - * @drive: IDE drive - * - * Check and clear INT Status register. - * Then call __scc_dma_end(). - */ - -static int scc_dma_end(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - void __iomem *dma_base = (void __iomem *)hwif->dma_base; - unsigned long intsts_port = hwif->dma_base + 0x014; - u32 reg; - int dma_stat, data_loss = 0; - static int retry = 0; - - /* errata A308 workaround: Step5 (check data loss) */ - /* We don't check non ide_disk because it is limited to UDMA4 */ - if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr) - & ATA_ERR) && - drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) { - reg = in_be32((void __iomem *)intsts_port); - if (!(reg & INTSTS_ACTEINT)) { - printk(KERN_WARNING "%s: operation failed (transfer data loss)\n", - drive->name); - data_loss = 1; - if (retry++) { - struct request *rq = hwif->rq; - ide_drive_t *drive; - int i; - - /* ERROR_RESET and drive->crc_count are needed - * to reduce DMA transfer mode in retry process. - */ - if (rq) - rq->errors |= ERROR_RESET; - - ide_port_for_each_dev(i, drive, hwif) - drive->crc_count++; - } - } - } - - while (1) { - reg = in_be32((void __iomem *)intsts_port); - - if (reg & INTSTS_SERROR) { - printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); - - out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_PRERR) { - u32 maea0, maec0; - unsigned long ctl_base = hwif->config_data; - - maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); - maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); - - printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); - - out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); - - out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_RERR) { - printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); - - out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_ICERR) { - out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS); - - printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); - continue; - } - - if (reg & INTSTS_BMSINT) { - printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); - - ide_do_reset(drive); - continue; - } - - if (reg & INTSTS_BMHE) { - out_be32((void __iomem *)intsts_port, INTSTS_BMHE); - continue; - } - - if (reg & INTSTS_ACTEINT) { - out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); - continue; - } - - if (reg & INTSTS_IOIRQS) { - out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); - continue; - } - break; - } - - dma_stat = __scc_dma_end(drive); - if (data_loss) - dma_stat |= 2; /* emulate DMA error (to retry command) */ - return dma_stat; -} - -/* returns 1 if dma irq issued, 0 otherwise */ -static int scc_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014); - - /* SCC errata A252,A308 workaround: Step4 */ - if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr) - & ATA_ERR) && - (int_stat & INTSTS_INTRQ)) - return 1; - - /* SCC errata A308 workaround: Step5 (polling IOIRQS) */ - if (int_stat & INTSTS_IOIRQS) - return 1; - - return 0; -} - -static u8 scc_udma_filter(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 mask = hwif->ultra_mask; - - /* errata A308 workaround: limit non ide_disk drive to UDMA4 */ - if ((drive->media != ide_disk) && (mask & 0xE0)) { - printk(KERN_INFO "%s: limit %s to UDMA4\n", - SCC_PATA_NAME, drive->name); - mask = ATA_UDMA4; - } - - return mask; -} - -/** - * setup_mmio_scc - map CTRL/BMID region - * @dev: PCI device we are configuring - * @name: device name - * - */ - -static int setup_mmio_scc (struct pci_dev *dev, const char *name) -{ - void __iomem *ctl_addr; - void __iomem *dma_addr; - int i, ret; - - for (i = 0; i < MAX_HWIFS; i++) { - if (scc_ports[i].ctl == 0) - break; - } - if (i >= MAX_HWIFS) - return -ENOMEM; - - ret = pci_request_selected_regions(dev, (1 << 2) - 1, name); - if (ret < 0) { - printk(KERN_ERR "%s: can't reserve resources\n", name); - return ret; - } - - ctl_addr = pci_ioremap_bar(dev, 0); - if (!ctl_addr) - goto fail_0; - - dma_addr = pci_ioremap_bar(dev, 1); - if (!dma_addr) - goto fail_1; - - pci_set_master(dev); - scc_ports[i].ctl = (unsigned long)ctl_addr; - scc_ports[i].dma = (unsigned long)dma_addr; - pci_set_drvdata(dev, (void *) &scc_ports[i]); - - return 1; - - fail_1: - iounmap(ctl_addr); - fail_0: - return -ENOMEM; -} - -static int scc_ide_setup_pci_device(struct pci_dev *dev, - const struct ide_port_info *d) -{ - struct scc_ports *ports = pci_get_drvdata(dev); - struct ide_host *host; - struct ide_hw hw, *hws[] = { &hw }; - int i, rc; - - memset(&hw, 0, sizeof(hw)); - for (i = 0; i <= 8; i++) - hw.io_ports_array[i] = ports->dma + 0x20 + i * 4; - hw.irq = dev->irq; - hw.dev = &dev->dev; - - rc = ide_host_add(d, hws, 1, &host); - if (rc) - return rc; - - ports->host = host; - - return 0; -} - -/** - * init_setup_scc - set up an SCC PATA Controller - * @dev: PCI device - * @d: IDE port info - * - * Perform the initial set up for this device. - */ - -static int init_setup_scc(struct pci_dev *dev, const struct ide_port_info *d) -{ - unsigned long ctl_base; - unsigned long dma_base; - unsigned long cckctrl_port; - unsigned long intmask_port; - unsigned long mode_port; - unsigned long ecmode_port; - u32 reg = 0; - struct scc_ports *ports; - int rc; - - rc = pci_enable_device(dev); - if (rc) - goto end; - - rc = setup_mmio_scc(dev, d->name); - if (rc < 0) - goto end; - - ports = pci_get_drvdata(dev); - ctl_base = ports->ctl; - dma_base = ports->dma; - cckctrl_port = ctl_base + 0xff0; - intmask_port = dma_base + 0x010; - mode_port = ctl_base + 0x024; - ecmode_port = ctl_base + 0xf00; - - /* controller initialization */ - reg = 0; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_ATACLKOEN; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_CRST; - out_be32((void*)cckctrl_port, reg); - - for (;;) { - reg = in_be32((void*)cckctrl_port); - if (reg & CCKCTRL_CRST) - break; - udelay(5000); - } - - reg |= CCKCTRL_ATARESET; - out_be32((void*)cckctrl_port, reg); - - out_be32((void*)ecmode_port, ECMODE_VALUE); - out_be32((void*)mode_port, MODE_JCUSFEN); - out_be32((void*)intmask_port, INTMASK_MSK); - - rc = scc_ide_setup_pci_device(dev, d); - - end: - return rc; -} - -static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) -{ - struct ide_io_ports *io_ports = &drive->hwif->io_ports; - - if (valid & IDE_VALID_FEATURE) - scc_ide_outb(tf->feature, io_ports->feature_addr); - if (valid & IDE_VALID_NSECT) - scc_ide_outb(tf->nsect, io_ports->nsect_addr); - if (valid & IDE_VALID_LBAL) - scc_ide_outb(tf->lbal, io_ports->lbal_addr); - if (valid & IDE_VALID_LBAM) - scc_ide_outb(tf->lbam, io_ports->lbam_addr); - if (valid & IDE_VALID_LBAH) - scc_ide_outb(tf->lbah, io_ports->lbah_addr); - if (valid & IDE_VALID_DEVICE) - scc_ide_outb(tf->device, io_ports->device_addr); -} - -static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) -{ - struct ide_io_ports *io_ports = &drive->hwif->io_ports; - - if (valid & IDE_VALID_ERROR) - tf->error = scc_ide_inb(io_ports->feature_addr); - if (valid & IDE_VALID_NSECT) - tf->nsect = scc_ide_inb(io_ports->nsect_addr); - if (valid & IDE_VALID_LBAL) - tf->lbal = scc_ide_inb(io_ports->lbal_addr); - if (valid & IDE_VALID_LBAM) - tf->lbam = scc_ide_inb(io_ports->lbam_addr); - if (valid & IDE_VALID_LBAH) - tf->lbah = scc_ide_inb(io_ports->lbah_addr); - if (valid & IDE_VALID_DEVICE) - tf->device = scc_ide_inb(io_ports->device_addr); -} - -static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, - void *buf, unsigned int len) -{ - unsigned long data_addr = drive->hwif->io_ports.data_addr; - - len++; - - if (drive->io_32bit) { - scc_ide_insl(data_addr, buf, len / 4); - - if ((len & 3) >= 2) - scc_ide_insw(data_addr, (u8 *)buf + (len & ~3), 1); - } else - scc_ide_insw(data_addr, buf, len / 2); -} - -static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd, - void *buf, unsigned int len) -{ - unsigned long data_addr = drive->hwif->io_ports.data_addr; - - len++; - - if (drive->io_32bit) { - scc_ide_outsl(data_addr, buf, len / 4); - - if ((len & 3) >= 2) - scc_ide_outsw(data_addr, (u8 *)buf + (len & ~3), 1); - } else - scc_ide_outsw(data_addr, buf, len / 2); -} - -/** - * init_mmio_iops_scc - set up the iops for MMIO - * @hwif: interface to set up - * - */ - -static void init_mmio_iops_scc(ide_hwif_t *hwif) -{ - struct pci_dev *dev = to_pci_dev(hwif->dev); - struct scc_ports *ports = pci_get_drvdata(dev); - unsigned long dma_base = ports->dma; - - ide_set_hwifdata(hwif, ports); - - hwif->dma_base = dma_base; - hwif->config_data = ports->ctl; -} - -/** - * init_iops_scc - set up iops - * @hwif: interface to set up - * - * Do the basic setup for the SCC hardware interface - * and then do the MMIO setup. - */ - -static void init_iops_scc(ide_hwif_t *hwif) -{ - struct pci_dev *dev = to_pci_dev(hwif->dev); - - hwif->hwif_data = NULL; - if (pci_get_drvdata(dev) == NULL) - return; - init_mmio_iops_scc(hwif); -} - -static int scc_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d) -{ - return ide_allocate_dma_engine(hwif); -} - -static u8 scc_cable_detect(ide_hwif_t *hwif) -{ - return ATA_CBL_PATA80; -} - -/** - * init_hwif_scc - set up hwif - * @hwif: interface to set up - * - * We do the basic set up of the interface structure. The SCC - * requires several custom handlers so we override the default - * ide DMA handlers appropriately. - */ - -static void init_hwif_scc(ide_hwif_t *hwif) -{ - /* PTERADD */ - out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); - - if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) - hwif->ultra_mask = ATA_UDMA6; /* 133MHz */ - else - hwif->ultra_mask = ATA_UDMA5; /* 100MHz */ -} - -static const struct ide_tp_ops scc_tp_ops = { - .exec_command = scc_exec_command, - .read_status = scc_read_status, - .read_altstatus = scc_read_altstatus, - .write_devctl = scc_write_devctl, - - .dev_select = ide_dev_select, - .tf_load = scc_tf_load, - .tf_read = scc_tf_read, - - .input_data = scc_input_data, - .output_data = scc_output_data, -}; - -static const struct ide_port_ops scc_port_ops = { - .set_pio_mode = scc_set_pio_mode, - .set_dma_mode = scc_set_dma_mode, - .udma_filter = scc_udma_filter, - .cable_detect = scc_cable_detect, -}; - -static const struct ide_dma_ops scc_dma_ops = { - .dma_host_set = scc_dma_host_set, - .dma_setup = scc_dma_setup, - .dma_start = scc_dma_start, - .dma_end = scc_dma_end, - .dma_test_irq = scc_dma_test_irq, - .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, - .dma_sff_read_status = scc_dma_sff_read_status, -}; - -static const struct ide_port_info scc_chipset = { - .name = "sccIDE", - .init_iops = init_iops_scc, - .init_dma = scc_init_dma, - .init_hwif = init_hwif_scc, - .tp_ops = &scc_tp_ops, - .port_ops = &scc_port_ops, - .dma_ops = &scc_dma_ops, - .host_flags = IDE_HFLAG_SINGLE, - .irq_flags = IRQF_SHARED, - .pio_mask = ATA_PIO4, - .chipset = ide_pci, -}; - -/** - * scc_init_one - pci layer discovery entry - * @dev: PCI device - * @id: ident table entry - * - * Called by the PCI code when it finds an SCC PATA controller. - * We then use the IDE PCI generic helper to do most of the work. - */ - -static int scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return init_setup_scc(dev, &scc_chipset); -} - -/** - * scc_remove - pci layer remove entry - * @dev: PCI device - * - * Called by the PCI code when it removes an SCC PATA controller. - */ - -static void scc_remove(struct pci_dev *dev) -{ - struct scc_ports *ports = pci_get_drvdata(dev); - struct ide_host *host = ports->host; - - ide_host_remove(host); - - iounmap((void*)ports->dma); - iounmap((void*)ports->ctl); - pci_release_selected_regions(dev, (1 << 2) - 1); - memset(ports, 0, sizeof(*ports)); -} - -static const struct pci_device_id scc_pci_tbl[] = { - { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, scc_pci_tbl); - -static struct pci_driver scc_pci_driver = { - .name = "SCC IDE", - .id_table = scc_pci_tbl, - .probe = scc_init_one, - .remove = scc_remove, -}; - -static int __init scc_ide_init(void) -{ - return ide_pci_register_driver(&scc_pci_driver); -} - -static void __exit scc_ide_exit(void) -{ - pci_unregister_driver(&scc_pci_driver); -} - -module_init(scc_ide_init); -module_exit(scc_ide_exit); - -MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index 54b3ae615a14..2fd2a995686b 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c @@ -389,7 +389,12 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, { int ret, i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, reg, NULL, 0, (u8 *) be_buf, len); @@ -424,7 +429,12 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, { int ret, i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, reg, NULL, 0, (u8 *) be_buf, len); @@ -459,7 +469,12 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, { int i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } for (i = 0; i < len_words; i++) be_buf[i] = cpu_to_be16(buf[i]); diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 9d649c4a21fd..8bfc61824fb2 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -54,6 +54,7 @@ #define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0) #define MMA9553_REG_CONF_ACTTHD 0x0E +#define MMA9553_MAX_ACTTHD GENMASK(15, 0) /* Pedometer status registers (R-only) */ #define MMA9553_REG_STATUS 0x00 @@ -317,22 +318,19 @@ static int mma9553_set_config(struct mma9553_data *data, u16 reg, static int mma9553_read_activity_stepcnt(struct mma9553_data *data, u8 *activity, u16 *stepcnt) { - u32 status_stepcnt; - u16 status; + u16 buf[2]; int ret; ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER, - MMA9553_REG_STATUS, sizeof(u32), - (u16 *) &status_stepcnt); + MMA9553_REG_STATUS, sizeof(u32), buf); if (ret < 0) { dev_err(&data->client->dev, "error reading status and stepcnt\n"); return ret; } - status = status_stepcnt & MMA9553_MASK_CONF_WORD; - *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY); - *stepcnt = status_stepcnt >> 16; + *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY); + *stepcnt = buf[1]; return 0; } @@ -842,6 +840,9 @@ static int mma9553_write_event_value(struct iio_dev *indio_dev, case IIO_EV_INFO_PERIOD: switch (chan->type) { case IIO_ACTIVITY: + if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC( + MMA9553_MAX_ACTTHD)) + return -EINVAL; mutex_lock(&data->mutex); ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD, &data->conf.actthd, @@ -941,7 +942,8 @@ static const struct iio_chan_spec_ext_info mma9553_ext_info[] = { .modified = 1, \ .channel2 = _chan2, \ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \ + BIT(IIO_CHAN_INFO_ENABLE), \ .event_spec = mma9553_activity_events, \ .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \ .ext_info = mma9553_ext_info, \ diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 970e9f904dde..4002e6410444 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -632,6 +632,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &accel_info; + mutex_init(&adata->tb.buf_lock); st_sensors_power_enable(indio_dev); diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 27197fd1517e..0c904edd6c00 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -53,39 +53,42 @@ static const struct iio_chan_spec const axp288_adc_channels[] = { .channel = 0, .address = AXP288_TS_ADC_H, .datasheet_name = "TS_PIN", + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .indexed = 1, .type = IIO_TEMP, .channel = 1, .address = AXP288_PMIC_ADC_H, .datasheet_name = "PMIC_TEMP", + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .indexed = 1, .type = IIO_TEMP, .channel = 2, .address = AXP288_GP_ADC_H, .datasheet_name = "GPADC", + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .indexed = 1, .type = IIO_CURRENT, .channel = 3, .address = AXP20X_BATT_CHRG_I_H, .datasheet_name = "BATT_CHG_I", - .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .indexed = 1, .type = IIO_CURRENT, .channel = 4, .address = AXP20X_BATT_DISCHRG_I_H, .datasheet_name = "BATT_DISCHRG_I", - .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .indexed = 1, .type = IIO_VOLTAGE, .channel = 5, .address = AXP20X_BATT_V_H, .datasheet_name = "BATT_V", - .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, }; @@ -151,9 +154,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, chan->address)) dev_err(&indio_dev->dev, "TS pin restore\n"); break; - case IIO_CHAN_INFO_PROCESSED: - ret = axp288_adc_read_channel(val, chan->address, info->regmap); - break; default: ret = -EINVAL; } diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 51e2a83c9404..115f6e99a7fa 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -35,8 +35,9 @@ #define CC10001_ADC_EOC_SET BIT(0) #define CC10001_ADC_CHSEL_SAMPLED 0x0c -#define CC10001_ADC_POWER_UP 0x10 -#define CC10001_ADC_POWER_UP_SET BIT(0) +#define CC10001_ADC_POWER_DOWN 0x10 +#define CC10001_ADC_POWER_DOWN_SET BIT(0) + #define CC10001_ADC_DEBUG 0x14 #define CC10001_ADC_DATA_COUNT 0x20 @@ -62,7 +63,6 @@ struct cc10001_adc_device { u16 *buf; struct mutex lock; - unsigned long channel_map; unsigned int start_delay_ns; unsigned int eoc_delay_ns; }; @@ -79,6 +79,18 @@ static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev, return readl(adc_dev->reg_base + reg); } +static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev) +{ + cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0); + ndelay(adc_dev->start_delay_ns); +} + +static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev) +{ + cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, + CC10001_ADC_POWER_DOWN_SET); +} + static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, unsigned int channel) { @@ -88,6 +100,7 @@ static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); + udelay(1); val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); val = val | CC10001_ADC_START_CONV; cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); @@ -129,6 +142,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) struct iio_dev *indio_dev; unsigned int delay_ns; unsigned int channel; + unsigned int scan_idx; bool sample_invalid; u16 *data; int i; @@ -139,20 +153,17 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) mutex_lock(&adc_dev->lock); - cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, - CC10001_ADC_POWER_UP_SET); - - /* Wait for 8 (6+2) clock cycles before activating START */ - ndelay(adc_dev->start_delay_ns); + cc10001_adc_power_up(adc_dev); /* Calculate delay step for eoc and sampled data */ delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; i = 0; sample_invalid = false; - for_each_set_bit(channel, indio_dev->active_scan_mask, + for_each_set_bit(scan_idx, indio_dev->active_scan_mask, indio_dev->masklength) { + channel = indio_dev->channels[scan_idx].channel; cc10001_adc_start(adc_dev, channel); data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); @@ -166,7 +177,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) } done: - cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); + cc10001_adc_power_down(adc_dev); mutex_unlock(&adc_dev->lock); @@ -185,11 +196,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, unsigned int delay_ns; u16 val; - cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, - CC10001_ADC_POWER_UP_SET); - - /* Wait for 8 (6+2) clock cycles before activating START */ - ndelay(adc_dev->start_delay_ns); + cc10001_adc_power_up(adc_dev); /* Calculate delay step for eoc and sampled data */ delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; @@ -198,7 +205,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); - cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); + cc10001_adc_power_down(adc_dev); return val; } @@ -224,7 +231,7 @@ static int cc10001_adc_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: ret = regulator_get_voltage(adc_dev->reg); - if (ret) + if (ret < 0) return ret; *val = ret / 1000; @@ -255,22 +262,22 @@ static const struct iio_info cc10001_adc_info = { .update_scan_mode = &cc10001_update_scan_mode, }; -static int cc10001_adc_channel_init(struct iio_dev *indio_dev) +static int cc10001_adc_channel_init(struct iio_dev *indio_dev, + unsigned long channel_map) { - struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); struct iio_chan_spec *chan_array, *timestamp; unsigned int bit, idx = 0; - indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map, - CC10001_ADC_NUM_CHANNELS); + indio_dev->num_channels = bitmap_weight(&channel_map, + CC10001_ADC_NUM_CHANNELS) + 1; - chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1, + chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels, sizeof(struct iio_chan_spec), GFP_KERNEL); if (!chan_array) return -ENOMEM; - for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) { + for_each_set_bit(bit, &channel_map, CC10001_ADC_NUM_CHANNELS) { struct iio_chan_spec *chan = &chan_array[idx]; chan->type = IIO_VOLTAGE; @@ -305,6 +312,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) unsigned long adc_clk_rate; struct resource *res; struct iio_dev *indio_dev; + unsigned long channel_map; int ret; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); @@ -313,9 +321,9 @@ static int cc10001_adc_probe(struct platform_device *pdev) adc_dev = iio_priv(indio_dev); - adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); + channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) - adc_dev->channel_map &= ~ret; + channel_map &= ~ret; adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); if (IS_ERR(adc_dev->reg)) @@ -361,7 +369,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; /* Setup the ADC channels available on the device */ - ret = cc10001_adc_channel_init(indio_dev); + ret = cc10001_adc_channel_init(indio_dev, channel_map); if (ret < 0) goto err_disable_clk; diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index efbfd12a4bfd..8d9c9b9215dd 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -60,12 +60,12 @@ struct mcp320x { struct spi_message msg; struct spi_transfer transfer[2]; - u8 tx_buf; - u8 rx_buf[2]; - struct regulator *reg; struct mutex lock; const struct mcp320x_chip_info *chip_info; + + u8 tx_buf ____cacheline_aligned; + u8 rx_buf[2]; }; static int mcp320x_channel_to_tx_data(int device_index, diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index 3211729bcb0b..0c4618b4d515 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -18,6 +18,7 @@ #include <linux/iio/iio.h> #include <linux/interrupt.h> #include <linux/kernel.h> +#include <linux/math64.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -471,11 +472,11 @@ static s32 vadc_calibrate(struct vadc_priv *vadc, const struct vadc_channel_prop *prop, u16 adc_code) { const struct vadc_prescale_ratio *prescale; - s32 voltage; + s64 voltage; voltage = adc_code - vadc->graph[prop->calibration].gnd; voltage *= vadc->graph[prop->calibration].dx; - voltage = voltage / vadc->graph[prop->calibration].dy; + voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); if (prop->calibration == VADC_CALIB_ABSOLUTE) voltage += vadc->graph[prop->calibration].dx; @@ -487,7 +488,7 @@ static s32 vadc_calibrate(struct vadc_priv *vadc, voltage = voltage * prescale->den; - return voltage / prescale->num; + return div64_s64(voltage, prescale->num); } static int vadc_decimation_from_dt(u32 value) diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index 89d8aa1d2818..df12c57e6ce0 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -1001,7 +1001,7 @@ static struct platform_driver twl6030_gpadc_driver = { module_platform_driver(twl6030_gpadc_driver); -MODULE_ALIAS("platform: " DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_AUTHOR("Balaji T K <balajitk@ti.com>"); MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com"); diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index a221f7329b79..ce93bd8e3f68 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -856,6 +856,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev, switch (chan->address) { case XADC_REG_VCCINT: case XADC_REG_VCCAUX: + case XADC_REG_VREFP: case XADC_REG_VCCBRAM: case XADC_REG_VCCPINT: case XADC_REG_VCCPAUX: @@ -996,7 +997,7 @@ static const struct iio_event_spec xadc_voltage_events[] = { .num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \ .scan_index = (_scan_index), \ .scan_type = { \ - .sign = 'u', \ + .sign = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \ .realbits = 12, \ .storagebits = 16, \ .shift = 4, \ @@ -1008,7 +1009,7 @@ static const struct iio_event_spec xadc_voltage_events[] = { static const struct iio_chan_spec xadc_channels[] = { XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP), XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true), - XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCINT, "vccaux", true), + XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCAUX, "vccaux", true), XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true), XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true), XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true), diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h index c7487e8d7f80..54adc5087210 100644 --- a/drivers/iio/adc/xilinx-xadc.h +++ b/drivers/iio/adc/xilinx-xadc.h @@ -145,9 +145,9 @@ static inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg, #define XADC_REG_MAX_VCCPINT 0x28 #define XADC_REG_MAX_VCCPAUX 0x29 #define XADC_REG_MAX_VCCO_DDR 0x2a -#define XADC_REG_MIN_VCCPINT 0x2b -#define XADC_REG_MIN_VCCPAUX 0x2c -#define XADC_REG_MIN_VCCO_DDR 0x2d +#define XADC_REG_MIN_VCCPINT 0x2c +#define XADC_REG_MIN_VCCPAUX 0x2d +#define XADC_REG_MIN_VCCO_DDR 0x2e #define XADC_REG_CONF0 0x40 #define XADC_REG_CONF1 0x41 diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index bf4b13f9defc..8086cbcff87d 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -314,8 +314,6 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, struct st_sensors_platform_data *of_pdata; int err = 0; - mutex_init(&sdata->tb.buf_lock); - /* If OF/DT pdata exists, it will take precedence of anything else */ of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata); if (of_pdata) diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 21395f26d227..ffe96642b6d0 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -400,6 +400,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &gyro_info; + mutex_init(&gdata->tb.buf_lock); st_sensors_power_enable(indio_dev); diff --git a/drivers/iio/imu/adis16400.h b/drivers/iio/imu/adis16400.h index 0916bf6b6c31..73b189c1c0fb 100644 --- a/drivers/iio/imu/adis16400.h +++ b/drivers/iio/imu/adis16400.h @@ -139,6 +139,7 @@ #define ADIS16400_NO_BURST BIT(1) #define ADIS16400_HAS_SLOW_MODE BIT(2) #define ADIS16400_HAS_SERIAL_NUMBER BIT(3) +#define ADIS16400_BURST_DIAG_STAT BIT(4) struct adis16400_state; @@ -165,6 +166,7 @@ struct adis16400_state { int filt_int; struct adis adis; + unsigned long avail_scan_mask[2]; }; /* At the moment triggers are only used for ring buffer diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c index 6e727ffe5262..90c24a23c679 100644 --- a/drivers/iio/imu/adis16400_buffer.c +++ b/drivers/iio/imu/adis16400_buffer.c @@ -18,7 +18,8 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, { struct adis16400_state *st = iio_priv(indio_dev); struct adis *adis = &st->adis; - uint16_t *tx; + unsigned int burst_length; + u8 *tx; if (st->variant->flags & ADIS16400_NO_BURST) return adis_update_scan_mode(indio_dev, scan_mask); @@ -26,26 +27,29 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, kfree(adis->xfer); kfree(adis->buffer); + /* All but the timestamp channel */ + burst_length = (indio_dev->num_channels - 1) * sizeof(u16); + if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) + burst_length += sizeof(u16); + adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); if (!adis->xfer) return -ENOMEM; - adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16), - GFP_KERNEL); + adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); if (!adis->buffer) return -ENOMEM; - tx = adis->buffer + indio_dev->scan_bytes; - + tx = adis->buffer + burst_length; tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); tx[1] = 0; adis->xfer[0].tx_buf = tx; adis->xfer[0].bits_per_word = 8; adis->xfer[0].len = 2; - adis->xfer[1].tx_buf = tx; + adis->xfer[1].rx_buf = adis->buffer; adis->xfer[1].bits_per_word = 8; - adis->xfer[1].len = indio_dev->scan_bytes; + adis->xfer[1].len = burst_length; spi_message_init(&adis->msg); spi_message_add_tail(&adis->xfer[0], &adis->msg); @@ -61,6 +65,7 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p) struct adis16400_state *st = iio_priv(indio_dev); struct adis *adis = &st->adis; u32 old_speed_hz = st->adis.spi->max_speed_hz; + void *buffer; int ret; if (!adis->buffer) @@ -81,7 +86,12 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p) spi_setup(st->adis.spi); } - iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer, + if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) + buffer = adis->buffer + sizeof(u16); + else + buffer = adis->buffer; + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index fa795dcd5f75..2fd68f2219a7 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -405,6 +405,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, *val = st->variant->temp_scale_nano / 1000000; *val2 = (st->variant->temp_scale_nano % 1000000); return IIO_VAL_INT_PLUS_MICRO; + case IIO_PRESSURE: + /* 20 uBar = 0.002kPascal */ + *val = 0; + *val2 = 2000; + return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -454,10 +459,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } } -#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \ +#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .channel = 0, \ + .channel = chn, \ .extend_name = name, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ @@ -474,10 +479,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } #define ADIS16400_SUPPLY_CHAN(addr, bits) \ - ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY) + ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY, 0) #define ADIS16400_AUX_ADC_CHAN(addr, bits) \ - ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC) + ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC, 1) #define ADIS16400_GYRO_CHAN(mod, addr, bits) { \ .type = IIO_ANGL_VEL, \ @@ -773,7 +778,8 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16448_channels, .num_channels = ARRAY_SIZE(adis16448_channels), .flags = ADIS16400_HAS_PROD_ID | - ADIS16400_HAS_SERIAL_NUMBER, + ADIS16400_HAS_SERIAL_NUMBER | + ADIS16400_BURST_DIAG_STAT, .gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */ .temp_scale_nano = 73860000, /* 0.07386 C */ @@ -791,11 +797,6 @@ static const struct iio_info adis16400_info = { .debugfs_reg_access = adis_debugfs_reg_access, }; -static const unsigned long adis16400_burst_scan_mask[] = { - ~0UL, - 0, -}; - static const char * const adis16400_status_error_msgs[] = { [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure", [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure", @@ -843,6 +844,20 @@ static const struct adis_data adis16400_data = { BIT(ADIS16400_DIAG_STAT_POWER_LOW), }; +static void adis16400_setup_chan_mask(struct adis16400_state *st) +{ + const struct adis16400_chip_info *chip_info = st->variant; + unsigned i; + + for (i = 0; i < chip_info->num_channels; i++) { + const struct iio_chan_spec *ch = &chip_info->channels[i]; + + if (ch->scan_index >= 0 && + ch->scan_index != ADIS16400_SCAN_TIMESTAMP) + st->avail_scan_mask[0] |= BIT(ch->scan_index); + } +} + static int adis16400_probe(struct spi_device *spi) { struct adis16400_state *st; @@ -866,8 +881,10 @@ static int adis16400_probe(struct spi_device *spi) indio_dev->info = &adis16400_info; indio_dev->modes = INDIO_DIRECT_MODE; - if (!(st->variant->flags & ADIS16400_NO_BURST)) - indio_dev->available_scan_masks = adis16400_burst_scan_mask; + if (!(st->variant->flags & ADIS16400_NO_BURST)) { + adis16400_setup_chan_mask(st); + indio_dev->available_scan_masks = st->avail_scan_mask; + } ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); if (ret) diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index db15684a4731..c5b999f0c519 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -38,7 +38,8 @@ static int iio_request_update_kfifo(struct iio_buffer *r) kfifo_free(&buf->kf); ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, buf->buffer.length); - buf->update_needed = false; + if (ret >= 0) + buf->update_needed = false; } else { kfifo_reset_out(&buf->kf); } diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index be9db9d985b2..0d248476f4c9 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -43,8 +43,6 @@ struct prox_state { static const struct iio_chan_spec prox_channels[] = { { .type = IIO_PROXIMITY, - .modified = 1, - .channel2 = IIO_NO_MOD, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) | @@ -253,7 +251,6 @@ static int hid_prox_probe(struct platform_device *pdev) struct iio_dev *indio_dev; struct prox_state *prox_state; struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; - struct iio_chan_spec *channels; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct prox_state)); @@ -272,20 +269,21 @@ static int hid_prox_probe(struct platform_device *pdev) return ret; } - channels = kmemdup(prox_channels, sizeof(prox_channels), GFP_KERNEL); - if (!channels) { + indio_dev->channels = kmemdup(prox_channels, sizeof(prox_channels), + GFP_KERNEL); + if (!indio_dev->channels) { dev_err(&pdev->dev, "failed to duplicate channels\n"); return -ENOMEM; } - ret = prox_parse_report(pdev, hsdev, channels, + ret = prox_parse_report(pdev, hsdev, + (struct iio_chan_spec *)indio_dev->channels, HID_USAGE_SENSOR_PROX, prox_state); if (ret) { dev_err(&pdev->dev, "failed to setup attributes\n"); goto error_free_dev_mem; } - indio_dev->channels = channels; indio_dev->num_channels = ARRAY_SIZE(prox_channels); indio_dev->dev.parent = &pdev->dev; diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 73574d912e7c..b4bcfb790f49 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -485,6 +485,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &magn_info; + mutex_init(&mdata->tb.buf_lock); st_sensors_power_enable(indio_dev); diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c index 7c623e2bd633..a2602d8dd6d5 100644 --- a/drivers/iio/pressure/bmp280.c +++ b/drivers/iio/pressure/bmp280.c @@ -172,6 +172,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data, var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) * ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) * ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14; + data->t_fine = var1 + var2; return (data->t_fine * 5 + 128) >> 8; } diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index c060bd847f54..6848d8c80eff 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c @@ -47,8 +47,6 @@ struct press_state { static const struct iio_chan_spec press_channels[] = { { .type = IIO_PRESSURE, - .modified = 1, - .channel2 = IIO_NO_MOD, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) | diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 97baf40d424b..e881fa6291e9 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -417,6 +417,7 @@ int st_press_common_probe(struct iio_dev *indio_dev) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &press_info; + mutex_init(&press_data->tb.buf_lock); st_sensors_power_enable(indio_dev); diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index f80da50d84a5..38339d220d7f 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -472,13 +472,8 @@ int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *dmac, } sgid_addr, dgid_addr; - ret = rdma_gid2ip(&sgid_addr._sockaddr, sgid); - if (ret) - return ret; - - ret = rdma_gid2ip(&dgid_addr._sockaddr, dgid); - if (ret) - return ret; + rdma_gid2ip(&sgid_addr._sockaddr, sgid); + rdma_gid2ip(&dgid_addr._sockaddr, dgid); memset(&dev_addr, 0, sizeof(dev_addr)); @@ -512,10 +507,8 @@ int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id) struct sockaddr_in6 _sockaddr_in6; } gid_addr; - ret = rdma_gid2ip(&gid_addr._sockaddr, sgid); + rdma_gid2ip(&gid_addr._sockaddr, sgid); - if (ret) - return ret; memset(&dev_addr, 0, sizeof(dev_addr)); ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id); if (ret) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index e28a494e2a3a..0271608a51c4 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -437,39 +437,38 @@ static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id) return cm_id_priv; } -static void cm_mask_copy(u8 *dst, u8 *src, u8 *mask) +static void cm_mask_copy(u32 *dst, const u32 *src, const u32 *mask) { int i; - for (i = 0; i < IB_CM_COMPARE_SIZE / sizeof(unsigned long); i++) - ((unsigned long *) dst)[i] = ((unsigned long *) src)[i] & - ((unsigned long *) mask)[i]; + for (i = 0; i < IB_CM_COMPARE_SIZE; i++) + dst[i] = src[i] & mask[i]; } static int cm_compare_data(struct ib_cm_compare_data *src_data, struct ib_cm_compare_data *dst_data) { - u8 src[IB_CM_COMPARE_SIZE]; - u8 dst[IB_CM_COMPARE_SIZE]; + u32 src[IB_CM_COMPARE_SIZE]; + u32 dst[IB_CM_COMPARE_SIZE]; if (!src_data || !dst_data) return 0; cm_mask_copy(src, src_data->data, dst_data->mask); cm_mask_copy(dst, dst_data->data, src_data->mask); - return memcmp(src, dst, IB_CM_COMPARE_SIZE); + return memcmp(src, dst, sizeof(src)); } -static int cm_compare_private_data(u8 *private_data, +static int cm_compare_private_data(u32 *private_data, struct ib_cm_compare_data *dst_data) { - u8 src[IB_CM_COMPARE_SIZE]; + u32 src[IB_CM_COMPARE_SIZE]; if (!dst_data) return 0; cm_mask_copy(src, private_data, dst_data->mask); - return memcmp(src, dst_data->data, IB_CM_COMPARE_SIZE); + return memcmp(src, dst_data->data, sizeof(src)); } /* @@ -538,7 +537,7 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) static struct cm_id_private * cm_find_listen(struct ib_device *device, __be64 service_id, - u8 *private_data) + u32 *private_data) { struct rb_node *node = cm.listen_service_table.rb_node; struct cm_id_private *cm_id_priv; @@ -862,6 +861,7 @@ retest: cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); break; case IB_CM_REQ_SENT: + case IB_CM_MRA_REQ_RCVD: ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); spin_unlock_irq(&cm_id_priv->lock); ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, @@ -880,7 +880,6 @@ retest: NULL, 0, NULL, 0); } break; - case IB_CM_MRA_REQ_RCVD: case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); @@ -953,7 +952,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask, cm_mask_copy(cm_id_priv->compare_data->data, compare_data->data, compare_data->mask); memcpy(cm_id_priv->compare_data->mask, compare_data->mask, - IB_CM_COMPARE_SIZE); + sizeof(compare_data->mask)); } cm_id->state = IB_CM_LISTEN; diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h index be068f47e47e..8b76f0ef965e 100644 --- a/drivers/infiniband/core/cm_msgs.h +++ b/drivers/infiniband/core/cm_msgs.h @@ -103,7 +103,7 @@ struct cm_req_msg { /* local ACK timeout:5, rsvd:3 */ u8 alt_offset139; - u8 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE]; + u32 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE / sizeof(u32)]; } __attribute__ ((packed)); @@ -801,7 +801,7 @@ struct cm_sidr_req_msg { __be16 rsvd; __be64 service_id; - u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE]; + u32 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE / sizeof(u32)]; } __attribute__ ((packed)); struct cm_sidr_rep_msg { diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d570030d899c..38ffe0981503 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -845,33 +845,49 @@ static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr; ib = (struct sockaddr_ib *) &id->route.addr.src_addr; ib->sib_family = listen_ib->sib_family; - ib->sib_pkey = path->pkey; - ib->sib_flowinfo = path->flow_label; - memcpy(&ib->sib_addr, &path->sgid, 16); + if (path) { + ib->sib_pkey = path->pkey; + ib->sib_flowinfo = path->flow_label; + memcpy(&ib->sib_addr, &path->sgid, 16); + } else { + ib->sib_pkey = listen_ib->sib_pkey; + ib->sib_flowinfo = listen_ib->sib_flowinfo; + ib->sib_addr = listen_ib->sib_addr; + } ib->sib_sid = listen_ib->sib_sid; ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL); ib->sib_scope_id = listen_ib->sib_scope_id; - ib = (struct sockaddr_ib *) &id->route.addr.dst_addr; - ib->sib_family = listen_ib->sib_family; - ib->sib_pkey = path->pkey; - ib->sib_flowinfo = path->flow_label; - memcpy(&ib->sib_addr, &path->dgid, 16); + if (path) { + ib = (struct sockaddr_ib *) &id->route.addr.dst_addr; + ib->sib_family = listen_ib->sib_family; + ib->sib_pkey = path->pkey; + ib->sib_flowinfo = path->flow_label; + memcpy(&ib->sib_addr, &path->dgid, 16); + } +} + +static __be16 ss_get_port(const struct sockaddr_storage *ss) +{ + if (ss->ss_family == AF_INET) + return ((struct sockaddr_in *)ss)->sin_port; + else if (ss->ss_family == AF_INET6) + return ((struct sockaddr_in6 *)ss)->sin6_port; + BUG(); } static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, struct cma_hdr *hdr) { - struct sockaddr_in *listen4, *ip4; + struct sockaddr_in *ip4; - listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr; ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; - ip4->sin_family = listen4->sin_family; + ip4->sin_family = AF_INET; ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; - ip4->sin_port = listen4->sin_port; + ip4->sin_port = ss_get_port(&listen_id->route.addr.src_addr); ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; - ip4->sin_family = listen4->sin_family; + ip4->sin_family = AF_INET; ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; ip4->sin_port = hdr->port; } @@ -879,16 +895,15 @@ static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_i static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, struct cma_hdr *hdr) { - struct sockaddr_in6 *listen6, *ip6; + struct sockaddr_in6 *ip6; - listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr; ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; - ip6->sin6_family = listen6->sin6_family; + ip6->sin6_family = AF_INET6; ip6->sin6_addr = hdr->dst_addr.ip6; - ip6->sin6_port = listen6->sin6_port; + ip6->sin6_port = ss_get_port(&listen_id->route.addr.src_addr); ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; - ip6->sin6_family = listen6->sin6_family; + ip6->sin6_family = AF_INET6; ip6->sin6_addr = hdr->src_addr.ip6; ip6->sin6_port = hdr->port; } @@ -898,9 +913,11 @@ static int cma_save_net_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id { struct cma_hdr *hdr; - if ((listen_id->route.addr.src_addr.ss_family == AF_IB) && - (ib_event->event == IB_CM_REQ_RECEIVED)) { - cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path); + if (listen_id->route.addr.src_addr.ss_family == AF_IB) { + if (ib_event->event == IB_CM_REQ_RECEIVED) + cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path); + else if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) + cma_save_ib_info(id, listen_id, NULL); return 0; } diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index b85ddbc979e0..e6ffa2e66c1a 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -33,7 +33,7 @@ #include "iwpm_util.h" -static const char iwpm_ulib_name[] = "iWarpPortMapperUser"; +static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser"; static int iwpm_ulib_version = 3; static int iwpm_user_pid = IWPM_PID_UNDEFINED; static atomic_t echo_nlmsg_seq; @@ -468,7 +468,8 @@ add_mapping_response_exit: } EXPORT_SYMBOL(iwpm_add_mapping_cb); -/* netlink attribute policy for the response to add and query mapping request */ +/* netlink attribute policy for the response to add and query mapping request + * and response with remote address info */ static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, @@ -559,6 +560,76 @@ query_mapping_response_exit: } EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); +/* + * iwpm_remote_info_cb - Process a port mapper message, containing + * the remote connecting peer address info + */ +int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; + struct sockaddr_storage *local_sockaddr, *remote_sockaddr; + struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; + struct iwpm_remote_info *rem_info; + const char *msg_type; + u8 nl_client; + int ret = -EINVAL; + + msg_type = "Remote Mapping info"; + if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, + resp_query_policy, nltb, msg_type)) + return ret; + + nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); + if (!iwpm_valid_client(nl_client)) { + pr_info("%s: Invalid port mapper client = %d\n", + __func__, nl_client); + return ret; + } + atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); + + local_sockaddr = (struct sockaddr_storage *) + nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); + remote_sockaddr = (struct sockaddr_storage *) + nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); + mapped_loc_sockaddr = (struct sockaddr_storage *) + nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); + mapped_rem_sockaddr = (struct sockaddr_storage *) + nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); + + if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || + mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { + pr_info("%s: Sockaddr family doesn't match the requested one\n", + __func__); + return ret; + } + rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); + if (!rem_info) { + pr_err("%s: Unable to allocate a remote info\n", __func__); + ret = -ENOMEM; + return ret; + } + memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, + sizeof(struct sockaddr_storage)); + memcpy(&rem_info->remote_sockaddr, remote_sockaddr, + sizeof(struct sockaddr_storage)); + memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, + sizeof(struct sockaddr_storage)); + rem_info->nl_client = nl_client; + + iwpm_add_remote_info(rem_info); + + iwpm_print_sockaddr(local_sockaddr, + "remote_info: Local sockaddr:"); + iwpm_print_sockaddr(mapped_loc_sockaddr, + "remote_info: Mapped local sockaddr:"); + iwpm_print_sockaddr(remote_sockaddr, + "remote_info: Remote sockaddr:"); + iwpm_print_sockaddr(mapped_rem_sockaddr, + "remote_info: Mapped remote sockaddr:"); + return ret; +} +EXPORT_SYMBOL(iwpm_remote_info_cb); + /* netlink attribute policy for the received request for mapping info */ static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 69e9f84c1605..a626795bf9c7 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -33,8 +33,10 @@ #include "iwpm_util.h" -#define IWPM_HASH_BUCKET_SIZE 512 -#define IWPM_HASH_BUCKET_MASK (IWPM_HASH_BUCKET_SIZE - 1) +#define IWPM_MAPINFO_HASH_SIZE 512 +#define IWPM_MAPINFO_HASH_MASK (IWPM_MAPINFO_HASH_SIZE - 1) +#define IWPM_REMINFO_HASH_SIZE 64 +#define IWPM_REMINFO_HASH_MASK (IWPM_REMINFO_HASH_SIZE - 1) static LIST_HEAD(iwpm_nlmsg_req_list); static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); @@ -42,31 +44,49 @@ static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); static struct hlist_head *iwpm_hash_bucket; static DEFINE_SPINLOCK(iwpm_mapinfo_lock); +static struct hlist_head *iwpm_reminfo_bucket; +static DEFINE_SPINLOCK(iwpm_reminfo_lock); + static DEFINE_MUTEX(iwpm_admin_lock); static struct iwpm_admin_data iwpm_admin; int iwpm_init(u8 nl_client) { + int ret = 0; if (iwpm_valid_client(nl_client)) return -EINVAL; mutex_lock(&iwpm_admin_lock); if (atomic_read(&iwpm_admin.refcount) == 0) { - iwpm_hash_bucket = kzalloc(IWPM_HASH_BUCKET_SIZE * + iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE * sizeof(struct hlist_head), GFP_KERNEL); if (!iwpm_hash_bucket) { - mutex_unlock(&iwpm_admin_lock); + ret = -ENOMEM; pr_err("%s Unable to create mapinfo hash table\n", __func__); - return -ENOMEM; + goto init_exit; + } + iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE * + sizeof(struct hlist_head), GFP_KERNEL); + if (!iwpm_reminfo_bucket) { + kfree(iwpm_hash_bucket); + ret = -ENOMEM; + pr_err("%s Unable to create reminfo hash table\n", __func__); + goto init_exit; } } atomic_inc(&iwpm_admin.refcount); +init_exit: mutex_unlock(&iwpm_admin_lock); - iwpm_set_valid(nl_client, 1); - return 0; + if (!ret) { + iwpm_set_valid(nl_client, 1); + pr_debug("%s: Mapinfo and reminfo tables are created\n", + __func__); + } + return ret; } EXPORT_SYMBOL(iwpm_init); static void free_hash_bucket(void); +static void free_reminfo_bucket(void); int iwpm_exit(u8 nl_client) { @@ -81,7 +101,8 @@ int iwpm_exit(u8 nl_client) } if (atomic_dec_and_test(&iwpm_admin.refcount)) { free_hash_bucket(); - pr_debug("%s: Mapinfo hash table is destroyed\n", __func__); + free_reminfo_bucket(); + pr_debug("%s: Resources are destroyed\n", __func__); } mutex_unlock(&iwpm_admin_lock); iwpm_set_valid(nl_client, 0); @@ -89,7 +110,7 @@ int iwpm_exit(u8 nl_client) } EXPORT_SYMBOL(iwpm_exit); -static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage *, +static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *, struct sockaddr_storage *); int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, @@ -99,9 +120,10 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, struct hlist_head *hash_bucket_head; struct iwpm_mapping_info *map_info; unsigned long flags; + int ret = -EINVAL; if (!iwpm_valid_client(nl_client)) - return -EINVAL; + return ret; map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); if (!map_info) { pr_err("%s: Unable to allocate a mapping info\n", __func__); @@ -115,13 +137,16 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, spin_lock_irqsave(&iwpm_mapinfo_lock, flags); if (iwpm_hash_bucket) { - hash_bucket_head = get_hash_bucket_head( + hash_bucket_head = get_mapinfo_hash_bucket( &map_info->local_sockaddr, &map_info->mapped_sockaddr); - hlist_add_head(&map_info->hlist_node, hash_bucket_head); + if (hash_bucket_head) { + hlist_add_head(&map_info->hlist_node, hash_bucket_head); + ret = 0; + } } spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); - return 0; + return ret; } EXPORT_SYMBOL(iwpm_create_mapinfo); @@ -136,9 +161,12 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr, spin_lock_irqsave(&iwpm_mapinfo_lock, flags); if (iwpm_hash_bucket) { - hash_bucket_head = get_hash_bucket_head( + hash_bucket_head = get_mapinfo_hash_bucket( local_sockaddr, mapped_local_addr); + if (!hash_bucket_head) + goto remove_mapinfo_exit; + hlist_for_each_entry_safe(map_info, tmp_hlist_node, hash_bucket_head, hlist_node) { @@ -152,6 +180,7 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr, } } } +remove_mapinfo_exit: spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); return ret; } @@ -166,7 +195,7 @@ static void free_hash_bucket(void) /* remove all the mapinfo data from the list */ spin_lock_irqsave(&iwpm_mapinfo_lock, flags); - for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { + for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { hlist_for_each_entry_safe(map_info, tmp_hlist_node, &iwpm_hash_bucket[i], hlist_node) { @@ -180,6 +209,96 @@ static void free_hash_bucket(void) spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); } +static void free_reminfo_bucket(void) +{ + struct hlist_node *tmp_hlist_node; + struct iwpm_remote_info *rem_info; + unsigned long flags; + int i; + + /* remove all the remote info from the list */ + spin_lock_irqsave(&iwpm_reminfo_lock, flags); + for (i = 0; i < IWPM_REMINFO_HASH_SIZE; i++) { + hlist_for_each_entry_safe(rem_info, tmp_hlist_node, + &iwpm_reminfo_bucket[i], hlist_node) { + + hlist_del_init(&rem_info->hlist_node); + kfree(rem_info); + } + } + /* free the hash list */ + kfree(iwpm_reminfo_bucket); + iwpm_reminfo_bucket = NULL; + spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); +} + +static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage *, + struct sockaddr_storage *); + +void iwpm_add_remote_info(struct iwpm_remote_info *rem_info) +{ + struct hlist_head *hash_bucket_head; + unsigned long flags; + + spin_lock_irqsave(&iwpm_reminfo_lock, flags); + if (iwpm_reminfo_bucket) { + hash_bucket_head = get_reminfo_hash_bucket( + &rem_info->mapped_loc_sockaddr, + &rem_info->mapped_rem_sockaddr); + if (hash_bucket_head) + hlist_add_head(&rem_info->hlist_node, hash_bucket_head); + } + spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); +} + +int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, + struct sockaddr_storage *mapped_rem_addr, + struct sockaddr_storage *remote_addr, + u8 nl_client) +{ + struct hlist_node *tmp_hlist_node; + struct hlist_head *hash_bucket_head; + struct iwpm_remote_info *rem_info = NULL; + unsigned long flags; + int ret = -EINVAL; + + if (!iwpm_valid_client(nl_client)) { + pr_info("%s: Invalid client = %d\n", __func__, nl_client); + return ret; + } + spin_lock_irqsave(&iwpm_reminfo_lock, flags); + if (iwpm_reminfo_bucket) { + hash_bucket_head = get_reminfo_hash_bucket( + mapped_loc_addr, + mapped_rem_addr); + if (!hash_bucket_head) + goto get_remote_info_exit; + hlist_for_each_entry_safe(rem_info, tmp_hlist_node, + hash_bucket_head, hlist_node) { + + if (!iwpm_compare_sockaddr(&rem_info->mapped_loc_sockaddr, + mapped_loc_addr) && + !iwpm_compare_sockaddr(&rem_info->mapped_rem_sockaddr, + mapped_rem_addr)) { + + memcpy(remote_addr, &rem_info->remote_sockaddr, + sizeof(struct sockaddr_storage)); + iwpm_print_sockaddr(remote_addr, + "get_remote_info: Remote sockaddr:"); + + hlist_del_init(&rem_info->hlist_node); + kfree(rem_info); + ret = 0; + break; + } + } + } +get_remote_info_exit: + spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); + return ret; +} +EXPORT_SYMBOL(iwpm_get_remote_info); + struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, u8 nl_client, gfp_t gfp) { @@ -409,31 +528,54 @@ static u32 iwpm_ipv4_jhash(struct sockaddr_in *ipv4_sockaddr) return hash; } -static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage - *local_sockaddr, - struct sockaddr_storage - *mapped_sockaddr) +static int get_hash_bucket(struct sockaddr_storage *a_sockaddr, + struct sockaddr_storage *b_sockaddr, u32 *hash) { - u32 local_hash, mapped_hash, hash; + u32 a_hash, b_hash; - if (local_sockaddr->ss_family == AF_INET) { - local_hash = iwpm_ipv4_jhash((struct sockaddr_in *) local_sockaddr); - mapped_hash = iwpm_ipv4_jhash((struct sockaddr_in *) mapped_sockaddr); + if (a_sockaddr->ss_family == AF_INET) { + a_hash = iwpm_ipv4_jhash((struct sockaddr_in *) a_sockaddr); + b_hash = iwpm_ipv4_jhash((struct sockaddr_in *) b_sockaddr); - } else if (local_sockaddr->ss_family == AF_INET6) { - local_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) local_sockaddr); - mapped_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) mapped_sockaddr); + } else if (a_sockaddr->ss_family == AF_INET6) { + a_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) a_sockaddr); + b_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) b_sockaddr); } else { pr_err("%s: Invalid sockaddr family\n", __func__); - return NULL; + return -EINVAL; } - if (local_hash == mapped_hash) /* if port mapper isn't available */ - hash = local_hash; + if (a_hash == b_hash) /* if port mapper isn't available */ + *hash = a_hash; else - hash = jhash_2words(local_hash, mapped_hash, 0); + *hash = jhash_2words(a_hash, b_hash, 0); + return 0; +} + +static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage + *local_sockaddr, struct sockaddr_storage + *mapped_sockaddr) +{ + u32 hash; + int ret; - return &iwpm_hash_bucket[hash & IWPM_HASH_BUCKET_MASK]; + ret = get_hash_bucket(local_sockaddr, mapped_sockaddr, &hash); + if (ret) + return NULL; + return &iwpm_hash_bucket[hash & IWPM_MAPINFO_HASH_MASK]; +} + +static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage + *mapped_loc_sockaddr, struct sockaddr_storage + *mapped_rem_sockaddr) +{ + u32 hash; + int ret; + + ret = get_hash_bucket(mapped_loc_sockaddr, mapped_rem_sockaddr, &hash); + if (ret) + return NULL; + return &iwpm_reminfo_bucket[hash & IWPM_REMINFO_HASH_MASK]; } static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) @@ -512,7 +654,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid) } skb_num++; spin_lock_irqsave(&iwpm_mapinfo_lock, flags); - for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { + for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { hlist_for_each_entry(map_info, &iwpm_hash_bucket[i], hlist_node) { if (map_info->nl_client != nl_client) @@ -595,7 +737,7 @@ int iwpm_mapinfo_available(void) spin_lock_irqsave(&iwpm_mapinfo_lock, flags); if (iwpm_hash_bucket) { - for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { + for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) { if (!hlist_empty(&iwpm_hash_bucket[i])) { full_bucket = 1; break; diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index 9777c869a140..ee2d9ff095be 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h @@ -76,6 +76,14 @@ struct iwpm_mapping_info { u8 nl_client; }; +struct iwpm_remote_info { + struct hlist_node hlist_node; + struct sockaddr_storage remote_sockaddr; + struct sockaddr_storage mapped_loc_sockaddr; + struct sockaddr_storage mapped_rem_sockaddr; + u8 nl_client; +}; + struct iwpm_admin_data { atomic_t refcount; atomic_t nlmsg_seq; @@ -128,6 +136,13 @@ int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request); int iwpm_get_nlmsg_seq(void); /** + * iwpm_add_reminfo - Add remote address info of the connecting peer + * to the remote info hash table + * @reminfo: The remote info to be added + */ +void iwpm_add_remote_info(struct iwpm_remote_info *reminfo); + +/** * iwpm_valid_client - Check if the port mapper client is valid * @nl_client: The index of the netlink client * diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 8b8cc6fa0ab0..40becdb3196e 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -446,7 +446,6 @@ static int ib_umem_odp_map_dma_single_page( int remove_existing_mapping = 0; int ret = 0; - mutex_lock(&umem->odp_data->umem_mutex); /* * Note: we avoid writing if seq is different from the initial seq, to * handle case of a racing notifier. This check also allows us to bail @@ -479,8 +478,6 @@ static int ib_umem_odp_map_dma_single_page( } out: - mutex_unlock(&umem->odp_data->umem_mutex); - /* On Demand Paging - avoid pinning the page */ if (umem->context->invalidate_range || !stored_page) put_page(page); @@ -586,6 +583,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, bcnt -= min_t(size_t, npages << PAGE_SHIFT, bcnt); user_virt += npages << PAGE_SHIFT; + mutex_lock(&umem->odp_data->umem_mutex); for (j = 0; j < npages; ++j) { ret = ib_umem_odp_map_dma_single_page( umem, k, base_virt_addr, local_page_list[j], @@ -594,6 +592,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, break; k++; } + mutex_unlock(&umem->odp_data->umem_mutex); if (ret < 0) { /* Release left over pages when handling errors. */ @@ -633,12 +632,11 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, * faults from completion. We might be racing with other * invalidations, so we must make sure we free each page only * once. */ + mutex_lock(&umem->odp_data->umem_mutex); for (addr = virt; addr < bound; addr += (u64)umem->page_size) { idx = (addr - ib_umem_start(umem)) / PAGE_SIZE; - mutex_lock(&umem->odp_data->umem_mutex); if (umem->odp_data->page_list[idx]) { struct page *page = umem->odp_data->page_list[idx]; - struct page *head_page = compound_head(page); dma_addr_t dma = umem->odp_data->dma_list[idx]; dma_addr_t dma_addr = dma & ODP_DMA_ADDR_MASK; @@ -646,7 +644,8 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, ib_dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma & ODP_WRITE_ALLOWED_BIT) + if (dma & ODP_WRITE_ALLOWED_BIT) { + struct page *head_page = compound_head(page); /* * set_page_dirty prefers being called with * the page lock. However, MMU notifiers are @@ -657,13 +656,14 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, * be removed. */ set_page_dirty(head_page); + } /* on demand pinning support */ if (!umem->context->invalidate_range) put_page(page); umem->odp_data->page_list[idx] = NULL; umem->odp_data->dma_list[idx] = 0; } - mutex_unlock(&umem->odp_data->umem_mutex); } + mutex_unlock(&umem->odp_data->umem_mutex); } EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages); diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 57176ddd4c50..3ad8dc798f52 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -583,6 +583,22 @@ static void c4iw_record_pm_msg(struct c4iw_ep *ep, sizeof(ep->com.mapped_remote_addr)); } +static int get_remote_addr(struct c4iw_ep *parent_ep, struct c4iw_ep *child_ep) +{ + int ret; + + print_addr(&parent_ep->com, __func__, "get_remote_addr parent_ep "); + print_addr(&child_ep->com, __func__, "get_remote_addr child_ep "); + + ret = iwpm_get_remote_info(&parent_ep->com.mapped_local_addr, + &child_ep->com.mapped_remote_addr, + &child_ep->com.remote_addr, RDMA_NL_C4IW); + if (ret) + PDBG("Unable to find remote peer addr info - err %d\n", ret); + + return ret; +} + static void best_mtu(const unsigned short *mtus, unsigned short mtu, unsigned int *idx, int use_ts, int ipv6) { @@ -675,7 +691,7 @@ static int send_connect(struct c4iw_ep *ep) if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { opt2 |= T5_OPT_2_VALID_F; opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); - opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ + opt2 |= T5_ISS_F; } t4_set_arp_err_handler(skb, ep, act_open_req_arp_failure); @@ -2042,9 +2058,12 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) status, status2errno(status)); if (is_neg_adv(status)) { - dev_warn(&dev->rdev.lldi.pdev->dev, - "Connection problems for atid %u status %u (%s)\n", - atid, status, neg_adv_str(status)); + PDBG("%s Connection problems for atid %u status %u (%s)\n", + __func__, atid, status, neg_adv_str(status)); + ep->stats.connect_neg_adv++; + mutex_lock(&dev->rdev.stats.lock); + dev->rdev.stats.neg_adv++; + mutex_unlock(&dev->rdev.stats.lock); return 0; } @@ -2214,7 +2233,7 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, u32 isn = (prandom_u32() & ~7UL) - 1; opt2 |= T5_OPT_2_VALID_F; opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE); - opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ + opt2 |= T5_ISS_F; rpl5 = (void *)rpl; memset(&rpl5->iss, 0, roundup(sizeof(*rpl5)-sizeof(*rpl), 16)); if (peer2peer) @@ -2352,27 +2371,57 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) state_set(&child_ep->com, CONNECTING); child_ep->com.dev = dev; child_ep->com.cm_id = NULL; + + /* + * The mapped_local and mapped_remote addresses get setup with + * the actual 4-tuple. The local address will be based on the + * actual local address of the connection, but on the port number + * of the parent listening endpoint. The remote address is + * setup based on a query to the IWPM since we don't know what it + * originally was before mapping. If no mapping was done, then + * mapped_remote == remote, and mapped_local == local. + */ if (iptype == 4) { struct sockaddr_in *sin = (struct sockaddr_in *) - &child_ep->com.local_addr; + &child_ep->com.mapped_local_addr; + sin->sin_family = PF_INET; sin->sin_port = local_port; sin->sin_addr.s_addr = *(__be32 *)local_ip; - sin = (struct sockaddr_in *)&child_ep->com.remote_addr; + + sin = (struct sockaddr_in *)&child_ep->com.local_addr; + sin->sin_family = PF_INET; + sin->sin_port = ((struct sockaddr_in *) + &parent_ep->com.local_addr)->sin_port; + sin->sin_addr.s_addr = *(__be32 *)local_ip; + + sin = (struct sockaddr_in *)&child_ep->com.mapped_remote_addr; sin->sin_family = PF_INET; sin->sin_port = peer_port; sin->sin_addr.s_addr = *(__be32 *)peer_ip; } else { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) - &child_ep->com.local_addr; + &child_ep->com.mapped_local_addr; + sin6->sin6_family = PF_INET6; sin6->sin6_port = local_port; memcpy(sin6->sin6_addr.s6_addr, local_ip, 16); - sin6 = (struct sockaddr_in6 *)&child_ep->com.remote_addr; + + sin6 = (struct sockaddr_in6 *)&child_ep->com.local_addr; + sin6->sin6_family = PF_INET6; + sin6->sin6_port = ((struct sockaddr_in6 *) + &parent_ep->com.local_addr)->sin6_port; + memcpy(sin6->sin6_addr.s6_addr, local_ip, 16); + + sin6 = (struct sockaddr_in6 *)&child_ep->com.mapped_remote_addr; sin6->sin6_family = PF_INET6; sin6->sin6_port = peer_port; memcpy(sin6->sin6_addr.s6_addr, peer_ip, 16); } + memcpy(&child_ep->com.remote_addr, &child_ep->com.mapped_remote_addr, + sizeof(child_ep->com.remote_addr)); + get_remote_addr(parent_ep, child_ep); + c4iw_get_ep(&parent_ep->com); child_ep->parent_ep = parent_ep; child_ep->tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid)); @@ -2520,9 +2569,13 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) ep = lookup_tid(t, tid); if (is_neg_adv(req->status)) { - dev_warn(&dev->rdev.lldi.pdev->dev, - "Negative advice on abort - tid %u status %d (%s)\n", - ep->hwtid, req->status, neg_adv_str(req->status)); + PDBG("%s Negative advice on abort- tid %u status %d (%s)\n", + __func__, ep->hwtid, req->status, + neg_adv_str(req->status)); + ep->stats.abort_neg_adv++; + mutex_lock(&dev->rdev.stats.lock); + dev->rdev.stats.neg_adv++; + mutex_unlock(&dev->rdev.stats.lock); return 0; } PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, @@ -3571,7 +3624,7 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, * TP will ignore any value > 0 for MSS index. */ req->tcb.opt0 = cpu_to_be64(MSS_IDX_V(0xF)); - req->cookie = (unsigned long)skb; + req->cookie = (uintptr_t)skb; set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id); ret = cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb); @@ -3931,9 +3984,11 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) return 0; } if (is_neg_adv(req->status)) { - dev_warn(&dev->rdev.lldi.pdev->dev, - "Negative advice on abort - tid %u status %d (%s)\n", - ep->hwtid, req->status, neg_adv_str(req->status)); + PDBG("%s Negative advice on abort- tid %u status %d (%s)\n", + __func__, ep->hwtid, req->status, + neg_adv_str(req->status)); + ep->stats.abort_neg_adv++; + dev->rdev.stats.neg_adv++; kfree_skb(skb); return 0; } diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index ab7692ac2044..68ddb3710215 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -55,7 +55,7 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, FW_RI_RES_WR_NRES_V(1) | FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); - res_wr->cookie = (unsigned long) &wr_wait; + res_wr->cookie = (uintptr_t)&wr_wait; res = res_wr->res; res->u.cq.restype = FW_RI_RES_TYPE_CQ; res->u.cq.op = FW_RI_RES_OP_RESET; @@ -125,7 +125,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, FW_RI_RES_WR_NRES_V(1) | FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); - res_wr->cookie = (unsigned long) &wr_wait; + res_wr->cookie = (uintptr_t)&wr_wait; res = res_wr->res; res->u.cq.restype = FW_RI_RES_TYPE_CQ; res->u.cq.op = FW_RI_RES_OP_WRITE; @@ -156,12 +156,19 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, goto err4; cq->gen = 1; - cq->gts = rdev->lldi.gts_reg; cq->rdev = rdev; if (user) { - cq->ugts = (u64)pci_resource_start(rdev->lldi.pdev, 2) + - (cq->cqid << rdev->cqshift); - cq->ugts &= PAGE_MASK; + u32 off = (cq->cqid << rdev->cqshift) & PAGE_MASK; + + cq->ugts = (u64)rdev->bar2_pa + off; + } else if (is_t4(rdev->lldi.adapter_type)) { + cq->gts = rdev->lldi.gts_reg; + cq->qid_mask = -1U; + } else { + u32 off = ((cq->cqid << rdev->cqshift) & PAGE_MASK) + 12; + + cq->gts = rdev->bar2_kva + off; + cq->qid_mask = rdev->qpmask; } return 0; err4: @@ -970,8 +977,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, } PDBG("%s cqid 0x%0x chp %p size %u memsize %zu, dma_addr 0x%0llx\n", __func__, chp->cq.cqid, chp, chp->cq.size, - chp->cq.memsize, - (unsigned long long) chp->cq.dma_addr); + chp->cq.memsize, (unsigned long long) chp->cq.dma_addr); return &chp->ibcq; err5: kfree(mm2); diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 8fb295e4a9ab..7e895d714b19 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -93,6 +93,7 @@ static struct ibnl_client_cbs c4iw_nl_cb_table[] = { [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, + [RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb}, [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} }; @@ -151,7 +152,7 @@ static int wr_log_show(struct seq_file *seq, void *v) int prev_ts_set = 0; int idx, end; -#define ts2ns(ts) div64_ul((ts) * dev->rdev.lldi.cclk_ps, 1000) +#define ts2ns(ts) div64_u64((ts) * dev->rdev.lldi.cclk_ps, 1000) idx = atomic_read(&dev->rdev.wr_log_idx) & (dev->rdev.wr_log_size - 1); @@ -489,6 +490,7 @@ static int stats_show(struct seq_file *seq, void *v) dev->rdev.stats.act_ofld_conn_fails); seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n", dev->rdev.stats.pas_ofld_conn_fails); + seq_printf(seq, "NEG_ADV_RCVD: %10llu\n", dev->rdev.stats.neg_adv); seq_printf(seq, "AVAILABLE IRD: %10u\n", dev->avail_ird); return 0; } @@ -560,10 +562,13 @@ static int dump_ep(int id, void *p, void *data) cc = snprintf(epd->buf + epd->pos, space, "ep %p cm_id %p qp %p state %d flags 0x%lx " "history 0x%lx hwtid %d atid %d " + "conn_na %u abort_na %u " "%pI4:%d/%d <-> %pI4:%d/%d\n", ep, ep->com.cm_id, ep->com.qp, (int)ep->com.state, ep->com.flags, ep->com.history, ep->hwtid, ep->atid, + ep->stats.connect_neg_adv, + ep->stats.abort_neg_adv, &lsin->sin_addr, ntohs(lsin->sin_port), ntohs(mapped_lsin->sin_port), &rsin->sin_addr, ntohs(rsin->sin_port), @@ -581,10 +586,13 @@ static int dump_ep(int id, void *p, void *data) cc = snprintf(epd->buf + epd->pos, space, "ep %p cm_id %p qp %p state %d flags 0x%lx " "history 0x%lx hwtid %d atid %d " + "conn_na %u abort_na %u " "%pI6:%d/%d <-> %pI6:%d/%d\n", ep, ep->com.cm_id, ep->com.qp, (int)ep->com.state, ep->com.flags, ep->com.history, ep->hwtid, ep->atid, + ep->stats.connect_neg_adv, + ep->stats.abort_neg_adv, &lsin6->sin6_addr, ntohs(lsin6->sin6_port), ntohs(mapped_lsin6->sin6_port), &rsin6->sin6_addr, ntohs(rsin6->sin6_port), @@ -765,6 +773,29 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) c4iw_init_dev_ucontext(rdev, &rdev->uctx); /* + * This implementation assumes udb_density == ucq_density! Eventually + * we might need to support this but for now fail the open. Also the + * cqid and qpid range must match for now. + */ + if (rdev->lldi.udb_density != rdev->lldi.ucq_density) { + pr_err(MOD "%s: unsupported udb/ucq densities %u/%u\n", + pci_name(rdev->lldi.pdev), rdev->lldi.udb_density, + rdev->lldi.ucq_density); + err = -EINVAL; + goto err1; + } + if (rdev->lldi.vr->qp.start != rdev->lldi.vr->cq.start || + rdev->lldi.vr->qp.size != rdev->lldi.vr->cq.size) { + pr_err(MOD "%s: unsupported qp and cq id ranges " + "qp start %u size %u cq start %u size %u\n", + pci_name(rdev->lldi.pdev), rdev->lldi.vr->qp.start, + rdev->lldi.vr->qp.size, rdev->lldi.vr->cq.size, + rdev->lldi.vr->cq.size); + err = -EINVAL; + goto err1; + } + + /* * qpshift is the number of bits to shift the qpid left in order * to get the correct address of the doorbell for that qp. */ @@ -784,10 +815,10 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) rdev->lldi.vr->qp.size, rdev->lldi.vr->cq.start, rdev->lldi.vr->cq.size); - PDBG("udb len 0x%x udb base %llx db_reg %p gts_reg %p qpshift %lu " + PDBG("udb len 0x%x udb base %p db_reg %p gts_reg %p qpshift %lu " "qpmask 0x%x cqshift %lu cqmask 0x%x\n", (unsigned)pci_resource_len(rdev->lldi.pdev, 2), - (u64)pci_resource_start(rdev->lldi.pdev, 2), + (void *)pci_resource_start(rdev->lldi.pdev, 2), rdev->lldi.db_reg, rdev->lldi.gts_reg, rdev->qpshift, rdev->qpmask, @@ -1355,7 +1386,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) t4_sq_host_wq_pidx(&qp->wq), t4_sq_wq_size(&qp->wq)); if (ret) { - pr_err(KERN_ERR MOD "%s: Fatal error - " + pr_err(MOD "%s: Fatal error - " "DB overflow recovery failed - " "error syncing SQ qid %u\n", pci_name(ctx->lldi.pdev), qp->wq.sq.qid); @@ -1371,7 +1402,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) t4_rq_wq_size(&qp->wq)); if (ret) { - pr_err(KERN_ERR MOD "%s: Fatal error - " + pr_err(MOD "%s: Fatal error - " "DB overflow recovery failed - " "error syncing RQ qid %u\n", pci_name(ctx->lldi.pdev), qp->wq.rq.qid); diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index d87e1650f643..97bb5550a6cf 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -137,6 +137,7 @@ struct c4iw_stats { u64 tcam_full; u64 act_ofld_conn_fails; u64 pas_ofld_conn_fails; + u64 neg_adv; }; struct c4iw_hw_queue { @@ -814,6 +815,11 @@ struct c4iw_listen_ep { int backlog; }; +struct c4iw_ep_stats { + unsigned connect_neg_adv; + unsigned abort_neg_adv; +}; + struct c4iw_ep { struct c4iw_ep_common com; struct c4iw_ep *parent_ep; @@ -846,6 +852,7 @@ struct c4iw_ep { unsigned int retry_count; int snd_win; int rcv_win; + struct c4iw_ep_stats stats; }; static inline void print_addr(struct c4iw_ep_common *epc, const char *func, diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 3ef0cf9f5c44..cff815b91707 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -144,7 +144,7 @@ static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, if (i == (num_wqe-1)) { req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | FW_WR_COMPL_F); - req->wr.wr_lo = (__force __be64)(unsigned long) &wr_wait; + req->wr.wr_lo = (__force __be64)&wr_wait; } else req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR)); req->wr.wr_mid = cpu_to_be32( @@ -676,12 +676,12 @@ struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc) mhp->attr.zbva = 0; mhp->attr.va_fbo = 0; mhp->attr.page_size = 0; - mhp->attr.len = ~0UL; + mhp->attr.len = ~0ULL; mhp->attr.pbl_size = 0; ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, php->pdid, FW_RI_STAG_NSMR, mhp->attr.perms, - mhp->attr.mw_bind_enable, 0, 0, ~0UL, 0, 0, 0); + mhp->attr.mw_bind_enable, 0, 0, ~0ULL, 0, 0, 0); if (ret) goto err1; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 15cae5a31018..389ced335bc5 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -275,7 +275,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, FW_RI_RES_WR_NRES_V(2) | FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); - res_wr->cookie = (unsigned long) &wr_wait; + res_wr->cookie = (uintptr_t)&wr_wait; res = res_wr->res; res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; res->u.sqrq.op = FW_RI_RES_OP_WRITE; @@ -1209,7 +1209,7 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, wqe->flowid_len16 = cpu_to_be32( FW_WR_FLOWID_V(ep->hwtid) | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); - wqe->cookie = (unsigned long) &ep->com.wr_wait; + wqe->cookie = (uintptr_t)&ep->com.wr_wait; wqe->u.fini.type = FW_RI_TYPE_FINI; ret = c4iw_ofld_send(&rhp->rdev, skb); @@ -1279,7 +1279,7 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) FW_WR_FLOWID_V(qhp->ep->hwtid) | FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); - wqe->cookie = (unsigned long) &qhp->ep->com.wr_wait; + wqe->cookie = (uintptr_t)&qhp->ep->com.wr_wait; wqe->u.init.type = FW_RI_TYPE_INIT; wqe->u.init.mpareqbit_p2ptype = @@ -1766,11 +1766,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize); insert_mmap(ucontext, mm2); mm3->key = uresp.sq_db_gts_key; - mm3->addr = (__force unsigned long) qhp->wq.sq.udb; + mm3->addr = (__force unsigned long)qhp->wq.sq.udb; mm3->len = PAGE_SIZE; insert_mmap(ucontext, mm3); mm4->key = uresp.rq_db_gts_key; - mm4->addr = (__force unsigned long) qhp->wq.rq.udb; + mm4->addr = (__force unsigned long)qhp->wq.rq.udb; mm4->len = PAGE_SIZE; insert_mmap(ucontext, mm4); if (mm5) { diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 871cdcac7be2..7f2a6c244d25 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -539,6 +539,7 @@ struct t4_cq { size_t memsize; __be64 bits_type_ts; u32 cqid; + u32 qid_mask; int vector; u16 size; /* including status page */ u16 cidx; @@ -563,12 +564,12 @@ static inline int t4_arm_cq(struct t4_cq *cq, int se) set_bit(CQ_ARMED, &cq->flags); while (cq->cidx_inc > CIDXINC_M) { val = SEINTARM_V(0) | CIDXINC_V(CIDXINC_M) | TIMERREG_V(7) | - INGRESSQID_V(cq->cqid); + INGRESSQID_V(cq->cqid & cq->qid_mask); writel(val, cq->gts); cq->cidx_inc -= CIDXINC_M; } val = SEINTARM_V(se) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(6) | - INGRESSQID_V(cq->cqid); + INGRESSQID_V(cq->cqid & cq->qid_mask); writel(val, cq->gts); cq->cidx_inc = 0; return 0; @@ -601,7 +602,7 @@ static inline void t4_hwcq_consume(struct t4_cq *cq) u32 val; val = SEINTARM_V(0) | CIDXINC_V(cq->cidx_inc) | TIMERREG_V(7) | - INGRESSQID_V(cq->cqid); + INGRESSQID_V(cq->cqid & cq->qid_mask); writel(val, cq->gts); cq->cidx_inc = 0; } diff --git a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h index 5e53327fc647..343e8daf2270 100644 --- a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h +++ b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h @@ -848,6 +848,8 @@ enum { /* TCP congestion control algorithms */ #define CONG_CNTRL_V(x) ((x) << CONG_CNTRL_S) #define CONG_CNTRL_G(x) (((x) >> CONG_CNTRL_S) & CONG_CNTRL_M) -#define CONG_CNTRL_VALID (1 << 18) +#define T5_ISS_S 18 +#define T5_ISS_V(x) ((x) << T5_ISS_S) +#define T5_ISS_F T5_ISS_V(1U) #endif /* _T4FW_RI_API_H_ */ diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c index 120aedf9f989..cec181532924 100644 --- a/drivers/infiniband/hw/ehca/ehca_mcast.c +++ b/drivers/infiniband/hw/ehca/ehca_mcast.c @@ -77,7 +77,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return -EINVAL; } - memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); + memcpy(&my_gid, gid->raw, sizeof(union ib_gid)); subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); interface_id = be64_to_cpu(my_gid.global.interface_id); @@ -114,7 +114,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return -EINVAL; } - memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid)); + memcpy(&my_gid, gid->raw, sizeof(union ib_gid)); subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix); interface_id = be64_to_cpu(my_gid.global.interface_id); diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 57070c529dfb..cc64400d41ac 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1569,8 +1569,7 @@ static void reset_gids_task(struct work_struct *work) MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); if (err) - pr_warn(KERN_WARNING - "set port %d command failed\n", gw->port); + pr_warn("set port %d command failed\n", gw->port); } mlx4_free_cmd_mailbox(dev, mailbox); diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 4d7024b899cb..d35f62d4f4c5 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -1392,7 +1392,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah, if (ah->ah_flags & IB_AH_GRH) { if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) { - pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n", + pr_err("sgid_index (%u) too large. max is %d\n", ah->grh.sgid_index, gen->port[port - 1].gid_table_len); return -EINVAL; } diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 3b2a6dc8ea99..9f9d5c563a61 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -116,6 +116,7 @@ static struct ibnl_client_cbs nes_nl_cb_table[] = { [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, + [RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb}, [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 6f09a72e78d7..72b43417cbe3 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -596,27 +596,52 @@ static void nes_form_reg_msg(struct nes_vnic *nesvnic, memcpy(pm_msg->if_name, nesvnic->netdev->name, IWPM_IFNAME_SIZE); } +static void record_sockaddr_info(struct sockaddr_storage *addr_info, + nes_addr_t *ip_addr, u16 *port_num) +{ + struct sockaddr_in *in_addr = (struct sockaddr_in *)addr_info; + + if (in_addr->sin_family == AF_INET) { + *ip_addr = ntohl(in_addr->sin_addr.s_addr); + *port_num = ntohs(in_addr->sin_port); + } +} + /* * nes_record_pm_msg - Save the received mapping info */ static void nes_record_pm_msg(struct nes_cm_info *cm_info, struct iwpm_sa_data *pm_msg) { - struct sockaddr_in *mapped_loc_addr = - (struct sockaddr_in *)&pm_msg->mapped_loc_addr; - struct sockaddr_in *mapped_rem_addr = - (struct sockaddr_in *)&pm_msg->mapped_rem_addr; - - if (mapped_loc_addr->sin_family == AF_INET) { - cm_info->mapped_loc_addr = - ntohl(mapped_loc_addr->sin_addr.s_addr); - cm_info->mapped_loc_port = ntohs(mapped_loc_addr->sin_port); - } - if (mapped_rem_addr->sin_family == AF_INET) { - cm_info->mapped_rem_addr = - ntohl(mapped_rem_addr->sin_addr.s_addr); - cm_info->mapped_rem_port = ntohs(mapped_rem_addr->sin_port); - } + record_sockaddr_info(&pm_msg->mapped_loc_addr, + &cm_info->mapped_loc_addr, &cm_info->mapped_loc_port); + + record_sockaddr_info(&pm_msg->mapped_rem_addr, + &cm_info->mapped_rem_addr, &cm_info->mapped_rem_port); +} + +/* + * nes_get_reminfo - Get the address info of the remote connecting peer + */ +static int nes_get_remote_addr(struct nes_cm_node *cm_node) +{ + struct sockaddr_storage mapped_loc_addr, mapped_rem_addr; + struct sockaddr_storage remote_addr; + int ret; + + nes_create_sockaddr(htonl(cm_node->mapped_loc_addr), + htons(cm_node->mapped_loc_port), &mapped_loc_addr); + nes_create_sockaddr(htonl(cm_node->mapped_rem_addr), + htons(cm_node->mapped_rem_port), &mapped_rem_addr); + + ret = iwpm_get_remote_info(&mapped_loc_addr, &mapped_rem_addr, + &remote_addr, RDMA_NL_NES); + if (ret) + nes_debug(NES_DBG_CM, "Unable to find remote peer address info\n"); + else + record_sockaddr_info(&remote_addr, &cm_node->rem_addr, + &cm_node->rem_port); + return ret; } /** @@ -1566,9 +1591,14 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, return NULL; /* set our node specific transport info */ - cm_node->loc_addr = cm_info->loc_addr; + if (listener) { + cm_node->loc_addr = listener->loc_addr; + cm_node->loc_port = listener->loc_port; + } else { + cm_node->loc_addr = cm_info->loc_addr; + cm_node->loc_port = cm_info->loc_port; + } cm_node->rem_addr = cm_info->rem_addr; - cm_node->loc_port = cm_info->loc_port; cm_node->rem_port = cm_info->rem_port; cm_node->mapped_loc_addr = cm_info->mapped_loc_addr; @@ -2151,6 +2181,7 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, cm_node->state = NES_CM_STATE_ESTABLISHED; if (datasize) { cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; + nes_get_remote_addr(cm_node); handle_rcv_mpa(cm_node, skb); } else { /* rcvd ACK only */ dev_kfree_skb_any(skb); diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index c9780d919769..b396344fae16 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -40,7 +40,7 @@ #include <be_roce.h> #include "ocrdma_sli.h" -#define OCRDMA_ROCE_DRV_VERSION "10.4.205.0u" +#define OCRDMA_ROCE_DRV_VERSION "10.6.0.0" #define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver" #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA" @@ -515,6 +515,8 @@ static inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev, memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6)); if (rdma_is_multicast_addr(&in6)) rdma_get_mcast_mac(&in6, mac_addr); + else if (rdma_link_local_addr(&in6)) + rdma_get_ll_mac(&in6, mac_addr); else memcpy(mac_addr, ah_attr->dmac, ETH_ALEN); return 0; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c index d812904f3984..f5a5ea836dbd 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c @@ -56,7 +56,13 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, vlan_tag = attr->vlan_id; if (!vlan_tag || (vlan_tag > 0xFFF)) vlan_tag = dev->pvid; - if (vlan_tag && (vlan_tag < 0x1000)) { + if (vlan_tag || dev->pfc_state) { + if (!vlan_tag) { + pr_err("ocrdma%d:Using VLAN with PFC is recommended\n", + dev->id); + pr_err("ocrdma%d:Using VLAN 0 for this connection\n", + dev->id); + } eth.eth_type = cpu_to_be16(0x8100); eth.roce_eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; @@ -121,7 +127,9 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) goto av_conf_err; } - if (pd->uctx) { + if ((pd->uctx) && + (!rdma_is_multicast_addr((struct in6_addr *)attr->grh.dgid.raw)) && + (!rdma_link_local_addr((struct in6_addr *)attr->grh.dgid.raw))) { status = rdma_addr_find_dmac_by_grh(&sgid, &attr->grh.dgid, attr->dmac, &attr->vlan_id); if (status) { diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 0c9e95909a64..47615ff33bc6 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -933,12 +933,18 @@ static irqreturn_t ocrdma_irq_handler(int irq, void *handle) struct ocrdma_eqe eqe; struct ocrdma_eqe *ptr; u16 cq_id; + u8 mcode; int budget = eq->cq_cnt; do { ptr = ocrdma_get_eqe(eq); eqe = *ptr; ocrdma_le32_to_cpu(&eqe, sizeof(eqe)); + mcode = (eqe.id_valid & OCRDMA_EQE_MAJOR_CODE_MASK) + >> OCRDMA_EQE_MAJOR_CODE_SHIFT; + if (mcode == OCRDMA_MAJOR_CODE_SENTINAL) + pr_err("EQ full on eqid = 0x%x, eqe = 0x%x\n", + eq->q.id, eqe.id_valid); if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0) break; @@ -1434,27 +1440,30 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev) struct ocrdma_alloc_pd_range_rsp *rsp; /* Pre allocate the DPP PDs */ - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - cmd->pd_count = dev->attr.max_dpp_pds; - cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd; - - if ((rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) && rsp->pd_count) { - dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >> - OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT; - dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid & - OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK; - dev->pd_mgr->max_dpp_pd = rsp->pd_count; - pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long); - dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size, - GFP_KERNEL); + if (dev->attr.max_dpp_pds) { + cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, + sizeof(*cmd)); + if (!cmd) + return -ENOMEM; + cmd->pd_count = dev->attr.max_dpp_pds; + cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP; + status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); + rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd; + + if (!status && (rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) && + rsp->pd_count) { + dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >> + OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT; + dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid & + OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK; + dev->pd_mgr->max_dpp_pd = rsp->pd_count; + pd_bitmap_size = + BITS_TO_LONGS(rsp->pd_count) * sizeof(long); + dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size, + GFP_KERNEL); + } + kfree(cmd); } - kfree(cmd); cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd)); if (!cmd) @@ -1462,10 +1471,8 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev) cmd->pd_count = dev->attr.max_pd - dev->attr.max_dpp_pds; status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd; - if (rsp->pd_count) { + if (!status && rsp->pd_count) { dev->pd_mgr->pd_norm_start = rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK; dev->pd_mgr->max_normal_pd = rsp->pd_count; @@ -1473,15 +1480,13 @@ static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev) dev->pd_mgr->pd_norm_bitmap = kzalloc(pd_bitmap_size, GFP_KERNEL); } + kfree(cmd); if (dev->pd_mgr->pd_norm_bitmap || dev->pd_mgr->pd_dpp_bitmap) { /* Enable PD resource manager */ dev->pd_mgr->pd_prealloc_valid = true; - } else { - return -ENOMEM; + return 0; } -mbx_err: - kfree(cmd); return status; } @@ -2406,7 +2411,7 @@ int ocrdma_mbx_query_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp, struct ocrdma_query_qp *cmd; struct ocrdma_query_qp_rsp *rsp; - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*cmd)); + cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*rsp)); if (!cmd) return status; cmd->qp_id = qp->id; @@ -2428,7 +2433,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp, int status; struct ib_ah_attr *ah_attr = &attrs->ah_attr; union ib_gid sgid, zgid; - u32 vlan_id; + u32 vlan_id = 0xFFFF; u8 mac_addr[6]; struct ocrdma_dev *dev = get_ocrdma_dev(qp->ibqp.device); @@ -2468,12 +2473,22 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp, cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8); if (attr_mask & IB_QP_VID) { vlan_id = attrs->vlan_id; + } else if (dev->pfc_state) { + vlan_id = 0; + pr_err("ocrdma%d:Using VLAN with PFC is recommended\n", + dev->id); + pr_err("ocrdma%d:Using VLAN 0 for this connection\n", + dev->id); + } + + if (vlan_id < 0x1000) { cmd->params.vlan_dmac_b4_to_b5 |= vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT; cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID; cmd->params.rnt_rc_sl_fl |= (dev->sl & 0x07) << OCRDMA_QP_PARAMS_SL_SHIFT; } + return 0; } @@ -2519,8 +2534,10 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp, cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID; } if (attr_mask & IB_QP_PATH_MTU) { - if (attrs->path_mtu < IB_MTU_256 || + if (attrs->path_mtu < IB_MTU_512 || attrs->path_mtu > IB_MTU_4096) { + pr_err("ocrdma%d: IB MTU %d is not supported\n", + dev->id, ib_mtu_enum_to_int(attrs->path_mtu)); status = -EINVAL; goto pmtu_err; } @@ -3147,9 +3164,9 @@ void ocrdma_cleanup_hw(struct ocrdma_dev *dev) ocrdma_free_pd_pool(dev); ocrdma_mbx_delete_ah_tbl(dev); - /* cleanup the eqs */ - ocrdma_destroy_eqs(dev); - /* cleanup the control path */ ocrdma_destroy_mq(dev); + + /* cleanup the eqs */ + ocrdma_destroy_eqs(dev); } diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 243c87c8bd65..02ad0aee99af 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -1176,6 +1176,8 @@ struct ocrdma_query_qp_rsp { struct ocrdma_mqe_hdr hdr; struct ocrdma_mbx_rsp rsp; struct ocrdma_qp_params params; + u32 dpp_credits_cqid; + u32 rbq_id; }; enum { @@ -1624,12 +1626,19 @@ struct ocrdma_delete_ah_tbl_rsp { enum { OCRDMA_EQE_VALID_SHIFT = 0, OCRDMA_EQE_VALID_MASK = BIT(0), + OCRDMA_EQE_MAJOR_CODE_MASK = 0x0E, + OCRDMA_EQE_MAJOR_CODE_SHIFT = 0x01, OCRDMA_EQE_FOR_CQE_MASK = 0xFFFE, OCRDMA_EQE_RESOURCE_ID_SHIFT = 16, OCRDMA_EQE_RESOURCE_ID_MASK = 0xFFFF << OCRDMA_EQE_RESOURCE_ID_SHIFT, }; +enum major_code { + OCRDMA_MAJOR_CODE_COMPLETION = 0x00, + OCRDMA_MAJOR_CODE_SENTINAL = 0x01 +}; + struct ocrdma_eqe { u32 id_valid; }; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 877175563634..9dcb66077d6c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -365,7 +365,7 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev, if (!pd) return ERR_PTR(-ENOMEM); - if (udata && uctx) { + if (udata && uctx && dev->attr.max_dpp_pds) { pd->dpp_enabled = ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R; pd->num_dpp_qp = @@ -1721,18 +1721,20 @@ int ocrdma_destroy_qp(struct ib_qp *ibqp) struct ocrdma_qp *qp; struct ocrdma_dev *dev; struct ib_qp_attr attrs; - int attr_mask = IB_QP_STATE; + int attr_mask; unsigned long flags; qp = get_ocrdma_qp(ibqp); dev = get_ocrdma_dev(ibqp->device); - attrs.qp_state = IB_QPS_ERR; pd = qp->pd; /* change the QP state to ERROR */ - _ocrdma_modify_qp(ibqp, &attrs, attr_mask); - + if (qp->state != OCRDMA_QPS_RST) { + attrs.qp_state = IB_QPS_ERR; + attr_mask = IB_QP_STATE; + _ocrdma_modify_qp(ibqp, &attrs, attr_mask); + } /* ensure that CQEs for newly created QP (whose id may be same with * one which just getting destroyed are same), dont get * discarded until the old CQEs are discarded. diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index ffd48bfc4923..7df16f74bb45 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h @@ -903,7 +903,7 @@ struct qib_devdata { /* PCI Device ID (here for NodeInfo) */ u16 deviceid; /* for write combining settings */ - unsigned long wc_cookie; + int wc_cookie; unsigned long wc_base; unsigned long wc_len; @@ -1136,7 +1136,6 @@ extern struct qib_devdata *qib_lookup(int unit); extern u32 qib_cpulist_count; extern unsigned long *qib_cpulist; -extern unsigned qib_wc_pat; extern unsigned qib_cc_table_size; int qib_init(struct qib_devdata *, int); int init_chip_wc_pat(struct qib_devdata *dd, u32); diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 9ea6c440a00c..725881890c4a 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -835,7 +835,8 @@ static int mmap_piobufs(struct vm_area_struct *vma, vma->vm_flags &= ~VM_MAYREAD; vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; - if (qib_wc_pat) + /* We used PAT if wc_cookie == 0 */ + if (!dd->wc_cookie) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 0d2ba59af30a..4b927809d1a1 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -3315,11 +3315,9 @@ static int init_6120_variables(struct qib_devdata *dd) qib_6120_config_ctxts(dd); qib_set_ctxtcnt(dd); - if (qib_wc_pat) { - ret = init_chip_wc_pat(dd, 0); - if (ret) - goto bail; - } + ret = init_chip_wc_pat(dd, 0); + if (ret) + goto bail; set_6120_baseaddrs(dd); /* set chip access pointers now */ ret = 0; diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 22affda8af88..00b2af211157 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -4126,11 +4126,9 @@ static int qib_init_7220_variables(struct qib_devdata *dd) qib_7220_config_ctxts(dd); qib_set_ctxtcnt(dd); /* needed for PAT setup */ - if (qib_wc_pat) { - ret = init_chip_wc_pat(dd, 0); - if (ret) - goto bail; - } + ret = init_chip_wc_pat(dd, 0); + if (ret) + goto bail; set_7220_baseaddrs(dd); /* set chip access pointers now */ ret = 0; diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index ef97b71c8f7d..f32b4628e991 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -6429,6 +6429,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd) unsigned features, pidx, sbufcnt; int ret, mtu; u32 sbufs, updthresh; + resource_size_t vl15off; /* pport structs are contiguous, allocated after devdata */ ppd = (struct qib_pportdata *)(dd + 1); @@ -6677,29 +6678,27 @@ static int qib_init_7322_variables(struct qib_devdata *dd) qib_7322_config_ctxts(dd); qib_set_ctxtcnt(dd); - if (qib_wc_pat) { - resource_size_t vl15off; - /* - * We do not set WC on the VL15 buffers to avoid - * a rare problem with unaligned writes from - * interrupt-flushed store buffers, so we need - * to map those separately here. We can't solve - * this for the rarely used mtrr case. - */ - ret = init_chip_wc_pat(dd, 0); - if (ret) - goto bail; + /* + * We do not set WC on the VL15 buffers to avoid + * a rare problem with unaligned writes from + * interrupt-flushed store buffers, so we need + * to map those separately here. We can't solve + * this for the rarely used mtrr case. + */ + ret = init_chip_wc_pat(dd, 0); + if (ret) + goto bail; - /* vl15 buffers start just after the 4k buffers */ - vl15off = dd->physaddr + (dd->piobufbase >> 32) + - dd->piobcnt4k * dd->align4k; - dd->piovl15base = ioremap_nocache(vl15off, - NUM_VL15_BUFS * dd->align4k); - if (!dd->piovl15base) { - ret = -ENOMEM; - goto bail; - } + /* vl15 buffers start just after the 4k buffers */ + vl15off = dd->physaddr + (dd->piobufbase >> 32) + + dd->piobcnt4k * dd->align4k; + dd->piovl15base = ioremap_nocache(vl15off, + NUM_VL15_BUFS * dd->align4k); + if (!dd->piovl15base) { + ret = -ENOMEM; + goto bail; } + qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ ret = 0; diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 2ee36953e234..7e00470adc30 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -91,15 +91,6 @@ MODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port"); unsigned qib_cc_table_size; module_param_named(cc_table_size, qib_cc_table_size, uint, S_IRUGO); MODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disabled - default), min = 128, max = 1984"); -/* - * qib_wc_pat parameter: - * 0 is WC via MTRR - * 1 is WC via PAT - * If PAT initialization fails, code reverts back to MTRR - */ -unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */ -module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO); -MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism"); static void verify_interrupt(unsigned long); @@ -1377,8 +1368,7 @@ static void cleanup_device_data(struct qib_devdata *dd) spin_unlock(&dd->pport[pidx].cc_shadow_lock); } - if (!qib_wc_pat) - qib_disable_wc(dd); + qib_disable_wc(dd); if (dd->pioavailregs_dma) { dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, @@ -1547,14 +1537,12 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto bail; } - if (!qib_wc_pat) { - ret = qib_enable_wc(dd); - if (ret) { - qib_dev_err(dd, - "Write combining not enabled (err %d): performance may be poor\n", - -ret); - ret = 0; - } + ret = qib_enable_wc(dd); + if (ret) { + qib_dev_err(dd, + "Write combining not enabled (err %d): performance may be poor\n", + -ret); + ret = 0; } qib_verify_pioperf(dd); diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c b/drivers/infiniband/hw/qib/qib_wc_x86_64.c index 81b225f2300a..edd0ddbd4481 100644 --- a/drivers/infiniband/hw/qib/qib_wc_x86_64.c +++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c @@ -116,21 +116,10 @@ int qib_enable_wc(struct qib_devdata *dd) } if (!ret) { - int cookie; - - cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); - if (cookie < 0) { - { - qib_devinfo(dd->pcidev, - "mtrr_add() WC for PIO bufs failed (%d)\n", - cookie); - ret = -EINVAL; - } - } else { - dd->wc_cookie = cookie; - dd->wc_base = (unsigned long) pioaddr; - dd->wc_len = (unsigned long) piolen; - } + dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen); + if (dd->wc_cookie < 0) + /* use error from routine */ + ret = dd->wc_cookie; } return ret; @@ -142,18 +131,7 @@ int qib_enable_wc(struct qib_devdata *dd) */ void qib_disable_wc(struct qib_devdata *dd) { - if (dd->wc_cookie) { - int r; - - r = mtrr_del(dd->wc_cookie, dd->wc_base, - dd->wc_len); - if (r < 0) - qib_devinfo(dd->pcidev, - "mtrr_del(%lx, %lx, %lx) failed: %d\n", - dd->wc_cookie, dd->wc_base, - dd->wc_len, r); - dd->wc_cookie = 0; /* even on failure */ - } + arch_phys_wc_del(dd->wc_cookie); } /** diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 56959adb6c7d..cf32a778e7d0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -386,8 +386,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i rx->rx_ring[i].mapping, GFP_KERNEL)) { ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); - ret = -ENOMEM; - goto err_count; + ret = -ENOMEM; + goto err_count; } ret = ipoib_cm_post_receive_nonsrq(dev, rx, &t->wr, t->sge, i); if (ret) { diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 327529ee85eb..3f40319a55da 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -547,11 +547,11 @@ isert_create_pi_ctx(struct fast_reg_descriptor *desc, return 0; err_prot_mr: - ib_dereg_mr(desc->pi_ctx->prot_mr); + ib_dereg_mr(pi_ctx->prot_mr); err_prot_frpl: - ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl); + ib_free_fast_reg_page_list(pi_ctx->prot_frpl); err_pi_ctx: - kfree(desc->pi_ctx); + kfree(pi_ctx); return ret; } diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index f362883c94e3..1d247bcf2ae2 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -747,6 +747,63 @@ static void joydev_cleanup(struct joydev *joydev) input_close_device(handle); } +static bool joydev_dev_is_absolute_mouse(struct input_dev *dev) +{ + DECLARE_BITMAP(jd_scratch, KEY_CNT); + + BUILD_BUG_ON(ABS_CNT > KEY_CNT || EV_CNT > KEY_CNT); + + /* + * Virtualization (VMware, etc) and remote management (HP + * ILO2) solutions use absolute coordinates for their virtual + * pointing devices so that there is one-to-one relationship + * between pointer position on the host screen and virtual + * guest screen, and so their mice use ABS_X, ABS_Y and 3 + * primary button events. This clashes with what joydev + * considers to be joysticks (a device with at minimum ABS_X + * axis). + * + * Here we are trying to separate absolute mice from + * joysticks. A device is, for joystick detection purposes, + * considered to be an absolute mouse if the following is + * true: + * + * 1) Event types are exactly EV_ABS, EV_KEY and EV_SYN. + * 2) Absolute events are exactly ABS_X and ABS_Y. + * 3) Keys are exactly BTN_LEFT, BTN_RIGHT and BTN_MIDDLE. + * 4) Device is not on "Amiga" bus. + */ + + bitmap_zero(jd_scratch, EV_CNT); + __set_bit(EV_ABS, jd_scratch); + __set_bit(EV_KEY, jd_scratch); + __set_bit(EV_SYN, jd_scratch); + if (!bitmap_equal(jd_scratch, dev->evbit, EV_CNT)) + return false; + + bitmap_zero(jd_scratch, ABS_CNT); + __set_bit(ABS_X, jd_scratch); + __set_bit(ABS_Y, jd_scratch); + if (!bitmap_equal(dev->absbit, jd_scratch, ABS_CNT)) + return false; + + bitmap_zero(jd_scratch, KEY_CNT); + __set_bit(BTN_LEFT, jd_scratch); + __set_bit(BTN_RIGHT, jd_scratch); + __set_bit(BTN_MIDDLE, jd_scratch); + + if (!bitmap_equal(dev->keybit, jd_scratch, KEY_CNT)) + return false; + + /* + * Amiga joystick (amijoy) historically uses left/middle/right + * button events. + */ + if (dev->id.bustype == BUS_AMIGA) + return false; + + return true; +} static bool joydev_match(struct input_handler *handler, struct input_dev *dev) { @@ -758,6 +815,10 @@ static bool joydev_match(struct input_handler *handler, struct input_dev *dev) if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) return false; + /* Avoid absolute mice */ + if (joydev_dev_is_absolute_mouse(dev)) + return false; + return true; } diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 7462d2fc8cfe..d7820d1152d2 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -156,7 +156,7 @@ config MOUSE_PS2_VMMOUSE Say Y here if you are running under control of VMware hypervisor (ESXi, Workstation or Fusion). Also make sure that when you enable this option, you remove the xf86-input-vmmouse user-space driver - or upgrade it to at least xf86-input-vmmouse 13.0.1, which doesn't + or upgrade it to at least xf86-input-vmmouse 13.1.0, which doesn't load in the presence of an in-kernel vmmouse driver. If unsure, say N. diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e6708f6efb4d..a353b7de6d22 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -941,6 +941,11 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, case V7_PACKET_ID_TWO: mt[1].x &= ~0x000F; mt[1].y |= 0x000F; + /* Detect false-postive touches where x & y report max value */ + if (mt[1].y == 0x7ff && mt[1].x == 0xff0) { + mt[1].x = 0; + /* y gets set to 0 at the end of this function */ + } break; case V7_PACKET_ID_MULTI: @@ -1058,9 +1063,8 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) right = (packet[1] & 0x02) >> 1; middle = (packet[1] & 0x04) >> 2; - /* Divide 2 since trackpoint's speed is too fast */ - input_report_rel(dev2, REL_X, (char)x / 2); - input_report_rel(dev2, REL_Y, -((char)y / 2)); + input_report_rel(dev2, REL_X, (char)x); + input_report_rel(dev2, REL_Y, -((char)y)); input_report_key(dev2, BTN_LEFT, left); input_report_key(dev2, BTN_RIGHT, right); diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 991dc6b20a58..ce3d40004458 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -315,7 +315,7 @@ static void elantech_report_semi_mt_data(struct input_dev *dev, unsigned int x2, unsigned int y2) { elantech_set_slot(dev, 0, num_fingers != 0, x1, y1); - elantech_set_slot(dev, 1, num_fingers == 2, x2, y2); + elantech_set_slot(dev, 1, num_fingers >= 2, x2, y2); } /* @@ -1376,10 +1376,11 @@ static bool elantech_is_signature_valid(const unsigned char *param) return true; /* - * Some models have a revision higher then 20. Meaning param[2] may - * be 10 or 20, skip the rates check for these. + * Some hw_version >= 4 models have a revision higher then 20. Meaning + * that param[2] may be 10 or 20, skip the rates check for these. */ - if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) + if ((param[0] & 0x0f) >= 0x06 && (param[1] & 0xaf) == 0x0f && + param[2] < 40) return true; for (i = 0; i < ARRAY_SIZE(rates); i++) @@ -1555,6 +1556,7 @@ static int elantech_set_properties(struct elantech_data *etd) case 9: case 10: case 13: + case 14: etd->hw_version = 4; break; default: diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 2d5ff86b343f..e4c31256a74d 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c @@ -164,7 +164,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data) STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN); /* start polling for touch_det to detect release */ - schedule_delayed_work(&ts->work, HZ / 50); + schedule_delayed_work(&ts->work, msecs_to_jiffies(50)); return IRQ_HANDLED; } diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c index aecb9ad2e701..642f4a53de50 100644 --- a/drivers/input/touchscreen/sx8654.c +++ b/drivers/input/touchscreen/sx8654.c @@ -187,7 +187,7 @@ static int sx8654_probe(struct i2c_client *client, return -ENOMEM; input = devm_input_allocate_device(&client->dev); - if (!sx8654) + if (!input) return -ENOMEM; input->name = "SX8654 I2C Touchscreen"; diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index e43d48956dea..e1c7e9e51045 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2930,6 +2930,7 @@ static void *alloc_coherent(struct device *dev, size_t size, size = PAGE_ALIGN(size); dma_mask = dev->coherent_dma_mask; flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); + flag |= __GFP_ZERO; page = alloc_pages(flag | __GFP_NOWARN, get_order(size)); if (!page) { diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index a1cbba9056fd..3465faf1809e 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -266,6 +266,7 @@ static void put_pasid_state(struct pasid_state *pasid_state) static void put_pasid_state_wait(struct pasid_state *pasid_state) { + atomic_dec(&pasid_state->count); wait_event(pasid_state->wq, !atomic_read(&pasid_state->count)); free_pasid_state(pasid_state); } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9f7e1d34a32b..66a803b9dd3a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -224,14 +224,7 @@ #define RESUME_TERMINATE (1 << 0) #define TTBCR2_SEP_SHIFT 15 -#define TTBCR2_SEP_MASK 0x7 - -#define TTBCR2_ADDR_32 0 -#define TTBCR2_ADDR_36 1 -#define TTBCR2_ADDR_40 2 -#define TTBCR2_ADDR_42 3 -#define TTBCR2_ADDR_44 4 -#define TTBCR2_ADDR_48 5 +#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT) #define TTBRn_HI_ASID_SHIFT 16 @@ -793,26 +786,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); if (smmu->version > ARM_SMMU_V1) { reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32; - switch (smmu->va_size) { - case 32: - reg |= (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT); - break; - case 36: - reg |= (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT); - break; - case 40: - reg |= (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT); - break; - case 42: - reg |= (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT); - break; - case 44: - reg |= (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT); - break; - case 48: - reg |= (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT); - break; - } + reg |= TTBCR2_SEP_UPSTREAM; writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2); } } else { diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 4015560bf486..cab214544237 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1004,20 +1004,18 @@ static int rk_iommu_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static const struct of_device_id rk_iommu_dt_ids[] = { { .compatible = "rockchip,iommu" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids); -#endif static struct platform_driver rk_iommu_driver = { .probe = rk_iommu_probe, .remove = rk_iommu_remove, .driver = { .name = "rk_iommu", - .of_match_table = of_match_ptr(rk_iommu_dt_ids), + .of_match_table = rk_iommu_dt_ids, }, }; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 9687f8afebff..1b7e155869f6 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -828,7 +828,14 @@ static int its_alloc_tables(struct its_node *its) u64 typer = readq_relaxed(its->base + GITS_TYPER); u32 ids = GITS_TYPER_DEVBITS(typer); - order = get_order((1UL << ids) * entry_size); + /* + * 'order' was initialized earlier to the default page + * granule of the the ITS. We can't have an allocation + * smaller than that. If the requested allocation + * is smaller, round up to the default page granule. + */ + order = max(get_order((1UL << ids) * entry_size), + order); if (order >= MAX_ORDER) { order = MAX_ORDER - 1; pr_warn("%s: Device Table too large, reduce its page order to %u\n", diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 7b315e385ba3..01999d74bd3a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -82,19 +82,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); #define NR_GIC_CPU_IF 8 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; -/* - * Supported arch specific GIC irq extension. - * Default make them NULL. - */ -struct irq_chip gic_arch_extn = { - .irq_eoi = NULL, - .irq_mask = NULL, - .irq_unmask = NULL, - .irq_retrigger = NULL, - .irq_set_type = NULL, - .irq_set_wake = NULL, -}; - #ifndef MAX_GIC_NR #define MAX_GIC_NR 1 #endif @@ -167,34 +154,16 @@ static int gic_peek_irq(struct irq_data *d, u32 offset) static void gic_mask_irq(struct irq_data *d) { - unsigned long flags; - - raw_spin_lock_irqsave(&irq_controller_lock, flags); gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); - if (gic_arch_extn.irq_mask) - gic_arch_extn.irq_mask(d); - raw_spin_unlock_irqrestore(&irq_controller_lock, flags); } static void gic_unmask_irq(struct irq_data *d) { - unsigned long flags; - - raw_spin_lock_irqsave(&irq_controller_lock, flags); - if (gic_arch_extn.irq_unmask) - gic_arch_extn.irq_unmask(d); gic_poke_irq(d, GIC_DIST_ENABLE_SET); - raw_spin_unlock_irqrestore(&irq_controller_lock, flags); } static void gic_eoi_irq(struct irq_data *d) { - if (gic_arch_extn.irq_eoi) { - raw_spin_lock(&irq_controller_lock); - gic_arch_extn.irq_eoi(d); - raw_spin_unlock(&irq_controller_lock); - } - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); } @@ -251,8 +220,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type) { void __iomem *base = gic_dist_base(d); unsigned int gicirq = gic_irq(d); - unsigned long flags; - int ret; /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) @@ -263,25 +230,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - raw_spin_lock_irqsave(&irq_controller_lock, flags); - - if (gic_arch_extn.irq_set_type) - gic_arch_extn.irq_set_type(d, type); - - ret = gic_configure_irq(gicirq, type, base, NULL); - - raw_spin_unlock_irqrestore(&irq_controller_lock, flags); - - return ret; -} - -static int gic_retrigger(struct irq_data *d) -{ - if (gic_arch_extn.irq_retrigger) - return gic_arch_extn.irq_retrigger(d); - - /* the genirq layer expects 0 if we can't retrigger in hardware */ - return 0; + return gic_configure_irq(gicirq, type, base, NULL); } #ifdef CONFIG_SMP @@ -312,21 +261,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, } #endif -#ifdef CONFIG_PM -static int gic_set_wake(struct irq_data *d, unsigned int on) -{ - int ret = -ENXIO; - - if (gic_arch_extn.irq_set_wake) - ret = gic_arch_extn.irq_set_wake(d, on); - - return ret; -} - -#else -#define gic_set_wake NULL -#endif - static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) { u32 irqstat, irqnr; @@ -385,11 +319,9 @@ static struct irq_chip gic_chip = { .irq_unmask = gic_unmask_irq, .irq_eoi = gic_eoi_irq, .irq_set_type = gic_set_type, - .irq_retrigger = gic_retrigger, #ifdef CONFIG_SMP .irq_set_affinity = gic_set_affinity, #endif - .irq_set_wake = gic_set_wake, .irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state, }; @@ -1055,7 +987,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, set_handle_irq(gic_handle_irq); } - gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); gic_cpu_init(gic); gic_pm_init(gic); diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 51c485d9a877..f67bbd80433e 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -264,7 +264,7 @@ static int tegra_ictlr_domain_alloc(struct irq_domain *domain, irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, &tegra_ictlr_chip, - &info->base[ictlr]); + info->base[ictlr]); } parent_args = *args; diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 7dc93aa004c8..312ffd3d0017 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -173,7 +173,7 @@ static void unmap_switcher(void) bool lguest_address_ok(const struct lguest *lg, unsigned long addr, unsigned long len) { - return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); + return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr); } /* diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 2bc56e2a3526..135a0907e9de 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -177,11 +177,16 @@ static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mdde * nr_pending is 0 and In_sync is clear, the entries we return will * still be in the same position on the list when we re-enter * list_for_each_entry_continue_rcu. + * + * Note that if entered with 'rdev == NULL' to start at the + * beginning, we temporarily assign 'rdev' to an address which + * isn't really an rdev, but which can be used by + * list_for_each_entry_continue_rcu() to find the first entry. */ rcu_read_lock(); if (rdev == NULL) /* start at the beginning */ - rdev = list_entry_rcu(&mddev->disks, struct md_rdev, same_set); + rdev = list_entry(&mddev->disks, struct md_rdev, same_set); else { /* release the previous rdev and start from there. */ rdev_dec_pending(rdev, mddev); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 9eeea196328a..5503e43e5f28 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -925,10 +925,11 @@ static int crypt_convert(struct crypt_config *cc, switch (r) { /* async */ - case -EINPROGRESS: case -EBUSY: wait_for_completion(&ctx->restart); reinit_completion(&ctx->restart); + /* fall through*/ + case -EINPROGRESS: ctx->req = NULL; ctx->cc_sector++; continue; @@ -1345,8 +1346,10 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); struct crypt_config *cc = io->cc; - if (error == -EINPROGRESS) + if (error == -EINPROGRESS) { + complete(&ctx->restart); return; + } if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); @@ -1357,15 +1360,12 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, crypt_free_req(cc, req_of_dmreq(cc, dmreq), io->base_bio); if (!atomic_dec_and_test(&ctx->cc_pending)) - goto done; + return; if (bio_data_dir(io->base_bio) == READ) kcryptd_crypt_read_done(io); else kcryptd_crypt_write_io_submit(io, 1); -done: - if (!completion_done(&ctx->restart)) - complete(&ctx->restart); } static void kcryptd_crypt(struct work_struct *work) diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 63953477a07c..eff7bdd7731d 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -429,9 +429,11 @@ static int __multipath_map(struct dm_target *ti, struct request *clone, /* blk-mq request-based interface */ *__clone = blk_get_request(bdev_get_queue(bdev), rq_data_dir(rq), GFP_ATOMIC); - if (IS_ERR(*__clone)) + if (IS_ERR(*__clone)) { /* ENOMEM, requeue */ + clear_mapinfo(m, map_context); return r; + } (*__clone)->bio = (*__clone)->biotail = NULL; (*__clone)->rq_disk = bdev->bd_disk; (*__clone)->cmd_flags |= REQ_FAILFAST_TRANSPORT; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index d9b00b8565c6..16ba55ad7089 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -820,6 +820,12 @@ void dm_consume_args(struct dm_arg_set *as, unsigned num_args) } EXPORT_SYMBOL(dm_consume_args); +static bool __table_type_request_based(unsigned table_type) +{ + return (table_type == DM_TYPE_REQUEST_BASED || + table_type == DM_TYPE_MQ_REQUEST_BASED); +} + static int dm_table_set_type(struct dm_table *t) { unsigned i; @@ -852,8 +858,7 @@ static int dm_table_set_type(struct dm_table *t) * Determine the type from the live device. * Default to bio-based if device is new. */ - if (live_md_type == DM_TYPE_REQUEST_BASED || - live_md_type == DM_TYPE_MQ_REQUEST_BASED) + if (__table_type_request_based(live_md_type)) request_based = 1; else bio_based = 1; @@ -903,7 +908,7 @@ static int dm_table_set_type(struct dm_table *t) } t->type = DM_TYPE_MQ_REQUEST_BASED; - } else if (hybrid && list_empty(devices) && live_md_type != DM_TYPE_NONE) { + } else if (list_empty(devices) && __table_type_request_based(live_md_type)) { /* inherit live MD type */ t->type = live_md_type; @@ -925,10 +930,7 @@ struct target_type *dm_table_get_immutable_target_type(struct dm_table *t) bool dm_table_request_based(struct dm_table *t) { - unsigned table_type = dm_table_get_type(t); - - return (table_type == DM_TYPE_REQUEST_BASED || - table_type == DM_TYPE_MQ_REQUEST_BASED); + return __table_type_request_based(dm_table_get_type(t)); } bool dm_table_mq_request_based(struct dm_table *t) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index a930b72314ac..2caf492890d6 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1082,13 +1082,11 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue) dm_put(md); } -static void free_rq_clone(struct request *clone, bool must_be_mapped) +static void free_rq_clone(struct request *clone) { struct dm_rq_target_io *tio = clone->end_io_data; struct mapped_device *md = tio->md; - WARN_ON_ONCE(must_be_mapped && !clone->q); - blk_rq_unprep_clone(clone); if (md->type == DM_TYPE_MQ_REQUEST_BASED) @@ -1132,7 +1130,7 @@ static void dm_end_request(struct request *clone, int error) rq->sense_len = clone->sense_len; } - free_rq_clone(clone, true); + free_rq_clone(clone); if (!rq->q->mq_ops) blk_end_request_all(rq, error); else @@ -1151,7 +1149,7 @@ static void dm_unprep_request(struct request *rq) } if (clone) - free_rq_clone(clone, false); + free_rq_clone(clone); } /* @@ -1164,6 +1162,7 @@ static void old_requeue_request(struct request *rq) spin_lock_irqsave(q->queue_lock, flags); blk_requeue_request(q, rq); + blk_run_queue_async(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -1724,8 +1723,7 @@ static int dm_merge_bvec(struct request_queue *q, struct mapped_device *md = q->queuedata; struct dm_table *map = dm_get_live_table_fast(md); struct dm_target *ti; - sector_t max_sectors; - int max_size = 0; + sector_t max_sectors, max_size = 0; if (unlikely(!map)) goto out; @@ -1740,8 +1738,16 @@ static int dm_merge_bvec(struct request_queue *q, max_sectors = min(max_io_len(bvm->bi_sector, ti), (sector_t) queue_max_sectors(q)); max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; - if (unlikely(max_size < 0)) /* this shouldn't _ever_ happen */ - max_size = 0; + + /* + * FIXME: this stop-gap fix _must_ be cleaned up (by passing a sector_t + * to the targets' merge function since it holds sectors not bytes). + * Just doing this as an interim fix for stable@ because the more + * comprehensive cleanup of switching to sector_t will impact every + * DM target that implements a ->merge hook. + */ + if (max_size > INT_MAX) + max_size = INT_MAX; /* * merge_bvec_fn() returns number of bytes @@ -1749,7 +1755,7 @@ static int dm_merge_bvec(struct request_queue *q, * max is precomputed maximal io size */ if (max_size && ti->type->merge) - max_size = ti->type->merge(ti, bvm, biovec, max_size); + max_size = ti->type->merge(ti, bvm, biovec, (int) max_size); /* * If the target doesn't support merge method and some of the devices * provided their merge_bvec method (we know this by looking for the @@ -1971,8 +1977,8 @@ static int map_request(struct dm_rq_target_io *tio, struct request *rq, dm_kill_unmapped_request(rq, r); return r; } - if (IS_ERR(clone)) - return DM_MAPIO_REQUEUE; + if (r != DM_MAPIO_REMAPPED) + return r; if (setup_clone(clone, rq, tio, GFP_ATOMIC)) { /* -ENOMEM */ ti->type->release_clone_rq(clone); @@ -2753,13 +2759,15 @@ static int dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx, if (dm_table_get_type(map) == DM_TYPE_REQUEST_BASED) { /* clone request is allocated at the end of the pdu */ tio->clone = (void *)blk_mq_rq_to_pdu(rq) + sizeof(struct dm_rq_target_io); - if (!clone_rq(rq, md, tio, GFP_ATOMIC)) - return BLK_MQ_RQ_QUEUE_BUSY; + (void) clone_rq(rq, md, tio, GFP_ATOMIC); queue_kthread_work(&md->kworker, &tio->work); } else { /* Direct call is fine since .queue_rq allows allocations */ - if (map_request(tio, rq, md) == DM_MAPIO_REQUEUE) - dm_requeue_unmapped_original_request(md, rq); + if (map_request(tio, rq, md) == DM_MAPIO_REQUEUE) { + /* Undo dm_start_request() before requeuing */ + rq_completed(md, rq_data_dir(rq), false); + return BLK_MQ_RQ_QUEUE_BUSY; + } } return BLK_MQ_RQ_QUEUE_OK; diff --git a/drivers/md/md.c b/drivers/md/md.c index d4f31e195e26..27506302eb7a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4211,12 +4211,12 @@ action_store(struct mddev *mddev, const char *page, size_t len) if (!mddev->pers || !mddev->pers->sync_request) return -EINVAL; - if (cmd_match(page, "frozen")) - set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - else - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); if (cmd_match(page, "idle") || cmd_match(page, "frozen")) { + if (cmd_match(page, "frozen")) + set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + else + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); flush_workqueue(md_misc_wq); if (mddev->sync_thread) { set_bit(MD_RECOVERY_INTR, &mddev->recovery); @@ -4229,16 +4229,17 @@ action_store(struct mddev *mddev, const char *page, size_t len) test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) return -EBUSY; else if (cmd_match(page, "resync")) - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); else if (cmd_match(page, "recover")) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } else if (cmd_match(page, "reshape")) { int err; if (mddev->pers->start_reshape == NULL) return -EINVAL; err = mddev_lock(mddev); if (!err) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); err = mddev->pers->start_reshape(mddev); mddev_unlock(mddev); } @@ -4250,6 +4251,7 @@ action_store(struct mddev *mddev, const char *page, size_t len) set_bit(MD_RECOVERY_CHECK, &mddev->recovery); else if (!cmd_match(page, "repair")) return -EINVAL; + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); set_bit(MD_RECOVERY_SYNC, &mddev->recovery); } @@ -4818,12 +4820,12 @@ static void md_free(struct kobject *ko) if (mddev->sysfs_state) sysfs_put(mddev->sysfs_state); + if (mddev->queue) + blk_cleanup_queue(mddev->queue); if (mddev->gendisk) { del_gendisk(mddev->gendisk); put_disk(mddev->gendisk); } - if (mddev->queue) - blk_cleanup_queue(mddev->queue); kfree(mddev); } diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 2cb59a641cd2..efb654eb5399 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -188,8 +188,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } dev[j] = rdev1; - disk_stack_limits(mddev->gendisk, rdev1->bdev, - rdev1->data_offset << 9); + if (mddev->queue) + disk_stack_limits(mddev->gendisk, rdev1->bdev, + rdev1->data_offset << 9); if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) conf->has_merge_bvec = 1; @@ -523,6 +524,9 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio) ? (sector & (chunk_sects-1)) : sector_div(sector, chunk_sects)); + /* Restore due to sector_div */ + sector = bio->bi_iter.bi_sector; + if (sectors < bio_sectors(bio)) { split = bio_split(bio, sectors, GFP_NOIO, fs_bio_set); bio_chain(split, bio); @@ -530,7 +534,6 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio) split = bio; } - sector = bio->bi_iter.bi_sector; zone = find_zone(mddev->private, §or); tmp_dev = map_sector(mddev, zone, sector, §or); split->bi_bdev = tmp_dev->bdev; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 77dfd720aaa0..553d54b87052 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -749,6 +749,7 @@ static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) static bool stripe_can_batch(struct stripe_head *sh) { return test_bit(STRIPE_BATCH_READY, &sh->state) && + !test_bit(STRIPE_BITMAP_PENDING, &sh->state) && is_full_stripe_write(sh); } @@ -837,6 +838,15 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh < IO_THRESHOLD) md_wakeup_thread(conf->mddev->thread); + if (test_and_clear_bit(STRIPE_BIT_DELAY, &sh->state)) { + int seq = sh->bm_seq; + if (test_bit(STRIPE_BIT_DELAY, &sh->batch_head->state) && + sh->batch_head->bm_seq > seq) + seq = sh->batch_head->bm_seq; + set_bit(STRIPE_BIT_DELAY, &sh->batch_head->state); + sh->batch_head->bm_seq = seq; + } + atomic_inc(&sh->count); unlock_out: unlock_two_stripes(head, sh); @@ -1078,9 +1088,6 @@ again: pr_debug("skip op %ld on disc %d for sector %llu\n", bi->bi_rw, i, (unsigned long long)sh->sector); clear_bit(R5_LOCKED, &sh->dev[i].flags); - if (sh->batch_head) - set_bit(STRIPE_BATCH_ERR, - &sh->batch_head->state); set_bit(STRIPE_HANDLE, &sh->state); } @@ -1825,7 +1832,7 @@ again: } else init_async_submit(&submit, 0, tx, NULL, NULL, to_addr_conv(sh, percpu, j)); - async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE, &submit); + tx = async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE, &submit); if (!last_stripe) { j++; sh = list_first_entry(&sh->batch_list, struct stripe_head, @@ -1971,17 +1978,30 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) put_cpu(); } +static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp) +{ + struct stripe_head *sh; + + sh = kmem_cache_zalloc(sc, gfp); + if (sh) { + spin_lock_init(&sh->stripe_lock); + spin_lock_init(&sh->batch_lock); + INIT_LIST_HEAD(&sh->batch_list); + INIT_LIST_HEAD(&sh->lru); + atomic_set(&sh->count, 1); + } + return sh; +} static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) { struct stripe_head *sh; - sh = kmem_cache_zalloc(conf->slab_cache, gfp); + + sh = alloc_stripe(conf->slab_cache, gfp); if (!sh) return 0; sh->raid_conf = conf; - spin_lock_init(&sh->stripe_lock); - if (grow_buffers(sh, gfp)) { shrink_buffers(sh); kmem_cache_free(conf->slab_cache, sh); @@ -1990,13 +2010,8 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) sh->hash_lock_index = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; /* we just created an active stripe so... */ - atomic_set(&sh->count, 1); atomic_inc(&conf->active_stripes); - INIT_LIST_HEAD(&sh->lru); - spin_lock_init(&sh->batch_lock); - INIT_LIST_HEAD(&sh->batch_list); - sh->batch_head = NULL; release_stripe(sh); conf->max_nr_stripes++; return 1; @@ -2060,6 +2075,35 @@ static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags) return ret; } +static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors) +{ + unsigned long cpu; + int err = 0; + + mddev_suspend(conf->mddev); + get_online_cpus(); + for_each_present_cpu(cpu) { + struct raid5_percpu *percpu; + struct flex_array *scribble; + + percpu = per_cpu_ptr(conf->percpu, cpu); + scribble = scribble_alloc(new_disks, + new_sectors / STRIPE_SECTORS, + GFP_NOIO); + + if (scribble) { + flex_array_free(percpu->scribble); + percpu->scribble = scribble; + } else { + err = -ENOMEM; + break; + } + } + put_online_cpus(); + mddev_resume(conf->mddev); + return err; +} + static int resize_stripes(struct r5conf *conf, int newsize) { /* Make all the stripes able to hold 'newsize' devices. @@ -2088,7 +2132,6 @@ static int resize_stripes(struct r5conf *conf, int newsize) struct stripe_head *osh, *nsh; LIST_HEAD(newstripes); struct disk_info *ndisks; - unsigned long cpu; int err; struct kmem_cache *sc; int i; @@ -2109,13 +2152,11 @@ static int resize_stripes(struct r5conf *conf, int newsize) return -ENOMEM; for (i = conf->max_nr_stripes; i; i--) { - nsh = kmem_cache_zalloc(sc, GFP_KERNEL); + nsh = alloc_stripe(sc, GFP_KERNEL); if (!nsh) break; nsh->raid_conf = conf; - spin_lock_init(&nsh->stripe_lock); - list_add(&nsh->lru, &newstripes); } if (i) { @@ -2142,13 +2183,11 @@ static int resize_stripes(struct r5conf *conf, int newsize) lock_device_hash_lock(conf, hash)); osh = get_free_stripe(conf, hash); unlock_device_hash_lock(conf, hash); - atomic_set(&nsh->count, 1); + for(i=0; i<conf->pool_size; i++) { nsh->dev[i].page = osh->dev[i].page; nsh->dev[i].orig_page = osh->dev[i].page; } - for( ; i<newsize; i++) - nsh->dev[i].page = NULL; nsh->hash_lock_index = hash; kmem_cache_free(conf->slab_cache, osh); cnt++; @@ -2174,25 +2213,6 @@ static int resize_stripes(struct r5conf *conf, int newsize) } else err = -ENOMEM; - get_online_cpus(); - for_each_present_cpu(cpu) { - struct raid5_percpu *percpu; - struct flex_array *scribble; - - percpu = per_cpu_ptr(conf->percpu, cpu); - scribble = scribble_alloc(newsize, conf->chunk_sectors / - STRIPE_SECTORS, GFP_NOIO); - - if (scribble) { - flex_array_free(percpu->scribble); - percpu->scribble = scribble; - } else { - err = -ENOMEM; - break; - } - } - put_online_cpus(); - /* Step 4, return new stripes to service */ while(!list_empty(&newstripes)) { nsh = list_entry(newstripes.next, struct stripe_head, lru); @@ -2212,7 +2232,8 @@ static int resize_stripes(struct r5conf *conf, int newsize) conf->slab_cache = sc; conf->active_name = 1-conf->active_name; - conf->pool_size = newsize; + if (!err) + conf->pool_size = newsize; return err; } @@ -2434,7 +2455,7 @@ static void raid5_end_write_request(struct bio *bi, int error) } rdev_dec_pending(rdev, conf->mddev); - if (sh->batch_head && !uptodate) + if (sh->batch_head && !uptodate && !replacement) set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) @@ -2976,14 +2997,32 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_iter.bi_sector, (unsigned long long)sh->sector, dd_idx); - spin_unlock_irq(&sh->stripe_lock); if (conf->mddev->bitmap && firstwrite) { + /* Cannot hold spinlock over bitmap_startwrite, + * but must ensure this isn't added to a batch until + * we have added to the bitmap and set bm_seq. + * So set STRIPE_BITMAP_PENDING to prevent + * batching. + * If multiple add_stripe_bio() calls race here they + * much all set STRIPE_BITMAP_PENDING. So only the first one + * to complete "bitmap_startwrite" gets to set + * STRIPE_BIT_DELAY. This is important as once a stripe + * is added to a batch, STRIPE_BIT_DELAY cannot be changed + * any more. + */ + set_bit(STRIPE_BITMAP_PENDING, &sh->state); + spin_unlock_irq(&sh->stripe_lock); bitmap_startwrite(conf->mddev->bitmap, sh->sector, STRIPE_SECTORS, 0); - sh->bm_seq = conf->seq_flush+1; - set_bit(STRIPE_BIT_DELAY, &sh->state); + spin_lock_irq(&sh->stripe_lock); + clear_bit(STRIPE_BITMAP_PENDING, &sh->state); + if (!sh->batch_head) { + sh->bm_seq = conf->seq_flush+1; + set_bit(STRIPE_BIT_DELAY, &sh->state); + } } + spin_unlock_irq(&sh->stripe_lock); if (stripe_can_batch(sh)) stripe_add_to_batch_list(conf, sh); @@ -3278,7 +3317,9 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s, /* reconstruct-write isn't being forced */ return 0; for (i = 0; i < s->failed; i++) { - if (!test_bit(R5_UPTODATE, &fdev[i]->flags) && + if (s->failed_num[i] != sh->pd_idx && + s->failed_num[i] != sh->qd_idx && + !test_bit(R5_UPTODATE, &fdev[i]->flags) && !test_bit(R5_OVERWRITE, &fdev[i]->flags)) return 1; } @@ -3298,6 +3339,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, */ BUG_ON(test_bit(R5_Wantcompute, &dev->flags)); BUG_ON(test_bit(R5_Wantread, &dev->flags)); + BUG_ON(sh->batch_head); if ((s->uptodate == disks - 1) && (s->failed && (disk_idx == s->failed_num[0] || disk_idx == s->failed_num[1]))) { @@ -3366,7 +3408,6 @@ static void handle_stripe_fill(struct stripe_head *sh, { int i; - BUG_ON(sh->batch_head); /* look for blocks to read/compute, skip this if a compute * is already in flight, or if the stripe contents are in the * midst of changing due to a write @@ -3379,6 +3420,8 @@ static void handle_stripe_fill(struct stripe_head *sh, set_bit(STRIPE_HANDLE, &sh->state); } +static void break_stripe_batch_list(struct stripe_head *head_sh, + unsigned long handle_flags); /* handle_stripe_clean_event * any written block on an uptodate or failed drive can be returned. * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but @@ -3392,7 +3435,6 @@ static void handle_stripe_clean_event(struct r5conf *conf, int discard_pending = 0; struct stripe_head *head_sh = sh; bool do_endio = false; - int wakeup_nr = 0; for (i = disks; i--; ) if (sh->dev[i].written) { @@ -3481,44 +3523,8 @@ unhash: if (atomic_dec_and_test(&conf->pending_full_writes)) md_wakeup_thread(conf->mddev->thread); - if (!head_sh->batch_head || !do_endio) - return; - for (i = 0; i < head_sh->disks; i++) { - if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags)) - wakeup_nr++; - } - while (!list_empty(&head_sh->batch_list)) { - int i; - sh = list_first_entry(&head_sh->batch_list, - struct stripe_head, batch_list); - list_del_init(&sh->batch_list); - - set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG, - head_sh->state & ~((1 << STRIPE_ACTIVE) | - (1 << STRIPE_PREREAD_ACTIVE) | - STRIPE_EXPAND_SYNC_FLAG)); - sh->check_state = head_sh->check_state; - sh->reconstruct_state = head_sh->reconstruct_state; - for (i = 0; i < sh->disks; i++) { - if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) - wakeup_nr++; - sh->dev[i].flags = head_sh->dev[i].flags; - } - - spin_lock_irq(&sh->stripe_lock); - sh->batch_head = NULL; - spin_unlock_irq(&sh->stripe_lock); - if (sh->state & STRIPE_EXPAND_SYNC_FLAG) - set_bit(STRIPE_HANDLE, &sh->state); - release_stripe(sh); - } - - spin_lock_irq(&head_sh->stripe_lock); - head_sh->batch_head = NULL; - spin_unlock_irq(&head_sh->stripe_lock); - wake_up_nr(&conf->wait_for_overlap, wakeup_nr); - if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG) - set_bit(STRIPE_HANDLE, &head_sh->state); + if (head_sh->batch_head && do_endio) + break_stripe_batch_list(head_sh, STRIPE_EXPAND_SYNC_FLAGS); } static void handle_stripe_dirtying(struct r5conf *conf, @@ -4159,9 +4165,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) static int clear_batch_ready(struct stripe_head *sh) { + /* Return '1' if this is a member of batch, or + * '0' if it is a lone stripe or a head which can now be + * handled. + */ struct stripe_head *tmp; if (!test_and_clear_bit(STRIPE_BATCH_READY, &sh->state)) - return 0; + return (sh->batch_head && sh->batch_head != sh); spin_lock(&sh->stripe_lock); if (!sh->batch_head) { spin_unlock(&sh->stripe_lock); @@ -4189,46 +4199,65 @@ static int clear_batch_ready(struct stripe_head *sh) return 0; } -static void check_break_stripe_batch_list(struct stripe_head *sh) +static void break_stripe_batch_list(struct stripe_head *head_sh, + unsigned long handle_flags) { - struct stripe_head *head_sh, *next; + struct stripe_head *sh, *next; int i; + int do_wakeup = 0; - if (!test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state)) - return; + list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) { - head_sh = sh; - do { - sh = list_first_entry(&sh->batch_list, - struct stripe_head, batch_list); - BUG_ON(sh == head_sh); - } while (!test_bit(STRIPE_DEGRADED, &sh->state)); - - while (sh != head_sh) { - next = list_first_entry(&sh->batch_list, - struct stripe_head, batch_list); list_del_init(&sh->batch_list); - set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG, - head_sh->state & ~((1 << STRIPE_ACTIVE) | - (1 << STRIPE_PREREAD_ACTIVE) | - (1 << STRIPE_DEGRADED) | - STRIPE_EXPAND_SYNC_FLAG)); + WARN_ON_ONCE(sh->state & ((1 << STRIPE_ACTIVE) | + (1 << STRIPE_SYNCING) | + (1 << STRIPE_REPLACED) | + (1 << STRIPE_PREREAD_ACTIVE) | + (1 << STRIPE_DELAYED) | + (1 << STRIPE_BIT_DELAY) | + (1 << STRIPE_FULL_WRITE) | + (1 << STRIPE_BIOFILL_RUN) | + (1 << STRIPE_COMPUTE_RUN) | + (1 << STRIPE_OPS_REQ_PENDING) | + (1 << STRIPE_DISCARD) | + (1 << STRIPE_BATCH_READY) | + (1 << STRIPE_BATCH_ERR) | + (1 << STRIPE_BITMAP_PENDING))); + WARN_ON_ONCE(head_sh->state & ((1 << STRIPE_DISCARD) | + (1 << STRIPE_REPLACED))); + + set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | + (1 << STRIPE_DEGRADED)), + head_sh->state & (1 << STRIPE_INSYNC)); + sh->check_state = head_sh->check_state; sh->reconstruct_state = head_sh->reconstruct_state; - for (i = 0; i < sh->disks; i++) + for (i = 0; i < sh->disks; i++) { + if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) + do_wakeup = 1; sh->dev[i].flags = head_sh->dev[i].flags & (~((1 << R5_WriteError) | (1 << R5_Overlap))); - + } spin_lock_irq(&sh->stripe_lock); sh->batch_head = NULL; spin_unlock_irq(&sh->stripe_lock); - - set_bit(STRIPE_HANDLE, &sh->state); + if (handle_flags == 0 || + sh->state & handle_flags) + set_bit(STRIPE_HANDLE, &sh->state); release_stripe(sh); - - sh = next; } + spin_lock_irq(&head_sh->stripe_lock); + head_sh->batch_head = NULL; + spin_unlock_irq(&head_sh->stripe_lock); + for (i = 0; i < head_sh->disks; i++) + if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags)) + do_wakeup = 1; + if (head_sh->state & handle_flags) + set_bit(STRIPE_HANDLE, &head_sh->state); + + if (do_wakeup) + wake_up(&head_sh->raid_conf->wait_for_overlap); } static void handle_stripe(struct stripe_head *sh) @@ -4253,7 +4282,8 @@ static void handle_stripe(struct stripe_head *sh) return; } - check_break_stripe_batch_list(sh); + if (test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state)) + break_stripe_batch_list(sh, 0); if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) { spin_lock(&sh->stripe_lock); @@ -4307,6 +4337,7 @@ static void handle_stripe(struct stripe_head *sh) if (s.failed > conf->max_degraded) { sh->check_state = 0; sh->reconstruct_state = 0; + break_stripe_batch_list(sh, 0); if (s.to_read+s.to_write+s.written) handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); if (s.syncing + s.replacing) @@ -6221,8 +6252,11 @@ static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu percpu->spare_page = alloc_page(GFP_KERNEL); if (!percpu->scribble) percpu->scribble = scribble_alloc(max(conf->raid_disks, - conf->previous_raid_disks), conf->chunk_sectors / - STRIPE_SECTORS, GFP_KERNEL); + conf->previous_raid_disks), + max(conf->chunk_sectors, + conf->prev_chunk_sectors) + / STRIPE_SECTORS, + GFP_KERNEL); if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { free_scratch_buffer(conf, percpu); @@ -7198,6 +7232,15 @@ static int check_reshape(struct mddev *mddev) if (!check_stripe_cache(mddev)) return -ENOSPC; + if (mddev->new_chunk_sectors > mddev->chunk_sectors || + mddev->delta_disks > 0) + if (resize_chunks(conf, + conf->previous_raid_disks + + max(0, mddev->delta_disks), + max(mddev->new_chunk_sectors, + mddev->chunk_sectors) + ) < 0) + return -ENOMEM; return resize_stripes(conf, (conf->previous_raid_disks + mddev->delta_disks)); } diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 7dc0dd86074b..896d603ad0da 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h @@ -337,9 +337,12 @@ enum { STRIPE_ON_RELEASE_LIST, STRIPE_BATCH_READY, STRIPE_BATCH_ERR, + STRIPE_BITMAP_PENDING, /* Being added to bitmap, don't add + * to batch yet. + */ }; -#define STRIPE_EXPAND_SYNC_FLAG \ +#define STRIPE_EXPAND_SYNC_FLAGS \ ((1 << STRIPE_EXPAND_SOURCE) |\ (1 << STRIPE_EXPAND_READY) |\ (1 << STRIPE_EXPANDING) |\ diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 9c64b5d01c6a..110fd70c7326 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -116,8 +116,8 @@ static struct mcam_format_struct { .planar = false, }, { - .desc = "UYVY 4:2:2", - .pixelformat = V4L2_PIX_FMT_UYVY, + .desc = "YVYU 4:2:2", + .pixelformat = V4L2_PIX_FMT_YVYU, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, @@ -748,7 +748,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam) switch (fmt->pixelformat) { case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: widthy = fmt->width * 2; widthuv = 0; break; @@ -784,15 +784,15 @@ static void mcam_ctlr_image(struct mcam_camera *cam) case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_YUV | C0_YUV_420PL | C0_YUVE_YVYU, C0_DF_MASK); + C0_DF_YUV | C0_YUV_420PL | C0_YUVE_VYUY, C0_DF_MASK); break; case V4L2_PIX_FMT_YUYV: mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_UYVY, C0_DF_MASK); + C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_NOSWAP, C0_DF_MASK); break; - case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_YUYV, C0_DF_MASK); + C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_SWAP24, C0_DF_MASK); break; case V4L2_PIX_FMT_JPEG: mcam_reg_write_mask(cam, REG_CTRL0, diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index aa0c6eac254a..7ffdf4dbaf8c 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h @@ -330,10 +330,10 @@ int mccic_resume(struct mcam_camera *cam); #define C0_YUVE_YVYU 0x00010000 /* Y1CrY0Cb */ #define C0_YUVE_VYUY 0x00020000 /* CrY1CbY0 */ #define C0_YUVE_UYVY 0x00030000 /* CbY1CrY0 */ -#define C0_YUVE_XYUV 0x00000000 /* 420: .YUV */ -#define C0_YUVE_XYVU 0x00010000 /* 420: .YVU */ -#define C0_YUVE_XUVY 0x00020000 /* 420: .UVY */ -#define C0_YUVE_XVUY 0x00030000 /* 420: .VUY */ +#define C0_YUVE_NOSWAP 0x00000000 /* no bytes swapping */ +#define C0_YUVE_SWAP13 0x00010000 /* swap byte 1 and 3 */ +#define C0_YUVE_SWAP24 0x00020000 /* swap byte 2 and 4 */ +#define C0_YUVE_SWAP1324 0x00030000 /* swap bytes 1&3 and 2&4 */ /* Bayer bits 18,19 if needed */ #define C0_EOF_VSYNC 0x00400000 /* Generate EOF by VSYNC */ #define C0_VEDGE_CTRL 0x00800000 /* Detect falling edge of VSYNC */ diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 9351f64dee7b..6460f8e1b07f 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -135,6 +135,8 @@ #define VIN_MAX_WIDTH 2048 #define VIN_MAX_HEIGHT 2048 +#define TIMEOUT_MS 100 + enum chip_id { RCAR_GEN2, RCAR_H1, @@ -820,7 +822,10 @@ static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv) if (priv->state == STOPPING) { priv->request_to_stop = true; spin_unlock_irq(&priv->lock); - wait_for_completion(&priv->capture_stop); + if (!wait_for_completion_timeout( + &priv->capture_stop, + msecs_to_jiffies(TIMEOUT_MS))) + priv->state = STOPPED; spin_lock_irq(&priv->lock); } } diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index ae498b53ee40..46e3840c7a37 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -433,6 +433,10 @@ EXPORT_SYMBOL_GPL(da9052_adc_read_temp); static const struct mfd_cell da9052_subdev_info[] = { { .name = "da9052-regulator", + .id = 0, + }, + { + .name = "da9052-regulator", .id = 1, }, { @@ -484,10 +488,6 @@ static const struct mfd_cell da9052_subdev_info[] = { .id = 13, }, { - .name = "da9052-regulator", - .id = 14, - }, - { .name = "da9052-onkey", }, { diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 2c25271f8c41..60f7141a6b02 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1029,6 +1029,18 @@ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) md->reset_done &= ~type; } +int mmc_access_rpmb(struct mmc_queue *mq) +{ + struct mmc_blk_data *md = mq->data; + /* + * If this is a RPMB partition access, return ture + */ + if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) + return true; + + return false; +} + static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq->data; diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 236d194c2883..8efa3684aef8 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -38,7 +38,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) return BLKPREP_KILL; } - if (mq && mmc_card_removed(mq->card)) + if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq))) return BLKPREP_KILL; req->cmd_flags |= REQ_DONTPREP; diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 5752d50049a3..99e6521e6169 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -73,4 +73,6 @@ extern void mmc_queue_bounce_post(struct mmc_queue_req *); extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *); extern void mmc_packed_clean(struct mmc_queue *); +extern int mmc_access_rpmb(struct mmc_queue *); + #endif diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c296bc098fe2..92e7671426eb 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2651,6 +2651,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, switch (mode) { case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: + case PM_RESTORE_PREPARE: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 1; spin_unlock_irqrestore(&host->lock, flags); diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 03d7c7521d97..9a39e0b7e583 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -1304,7 +1304,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->clock) { unsigned int clock_min = ~0U; - u32 clkdiv; + int clkdiv; spin_lock_bh(&host->lock); if (!host->mode_reg) { @@ -1328,7 +1328,12 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* Calculate clock divider */ if (host->caps.has_odd_clk_div) { clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; - if (clkdiv > 511) { + if (clkdiv < 0) { + dev_warn(&mmc->class_dev, + "clock %u too fast; using %lu\n", + clock_min, host->bus_hz / 2); + clkdiv = 0; + } else if (clkdiv > 511) { dev_warn(&mmc->class_dev, "clock %u too slow; using %lu\n", clock_min, host->bus_hz / (511 + 2)); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 38b29265cc7c..5f5adafb253a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -589,9 +589,11 @@ static int dw_mci_idmac_init(struct dw_mci *host) host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); /* Forward link the descriptor list */ - for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) + for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) { p->des3 = cpu_to_le32(host->sg_dma + (sizeof(struct idmac_desc) * (i + 1))); + p->des1 = 0; + } /* Set the last descriptor as the end-of-ring descriptor */ p->des3 = cpu_to_le32(host->sg_dma); @@ -1300,7 +1302,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ - if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) + if ((brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) || + (mmc->caps & MMC_CAP_NONREMOVABLE)) present = 1; else if (!IS_ERR_VALUE(gpio_cd)) present = gpio_cd; diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 2b6ef6bd5d5f..7eff087cf515 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -1408,7 +1408,7 @@ static int sh_mmcif_probe(struct platform_device *pdev) host = mmc_priv(mmc); host->mmc = mmc; host->addr = reg; - host->timeout = msecs_to_jiffies(1000); + host->timeout = msecs_to_jiffies(10000); host->ccs_enable = !pd || !pd->ccs_unsupported; host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 7c8b1694a134..3af137f49ac9 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -223,7 +223,7 @@ static int m25p_probe(struct spi_device *spi) */ if (data && data->type) flash_name = data->type; - else if (!strcmp(spi->modalias, "nor-jedec")) + else if (!strcmp(spi->modalias, "spi-nor")) flash_name = NULL; /* auto-detect */ else flash_name = spi->modalias; @@ -255,7 +255,7 @@ static int m25p_remove(struct spi_device *spi) * since most of these flash are compatible to some extent, and their * differences can often be differentiated by the JEDEC read-ID command, we * encourage new users to add support to the spi-nor library, and simply bind - * against a generic string here (e.g., "nor-jedec"). + * against a generic string here (e.g., "jedec,spi-nor"). * * Many flash names are kept here in this list (as well as in spi-nor.c) to * keep them available as module aliases for existing platforms. @@ -305,7 +305,7 @@ static const struct spi_device_id m25p_ids[] = { * Generic support for SPI NOR that can be identified by the JEDEC READ * ID opcode (0x9F). Use this, if possible. */ - {"nor-jedec"}, + {"spi-nor"}, { }, }; MODULE_DEVICE_TABLE(spi, m25p_ids); diff --git a/drivers/mtd/tests/readtest.c b/drivers/mtd/tests/readtest.c index a3196b750a22..58df07acdbdb 100644 --- a/drivers/mtd/tests/readtest.c +++ b/drivers/mtd/tests/readtest.c @@ -191,9 +191,11 @@ static int __init mtd_readtest_init(void) err = ret; } - err = mtdtest_relax(); - if (err) + ret = mtdtest_relax(); + if (ret) { + err = ret; goto out; + } } if (err) diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index db2c05b6fe7f..c9eb78f10a0d 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -310,6 +310,8 @@ static void ubiblock_do_work(struct work_struct *work) blk_rq_map_sg(req->q, req, pdu->usgl.sg); ret = ubiblock_read(pdu); + rq_flush_dcache_pages(req); + blk_mq_end_request(req, ret); } diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 4df28943d222..e8d3c1d35453 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -624,7 +624,7 @@ int __bond_opt_set(struct bonding *bond, out: if (ret) bond_opt_error_interpret(bond, opt, ret, val); - else + else if (bond->dev->reg_state == NETREG_REGISTERED) call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev); return ret; diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 6bddfe062b51..fc55e8e0351d 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -509,10 +509,11 @@ static int xcan_rx(struct net_device *ndev) cf->can_id |= CAN_RTR_FLAG; } - if (!(id_xcan & XCAN_IDR_SRR_MASK)) { - data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET); - data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET); + /* DW1/DW2 must always be read to remove message from RXFIFO */ + data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET); + data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET); + if (!(cf->can_id & CAN_RTR_FLAG)) { /* Change Xilinx CAN data format to socketCAN data format */ if (cf->can_dlc > 0) *(__be32 *)(cf->data) = cpu_to_be32(data[0]); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index af639ab4c55b..cf309aa92802 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1469,6 +1469,9 @@ static void __exit mv88e6xxx_cleanup(void) #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) unregister_switch_driver(&mv88e6171_switch_driver); #endif +#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) + unregister_switch_driver(&mv88e6352_switch_driver); +#endif #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) unregister_switch_driver(&mv88e6123_61_65_switch_driver); #endif diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 089c269637b7..426916036151 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -180,6 +180,7 @@ config SUNLANCE config AMD_XGBE tristate "AMD 10GbE Ethernet driver" depends on (OF_NET || ACPI) && HAS_IOMEM && HAS_DMA + depends on ARM64 || COMPILE_TEST select PHYLIB select AMD_XGBE_PHY select BITREVERSE diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig index f4054d242f3c..19e38afbc5ee 100644 --- a/drivers/net/ethernet/apm/xgene/Kconfig +++ b/drivers/net/ethernet/apm/xgene/Kconfig @@ -1,6 +1,7 @@ config NET_XGENE tristate "APM X-Gene SoC Ethernet Driver" depends on HAS_DMA + depends on ARCH_XGENE || COMPILE_TEST select PHYLIB help This is the Ethernet driver for the on-chip ethernet interface on the diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index a3b0f7a0c61e..1f82a04ce01a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1774,7 +1774,7 @@ struct bnx2x { int stats_state; /* used for synchronization of concurrent threads statistics handling */ - struct mutex stats_lock; + struct semaphore stats_lock; /* used by dmae command loader */ struct dmae_command stats_dmae; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index a8bb8f664d3d..ec56a9b65dc3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -4786,6 +4786,11 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { struct bnx2x *bp = netdev_priv(dev); + if (pci_num_vf(bp->pdev)) { + DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n"); + return -EPERM; + } + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { BNX2X_ERR("Can't perform change MTU during parity recovery\n"); return -EAGAIN; @@ -4938,11 +4943,6 @@ int bnx2x_resume(struct pci_dev *pdev) } bp = netdev_priv(dev); - if (pci_num_vf(bp->pdev)) { - DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n"); - return -EPERM; - } - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { BNX2X_ERR("Handling parity error recovery. Try again later\n"); return -EAGAIN; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 556dcc162a62..33501bcddc48 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12054,7 +12054,7 @@ static int bnx2x_init_bp(struct bnx2x *bp) mutex_init(&bp->port.phy_mutex); mutex_init(&bp->fw_mb_mutex); mutex_init(&bp->drv_info_mutex); - mutex_init(&bp->stats_lock); + sema_init(&bp->stats_lock, 1); bp->drv_info_mng_owner = false; INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); @@ -13371,8 +13371,13 @@ static int bnx2x_init_one(struct pci_dev *pdev, /* Management FW 'remembers' living interfaces. Allow it some time * to forget previously living interfaces, allowing a proper re-load. */ - if (is_kdump_kernel()) - msleep(5000); + if (is_kdump_kernel()) { + ktime_t now = ktime_get_boottime(); + ktime_t fw_ready_time = ktime_set(5, 0); + + if (ktime_before(now, fw_ready_time)) + msleep(ktime_ms_delta(fw_ready_time, now)); + } /* An estimated maximum supported CoS number according to the chip * version. @@ -13685,9 +13690,10 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) cancel_delayed_work_sync(&bp->sp_task); cancel_delayed_work_sync(&bp->period_task); - mutex_lock(&bp->stats_lock); - bp->stats_state = STATS_STATE_DISABLED; - mutex_unlock(&bp->stats_lock); + if (!down_timeout(&bp->stats_lock, HZ / 10)) { + bp->stats_state = STATS_STATE_DISABLED; + up(&bp->stats_lock); + } bnx2x_save_statistics(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 266b055c2360..69d699f0730a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1372,19 +1372,23 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) * that context in case someone is in the middle of a transition. * For other events, wait a bit until lock is taken. */ - if (!mutex_trylock(&bp->stats_lock)) { + if (down_trylock(&bp->stats_lock)) { if (event == STATS_EVENT_UPDATE) return; DP(BNX2X_MSG_STATS, "Unlikely stats' lock contention [event %d]\n", event); - mutex_lock(&bp->stats_lock); + if (unlikely(down_timeout(&bp->stats_lock, HZ / 10))) { + BNX2X_ERR("Failed to take stats lock [event %d]\n", + event); + return; + } } bnx2x_stats_stm[state][event].action(bp); bp->stats_state = bnx2x_stats_stm[state][event].next_state; - mutex_unlock(&bp->stats_lock); + up(&bp->stats_lock); if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", @@ -1970,7 +1974,11 @@ int bnx2x_stats_safe_exec(struct bnx2x *bp, /* Wait for statistics to end [while blocking further requests], * then run supplied function 'safely'. */ - mutex_lock(&bp->stats_lock); + rc = down_timeout(&bp->stats_lock, HZ / 10); + if (unlikely(rc)) { + BNX2X_ERR("Failed to take statistics lock for safe execution\n"); + goto out_no_lock; + } bnx2x_stats_comp(bp); while (bp->stats_pending && cnt--) @@ -1988,7 +1996,7 @@ out: /* No need to restart statistics - if they're enabled, the timer * will restart the statistics. */ - mutex_unlock(&bp->stats_lock); - + up(&bp->stats_lock); +out_no_lock: return rc; } diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 594a2ab36d31..68f3c13c9ef6 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -2414,7 +2414,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, if (status == BFA_STATUS_OK) bfa_ioc_lpu_start(ioc); else - bfa_nw_iocpf_timeout(ioc); + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); return status; } @@ -3029,7 +3029,7 @@ bfa_ioc_poll_fwinit(struct bfa_ioc *ioc) } if (ioc->iocpf.poll_time >= BFA_IOC_TOV) { - bfa_nw_iocpf_timeout(ioc); + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); } else { ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; mod_timer(&ioc->iocpf_timer, jiffies + diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 37072a83f9d6..caae6cb2bc1a 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -3701,10 +3701,6 @@ bnad_pci_probe(struct pci_dev *pdev, setup_timer(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout, ((unsigned long)bnad)); - /* Now start the timer before calling IOC */ - mod_timer(&bnad->bna.ioceth.ioc.iocpf_timer, - jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ)); - /* * Start the chip * If the call back comes with error, we bail out. diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c index ebf462d8082f..badea368bdc8 100644 --- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c +++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c @@ -30,6 +30,7 @@ cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, u32 *bfi_image_size, char *fw_name) { const struct firmware *fw; + u32 n; if (request_firmware(&fw, fw_name, &pdev->dev)) { pr_alert("Can't locate firmware %s\n", fw_name); @@ -40,6 +41,12 @@ cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, *bfi_image_size = fw->size/sizeof(u32); bfi_fw = fw; + /* Convert loaded firmware to host order as it is stored in file + * as sequence of LE32 integers. + */ + for (n = 0; n < *bfi_image_size; n++) + le32_to_cpus(*bfi_image + n); + return *bfi_image; error: return NULL; diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 4104d49f005d..fc646a41d548 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -350,6 +350,9 @@ static int macb_mii_probe(struct net_device *dev) else phydev->supported &= PHY_BASIC_FEATURES; + if (bp->caps & MACB_CAPS_NO_GIGABIT_HALF) + phydev->supported &= ~SUPPORTED_1000baseT_Half; + phydev->advertising = phydev->supported; bp->link = 0; @@ -981,7 +984,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) struct macb_queue *queue = dev_id; struct macb *bp = queue->bp; struct net_device *dev = bp->dev; - u32 status; + u32 status, ctrl; status = queue_readl(queue, ISR); @@ -1037,6 +1040,21 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) * add that if/when we get our hands on a full-blown MII PHY. */ + /* There is a hardware issue under heavy load where DMA can + * stop, this causes endless "used buffer descriptor read" + * interrupts but it can be cleared by re-enabling RX. See + * the at91 manual, section 41.3.1 or the Zynq manual + * section 16.7.4 for details. + */ + if (status & MACB_BIT(RXUBR)) { + ctrl = macb_readl(bp, NCR); + macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); + macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); + + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + macb_writel(bp, ISR, MACB_BIT(RXUBR)); + } + if (status & MACB_BIT(ISR_ROVR)) { /* We missed at least one packet */ if (macb_is_gem(bp)) @@ -2684,6 +2702,14 @@ static const struct macb_config emac_config = { .init = at91ether_init, }; +static const struct macb_config zynq_config = { + .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE | + MACB_CAPS_NO_GIGABIT_HALF, + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, +}; + static const struct of_device_id macb_dt_ids[] = { { .compatible = "cdns,at32ap7000-macb" }, { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, @@ -2694,6 +2720,7 @@ static const struct of_device_id macb_dt_ids[] = { { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config }, { .compatible = "cdns,at91rm9200-emac", .data = &emac_config }, { .compatible = "cdns,emac", .data = &emac_config }, + { .compatible = "cdns,zynq-gem", .data = &zynq_config }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, macb_dt_ids); diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index eb7d76f7bf6a..24b1d9bcd865 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -393,6 +393,7 @@ #define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x00000001 #define MACB_CAPS_USRIO_HAS_CLKEN 0x00000002 #define MACB_CAPS_USRIO_DEFAULT_IS_MII 0x00000004 +#define MACB_CAPS_NO_GIGABIT_HALF 0x00000008 #define MACB_CAPS_FIFO_MODE 0x10000000 #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 #define MACB_CAPS_SG_DISABLED 0x40000000 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a6dcbf850c1f..6f9ffb9026cd 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2358,11 +2358,11 @@ static int be_evt_queues_create(struct be_adapter *adapter) adapter->cfg_num_qs); for_all_evt_queues(adapter, eqo, i) { + int numa_node = dev_to_node(&adapter->pdev->dev); if (!zalloc_cpumask_var(&eqo->affinity_mask, GFP_KERNEL)) return -ENOMEM; - cpumask_set_cpu_local_first(i, dev_to_node(&adapter->pdev->dev), - eqo->affinity_mask); - + cpumask_set_cpu(cpumask_local_spread(i, numa_node), + eqo->affinity_mask); netif_napi_add(adapter->netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT); napi_hash_add(&eqo->napi); diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index de7919322190..b9df0cbd0a38 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2084,12 +2084,8 @@ static void emac_ethtool_get_pauseparam(struct net_device *ndev, static int emac_get_regs_len(struct emac_instance *dev) { - if (emac_has_feature(dev, EMAC_FTR_EMAC4)) - return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC4_ETHTOOL_REGS_SIZE(dev); - else return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC_ETHTOOL_REGS_SIZE(dev); + sizeof(struct emac_regs); } static int emac_ethtool_get_regs_len(struct net_device *ndev) @@ -2114,15 +2110,15 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf) struct emac_ethtool_regs_subhdr *hdr = buf; hdr->index = dev->cell_index; - if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) { + hdr->version = EMAC4SYNC_ETHTOOL_REGS_VER; + } else if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { hdr->version = EMAC4_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); - return (void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev); } else { hdr->version = EMAC_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); - return (void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev); } + memcpy_fromio(hdr + 1, dev->emacp, sizeof(struct emac_regs)); + return (void *)(hdr + 1) + sizeof(struct emac_regs); } static void emac_ethtool_get_regs(struct net_device *ndev, diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h index 67f342a9f65e..28df37420da9 100644 --- a/drivers/net/ethernet/ibm/emac/core.h +++ b/drivers/net/ethernet/ibm/emac/core.h @@ -461,10 +461,7 @@ struct emac_ethtool_regs_subhdr { }; #define EMAC_ETHTOOL_REGS_VER 0 -#define EMAC_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ - (dev)->rsrc_regs.start + 1) -#define EMAC4_ETHTOOL_REGS_VER 1 -#define EMAC4_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ - (dev)->rsrc_regs.start + 1) +#define EMAC4_ETHTOOL_REGS_VER 1 +#define EMAC4SYNC_ETHTOOL_REGS_VER 2 #endif /* __IBM_NEWEMAC_CORE_H */ diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 5d9ceb17b4cb..0abc942c966e 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -40,6 +40,7 @@ #include <linux/ptp_classify.h> #include <linux/mii.h> #include <linux/mdio.h> +#include <linux/pm_qos.h> #include "hw.h" struct e1000_info; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 1b0661e3573b..c754b2027281 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -610,7 +610,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, unsigned int total_bytes = 0, total_packets = 0; u16 cleaned_count = fm10k_desc_unused(rx_ring); - do { + while (likely(total_packets < budget)) { union fm10k_rx_desc *rx_desc; /* return some buffers to hardware, one at a time is too slow */ @@ -659,7 +659,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, /* update budget accounting */ total_packets++; - } while (likely(total_packets < budget)); + } /* place incomplete frames back on ring for completion */ rx_ring->skb = skb; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8457d0306e3a..a0a9b1fcb5e8 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1036,7 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL; if (q_vector->rx.ring) - adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL; + adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; netif_napi_del(&q_vector->napi); @@ -1207,6 +1207,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, q_vector = adapter->q_vector[v_idx]; if (!q_vector) q_vector = kzalloc(size, GFP_KERNEL); + else + memset(q_vector, 0, size); if (!q_vector) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index a16d267fbce4..e71cdde9cb01 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -3612,7 +3612,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL); if (!dst_mac || is_link_local_ether_addr(dst_mac)) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 4f7dc044601e..529ef0594b90 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -714,8 +714,13 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param, msecs_to_jiffies(timeout))) { mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n", op); - err = -EIO; - goto out_reset; + if (op == MLX4_CMD_NOP) { + err = -EBUSY; + goto out; + } else { + err = -EIO; + goto out_reset; + } } err = context->result; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 32f5ec737472..cf467a9f6cc7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1501,17 +1501,13 @@ static int mlx4_en_init_affinity_hint(struct mlx4_en_priv *priv, int ring_idx) { struct mlx4_en_rx_ring *ring = priv->rx_ring[ring_idx]; int numa_node = priv->mdev->dev->numa_node; - int ret = 0; if (!zalloc_cpumask_var(&ring->affinity_mask, GFP_KERNEL)) return -ENOMEM; - ret = cpumask_set_cpu_local_first(ring_idx, numa_node, - ring->affinity_mask); - if (ret) - free_cpumask_var(ring->affinity_mask); - - return ret; + cpumask_set_cpu(cpumask_local_spread(ring_idx, numa_node), + ring->affinity_mask); + return 0; } static void mlx4_en_free_affinity_hint(struct mlx4_en_priv *priv, int ring_idx) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index 54f0e5ab2e55..0a56f010c846 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c @@ -139,7 +139,7 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num) int i; int offset = next - start; - for (i = 0; i <= num; i++) { + for (i = 0; i < num; i++) { ret += be64_to_cpu(*curr); curr += offset; } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index f7bf312fb443..7bed3a88579f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -144,9 +144,9 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, ring->queue_index = queue_index; if (queue_index < priv->num_tx_rings_p_up) - cpumask_set_cpu_local_first(queue_index, - priv->mdev->dev->numa_node, - &ring->affinity_mask); + cpumask_set_cpu(cpumask_local_spread(queue_index, + priv->mdev->dev->numa_node), + &ring->affinity_mask); *pring = ring; return 0; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index c7f28bf4b8e2..bafe2180cf0c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2845,7 +2845,7 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave, { int err; int eqn = vhcr->in_modifier; - int res_id = (slave << 8) | eqn; + int res_id = (slave << 10) | eqn; struct mlx4_eq_context *eqc = inbox->buf; int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz; int mtt_size = eq_get_mtt_size(eqc); @@ -3051,7 +3051,7 @@ int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_info *cmd) { int eqn = vhcr->in_modifier; - int res_id = eqn | (slave << 8); + int res_id = eqn | (slave << 10); struct res_eq *eq; int err; @@ -3108,7 +3108,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) return 0; mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]); - res_id = (slave << 8) | event_eq->eqn; + res_id = (slave << 10) | event_eq->eqn; err = get_res(dev, slave, res_id, RES_EQ, &req); if (err) goto unlock; @@ -3131,7 +3131,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) memcpy(mailbox->buf, (u8 *) eqe, 28); - in_modifier = (slave & 0xff) | ((event_eq->eqn & 0xff) << 16); + in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16); err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0, MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B, @@ -3157,7 +3157,7 @@ int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_info *cmd) { int eqn = vhcr->in_modifier; - int res_id = eqn | (slave << 8); + int res_id = eqn | (slave << 10); struct res_eq *eq; int err; @@ -3187,7 +3187,7 @@ int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave, int cqn = vhcr->in_modifier; struct mlx4_cq_context *cqc = inbox->buf; int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz; - struct res_cq *cq; + struct res_cq *cq = NULL; struct res_mtt *mtt; err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq); @@ -3223,7 +3223,7 @@ int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave, { int err; int cqn = vhcr->in_modifier; - struct res_cq *cq; + struct res_cq *cq = NULL; err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq); if (err) @@ -3362,7 +3362,7 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave, int err; int srqn = vhcr->in_modifier; struct res_mtt *mtt; - struct res_srq *srq; + struct res_srq *srq = NULL; struct mlx4_srq_context *srqc = inbox->buf; int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz; @@ -3406,7 +3406,7 @@ int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave, { int err; int srqn = vhcr->in_modifier; - struct res_srq *srq; + struct res_srq *srq = NULL; err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq); if (err) @@ -4714,13 +4714,13 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave) break; case RES_EQ_HW: - err = mlx4_cmd(dev, slave, eqn & 0xff, + err = mlx4_cmd(dev, slave, eqn & 0x3ff, 1, MLX4_CMD_HW2SW_EQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); if (err) mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n", - slave, eqn); + slave, eqn & 0x3ff); atomic_dec(&eq->mtt->ref_count); state = RES_EQ_RESERVED; break; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 8da7c3faf817..7b43a3b4abdc 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -1764,7 +1764,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) int done = 0; struct nx_host_tx_ring *tx_ring = adapter->tx_ring; - if (!spin_trylock(&adapter->tx_clean_lock)) + if (!spin_trylock_bh(&adapter->tx_clean_lock)) return 1; sw_consumer = tx_ring->sw_consumer; @@ -1819,7 +1819,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) */ hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); done = (sw_consumer == hw_consumer); - spin_unlock(&adapter->tx_clean_lock); + spin_unlock_bh(&adapter->tx_clean_lock); return done; } diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index e0c31e3947d1..6409a06bbdf6 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -3025,9 +3025,9 @@ netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj, u8 dw, rows, cols, banks, ranks; u32 val; - if (size != sizeof(struct netxen_dimm_cfg)) { + if (size < attr->size) { netdev_err(netdev, "Invalid size\n"); - return -1; + return -EINVAL; } memset(&dimm, 0, sizeof(struct netxen_dimm_cfg)); @@ -3137,7 +3137,7 @@ out: static struct bin_attribute bin_attr_dimm = { .attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) }, - .size = 0, + .size = sizeof(struct netxen_dimm_cfg), .read = netxen_sysfs_read_dimm, }; diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index f66641d961e3..6af028d5f9bc 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -912,6 +912,8 @@ qca_spi_probe(struct spi_device *spi_device) qca->spi_dev = spi_device; qca->legacy_mode = legacy_mode; + spi_set_drvdata(spi_device, qcaspi_devs); + mac = of_get_mac_address(spi_device->dev.of_node); if (mac) @@ -944,8 +946,6 @@ qca_spi_probe(struct spi_device *spi_device) return -EFAULT; } - spi_set_drvdata(spi_device, qcaspi_devs); - qcaspi_init_device_debugfs(qca); return 0; diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c70ab40d8698..3df51faf18ae 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -6884,7 +6884,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp, rtl8169_start_xmit(nskb, tp->dev); } while (segs); - dev_kfree_skb(skb); + dev_consume_skb_any(skb); } else if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb_checksum_help(skb) < 0) goto drop; @@ -6896,7 +6896,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp, drop: stats = &tp->dev->stats; stats->tx_dropped++; - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } } diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index ec251531bd9f..cf98cc9bbc8d 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -2921,10 +2921,11 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port, struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr); int err = 0; - if (!n) + if (!n) { n = neigh_create(&arp_tbl, &ip_addr, dev); - if (!n) - return -ENOMEM; + if (IS_ERR(n)) + return IS_ERR(n); + } /* If the neigh is already resolved, then go ahead and * install the entry, otherwise start the ARP process to @@ -2936,6 +2937,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port, else neigh_event_send(n, NULL); + neigh_release(n); return err; } diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index c0ad95d2f63d..809ea4610a77 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -224,12 +224,17 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, } } -static void efx_free_rx_buffer(struct efx_rx_buffer *rx_buf) +static void efx_free_rx_buffers(struct efx_rx_queue *rx_queue, + struct efx_rx_buffer *rx_buf, + unsigned int num_bufs) { - if (rx_buf->page) { - put_page(rx_buf->page); - rx_buf->page = NULL; - } + do { + if (rx_buf->page) { + put_page(rx_buf->page); + rx_buf->page = NULL; + } + rx_buf = efx_rx_buf_next(rx_queue, rx_buf); + } while (--num_bufs); } /* Attempt to recycle the page if there is an RX recycle ring; the page can @@ -278,7 +283,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, /* If this is the last buffer in a page, unmap and free it. */ if (rx_buf->flags & EFX_RX_BUF_LAST_IN_PAGE) { efx_unmap_rx_buffer(rx_queue->efx, rx_buf); - efx_free_rx_buffer(rx_buf); + efx_free_rx_buffers(rx_queue, rx_buf, 1); } rx_buf->page = NULL; } @@ -304,10 +309,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel, efx_recycle_rx_pages(channel, rx_buf, n_frags); - do { - efx_free_rx_buffer(rx_buf); - rx_buf = efx_rx_buf_next(rx_queue, rx_buf); - } while (--n_frags); + efx_free_rx_buffers(rx_queue, rx_buf, n_frags); } /** @@ -431,11 +433,10 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, skb = napi_get_frags(napi); if (unlikely(!skb)) { - while (n_frags--) { - put_page(rx_buf->page); - rx_buf->page = NULL; - rx_buf = efx_rx_buf_next(&channel->rx_queue, rx_buf); - } + struct efx_rx_queue *rx_queue; + + rx_queue = efx_channel_get_rx_queue(channel); + efx_free_rx_buffers(rx_queue, rx_buf, n_frags); return; } @@ -622,7 +623,10 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, skb = efx_rx_mk_skb(channel, rx_buf, n_frags, eh, hdr_len); if (unlikely(skb == NULL)) { - efx_free_rx_buffer(rx_buf); + struct efx_rx_queue *rx_queue; + + rx_queue = efx_channel_get_rx_queue(channel); + efx_free_rx_buffers(rx_queue, rx_buf, n_frags); return; } skb_record_rx_queue(skb, channel->rx_queue.core_index); @@ -661,8 +665,12 @@ void __efx_rx_packet(struct efx_channel *channel) * loopback layer, and free the rx_buf here */ if (unlikely(efx->loopback_selftest)) { + struct efx_rx_queue *rx_queue; + efx_loopback_rx_packet(efx, eh, rx_buf->len); - efx_free_rx_buffer(rx_buf); + rx_queue = efx_channel_get_rx_queue(channel); + efx_free_rx_buffers(rx_queue, rx_buf, + channel->rx_pkt_n_frags); goto out; } diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 14b363a25c02..630f0b7800e4 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -2238,9 +2238,10 @@ static int smc_drv_probe(struct platform_device *pdev) const struct of_device_id *match = NULL; struct smc_local *lp; struct net_device *ndev; - struct resource *res, *ires; + struct resource *res; unsigned int __iomem *addr; unsigned long irq_flags = SMC_IRQ_FLAGS; + unsigned long irq_resflags; int ret; ndev = alloc_etherdev(sizeof(struct smc_local)); @@ -2332,16 +2333,19 @@ static int smc_drv_probe(struct platform_device *pdev) goto out_free_netdev; } - ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!ires) { + ndev->irq = platform_get_irq(pdev, 0); + if (ndev->irq <= 0) { ret = -ENODEV; goto out_release_io; } - - ndev->irq = ires->start; - - if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) - irq_flags = ires->flags & IRQF_TRIGGER_MASK; + /* + * If this platform does not specify any special irqflags, or if + * the resource supplies a trigger, override the irqflags with + * the trigger flags from the resource. + */ + irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq)); + if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK) + irq_flags = irq_resflags & IRQF_TRIGGER_MASK; ret = smc_request_attrib(pdev, ndev); if (ret) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 41047c9143d0..959aeeade0c9 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2418,9 +2418,9 @@ static int smsc911x_drv_probe(struct platform_device *pdev) struct net_device *dev; struct smsc911x_data *pdata; struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev); - struct resource *res, *irq_res; + struct resource *res; unsigned int intcfg = 0; - int res_size, irq_flags; + int res_size, irq, irq_flags; int retval; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -2434,8 +2434,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev) } res_size = resource_size(res); - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) { + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { pr_warn("Could not allocate irq resource\n"); retval = -ENODEV; goto out_0; @@ -2455,8 +2455,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev) SET_NETDEV_DEV(dev, &pdev->dev); pdata = netdev_priv(dev); - dev->irq = irq_res->start; - irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; + dev->irq = irq; + irq_flags = irq_get_trigger_type(irq); pdata->ioaddr = ioremap_nocache(res->start, res_size); pdata->dev = dev; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 2ac9552d1fa3..73bab983edd9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -117,6 +117,12 @@ struct stmmac_priv { int use_riwt; int irq_wake; spinlock_t ptp_lock; + +#ifdef CONFIG_DEBUG_FS + struct dentry *dbgfs_dir; + struct dentry *dbgfs_rings_status; + struct dentry *dbgfs_dma_cap; +#endif }; int stmmac_mdio_unregister(struct net_device *ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 05c146f718a3..2c5ce2baca87 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -118,7 +118,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id); #ifdef CONFIG_DEBUG_FS static int stmmac_init_fs(struct net_device *dev); -static void stmmac_exit_fs(void); +static void stmmac_exit_fs(struct net_device *dev); #endif #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) @@ -1916,7 +1916,7 @@ static int stmmac_release(struct net_device *dev) netif_carrier_off(dev); #ifdef CONFIG_DEBUG_FS - stmmac_exit_fs(); + stmmac_exit_fs(dev); #endif stmmac_release_ptp(priv); @@ -2508,8 +2508,6 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #ifdef CONFIG_DEBUG_FS static struct dentry *stmmac_fs_dir; -static struct dentry *stmmac_rings_status; -static struct dentry *stmmac_dma_cap; static void sysfs_display_ring(void *head, int size, int extend_desc, struct seq_file *seq) @@ -2648,36 +2646,39 @@ static const struct file_operations stmmac_dma_cap_fops = { static int stmmac_init_fs(struct net_device *dev) { - /* Create debugfs entries */ - stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); + struct stmmac_priv *priv = netdev_priv(dev); + + /* Create per netdev entries */ + priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir); - if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { - pr_err("ERROR %s, debugfs create directory failed\n", - STMMAC_RESOURCE_NAME); + if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) { + pr_err("ERROR %s/%s, debugfs create directory failed\n", + STMMAC_RESOURCE_NAME, dev->name); return -ENOMEM; } /* Entry to report DMA RX/TX rings */ - stmmac_rings_status = debugfs_create_file("descriptors_status", - S_IRUGO, stmmac_fs_dir, dev, - &stmmac_rings_status_fops); + priv->dbgfs_rings_status = + debugfs_create_file("descriptors_status", S_IRUGO, + priv->dbgfs_dir, dev, + &stmmac_rings_status_fops); - if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { + if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) { pr_info("ERROR creating stmmac ring debugfs file\n"); - debugfs_remove(stmmac_fs_dir); + debugfs_remove_recursive(priv->dbgfs_dir); return -ENOMEM; } /* Entry to report the DMA HW features */ - stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, - dev, &stmmac_dma_cap_fops); + priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, + priv->dbgfs_dir, + dev, &stmmac_dma_cap_fops); - if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { + if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) { pr_info("ERROR creating stmmac MMC debugfs file\n"); - debugfs_remove(stmmac_rings_status); - debugfs_remove(stmmac_fs_dir); + debugfs_remove_recursive(priv->dbgfs_dir); return -ENOMEM; } @@ -2685,11 +2686,11 @@ static int stmmac_init_fs(struct net_device *dev) return 0; } -static void stmmac_exit_fs(void) +static void stmmac_exit_fs(struct net_device *dev) { - debugfs_remove(stmmac_rings_status); - debugfs_remove(stmmac_dma_cap); - debugfs_remove(stmmac_fs_dir); + struct stmmac_priv *priv = netdev_priv(dev); + + debugfs_remove_recursive(priv->dbgfs_dir); } #endif /* CONFIG_DEBUG_FS */ @@ -3149,6 +3150,35 @@ err: __setup("stmmaceth=", stmmac_cmdline_opt); #endif /* MODULE */ +static int __init stmmac_init(void) +{ +#ifdef CONFIG_DEBUG_FS + /* Create debugfs main directory if it doesn't exist yet */ + if (!stmmac_fs_dir) { + stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); + + if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { + pr_err("ERROR %s, debugfs create directory failed\n", + STMMAC_RESOURCE_NAME); + + return -ENOMEM; + } + } +#endif + + return 0; +} + +static void __exit stmmac_exit(void) +{ +#ifdef CONFIG_DEBUG_FS + debugfs_remove_recursive(stmmac_fs_dir); +#endif +} + +module_init(stmmac_init) +module_exit(stmmac_exit) + MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 705bbdf93940..68aec5c460db 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -23,6 +23,7 @@ *******************************************************************************/ #include <linux/platform_device.h> +#include <linux/module.h> #include <linux/io.h> #include <linux/of.h> #include <linux/of_net.h> diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 690a4c36b316..af2694dc6f90 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -707,8 +707,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->app0 |= STS_CTRL_APP0_SOP; cur_p->len = skb_headlen(skb); - cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, - DMA_TO_DEVICE); + cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); cur_p->app4 = (unsigned long)skb; for (ii = 0; ii < num_frag; ii++) { diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 2d9ef533cc48..ea091bc5ff09 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -826,7 +826,6 @@ int netvsc_send(struct hv_device *device, u16 q_idx = packet->q_idx; u32 pktlen = packet->total_data_buflen, msd_len = 0; unsigned int section_index = NETVSC_INVALID_INDEX; - struct sk_buff *skb = NULL; unsigned long flag; struct multi_send_data *msdp; struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; @@ -924,12 +923,8 @@ int netvsc_send(struct hv_device *device, if (cur_send) ret = netvsc_send_pkt(cur_send, net_device); - if (ret != 0) { - if (section_index != NETVSC_INVALID_INDEX) - netvsc_free_send_slot(net_device, section_index); - } else if (skb) { - dev_kfree_skb_any(skb); - } + if (ret != 0 && section_index != NETVSC_INVALID_INDEX) + netvsc_free_send_slot(net_device, section_index); return ret; } diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 38026650c038..67d00fbc2e0e 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -85,6 +85,7 @@ struct at86rf230_local { struct ieee802154_hw *hw; struct at86rf2xx_chip_data *data; struct regmap *regmap; + int slp_tr; struct completion state_complete; struct at86rf230_state_change state; @@ -95,163 +96,164 @@ struct at86rf230_local { unsigned long cal_timeout; s8 max_frame_retries; bool is_tx; + bool is_tx_from_off; u8 tx_retry; struct sk_buff *tx_skb; struct at86rf230_state_change tx; }; -#define RG_TRX_STATUS (0x01) -#define SR_TRX_STATUS 0x01, 0x1f, 0 -#define SR_RESERVED_01_3 0x01, 0x20, 5 -#define SR_CCA_STATUS 0x01, 0x40, 6 -#define SR_CCA_DONE 0x01, 0x80, 7 -#define RG_TRX_STATE (0x02) -#define SR_TRX_CMD 0x02, 0x1f, 0 -#define SR_TRAC_STATUS 0x02, 0xe0, 5 -#define RG_TRX_CTRL_0 (0x03) -#define SR_CLKM_CTRL 0x03, 0x07, 0 -#define SR_CLKM_SHA_SEL 0x03, 0x08, 3 -#define SR_PAD_IO_CLKM 0x03, 0x30, 4 -#define SR_PAD_IO 0x03, 0xc0, 6 -#define RG_TRX_CTRL_1 (0x04) -#define SR_IRQ_POLARITY 0x04, 0x01, 0 -#define SR_IRQ_MASK_MODE 0x04, 0x02, 1 -#define SR_SPI_CMD_MODE 0x04, 0x0c, 2 -#define SR_RX_BL_CTRL 0x04, 0x10, 4 -#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5 -#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6 -#define SR_PA_EXT_EN 0x04, 0x80, 7 -#define RG_PHY_TX_PWR (0x05) -#define SR_TX_PWR 0x05, 0x0f, 0 -#define SR_PA_LT 0x05, 0x30, 4 -#define SR_PA_BUF_LT 0x05, 0xc0, 6 -#define RG_PHY_RSSI (0x06) -#define SR_RSSI 0x06, 0x1f, 0 -#define SR_RND_VALUE 0x06, 0x60, 5 -#define SR_RX_CRC_VALID 0x06, 0x80, 7 -#define RG_PHY_ED_LEVEL (0x07) -#define SR_ED_LEVEL 0x07, 0xff, 0 -#define RG_PHY_CC_CCA (0x08) -#define SR_CHANNEL 0x08, 0x1f, 0 -#define SR_CCA_MODE 0x08, 0x60, 5 -#define SR_CCA_REQUEST 0x08, 0x80, 7 -#define RG_CCA_THRES (0x09) -#define SR_CCA_ED_THRES 0x09, 0x0f, 0 -#define SR_RESERVED_09_1 0x09, 0xf0, 4 -#define RG_RX_CTRL (0x0a) -#define SR_PDT_THRES 0x0a, 0x0f, 0 -#define SR_RESERVED_0a_1 0x0a, 0xf0, 4 -#define RG_SFD_VALUE (0x0b) -#define SR_SFD_VALUE 0x0b, 0xff, 0 -#define RG_TRX_CTRL_2 (0x0c) -#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0 -#define SR_SUB_MODE 0x0c, 0x04, 2 -#define SR_BPSK_QPSK 0x0c, 0x08, 3 -#define SR_OQPSK_SUB1_RC_EN 0x0c, 0x10, 4 -#define SR_RESERVED_0c_5 0x0c, 0x60, 5 -#define SR_RX_SAFE_MODE 0x0c, 0x80, 7 -#define RG_ANT_DIV (0x0d) -#define SR_ANT_CTRL 0x0d, 0x03, 0 -#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2 -#define SR_ANT_DIV_EN 0x0d, 0x08, 3 -#define SR_RESERVED_0d_2 0x0d, 0x70, 4 -#define SR_ANT_SEL 0x0d, 0x80, 7 -#define RG_IRQ_MASK (0x0e) -#define SR_IRQ_MASK 0x0e, 0xff, 0 -#define RG_IRQ_STATUS (0x0f) -#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 -#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 -#define SR_IRQ_2_RX_START 0x0f, 0x04, 2 -#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 -#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4 -#define SR_IRQ_5_AMI 0x0f, 0x20, 5 -#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 -#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 -#define RG_VREG_CTRL (0x10) -#define SR_RESERVED_10_6 0x10, 0x03, 0 -#define SR_DVDD_OK 0x10, 0x04, 2 -#define SR_DVREG_EXT 0x10, 0x08, 3 -#define SR_RESERVED_10_3 0x10, 0x30, 4 -#define SR_AVDD_OK 0x10, 0x40, 6 -#define SR_AVREG_EXT 0x10, 0x80, 7 -#define RG_BATMON (0x11) -#define SR_BATMON_VTH 0x11, 0x0f, 0 -#define SR_BATMON_HR 0x11, 0x10, 4 -#define SR_BATMON_OK 0x11, 0x20, 5 -#define SR_RESERVED_11_1 0x11, 0xc0, 6 -#define RG_XOSC_CTRL (0x12) -#define SR_XTAL_TRIM 0x12, 0x0f, 0 -#define SR_XTAL_MODE 0x12, 0xf0, 4 -#define RG_RX_SYN (0x15) -#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0 -#define SR_RESERVED_15_2 0x15, 0x70, 4 -#define SR_RX_PDT_DIS 0x15, 0x80, 7 -#define RG_XAH_CTRL_1 (0x17) -#define SR_RESERVED_17_8 0x17, 0x01, 0 -#define SR_AACK_PROM_MODE 0x17, 0x02, 1 -#define SR_AACK_ACK_TIME 0x17, 0x04, 2 -#define SR_RESERVED_17_5 0x17, 0x08, 3 -#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4 -#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5 -#define SR_CSMA_LBT_MODE 0x17, 0x40, 6 -#define SR_RESERVED_17_1 0x17, 0x80, 7 -#define RG_FTN_CTRL (0x18) -#define SR_RESERVED_18_2 0x18, 0x7f, 0 -#define SR_FTN_START 0x18, 0x80, 7 -#define RG_PLL_CF (0x1a) -#define SR_RESERVED_1a_2 0x1a, 0x7f, 0 -#define SR_PLL_CF_START 0x1a, 0x80, 7 -#define RG_PLL_DCU (0x1b) -#define SR_RESERVED_1b_3 0x1b, 0x3f, 0 -#define SR_RESERVED_1b_2 0x1b, 0x40, 6 -#define SR_PLL_DCU_START 0x1b, 0x80, 7 -#define RG_PART_NUM (0x1c) -#define SR_PART_NUM 0x1c, 0xff, 0 -#define RG_VERSION_NUM (0x1d) -#define SR_VERSION_NUM 0x1d, 0xff, 0 -#define RG_MAN_ID_0 (0x1e) -#define SR_MAN_ID_0 0x1e, 0xff, 0 -#define RG_MAN_ID_1 (0x1f) -#define SR_MAN_ID_1 0x1f, 0xff, 0 -#define RG_SHORT_ADDR_0 (0x20) -#define SR_SHORT_ADDR_0 0x20, 0xff, 0 -#define RG_SHORT_ADDR_1 (0x21) -#define SR_SHORT_ADDR_1 0x21, 0xff, 0 -#define RG_PAN_ID_0 (0x22) -#define SR_PAN_ID_0 0x22, 0xff, 0 -#define RG_PAN_ID_1 (0x23) -#define SR_PAN_ID_1 0x23, 0xff, 0 -#define RG_IEEE_ADDR_0 (0x24) -#define SR_IEEE_ADDR_0 0x24, 0xff, 0 -#define RG_IEEE_ADDR_1 (0x25) -#define SR_IEEE_ADDR_1 0x25, 0xff, 0 -#define RG_IEEE_ADDR_2 (0x26) -#define SR_IEEE_ADDR_2 0x26, 0xff, 0 -#define RG_IEEE_ADDR_3 (0x27) -#define SR_IEEE_ADDR_3 0x27, 0xff, 0 -#define RG_IEEE_ADDR_4 (0x28) -#define SR_IEEE_ADDR_4 0x28, 0xff, 0 -#define RG_IEEE_ADDR_5 (0x29) -#define SR_IEEE_ADDR_5 0x29, 0xff, 0 -#define RG_IEEE_ADDR_6 (0x2a) -#define SR_IEEE_ADDR_6 0x2a, 0xff, 0 -#define RG_IEEE_ADDR_7 (0x2b) -#define SR_IEEE_ADDR_7 0x2b, 0xff, 0 -#define RG_XAH_CTRL_0 (0x2c) -#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0 -#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 -#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 -#define RG_CSMA_SEED_0 (0x2d) -#define SR_CSMA_SEED_0 0x2d, 0xff, 0 -#define RG_CSMA_SEED_1 (0x2e) -#define SR_CSMA_SEED_1 0x2e, 0x07, 0 -#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3 -#define SR_AACK_DIS_ACK 0x2e, 0x10, 4 -#define SR_AACK_SET_PD 0x2e, 0x20, 5 -#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6 -#define RG_CSMA_BE (0x2f) -#define SR_MIN_BE 0x2f, 0x0f, 0 -#define SR_MAX_BE 0x2f, 0xf0, 4 +#define RG_TRX_STATUS (0x01) +#define SR_TRX_STATUS 0x01, 0x1f, 0 +#define SR_RESERVED_01_3 0x01, 0x20, 5 +#define SR_CCA_STATUS 0x01, 0x40, 6 +#define SR_CCA_DONE 0x01, 0x80, 7 +#define RG_TRX_STATE (0x02) +#define SR_TRX_CMD 0x02, 0x1f, 0 +#define SR_TRAC_STATUS 0x02, 0xe0, 5 +#define RG_TRX_CTRL_0 (0x03) +#define SR_CLKM_CTRL 0x03, 0x07, 0 +#define SR_CLKM_SHA_SEL 0x03, 0x08, 3 +#define SR_PAD_IO_CLKM 0x03, 0x30, 4 +#define SR_PAD_IO 0x03, 0xc0, 6 +#define RG_TRX_CTRL_1 (0x04) +#define SR_IRQ_POLARITY 0x04, 0x01, 0 +#define SR_IRQ_MASK_MODE 0x04, 0x02, 1 +#define SR_SPI_CMD_MODE 0x04, 0x0c, 2 +#define SR_RX_BL_CTRL 0x04, 0x10, 4 +#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5 +#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6 +#define SR_PA_EXT_EN 0x04, 0x80, 7 +#define RG_PHY_TX_PWR (0x05) +#define SR_TX_PWR 0x05, 0x0f, 0 +#define SR_PA_LT 0x05, 0x30, 4 +#define SR_PA_BUF_LT 0x05, 0xc0, 6 +#define RG_PHY_RSSI (0x06) +#define SR_RSSI 0x06, 0x1f, 0 +#define SR_RND_VALUE 0x06, 0x60, 5 +#define SR_RX_CRC_VALID 0x06, 0x80, 7 +#define RG_PHY_ED_LEVEL (0x07) +#define SR_ED_LEVEL 0x07, 0xff, 0 +#define RG_PHY_CC_CCA (0x08) +#define SR_CHANNEL 0x08, 0x1f, 0 +#define SR_CCA_MODE 0x08, 0x60, 5 +#define SR_CCA_REQUEST 0x08, 0x80, 7 +#define RG_CCA_THRES (0x09) +#define SR_CCA_ED_THRES 0x09, 0x0f, 0 +#define SR_RESERVED_09_1 0x09, 0xf0, 4 +#define RG_RX_CTRL (0x0a) +#define SR_PDT_THRES 0x0a, 0x0f, 0 +#define SR_RESERVED_0a_1 0x0a, 0xf0, 4 +#define RG_SFD_VALUE (0x0b) +#define SR_SFD_VALUE 0x0b, 0xff, 0 +#define RG_TRX_CTRL_2 (0x0c) +#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0 +#define SR_SUB_MODE 0x0c, 0x04, 2 +#define SR_BPSK_QPSK 0x0c, 0x08, 3 +#define SR_OQPSK_SUB1_RC_EN 0x0c, 0x10, 4 +#define SR_RESERVED_0c_5 0x0c, 0x60, 5 +#define SR_RX_SAFE_MODE 0x0c, 0x80, 7 +#define RG_ANT_DIV (0x0d) +#define SR_ANT_CTRL 0x0d, 0x03, 0 +#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2 +#define SR_ANT_DIV_EN 0x0d, 0x08, 3 +#define SR_RESERVED_0d_2 0x0d, 0x70, 4 +#define SR_ANT_SEL 0x0d, 0x80, 7 +#define RG_IRQ_MASK (0x0e) +#define SR_IRQ_MASK 0x0e, 0xff, 0 +#define RG_IRQ_STATUS (0x0f) +#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 +#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 +#define SR_IRQ_2_RX_START 0x0f, 0x04, 2 +#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 +#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4 +#define SR_IRQ_5_AMI 0x0f, 0x20, 5 +#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 +#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 +#define RG_VREG_CTRL (0x10) +#define SR_RESERVED_10_6 0x10, 0x03, 0 +#define SR_DVDD_OK 0x10, 0x04, 2 +#define SR_DVREG_EXT 0x10, 0x08, 3 +#define SR_RESERVED_10_3 0x10, 0x30, 4 +#define SR_AVDD_OK 0x10, 0x40, 6 +#define SR_AVREG_EXT 0x10, 0x80, 7 +#define RG_BATMON (0x11) +#define SR_BATMON_VTH 0x11, 0x0f, 0 +#define SR_BATMON_HR 0x11, 0x10, 4 +#define SR_BATMON_OK 0x11, 0x20, 5 +#define SR_RESERVED_11_1 0x11, 0xc0, 6 +#define RG_XOSC_CTRL (0x12) +#define SR_XTAL_TRIM 0x12, 0x0f, 0 +#define SR_XTAL_MODE 0x12, 0xf0, 4 +#define RG_RX_SYN (0x15) +#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0 +#define SR_RESERVED_15_2 0x15, 0x70, 4 +#define SR_RX_PDT_DIS 0x15, 0x80, 7 +#define RG_XAH_CTRL_1 (0x17) +#define SR_RESERVED_17_8 0x17, 0x01, 0 +#define SR_AACK_PROM_MODE 0x17, 0x02, 1 +#define SR_AACK_ACK_TIME 0x17, 0x04, 2 +#define SR_RESERVED_17_5 0x17, 0x08, 3 +#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4 +#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5 +#define SR_CSMA_LBT_MODE 0x17, 0x40, 6 +#define SR_RESERVED_17_1 0x17, 0x80, 7 +#define RG_FTN_CTRL (0x18) +#define SR_RESERVED_18_2 0x18, 0x7f, 0 +#define SR_FTN_START 0x18, 0x80, 7 +#define RG_PLL_CF (0x1a) +#define SR_RESERVED_1a_2 0x1a, 0x7f, 0 +#define SR_PLL_CF_START 0x1a, 0x80, 7 +#define RG_PLL_DCU (0x1b) +#define SR_RESERVED_1b_3 0x1b, 0x3f, 0 +#define SR_RESERVED_1b_2 0x1b, 0x40, 6 +#define SR_PLL_DCU_START 0x1b, 0x80, 7 +#define RG_PART_NUM (0x1c) +#define SR_PART_NUM 0x1c, 0xff, 0 +#define RG_VERSION_NUM (0x1d) +#define SR_VERSION_NUM 0x1d, 0xff, 0 +#define RG_MAN_ID_0 (0x1e) +#define SR_MAN_ID_0 0x1e, 0xff, 0 +#define RG_MAN_ID_1 (0x1f) +#define SR_MAN_ID_1 0x1f, 0xff, 0 +#define RG_SHORT_ADDR_0 (0x20) +#define SR_SHORT_ADDR_0 0x20, 0xff, 0 +#define RG_SHORT_ADDR_1 (0x21) +#define SR_SHORT_ADDR_1 0x21, 0xff, 0 +#define RG_PAN_ID_0 (0x22) +#define SR_PAN_ID_0 0x22, 0xff, 0 +#define RG_PAN_ID_1 (0x23) +#define SR_PAN_ID_1 0x23, 0xff, 0 +#define RG_IEEE_ADDR_0 (0x24) +#define SR_IEEE_ADDR_0 0x24, 0xff, 0 +#define RG_IEEE_ADDR_1 (0x25) +#define SR_IEEE_ADDR_1 0x25, 0xff, 0 +#define RG_IEEE_ADDR_2 (0x26) +#define SR_IEEE_ADDR_2 0x26, 0xff, 0 +#define RG_IEEE_ADDR_3 (0x27) +#define SR_IEEE_ADDR_3 0x27, 0xff, 0 +#define RG_IEEE_ADDR_4 (0x28) +#define SR_IEEE_ADDR_4 0x28, 0xff, 0 +#define RG_IEEE_ADDR_5 (0x29) +#define SR_IEEE_ADDR_5 0x29, 0xff, 0 +#define RG_IEEE_ADDR_6 (0x2a) +#define SR_IEEE_ADDR_6 0x2a, 0xff, 0 +#define RG_IEEE_ADDR_7 (0x2b) +#define SR_IEEE_ADDR_7 0x2b, 0xff, 0 +#define RG_XAH_CTRL_0 (0x2c) +#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0 +#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 +#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 +#define RG_CSMA_SEED_0 (0x2d) +#define SR_CSMA_SEED_0 0x2d, 0xff, 0 +#define RG_CSMA_SEED_1 (0x2e) +#define SR_CSMA_SEED_1 0x2e, 0x07, 0 +#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3 +#define SR_AACK_DIS_ACK 0x2e, 0x10, 4 +#define SR_AACK_SET_PD 0x2e, 0x20, 5 +#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6 +#define RG_CSMA_BE (0x2f) +#define SR_MIN_BE 0x2f, 0x0f, 0 +#define SR_MAX_BE 0x2f, 0xf0, 4 #define CMD_REG 0x80 #define CMD_REG_MASK 0x3f @@ -292,6 +294,8 @@ struct at86rf230_local { #define STATE_BUSY_RX_AACK_NOCLK 0x1E #define STATE_TRANSITION_IN_PROGRESS 0x1F +#define TRX_STATE_MASK (0x1F) + #define AT86RF2XX_NUMREGS 0x3F static void @@ -336,6 +340,14 @@ at86rf230_write_subreg(struct at86rf230_local *lp, return regmap_update_bits(lp->regmap, addr, mask, data << shift); } +static inline void +at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp) +{ + gpio_set_value(lp->slp_tr, 1); + udelay(1); + gpio_set_value(lp->slp_tr, 0); +} + static bool at86rf230_reg_writeable(struct device *dev, unsigned int reg) { @@ -509,7 +521,7 @@ at86rf230_async_state_assert(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; const u8 *buf = ctx->buf; - const u8 trx_state = buf[1] & 0x1f; + const u8 trx_state = buf[1] & TRX_STATE_MASK; /* Assert state change */ if (trx_state != ctx->to_state) { @@ -609,11 +621,17 @@ at86rf230_async_state_delay(void *context) switch (ctx->to_state) { case STATE_RX_AACK_ON: tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC); + /* state change from TRX_OFF to RX_AACK_ON to do a + * calibration, we need to reset the timeout for the + * next one. + */ + lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; goto change; + case STATE_TX_ARET_ON: case STATE_TX_ON: tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC); - /* state change from TRX_OFF to TX_ON to do a - * calibration, we need to reset the timeout for the + /* state change from TRX_OFF to TX_ON or ARET_ON to do + * a calibration, we need to reset the timeout for the * next one. */ lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; @@ -667,7 +685,7 @@ at86rf230_async_state_change_start(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; u8 *buf = ctx->buf; - const u8 trx_state = buf[1] & 0x1f; + const u8 trx_state = buf[1] & TRX_STATE_MASK; int rc; /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ @@ -773,16 +791,6 @@ at86rf230_tx_on(void *context) } static void -at86rf230_tx_trac_error(void *context) -{ - struct at86rf230_state_change *ctx = context; - struct at86rf230_local *lp = ctx->lp; - - at86rf230_async_state_change(lp, ctx, STATE_TX_ON, - at86rf230_tx_on, true); -} - -static void at86rf230_tx_trac_check(void *context) { struct at86rf230_state_change *ctx = context; @@ -791,12 +799,12 @@ at86rf230_tx_trac_check(void *context) const u8 trac = (buf[1] & 0xe0) >> 5; /* If trac status is different than zero we need to do a state change - * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver - * state to TX_ON. + * to STATE_FORCE_TRX_OFF then STATE_RX_AACK_ON to recover the + * transceiver. */ if (trac) at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, - at86rf230_tx_trac_error, true); + at86rf230_tx_on, true); else at86rf230_tx_on(context); } @@ -941,13 +949,18 @@ at86rf230_write_frame_complete(void *context) u8 *buf = ctx->buf; int rc; - buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE; - buf[1] = STATE_BUSY_TX; ctx->trx.len = 2; - ctx->msg.complete = NULL; - rc = spi_async(lp->spi, &ctx->msg); - if (rc) - at86rf230_async_error(lp, ctx, rc); + + if (gpio_is_valid(lp->slp_tr)) { + at86rf230_slp_tr_rising_edge(lp); + } else { + buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE; + buf[1] = STATE_BUSY_TX; + ctx->msg.complete = NULL; + rc = spi_async(lp->spi, &ctx->msg); + if (rc) + at86rf230_async_error(lp, ctx, rc); + } } static void @@ -993,12 +1006,21 @@ at86rf230_xmit_start(void *context) * are in STATE_TX_ON. The pfad differs here, so we change * the complete handler. */ - if (lp->tx_aret) - at86rf230_async_state_change(lp, ctx, STATE_TX_ON, - at86rf230_xmit_tx_on, false); - else + if (lp->tx_aret) { + if (lp->is_tx_from_off) { + lp->is_tx_from_off = false; + at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, + at86rf230_xmit_tx_on, + false); + } else { + at86rf230_async_state_change(lp, ctx, STATE_TX_ON, + at86rf230_xmit_tx_on, + false); + } + } else { at86rf230_async_state_change(lp, ctx, STATE_TX_ON, at86rf230_write_frame, false); + } } static int @@ -1017,11 +1039,13 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) * to TX_ON, the lp->cal_timeout should be reinit by state_delay * function then to start in the next 5 minutes. */ - if (time_is_before_jiffies(lp->cal_timeout)) + if (time_is_before_jiffies(lp->cal_timeout)) { + lp->is_tx_from_off = true; at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF, at86rf230_xmit_start, false); - else + } else { at86rf230_xmit_start(ctx); + } return 0; } @@ -1037,9 +1061,6 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level) static int at86rf230_start(struct ieee802154_hw *hw) { - struct at86rf230_local *lp = hw->priv; - - lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); } @@ -1673,6 +1694,7 @@ static int at86rf230_probe(struct spi_device *spi) lp = hw->priv; lp->hw = hw; lp->spi = spi; + lp->slp_tr = slp_tr; hw->parent = &spi->dev; hw->vif_data_size = sizeof(*lp); ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index b227a13f6473..9f59f17dc317 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -599,10 +599,18 @@ static int macvlan_open(struct net_device *dev) goto del_unicast; } + if (dev->flags & IFF_PROMISC) { + err = dev_set_promiscuity(lowerdev, 1); + if (err < 0) + goto clear_multi; + } + hash_add: macvlan_hash_add(vlan); return 0; +clear_multi: + dev_set_allmulti(lowerdev, -1); del_unicast: dev_uc_del(lowerdev, dev->dev_addr); out: @@ -638,6 +646,9 @@ static int macvlan_stop(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(lowerdev, -1); + if (dev->flags & IFF_PROMISC) + dev_set_promiscuity(lowerdev, -1); + dev_uc_del(lowerdev, dev->dev_addr); hash_del: @@ -696,6 +707,10 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change) if (dev->flags & IFF_UP) { if (change & IFF_ALLMULTI) dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); + if (change & IFF_PROMISC) + dev_set_promiscuity(lowerdev, + dev->flags & IFF_PROMISC ? 1 : -1); + } } diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 8fadaa14b9f0..70641d2c0429 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -27,6 +27,7 @@ config AMD_PHY config AMD_XGBE_PHY tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs" depends on (OF || ACPI) && HAS_IOMEM + depends on ARM64 || COMPILE_TEST ---help--- Currently supports the AMD 10GbE PHY diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c index fb276f64cd64..34a75cba3b73 100644 --- a/drivers/net/phy/amd-xgbe-phy.c +++ b/drivers/net/phy/amd-xgbe-phy.c @@ -755,6 +755,45 @@ static int amd_xgbe_phy_set_mode(struct phy_device *phydev, return ret; } +static bool amd_xgbe_phy_use_xgmii_mode(struct phy_device *phydev) +{ + if (phydev->autoneg == AUTONEG_ENABLE) { + if (phydev->advertising & ADVERTISED_10000baseKR_Full) + return true; + } else { + if (phydev->speed == SPEED_10000) + return true; + } + + return false; +} + +static bool amd_xgbe_phy_use_gmii_2500_mode(struct phy_device *phydev) +{ + if (phydev->autoneg == AUTONEG_ENABLE) { + if (phydev->advertising & ADVERTISED_2500baseX_Full) + return true; + } else { + if (phydev->speed == SPEED_2500) + return true; + } + + return false; +} + +static bool amd_xgbe_phy_use_gmii_mode(struct phy_device *phydev) +{ + if (phydev->autoneg == AUTONEG_ENABLE) { + if (phydev->advertising & ADVERTISED_1000baseKX_Full) + return true; + } else { + if (phydev->speed == SPEED_1000) + return true; + } + + return false; +} + static int amd_xgbe_phy_set_an(struct phy_device *phydev, bool enable, bool restart) { @@ -1235,11 +1274,11 @@ static int amd_xgbe_phy_config_init(struct phy_device *phydev) /* Set initial mode - call the mode setting routines * directly to insure we are properly configured */ - if (phydev->advertising & SUPPORTED_10000baseKR_Full) + if (amd_xgbe_phy_use_xgmii_mode(phydev)) ret = amd_xgbe_phy_xgmii_mode(phydev); - else if (phydev->advertising & SUPPORTED_1000baseKX_Full) + else if (amd_xgbe_phy_use_gmii_mode(phydev)) ret = amd_xgbe_phy_gmii_mode(phydev); - else if (phydev->advertising & SUPPORTED_2500baseX_Full) + else if (amd_xgbe_phy_use_gmii_2500_mode(phydev)) ret = amd_xgbe_phy_gmii_2500_mode(phydev); else ret = -EINVAL; diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 64c74c6a4828..b5dc59de094e 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -404,7 +404,7 @@ static struct phy_driver bcm7xxx_driver[] = { .name = "Broadcom BCM7425", .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = 0, + .flags = PHY_IS_INTERNAL, .config_init = bcm7xxx_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 496e02f961d3..00cb41e71312 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -47,7 +47,7 @@ #define PSF_TX 0x1000 #define EXT_EVENT 1 #define CAL_EVENT 7 -#define CAL_TRIGGER 7 +#define CAL_TRIGGER 1 #define DP83640_N_PINS 12 #define MII_DP83640_MICR 0x11 @@ -496,7 +496,9 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, else evnt |= EVNT_RISE; } + mutex_lock(&clock->extreg_lock); ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); + mutex_unlock(&clock->extreg_lock); return 0; case PTP_CLK_REQ_PEROUT: @@ -532,6 +534,8 @@ static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F }; static void enable_status_frames(struct phy_device *phydev, bool on) { + struct dp83640_private *dp83640 = phydev->priv; + struct dp83640_clock *clock = dp83640->clock; u16 cfg0 = 0, ver; if (on) @@ -539,9 +543,13 @@ static void enable_status_frames(struct phy_device *phydev, bool on) ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT; + mutex_lock(&clock->extreg_lock); + ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0); ext_write(0, phydev, PAGE6, PSF_CFG1, ver); + mutex_unlock(&clock->extreg_lock); + if (!phydev->attached_dev) { pr_warn("expected to find an attached netdevice\n"); return; @@ -838,7 +846,7 @@ static void decode_rxts(struct dp83640_private *dp83640, list_del_init(&rxts->list); phy2rxts(phy_rxts, rxts); - spin_lock_irqsave(&dp83640->rx_queue.lock, flags); + spin_lock(&dp83640->rx_queue.lock); skb_queue_walk(&dp83640->rx_queue, skb) { struct dp83640_skb_info *skb_info; @@ -853,7 +861,7 @@ static void decode_rxts(struct dp83640_private *dp83640, break; } } - spin_unlock_irqrestore(&dp83640->rx_queue.lock, flags); + spin_unlock(&dp83640->rx_queue.lock); if (!shhwtstamps) list_add_tail(&rxts->list, &dp83640->rxts); @@ -1173,11 +1181,18 @@ static int dp83640_config_init(struct phy_device *phydev) if (clock->chosen && !list_empty(&clock->phylist)) recalibrate(clock); - else + else { + mutex_lock(&clock->extreg_lock); enable_broadcast(phydev, clock->page, 1); + mutex_unlock(&clock->extreg_lock); + } enable_status_frames(phydev, true); + + mutex_lock(&clock->extreg_lock); ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); + mutex_unlock(&clock->extreg_lock); + return 0; } diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index c9cb486c753d..53d18150f4e2 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -168,7 +168,10 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, if (!new_bus->irq[i]) new_bus->irq[i] = PHY_POLL; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); + if (bus_id != -1) + snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); + else + strncpy(new_bus->id, "gpio", MII_BUS_ID_SIZE); if (devm_gpio_request(dev, bitbang->mdc, "mdc")) goto out_free_bus; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 1190fd8f0088..ebdc357c5131 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -548,7 +548,8 @@ static int kszphy_probe(struct phy_device *phydev) } clk = devm_clk_get(&phydev->dev, "rmii-ref"); - if (!IS_ERR(clk)) { + /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */ + if (!IS_ERR_OR_NULL(clk)) { unsigned long rate = clk_get_rate(clk); bool rmii_ref_clk_sel_25_mhz; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 52cd8db2c57d..47cd578052fc 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -742,6 +742,9 @@ EXPORT_SYMBOL(phy_stop); */ void phy_start(struct phy_device *phydev) { + bool do_resume = false; + int err = 0; + mutex_lock(&phydev->lock); switch (phydev->state) { @@ -752,11 +755,22 @@ void phy_start(struct phy_device *phydev) phydev->state = PHY_UP; break; case PHY_HALTED: + /* make sure interrupts are re-enabled for the PHY */ + err = phy_enable_interrupts(phydev); + if (err < 0) + break; + phydev->state = PHY_RESUMING; + do_resume = true; + break; default: break; } mutex_unlock(&phydev->lock); + + /* if phy was suspended, bring the physical link up again */ + if (do_resume) + phy_resume(phydev); } EXPORT_SYMBOL(phy_start); @@ -769,7 +783,7 @@ void phy_state_machine(struct work_struct *work) struct delayed_work *dwork = to_delayed_work(work); struct phy_device *phydev = container_of(dwork, struct phy_device, state_queue); - bool needs_aneg = false, do_suspend = false, do_resume = false; + bool needs_aneg = false, do_suspend = false; int err = 0; mutex_lock(&phydev->lock); @@ -888,14 +902,6 @@ void phy_state_machine(struct work_struct *work) } break; case PHY_RESUMING: - err = phy_clear_interrupt(phydev); - if (err) - break; - - err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); - if (err) - break; - if (AUTONEG_ENABLE == phydev->autoneg) { err = phy_aneg_done(phydev); if (err < 0) @@ -933,7 +939,6 @@ void phy_state_machine(struct work_struct *work) } phydev->adjust_link(phydev->attached_dev); } - do_resume = true; break; } @@ -943,8 +948,6 @@ void phy_state_machine(struct work_struct *work) err = phy_start_aneg(phydev); else if (do_suspend) phy_suspend(phydev); - else if (do_resume) - phy_resume(phydev); if (err < 0) phy_error(phydev); @@ -1053,13 +1056,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) { /* According to 802.3az,the EEE is supported only in full duplex-mode. * Also EEE feature is active when core is operating with MII, GMII - * or RGMII. Internal PHYs are also allowed to proceed and should - * return an error if they do not support EEE. + * or RGMII (all kinds). Internal PHYs are also allowed to proceed and + * should return an error if they do not support EEE. */ if ((phydev->duplex == DUPLEX_FULL) && ((phydev->interface == PHY_INTERFACE_MODE_MII) || (phydev->interface == PHY_INTERFACE_MODE_GMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII) || + (phydev->interface >= PHY_INTERFACE_MODE_RGMII && + phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID) || phy_is_internal(phydev))) { int eee_lp, eee_cap, eee_adv; u32 lp, cap, adv; diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index aa1dd926623a..b62a5e3a1c65 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -465,6 +465,10 @@ static void pppoe_unbind_sock_work(struct work_struct *work) struct sock *sk = sk_pppox(po); lock_sock(sk); + if (po->pppoe_dev) { + dev_put(po->pppoe_dev); + po->pppoe_dev = NULL; + } pppox_unbind_sock(sk); release_sock(sk); sock_put(sk); diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index c3e4da9e79ca..8067b8fbb0ee 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1182,7 +1182,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) * payload data instead. */ usbnet_set_skb_tx_stats(skb_out, n, - ctx->tx_curr_frame_payload - skb_out->len); + (long)ctx->tx_curr_frame_payload - skb_out->len); return skb_out; diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ac4d03b328b1..aafa1a1898e4 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -4116,6 +4116,7 @@ static struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, {} }; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 733f4feb2ef3..3c86b107275a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1285,7 +1285,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { struct usbnet *dev = netdev_priv(net); - int length; + unsigned int length; struct urb *urb = NULL; struct skb_data *entry; struct driver_info *info = dev->driver_info; @@ -1413,7 +1413,7 @@ not_drop: } } else netif_dbg(dev, tx_queued, dev->net, - "> tx, len %d, type 0x%x\n", length, skb->protocol); + "> tx, len %u, type 0x%x\n", length, skb->protocol); #ifdef CONFIG_PM deferred: #endif diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 27a5f954f8e9..21a0fbf1ed94 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2961,7 +2961,7 @@ static void __net_exit vxlan_exit_net(struct net *net) * to the list by the previous loop. */ if (!net_eq(dev_net(vxlan->dev), net)) - unregister_netdevice_queue(dev, &list); + unregister_netdevice_queue(vxlan->dev, &list); } unregister_netdevice_many(&list); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0acd079ba96b..3ad79bb4f2c2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1103,28 +1103,14 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, struct sk_buff *skb; struct ath_frame_info *fi; struct ieee80211_tx_info *info; - struct ieee80211_vif *vif; struct ath_hw *ah = sc->sc_ah; if (sc->tx99_state || !ah->tpc_enabled) return MAX_RATE_POWER; skb = bf->bf_mpdu; - info = IEEE80211_SKB_CB(skb); - vif = info->control.vif; - - if (!vif) { - max_power = sc->cur_chan->cur_txpower; - goto out; - } - - if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) { - max_power = min_t(u8, sc->cur_chan->cur_txpower, - 2 * vif->bss_conf.txpower); - goto out; - } - fi = get_frame_info(skb); + info = IEEE80211_SKB_CB(skb); if (!AR_SREV_9300_20_OR_LATER(ah)) { int txpower = fi->tx_power; @@ -1161,25 +1147,26 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, txpower -= 2; txpower = max(txpower, 0); - max_power = min_t(u8, ah->tx_power[rateidx], - 2 * vif->bss_conf.txpower); - max_power = min_t(u8, max_power, txpower); + max_power = min_t(u8, ah->tx_power[rateidx], txpower); + + /* XXX: clamp minimum TX power at 1 for AR9160 since if + * max_power is set to 0, frames are transmitted at max + * TX power + */ + if (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) + max_power = 1; } else if (!bf->bf_state.bfs_paprd) { if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) max_power = min_t(u8, ah->tx_power_stbc[rateidx], - 2 * vif->bss_conf.txpower); + fi->tx_power); else max_power = min_t(u8, ah->tx_power[rateidx], - 2 * vif->bss_conf.txpower); - max_power = min(max_power, fi->tx_power); + fi->tx_power); } else { max_power = ah->paprd_training_power; } -out: - /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power - * is set to 0, frames are transmitted at max TX power - */ - return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power; + + return max_power; } static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, @@ -2129,6 +2116,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct ath_node *an = NULL; enum ath9k_key_type keytype; bool short_preamble = false; + u8 txpower; /* * We check if Short Preamble is needed for the CTS rate by @@ -2145,6 +2133,16 @@ static void setup_frame_info(struct ieee80211_hw *hw, if (sta) an = (struct ath_node *) sta->drv_priv; + if (tx_info->control.vif) { + struct ieee80211_vif *vif = tx_info->control.vif; + + txpower = 2 * vif->bss_conf.txpower; + } else { + struct ath_softc *sc = hw->priv; + + txpower = sc->cur_chan->cur_txpower; + } + memset(fi, 0, sizeof(*fi)); fi->txq = -1; if (hw_key) @@ -2155,7 +2153,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; - fi->tx_power = MAX_RATE_POWER; + fi->tx_power = txpower; if (!rate) return; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 4ec9811f49c8..65efb1468988 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c @@ -511,11 +511,9 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, msgbuf->rx_pktids, msgbuf->ioctl_resp_pktid); if (msgbuf->ioctl_resp_ret_len != 0) { - if (!skb) { - brcmf_err("Invalid packet id idx recv'd %d\n", - msgbuf->ioctl_resp_pktid); + if (!skb) return -EBADF; - } + memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? len : msgbuf->ioctl_resp_ret_len); } @@ -874,10 +872,8 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, msgbuf->tx_pktids, idx); - if (!skb) { - brcmf_err("Invalid packet id idx recv'd %d\n", idx); + if (!skb) return; - } set_bit(flowid, msgbuf->txstatus_done_map); commonring = msgbuf->flowrings[flowid]; @@ -1156,6 +1152,8 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, msgbuf->rx_pktids, idx); + if (!skb) + return; if (data_offset) skb_pull(skb, data_offset); diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ab019b45551b..f89f446e5c8a 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -21,6 +21,7 @@ config IWLWIFI Intel 7260 Wi-Fi Adapter Intel 3160 Wi-Fi Adapter Intel 7265 Wi-Fi Adapter + Intel 3165 Wi-Fi Adapter This driver uses the kernel's mac80211 subsystem. diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 36e786f0387b..74ad278116be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -70,15 +70,14 @@ /* Highest firmware API version supported */ #define IWL7260_UCODE_API_MAX 13 -#define IWL3160_UCODE_API_MAX 13 /* Oldest version we won't warn about */ #define IWL7260_UCODE_API_OK 12 -#define IWL3160_UCODE_API_OK 12 +#define IWL3165_UCODE_API_OK 13 /* Lowest firmware API version supported */ #define IWL7260_UCODE_API_MIN 10 -#define IWL3160_UCODE_API_MIN 10 +#define IWL3165_UCODE_API_MIN 13 /* NVM versions */ #define IWL7260_NVM_VERSION 0x0a1d @@ -104,9 +103,6 @@ #define IWL3160_FW_PRE "iwlwifi-3160-" #define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" -#define IWL3165_FW_PRE "iwlwifi-3165-" -#define IWL3165_MODULE_FIRMWARE(api) IWL3165_FW_PRE __stringify(api) ".ucode" - #define IWL7265_FW_PRE "iwlwifi-7265-" #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" @@ -248,8 +244,13 @@ static const struct iwl_ht_params iwl7265_ht_params = { const struct iwl_cfg iwl3165_2ac_cfg = { .name = "Intel(R) Dual Band Wireless AC 3165", - .fw_name_pre = IWL3165_FW_PRE, + .fw_name_pre = IWL7265D_FW_PRE, IWL_DEVICE_7000, + /* sparse doens't like the re-assignment but it is safe */ +#ifndef __CHECKER__ + .ucode_api_ok = IWL3165_UCODE_API_OK, + .ucode_api_min = IWL3165_UCODE_API_MIN, +#endif .ht_params = &iwl7000_ht_params, .nvm_ver = IWL3165_NVM_VERSION, .nvm_calib_ver = IWL3165_TX_POWER_VERSION, @@ -325,6 +326,5 @@ const struct iwl_cfg iwl7265d_n_cfg = { MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); -MODULE_FIRMWARE(IWL3165_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 41ff85de7334..21302b6f2bfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -6,6 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,6 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -748,6 +750,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, return; } + if (data->sku_cap_mimo_disabled) + rx_chains = 1; + ht_info->ht_supported = true; ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index 5234a0bf11e4..750c8c9ee70d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h @@ -6,6 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,6 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,6 +86,7 @@ struct iwl_nvm_data { bool sku_cap_11ac_enable; bool sku_cap_amt_enable; bool sku_cap_ipan_enable; + bool sku_cap_mimo_disabled; u16 radio_cfg_type; u8 radio_cfg_step; diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index bfdf3faa6c47..62db2e5e45eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag { * longer than the passive one, which is essential for fragmented scan. * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source. * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR + * @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power. * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, * regardless of the band or the number of the probes. FW will calculate * the actual dwell time. @@ -260,6 +261,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = BIT(9), IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), + IWL_UCODE_TLV_API_TX_POWER_DEV = BIT(11), IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), IWL_UCODE_TLV_API_SCD_CFG = BIT(15), IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 83903a5025c2..8e604a3931ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -32,7 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -116,10 +116,11 @@ enum family_8000_nvm_offsets { /* SKU Capabilities (actual values from NVM definition) */ enum nvm_sku_bits { - NVM_SKU_CAP_BAND_24GHZ = BIT(0), - NVM_SKU_CAP_BAND_52GHZ = BIT(1), - NVM_SKU_CAP_11N_ENABLE = BIT(2), - NVM_SKU_CAP_11AC_ENABLE = BIT(3), + NVM_SKU_CAP_BAND_24GHZ = BIT(0), + NVM_SKU_CAP_BAND_52GHZ = BIT(1), + NVM_SKU_CAP_11N_ENABLE = BIT(2), + NVM_SKU_CAP_11AC_ENABLE = BIT(3), + NVM_SKU_CAP_MIMO_DISABLE = BIT(5), }; /* @@ -368,6 +369,11 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, if (cfg->ht_params->ldpc) vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + if (data->sku_cap_mimo_disabled) { + num_rx_ants = 1; + num_tx_ants = 1; + } + if (num_tx_ants > 1) vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; else @@ -465,7 +471,7 @@ static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, if (cfg->device_family != IWL_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + RADIO_CFG); - return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); + return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_8000)); } @@ -527,6 +533,10 @@ static void iwl_set_hw_address_family_8000(struct device *dev, const u8 *hw_addr; if (mac_override) { + static const u8 reserved_mac[] = { + 0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00 + }; + hw_addr = (const u8 *)(mac_override + MAC_ADDRESS_OVERRIDE_FAMILY_8000); @@ -538,7 +548,12 @@ static void iwl_set_hw_address_family_8000(struct device *dev, data->hw_addr[4] = hw_addr[5]; data->hw_addr[5] = hw_addr[4]; - if (is_valid_ether_addr(data->hw_addr)) + /* + * Force the use of the OTP MAC address in case of reserved MAC + * address in the NVM, or if address is given but invalid. + */ + if (is_valid_ether_addr(data->hw_addr) && + memcmp(reserved_mac, hw_addr, ETH_ALEN) != 0) return; IWL_ERR_DEV(dev, @@ -610,6 +625,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, data->sku_cap_11n_enable = false; data->sku_cap_11ac_enable = data->sku_cap_11n_enable && (sku & NVM_SKU_CAP_11AC_ENABLE); + data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE; data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 6dfed1259260..56254a837214 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -32,7 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -421,8 +421,9 @@ struct iwl_trans_txq_scd_cfg { * * All the handlers MUST be implemented * - * @start_hw: starts the HW- from that point on, the HW can send interrupts - * May sleep + * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken + * out of a low power state. From that point on, the HW can send + * interrupts. May sleep. * @op_mode_leave: Turn off the HW RF kill indication if on * May sleep * @start_fw: allocates and inits all the resources for the transport @@ -432,10 +433,11 @@ struct iwl_trans_txq_scd_cfg { * the SCD base address in SRAM, then provide it here, or 0 otherwise. * May sleep * @stop_device: stops the whole device (embedded CPU put to reset) and stops - * the HW. From that point on, the HW will be in low power but will still - * issue interrupt if the HW RF kill is triggered. This callback must do - * the right thing and not crash even if start_hw() was called but not - * start_fw(). May sleep + * the HW. If low_power is true, the NIC will be put in low power state. + * From that point on, the HW will be stopped but will still issue an + * interrupt if the HW RF kill switch is triggered. + * This callback must do the right thing and not crash even if %start_hw() + * was called but not &start_fw(). May sleep. * @d3_suspend: put the device into the correct mode for WoWLAN during * suspend. This is optional, if not implemented WoWLAN will not be * supported. This callback may sleep. @@ -491,14 +493,14 @@ struct iwl_trans_txq_scd_cfg { */ struct iwl_trans_ops { - int (*start_hw)(struct iwl_trans *iwl_trans); + int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power); void (*op_mode_leave)(struct iwl_trans *iwl_trans); int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill); int (*update_sf)(struct iwl_trans *trans, struct iwl_sf_region *st_fwrd_space); void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); - void (*stop_device)(struct iwl_trans *trans); + void (*stop_device)(struct iwl_trans *trans, bool low_power); void (*d3_suspend)(struct iwl_trans *trans, bool test); int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, @@ -652,11 +654,16 @@ static inline void iwl_trans_configure(struct iwl_trans *trans, trans->ops->configure(trans, trans_cfg); } -static inline int iwl_trans_start_hw(struct iwl_trans *trans) +static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power) { might_sleep(); - return trans->ops->start_hw(trans); + return trans->ops->start_hw(trans, low_power); +} + +static inline int iwl_trans_start_hw(struct iwl_trans *trans) +{ + return trans->ops->start_hw(trans, true); } static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans) @@ -703,15 +710,21 @@ static inline int iwl_trans_update_sf(struct iwl_trans *trans, return 0; } -static inline void iwl_trans_stop_device(struct iwl_trans *trans) +static inline void _iwl_trans_stop_device(struct iwl_trans *trans, + bool low_power) { might_sleep(); - trans->ops->stop_device(trans); + trans->ops->stop_device(trans, low_power); trans->state = IWL_TRANS_NO_FW; } +static inline void iwl_trans_stop_device(struct iwl_trans *trans) +{ + _iwl_trans_stop_device(trans, true); +} + static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test) { might_sleep(); diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index d954591e0be5..6ac6de2af977 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -776,7 +776,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, struct iwl_host_cmd cmd = { .id = BT_CONFIG, .len = { sizeof(*bt_cmd), }, - .dataflags = { IWL_HCMD_DFL_NOCOPY, }, + .dataflags = { IWL_HCMD_DFL_DUP, }, .flags = CMD_ASYNC, }; struct iwl_mvm_sta *mvmsta; diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index a6c48c7b1e16..4310cf102d78 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1726,7 +1726,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, results->matched_profiles = le32_to_cpu(query->matched_profiles); memcpy(results->matches, query->matches, sizeof(results->matches)); -#ifdef CPTCFG_IWLWIFI_DEBUGFS +#ifdef CONFIG_IWLWIFI_DEBUGFS mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); #endif @@ -1750,8 +1750,10 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, int i, j, n_matches, ret; fw_status = iwl_mvm_get_wakeup_status(mvm, vif); - if (!IS_ERR_OR_NULL(fw_status)) + if (!IS_ERR_OR_NULL(fw_status)) { reasons = le32_to_cpu(fw_status->wakeup_reasons); + kfree(fw_status); + } if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) wakeup.rfkill_release = true; @@ -1868,15 +1870,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* get the BSS vif pointer again */ vif = iwl_mvm_get_bss_vif(mvm); if (IS_ERR_OR_NULL(vif)) - goto out_unlock; + goto err; ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test); if (ret) - goto out_unlock; + goto err; if (d3_status != IWL_D3_STATUS_ALIVE) { IWL_INFO(mvm, "Device was reset during suspend\n"); - goto out_unlock; + goto err; } /* query SRAM first in case we want event logging */ @@ -1902,7 +1904,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto out_iterate; } - out_unlock: +err: + iwl_mvm_free_nd(mvm); mutex_unlock(&mvm->mutex); out_iterate: @@ -1915,6 +1918,14 @@ out: /* return 1 to reconfigure the device */ set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); + + /* We always return 1, which causes mac80211 to do a reconfig + * with IEEE80211_RECONFIG_TYPE_RESTART. This type of + * reconfig calls iwl_mvm_restart_complete(), where we unref + * the IWL_MVM_REF_UCODE_DOWN, so we need to take the + * reference here. + */ + iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); return 1; } @@ -2021,7 +2032,6 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) __iwl_mvm_resume(mvm, true); rtnl_unlock(); iwl_abort_notification_waits(&mvm->notif_wait); - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); ieee80211_restart_hw(mvm->hw); /* wait for restart and disconnect all interfaces */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 4fc0938b3fb6..b1baa33cc19b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -298,6 +298,40 @@ struct iwl_uapsd_misbehaving_ap_notif { } __packed; /** + * struct iwl_reduce_tx_power_cmd - TX power reduction command + * REDUCE_TX_POWER_CMD = 0x9f + * @flags: (reserved for future implementation) + * @mac_context_id: id of the mac ctx for which we are reducing TX power. + * @pwr_restriction: TX power restriction in dBms. + */ +struct iwl_reduce_tx_power_cmd { + u8 flags; + u8 mac_context_id; + __le16 pwr_restriction; +} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */ + +/** + * struct iwl_dev_tx_power_cmd - TX power reduction command + * REDUCE_TX_POWER_CMD = 0x9f + * @set_mode: 0 - MAC tx power, 1 - device tx power + * @mac_context_id: id of the mac ctx for which we are reducing TX power. + * @pwr_restriction: TX power restriction in 1/8 dBms. + * @dev_24: device TX power restriction in 1/8 dBms + * @dev_52_low: device TX power restriction upper band - low + * @dev_52_high: device TX power restriction upper band - high + */ +struct iwl_dev_tx_power_cmd { + __le32 set_mode; + __le32 mac_context_id; + __le16 pwr_restriction; + __le16 dev_24; + __le16 dev_52_low; + __le16 dev_52_high; +} __packed; /* TX_REDUCED_POWER_API_S_VER_2 */ + +#define IWL_DEV_MAX_TX_POWER 0x7FFF + +/** * struct iwl_beacon_filter_cmd * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) * @id_and_color: MAC contex identifier diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 4f81dcf57a73..d6cced47d561 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -122,46 +122,6 @@ enum iwl_scan_complete_status { SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C, }; -/** - * struct iwl_scan_results_notif - scan results for one channel - * ( SCAN_RESULTS_NOTIFICATION = 0x83 ) - * @channel: which channel the results are from - * @band: 0 for 5.2 GHz, 1 for 2.4 GHz - * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request - * @num_probe_not_sent: # of request that weren't sent due to not enough time - * @duration: duration spent in channel, in usecs - * @statistics: statistics gathered for this channel - */ -struct iwl_scan_results_notif { - u8 channel; - u8 band; - u8 probe_status; - u8 num_probe_not_sent; - __le32 duration; - __le32 statistics[SCAN_RESULTS_STATISTICS]; -} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */ - -/** - * struct iwl_scan_complete_notif - notifies end of scanning (all channels) - * ( SCAN_COMPLETE_NOTIFICATION = 0x84 ) - * @scanned_channels: number of channels scanned (and number of valid results) - * @status: one of SCAN_COMP_STATUS_* - * @bt_status: BT on/off status - * @last_channel: last channel that was scanned - * @tsf_low: TSF timer (lower half) in usecs - * @tsf_high: TSF timer (higher half) in usecs - * @results: array of scan results, only "scanned_channels" of them are valid - */ -struct iwl_scan_complete_notif { - u8 scanned_channels; - u8 status; - u8 bt_status; - u8 last_channel; - __le32 tsf_low; - __le32 tsf_high; - struct iwl_scan_results_notif results[]; -} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */ - /* scan offload */ #define IWL_SCAN_MAX_BLACKLIST_LEN 64 #define IWL_SCAN_SHORT_BLACKLIST_LEN 16 @@ -554,7 +514,7 @@ struct iwl_scan_req_unified_lmac { } __packed; /** - * struct iwl_lmac_scan_results_notif - scan results for one channel - + * struct iwl_scan_results_notif - scan results for one channel - * SCAN_RESULT_NTF_API_S_VER_3 * @channel: which channel the results are from * @band: 0 for 5.2 GHz, 1 for 2.4 GHz @@ -562,7 +522,7 @@ struct iwl_scan_req_unified_lmac { * @num_probe_not_sent: # of request that weren't sent due to not enough time * @duration: duration spent in channel, in usecs */ -struct iwl_lmac_scan_results_notif { +struct iwl_scan_results_notif { u8 channel; u8 band; u8 probe_status; diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index aab68cbae754..01b1da6ad359 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -281,19 +281,6 @@ struct iwl_tx_ant_cfg_cmd { __le32 valid; } __packed; -/** - * struct iwl_reduce_tx_power_cmd - TX power reduction command - * REDUCE_TX_POWER_CMD = 0x9f - * @flags: (reserved for future implementation) - * @mac_context_id: id of the mac ctx for which we are reducing TX power. - * @pwr_restriction: TX power restriction in dBms. - */ -struct iwl_reduce_tx_power_cmd { - u8 flags; - u8 mac_context_id; - __le16 pwr_restriction; -} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */ - /* * Calibration control struct. * Sent as part of the phy configuration command. diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index bc5eac4960e1..df869633f4dd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -32,7 +32,7 @@ * BSD LICENSE * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -322,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) lockdep_assert_held(&mvm->mutex); - if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating)) + if (WARN_ON_ONCE(mvm->calibrating)) return 0; iwl_init_notification_wait(&mvm->notif_wait, @@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) */ ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, MVM_UCODE_CALIB_TIMEOUT); - if (!ret) - mvm->init_ucode_complete = true; if (ret && iwl_mvm_is_radio_killed(mvm)) { IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n"); @@ -494,15 +492,6 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm, mvm->fw_dump_desc = desc; - /* stop recording */ - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); - } else { - iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); - /* wait before we collect the data till the DBGC stop */ - udelay(100); - } - queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay); return 0; @@ -658,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm) * module loading, load init ucode now * (for example, if we were in RFKILL) */ - if (!mvm->init_ucode_complete) { - ret = iwl_run_init_mvm_ucode(mvm, false); - if (ret && !iwlmvm_mod_params.init_dbg) { - IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); - /* this can't happen */ - if (WARN_ON(ret > 0)) - ret = -ERFKILL; - goto error; - } - if (!iwlmvm_mod_params.init_dbg) { - /* - * should stop and start HW since that INIT - * image just loaded - */ - iwl_trans_stop_device(mvm->trans); - ret = iwl_trans_start_hw(mvm->trans); - if (ret) - return ret; - } + ret = iwl_run_init_mvm_ucode(mvm, false); + if (ret && !iwlmvm_mod_params.init_dbg) { + IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); + /* this can't happen */ + if (WARN_ON(ret > 0)) + ret = -ERFKILL; + goto error; + } + if (!iwlmvm_mod_params.init_dbg) { + /* + * Stop and start the transport without entering low power + * mode. This will save the state of other components on the + * device that are triggered by the INIT firwmare (MFUART). + */ + _iwl_trans_stop_device(mvm->trans, false); + _iwl_trans_start_hw(mvm->trans, false); + if (ret) + return ret; } if (iwlmvm_mod_params.init_dbg) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 84555170b6f7..dda9f7b5f342 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1322,7 +1322,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); iwl_mvm_d0i3_enable_tx(mvm, NULL); - ret = iwl_mvm_update_quotas(mvm, false, NULL); + ret = iwl_mvm_update_quotas(mvm, true, NULL); if (ret) IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", ret); @@ -1471,8 +1471,8 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) return NULL; } -static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - s8 tx_power) +static int iwl_mvm_set_tx_power_old(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, s8 tx_power) { /* FW is in charge of regulatory enforcement */ struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { @@ -1485,6 +1485,26 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, &reduce_txpwr_cmd); } +static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + s16 tx_power) +{ + struct iwl_dev_tx_power_cmd cmd = { + .set_mode = 0, + .mac_context_id = + cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id), + .pwr_restriction = cpu_to_le16(8 * tx_power), + }; + + if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_TX_POWER_DEV)) + return iwl_mvm_set_tx_power_old(mvm, vif, tx_power); + + if (tx_power == IWL_DEFAULT_MAX_TX_POWER) + cmd.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); + + return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, + sizeof(cmd), &cmd); +} + static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -3975,9 +3995,6 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) return; - if (event->u.mlme.status == MLME_SUCCESS) - return; - trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME); trig_mlme = (void *)trig->data; if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d5522a161242..cf70f681d1ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -603,7 +603,6 @@ struct iwl_mvm { enum iwl_ucode_type cur_ucode; bool ucode_loaded; - bool init_ucode_complete; bool calibrating; u32 error_event_table; u32 log_event_table; diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index a08b03d58d4b..2ea01238754e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -865,6 +865,16 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) return; mutex_lock(&mvm->mutex); + + /* stop recording */ + if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); + } else { + iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); + /* wait before we collect the data till the DBGC stop */ + udelay(100); + } + iwl_mvm_fw_error_dump(mvm); /* start recording again if the firmware is not crashed */ @@ -1253,11 +1263,13 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) ieee80211_iterate_active_interfaces( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_d0i3_disconnect_iter, mvm); - - iwl_free_resp(&get_status_cmd); out: iwl_mvm_d0i3_enable_tx(mvm, qos_seq); + /* qos_seq might point inside resp_pkt, so free it only now */ + if (get_status_cmd.resp_pkt) + iwl_free_resp(&get_status_cmd); + /* the FW might have updated the regdomain */ iwl_mvm_update_changed_regdom(mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index f9928f2c125f..33cd68ae7bf9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -180,6 +180,9 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (iwl_mvm_vif_low_latency(mvmvif) && mvmsta->vif->p2p) return false; + if (mvm->nvm_data->sku_cap_mimo_disabled) + return false; + return true; } diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 78ec7db64ba5..d6314ddf57b5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -478,6 +478,11 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, if (vif->type != NL80211_IFTYPE_STATION) return; + if (sig == 0) { + IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n"); + return; + } + mvmvif->bf_data.ave_beacon_signal = sig; /* BT Coex */ diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 74e1c86289dc..1075a213bd6a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -319,7 +319,7 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scan_complete_notif *notif = (void *)pkt->data; + struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data; IWL_DEBUG_SCAN(mvm, "Scan offload iteration complete: status=0x%x scanned channels=%d\n", diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 01996c9d98a7..376b84e54ad7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -1,7 +1,7 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -320,7 +320,7 @@ struct iwl_trans_pcie { /*protect hw register */ spinlock_t reg_lock; - bool cmd_in_flight; + bool cmd_hold_nic_awake; bool ref_cmd_in_flight; /* protect ref counter */ diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 2de8fbfe4edf..dc179094e6a0 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -5,8 +5,8 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,8 +31,8 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,7 +104,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct page *page; + struct page *page = NULL; dma_addr_t phys; u32 size; u8 power; @@ -131,6 +131,7 @@ static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, phys)) { __free_pages(page, order); + page = NULL; continue; } IWL_INFO(trans, @@ -1020,7 +1021,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) iwl_pcie_tx_start(trans, scd_addr); } -static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) +static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill, was_hw_rfkill; @@ -1048,9 +1049,11 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) iwl_pcie_rx_stop(trans); /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(trans, APMG_CLK_DIS_REG, - APMG_CLK_VAL_DMA_CLK_RQT); - udelay(5); + if (trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) { + iwl_write_prph(trans, APMG_CLK_DIS_REG, + APMG_CLK_VAL_DMA_CLK_RQT); + udelay(5); + } } /* Make sure (redundant) we've released our request to stay awake */ @@ -1115,7 +1118,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) { if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) - iwl_trans_pcie_stop_device(trans); + iwl_trans_pcie_stop_device(trans, true); } static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) @@ -1200,7 +1203,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, return 0; } -static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) +static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) { bool hw_rfkill; int err; @@ -1369,7 +1372,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, spin_lock_irqsave(&trans_pcie->reg_lock, *flags); - if (trans_pcie->cmd_in_flight) + if (trans_pcie->cmd_hold_nic_awake) goto out; /* this bit wakes up the NIC */ @@ -1435,7 +1438,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, */ __acquire(&trans_pcie->reg_lock); - if (trans_pcie->cmd_in_flight) + if (trans_pcie->cmd_hold_nic_awake) goto out; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 06952aadfd7b..5ef8044c2ea3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1039,18 +1039,14 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, iwl_trans_pcie_ref(trans); } - if (trans_pcie->cmd_in_flight) - return 0; - - trans_pcie->cmd_in_flight = true; - /* * wake up the NIC to make sure that the firmware will see the host * command - we will let the NIC sleep once all the host commands * returned. This needs to be done only on NICs that have * apmg_wake_up_wa set. */ - if (trans->cfg->base_params->apmg_wake_up_wa) { + if (trans->cfg->base_params->apmg_wake_up_wa && + !trans_pcie->cmd_hold_nic_awake) { __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) @@ -1064,10 +1060,10 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, if (ret < 0) { __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - trans_pcie->cmd_in_flight = false; IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); return -EIO; } + trans_pcie->cmd_hold_nic_awake = true; } return 0; @@ -1085,15 +1081,14 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) iwl_trans_pcie_unref(trans); } - if (WARN_ON(!trans_pcie->cmd_in_flight)) - return 0; - - trans_pcie->cmd_in_flight = false; + if (trans->cfg->base_params->apmg_wake_up_wa) { + if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) + return 0; - if (trans->cfg->base_params->apmg_wake_up_wa) + trans_pcie->cmd_hold_nic_awake = false; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + } return 0; } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f0188c83c79f..2721cf89fb16 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -126,7 +126,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, do { status = usb_control_msg(udev, pipe, request, reqtype, value, - index, pdata, len, 0); /*max. timeout*/ + index, pdata, len, 1000); if (status < 0) { /* firmware download is checksumed, don't retry */ if ((value >= FW_8192C_START_ADDRESS && diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 4de46aa61d95..0d2594395ffb 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1250,7 +1250,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, netdev_err(queue->vif->dev, "txreq.offset: %x, size: %u, end: %lu\n", txreq.offset, txreq.size, - (txreq.offset&~PAGE_MASK) + txreq.size); + (unsigned long)(txreq.offset&~PAGE_MASK) + txreq.size); xenvif_fatal_tx_err(queue->vif); break; } diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 3d8dbf5f2d39..968787abf78d 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -34,6 +34,8 @@ struct backend_info { enum xenbus_state frontend_state; struct xenbus_watch hotplug_status_watch; u8 have_hotplug_status_watch:1; + + const char *hotplug_script; }; static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); @@ -238,6 +240,7 @@ static int netback_remove(struct xenbus_device *dev) xenvif_free(be->vif); be->vif = NULL; } + kfree(be->hotplug_script); kfree(be); dev_set_drvdata(&dev->dev, NULL); return 0; @@ -255,6 +258,7 @@ static int netback_probe(struct xenbus_device *dev, struct xenbus_transaction xbt; int err; int sg; + const char *script; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { @@ -347,6 +351,15 @@ static int netback_probe(struct xenbus_device *dev, if (err) pr_debug("Error writing multi-queue-max-queues\n"); + script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL); + if (IS_ERR(script)) { + err = PTR_ERR(script); + xenbus_dev_fatal(dev, err, "reading script"); + goto fail; + } + + be->hotplug_script = script; + err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) goto fail; @@ -379,22 +392,14 @@ static int netback_uevent(struct xenbus_device *xdev, struct kobj_uevent_env *env) { struct backend_info *be = dev_get_drvdata(&xdev->dev); - char *val; - val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); - if (IS_ERR(val)) { - int err = PTR_ERR(val); - xenbus_dev_fatal(xdev, err, "reading script"); - return err; - } else { - if (add_uevent_var(env, "script=%s", val)) { - kfree(val); - return -ENOMEM; - } - kfree(val); - } + if (!be) + return 0; - if (!be || !be->vif) + if (add_uevent_var(env, "script=%s", be->hotplug_script)) + return -ENOMEM; + + if (!be->vif) return 0; return add_uevent_var(env, "vif=%s", be->vif->dev->name); @@ -793,6 +798,7 @@ static void connect(struct backend_info *be) goto err; } + queue->credit_bytes = credit_bytes; queue->remaining_credit = credit_bytes; queue->credit_usec = credit_usec; diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 3f45afd4382e..e031c943286e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1698,6 +1698,7 @@ static void xennet_destroy_queues(struct netfront_info *info) if (netif_running(info->netdev)) napi_disable(&queue->napi); + del_timer_sync(&queue->rx_refill_timer); netif_napi_del(&queue->napi); } @@ -2102,9 +2103,6 @@ static const struct attribute_group xennet_dev_group = { static int xennet_remove(struct xenbus_device *dev) { struct netfront_info *info = dev_get_drvdata(&dev->dev); - unsigned int num_queues = info->netdev->real_num_tx_queues; - struct netfront_queue *queue = NULL; - unsigned int i = 0; dev_dbg(&dev->dev, "%s\n", dev->nodename); @@ -2112,16 +2110,7 @@ static int xennet_remove(struct xenbus_device *dev) unregister_netdev(info->netdev); - for (i = 0; i < num_queues; ++i) { - queue = &info->queues[i]; - del_timer_sync(&queue->rx_refill_timer); - } - - if (num_queues) { - kfree(info->queues); - info->queues = NULL; - } - + xennet_destroy_queues(info); xennet_free_netdev(info->netdev); return 0; diff --git a/drivers/of/base.c b/drivers/of/base.c index 99764db0875a..f0650265febf 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -189,7 +189,7 @@ int __of_attach_node_sysfs(struct device_node *np) return 0; } -static int __init of_init(void) +void __init of_core_init(void) { struct device_node *np; @@ -198,7 +198,8 @@ static int __init of_init(void) of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); if (!of_kset) { mutex_unlock(&of_mutex); - return -ENOMEM; + pr_err("devicetree: failed to register existing nodes\n"); + return; } for_each_of_allnodes(np) __of_attach_node_sysfs(np); @@ -207,10 +208,7 @@ static int __init of_init(void) /* Symlink in /proc as required by userspace ABI */ if (of_root) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); - - return 0; } -core_initcall(of_init); static struct property *__of_find_property(const struct device_node *np, const char *name, int *lenp) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 3351ef408125..53826b84e0ec 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -225,7 +225,7 @@ void __of_attach_node(struct device_node *np) phandle = __of_get_property(np, "phandle", &sz); if (!phandle) phandle = __of_get_property(np, "linux,phandle", &sz); - if (IS_ENABLED(PPC_PSERIES) && !phandle) + if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) phandle = __of_get_property(np, "ibm,phandle", &sz); np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 8be2096c8423..deeaed544222 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) BUG(); return -1; } - printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n", + printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n", pci_name(pcidev), pcidev->vendor, pcidev->device, __builtin_return_address(0)); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4fd0cacf7ca0..508cc56130e3 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -428,16 +428,19 @@ static void __assign_resources_sorted(struct list_head *head, * consistent. */ if (add_align > dev_res->res->start) { + resource_size_t r_size = resource_size(dev_res->res); + dev_res->res->start = add_align; - dev_res->res->end = add_align + - resource_size(dev_res->res); + dev_res->res->end = add_align + r_size - 1; list_for_each_entry(dev_res2, head, list) { align = pci_resource_alignment(dev_res2->dev, dev_res2->res); - if (add_align > align) + if (add_align > align) { list_move_tail(&dev_res->list, &dev_res2->list); + break; + } } } diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index a53bd5b52df9..fc9b9f0ea91e 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -38,7 +38,9 @@ config ARMADA375_USBCLUSTER_PHY config PHY_DM816X_USB tristate "TI dm816x USB PHY driver" depends on ARCH_OMAP2PLUS + depends on USB_SUPPORT select GENERIC_PHY + select USB_PHY help Enable this for dm816x USB to work. @@ -97,8 +99,9 @@ config OMAP_CONTROL_PHY config OMAP_USB2 tristate "OMAP USB2 PHY Driver" depends on ARCH_OMAP2PLUS - depends on USB_PHY + depends on USB_SUPPORT select GENERIC_PHY + select USB_PHY select OMAP_CONTROL_PHY depends on OMAP_OCP2SCP help @@ -122,8 +125,9 @@ config TI_PIPE3 config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS - depends on USB_PHY + depends on USB_SUPPORT select GENERIC_PHY + select USB_PHY help Enable this to support the USB OTG transceiver on TWL4030 family chips (including the TWL5030 and TPS659x0 devices). @@ -304,7 +308,7 @@ config PHY_STIH41X_USB config PHY_QCOM_UFS tristate "Qualcomm UFS PHY driver" - depends on OF && ARCH_MSM + depends on OF && ARCH_QCOM select GENERIC_PHY help Support for UFS PHY on QCOM chipsets. diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 3791838f4bd4..63bc12d7a73e 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -530,7 +530,7 @@ struct phy *phy_optional_get(struct device *dev, const char *string) { struct phy *phy = phy_get(dev, string); - if (PTR_ERR(phy) == -ENODEV) + if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV)) phy = NULL; return phy; @@ -584,7 +584,7 @@ struct phy *devm_phy_optional_get(struct device *dev, const char *string) { struct phy *phy = devm_phy_get(dev, string); - if (PTR_ERR(phy) == -ENODEV) + if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV)) phy = NULL; return phy; diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 183ef4368101..c1a468686bdc 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -275,6 +275,7 @@ static int omap_usb2_probe(struct platform_device *pdev) phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); + pm_runtime_disable(phy->dev); return PTR_ERR(phy->wkupclk); } else { dev_warn(&pdev->dev, diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c index 778276aba3aa..97d45f47d1ad 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/phy-rcar-gen2.c @@ -23,7 +23,7 @@ #define USBHS_LPSTS 0x02 #define USBHS_UGCTRL 0x80 #define USBHS_UGCTRL2 0x84 -#define USBHS_UGSTS 0x88 /* The manuals have 0x90 */ +#define USBHS_UGSTS 0x88 /* From technical update */ /* Low Power Status register (LPSTS) */ #define USBHS_LPSTS_SUSPM 0x4000 @@ -41,7 +41,7 @@ #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030 /* USB General status register (UGSTS) */ -#define USBHS_UGSTS_LOCK 0x00000300 /* The manuals have 0x3 */ +#define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */ #define PHYS_PER_CHANNEL 2 diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c b/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c index 4ad5c1a996e3..e406e3d8c1c7 100644 --- a/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c @@ -643,7 +643,9 @@ static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = { CYGNUS_PINRANGE(87, 104, 12), CYGNUS_PINRANGE(99, 102, 2), CYGNUS_PINRANGE(101, 90, 4), - CYGNUS_PINRANGE(105, 116, 10), + CYGNUS_PINRANGE(105, 116, 6), + CYGNUS_PINRANGE(111, 100, 2), + CYGNUS_PINRANGE(113, 122, 4), CYGNUS_PINRANGE(123, 11, 1), CYGNUS_PINRANGE(124, 38, 4), CYGNUS_PINRANGE(128, 43, 1), diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 89dca77ca038..18ee2089df4a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1110,7 +1110,7 @@ void devm_pinctrl_put(struct pinctrl *p) EXPORT_SYMBOL_GPL(devm_pinctrl_put); int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, - bool dup, bool locked) + bool dup) { int i, ret; struct pinctrl_maps *maps_node; @@ -1178,11 +1178,9 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, maps_node->maps = maps; } - if (!locked) - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_maps_mutex); list_add_tail(&maps_node->node, &pinctrl_maps); - if (!locked) - mutex_unlock(&pinctrl_maps_mutex); + mutex_unlock(&pinctrl_maps_mutex); return 0; } @@ -1197,7 +1195,7 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, int pinctrl_register_mappings(struct pinctrl_map const *maps, unsigned num_maps) { - return pinctrl_register_map(maps, num_maps, true, false); + return pinctrl_register_map(maps, num_maps, true); } void pinctrl_unregister_map(struct pinctrl_map const *map) diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 75476b3d87da..b24ea846c867 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -183,7 +183,7 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, } int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, - bool dup, bool locked); + bool dup); void pinctrl_unregister_map(struct pinctrl_map const *map); extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index eda13de2e7c0..0bbf7d71b281 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -92,7 +92,7 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, dt_map->num_maps = num_maps; list_add_tail(&dt_map->node, &p->dt_maps); - return pinctrl_register_map(map, num_maps, false, true); + return pinctrl_register_map(map, num_maps, false); } struct pinctrl_dev *of_pinctrl_get(struct device_node *np) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 82f691eeeec4..732ff757a95f 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1292,6 +1292,49 @@ static void chv_gpio_irq_unmask(struct irq_data *d) chv_gpio_irq_mask_unmask(d, false); } +static unsigned chv_gpio_irq_startup(struct irq_data *d) +{ + /* + * Check if the interrupt has been requested with 0 as triggering + * type. In that case it is assumed that the current values + * programmed to the hardware are used (e.g BIOS configured + * defaults). + * + * In that case ->irq_set_type() will never be called so we need to + * read back the values from hardware now, set correct flow handler + * and update mappings before the interrupt is being used. + */ + if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); + unsigned offset = irqd_to_hwirq(d); + int pin = chv_gpio_offset_to_pin(pctrl, offset); + irq_flow_handler_t handler; + unsigned long flags; + u32 intsel, value; + + intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intsel &= CHV_PADCTRL0_INTSEL_MASK; + intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; + + value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) + handler = handle_level_irq; + else + handler = handle_edge_irq; + + spin_lock_irqsave(&pctrl->lock, flags); + if (!pctrl->intr_lines[intsel]) { + __irq_set_handler_locked(d->irq, handler); + pctrl->intr_lines[intsel] = offset; + } + spin_unlock_irqrestore(&pctrl->lock, flags); + } + + chv_gpio_irq_unmask(d); + return 0; +} + static int chv_gpio_irq_type(struct irq_data *d, unsigned type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); @@ -1357,6 +1400,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type) static struct irq_chip chv_gpio_irqchip = { .name = "chv-gpio", + .irq_startup = chv_gpio_irq_startup, .irq_ack = chv_gpio_irq_ack, .irq_mask = chv_gpio_irq_mask, .irq_unmask = chv_gpio_irq_unmask, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 493294c0ebe6..474812e2b0cb 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -881,6 +881,8 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, if (!mtk_eint_get_mask(pctl, eint_num)) { mtk_eint_mask(d); unmask = 1; + } else { + unmask = 0; } clr_bit = 0xff << eint_offset; diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index edcd140e0899..a70a5fe79d44 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -569,7 +569,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) domain->chip.direction_output = meson_gpio_direction_output; domain->chip.get = meson_gpio_get; domain->chip.set = meson_gpio_set; - domain->chip.base = -1; + domain->chip.base = domain->data->pin_base; domain->chip.ngpio = domain->data->num_pins; domain->chip.can_sleep = false; domain->chip.of_node = domain->of_node; diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c index 2f7ea6229880..9677807db364 100644 --- a/drivers/pinctrl/meson/pinctrl-meson8b.c +++ b/drivers/pinctrl/meson/pinctrl-meson8b.c @@ -876,13 +876,13 @@ static struct meson_domain_data meson8b_domain_data[] = { .banks = meson8b_banks, .num_banks = ARRAY_SIZE(meson8b_banks), .pin_base = 0, - .num_pins = 83, + .num_pins = 130, }, { .name = "ao-bank", .banks = meson8b_ao_banks, .num_banks = ARRAY_SIZE(meson8b_ao_banks), - .pin_base = 83, + .pin_base = 130, .num_pins = 16, }, }; diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index 42f930f70de3..03aa58c4cb85 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c @@ -364,7 +364,7 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { MPP_FUNCTION(0x5, "audio", "mclk"), MPP_FUNCTION(0x6, "uart0", "cts")), MPP_MODE(63, - MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x0, "gpio", NULL), MPP_FUNCTION(0x1, "spi0", "sck"), MPP_FUNCTION(0x2, "tclk", NULL)), MPP_MODE(64, diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index b2d22218a258..ae4115e4b4ef 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -260,6 +260,7 @@ static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function, val = 1; } + val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; @@ -417,7 +418,7 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, return ret; val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; - val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; + val |= pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); if (ret < 0) @@ -466,12 +467,13 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, seq_puts(s, " ---"); } else { - if (!pad->input_enabled) { + if (pad->input_enabled) { ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); - if (!ret) { - ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; - pad->out_value = ret; - } + if (ret < 0) + return; + + ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; + pad->out_value = ret; } seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index 8f36c5f91949..211b942ad6d5 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -370,6 +370,7 @@ static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function, } } + val = val << PMIC_MPP_REG_MODE_DIR_SHIFT; val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; @@ -576,10 +577,11 @@ static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev, if (pad->input_enabled) { ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); - if (!ret) { - ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; - pad->out_value = ret; - } + if (ret < 0) + return; + + ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; + pad->out_value = ret; } seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index d9a09d9637d9..aad16bc9e630 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -158,8 +158,8 @@ static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd) struct goldfish_pipe_dev *dev = pipe->dev; spin_lock_irqsave(&dev->lock, flags); - gf_write64((u64)(unsigned long)pipe, dev->base + PIPE_REG_CHANNEL, - dev->base + PIPE_REG_CHANNEL_HIGH); + gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, + dev->base + PIPE_REG_CHANNEL_HIGH); writel(cmd, dev->base + PIPE_REG_COMMAND); status = readl(dev->base + PIPE_REG_STATUS); spin_unlock_irqrestore(&dev->lock, flags); @@ -172,8 +172,8 @@ static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd) struct goldfish_pipe_dev *dev = pipe->dev; spin_lock_irqsave(&dev->lock, flags); - gf_write64((u64)(unsigned long)pipe, dev->base + PIPE_REG_CHANNEL, - dev->base + PIPE_REG_CHANNEL_HIGH); + gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, + dev->base + PIPE_REG_CHANNEL_HIGH); writel(cmd, dev->base + PIPE_REG_COMMAND); spin_unlock_irqrestore(&dev->lock, flags); } @@ -327,12 +327,12 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer, spin_lock_irqsave(&dev->lock, irq_flags); if (access_with_param(dev, CMD_WRITE_BUFFER + cmd_offset, address, avail, pipe, &status)) { - gf_write64((u64)(unsigned long)pipe, - dev->base + PIPE_REG_CHANNEL, - dev->base + PIPE_REG_CHANNEL_HIGH); + gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, + dev->base + PIPE_REG_CHANNEL_HIGH); writel(avail, dev->base + PIPE_REG_SIZE); - gf_write64(address, dev->base + PIPE_REG_ADDRESS, - dev->base + PIPE_REG_ADDRESS_HIGH); + gf_write_ptr((void *)address, + dev->base + PIPE_REG_ADDRESS, + dev->base + PIPE_REG_ADDRESS_HIGH); writel(CMD_WRITE_BUFFER + cmd_offset, dev->base + PIPE_REG_COMMAND); status = readl(dev->base + PIPE_REG_STATUS); diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index b3d419a84723..b496db87bc05 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -830,6 +830,13 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) */ static const struct dmi_system_id no_hw_rfkill_list[] = { { + .ident = "Lenovo G40-30", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo G40-30"), + }, + }, + { .ident = "Lenovo Yoga 2 11 / 13 / Pro", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7769575345d8..28f328136f0d 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2115,7 +2115,7 @@ static int hotkey_mask_get(void) return 0; } -void static hotkey_mask_warn_incomplete_mask(void) +static void hotkey_mask_warn_incomplete_mask(void) { /* log only what the user can fix... */ const u32 wantedmask = hotkey_driver_mask & @@ -2897,7 +2897,7 @@ static ssize_t hotkey_wakeup_reason_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); } -static DEVICE_ATTR_RO(hotkey_wakeup_reason); +static DEVICE_ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); static void hotkey_wakeup_reason_notify_change(void) { @@ -2913,7 +2913,8 @@ static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); } -static DEVICE_ATTR_RO(hotkey_wakeup_hotunplug_complete); +static DEVICE_ATTR(wakeup_hotunplug_complete, S_IRUGO, + hotkey_wakeup_hotunplug_complete_show, NULL); static void hotkey_wakeup_hotunplug_complete_notify_change(void) { @@ -2978,8 +2979,8 @@ static struct attribute *hotkey_attributes[] __initdata = { &dev_attr_hotkey_enable.attr, &dev_attr_hotkey_bios_enabled.attr, &dev_attr_hotkey_bios_mask.attr, - &dev_attr_hotkey_wakeup_reason.attr, - &dev_attr_hotkey_wakeup_hotunplug_complete.attr, + &dev_attr_wakeup_reason.attr, + &dev_attr_wakeup_hotunplug_complete.attr, &dev_attr_hotkey_mask.attr, &dev_attr_hotkey_all_mask.attr, &dev_attr_hotkey_recommended_mask.attr, @@ -4393,12 +4394,13 @@ static ssize_t wan_enable_store(struct device *dev, attr, buf, count); } -static DEVICE_ATTR_RW(wan_enable); +static DEVICE_ATTR(wwan_enable, S_IWUSR | S_IRUGO, + wan_enable_show, wan_enable_store); /* --------------------------------------------------------------------- */ static struct attribute *wan_attributes[] = { - &dev_attr_wan_enable.attr, + &dev_attr_wwan_enable.attr, NULL }; @@ -8138,7 +8140,8 @@ static ssize_t fan_pwm1_enable_store(struct device *dev, return count; } -static DEVICE_ATTR_RW(fan_pwm1_enable); +static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, + fan_pwm1_enable_show, fan_pwm1_enable_store); /* sysfs fan pwm1 ------------------------------------------------------ */ static ssize_t fan_pwm1_show(struct device *dev, @@ -8198,7 +8201,7 @@ static ssize_t fan_pwm1_store(struct device *dev, return (rc) ? rc : count; } -static DEVICE_ATTR_RW(fan_pwm1); +static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store); /* sysfs fan fan1_input ------------------------------------------------ */ static ssize_t fan_fan1_input_show(struct device *dev, @@ -8215,7 +8218,7 @@ static ssize_t fan_fan1_input_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", speed); } -static DEVICE_ATTR_RO(fan_fan1_input); +static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL); /* sysfs fan fan2_input ------------------------------------------------ */ static ssize_t fan_fan2_input_show(struct device *dev, @@ -8232,7 +8235,7 @@ static ssize_t fan_fan2_input_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", speed); } -static DEVICE_ATTR_RO(fan_fan2_input); +static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL); /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ static ssize_t fan_fan_watchdog_show(struct device_driver *drv, @@ -8265,8 +8268,8 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO, /* --------------------------------------------------------------------- */ static struct attribute *fan_attributes[] = { - &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, - &dev_attr_fan_fan1_input.attr, + &dev_attr_pwm1_enable.attr, &dev_attr_pwm1.attr, + &dev_attr_fan1_input.attr, NULL, /* for fan2_input */ NULL }; @@ -8400,7 +8403,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (tp_features.second_fan) { /* attach second fan tachometer */ fan_attributes[ARRAY_SIZE(fan_attributes)-2] = - &dev_attr_fan_fan2_input.attr; + &dev_attr_fan2_input.attr; } rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); @@ -8848,7 +8851,7 @@ static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); } -static DEVICE_ATTR_RO(thinkpad_acpi_pdev_name); +static DEVICE_ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); /* --------------------------------------------------------------------- */ @@ -9390,8 +9393,7 @@ static void thinkpad_acpi_module_exit(void) hwmon_device_unregister(tpacpi_hwmon); if (tp_features.sensors_pdev_attrs_registered) - device_remove_file(&tpacpi_sensors_pdev->dev, - &dev_attr_thinkpad_acpi_pdev_name); + device_remove_file(&tpacpi_sensors_pdev->dev, &dev_attr_name); if (tpacpi_sensors_pdev) platform_device_unregister(tpacpi_sensors_pdev); if (tpacpi_pdev) @@ -9512,8 +9514,7 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } - ret = device_create_file(&tpacpi_sensors_pdev->dev, - &dev_attr_thinkpad_acpi_pdev_name); + ret = device_create_file(&tpacpi_sensors_pdev->dev, &dev_attr_name); if (ret) { pr_err("unable to create sysfs hwmon device attributes\n"); thinkpad_acpi_module_exit(); diff --git a/drivers/power/axp288_fuel_gauge.c b/drivers/power/axp288_fuel_gauge.c index ca1cc5a47eb1..bd1dbfee2515 100644 --- a/drivers/power/axp288_fuel_gauge.c +++ b/drivers/power/axp288_fuel_gauge.c @@ -1149,6 +1149,7 @@ static struct platform_driver axp288_fuel_gauge_driver = { module_platform_driver(axp288_fuel_gauge_driver); +MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>"); MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>"); MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index a57433de5c24..b6b98378faa3 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -1109,6 +1109,14 @@ static void __exit bq27x00_battery_exit(void) } module_exit(bq27x00_battery_exit); +#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM +MODULE_ALIAS("platform:bq27000-battery"); +#endif + +#ifdef CONFIG_BATTERY_BQ27X00_I2C +MODULE_ALIAS("i2c:bq27000-battery"); +#endif + MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index 2da9ed8ccbb5..8a971b3dbe58 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c @@ -347,7 +347,7 @@ static int collie_bat_probe(struct ucb1x00_dev *dev) goto err_psy_reg_main; } - psy_main_cfg.drv_data = &collie_bat_bu; + psy_bu_cfg.drv_data = &collie_bat_bu; collie_bat_bu.psy = power_supply_register(&dev->ucb->dev, &collie_bat_bu_desc, &psy_bu_cfg); diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index aad9c3318c02..17d93a73c513 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -41,6 +41,7 @@ config POWER_RESET_AXXIA config POWER_RESET_BRCMSTB bool "Broadcom STB reset driver" depends on ARM || MIPS || COMPILE_TEST + depends on MFD_SYSCON default ARCH_BRCMSTB help This driver provides restart support for Broadcom STB boards. diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 01c7055c4200..ca461ebc7ae8 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -212,9 +212,9 @@ static int at91_reset_platform_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 ); at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (IS_ERR(at91_ramc_base[idx])) { + if (!at91_ramc_base[idx]) { dev_err(&pdev->dev, "Could not map ram controller address\n"); - return PTR_ERR(at91_ramc_base[idx]); + return -ENOMEM; } } diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c index 7ef193b6f7fe..1e08195551fe 100644 --- a/drivers/power/reset/ltc2952-poweroff.c +++ b/drivers/power/reset/ltc2952-poweroff.c @@ -120,18 +120,7 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer) static void ltc2952_poweroff_start_wde(struct ltc2952_poweroff *data) { - if (hrtimer_start(&data->timer_wde, data->wde_interval, - HRTIMER_MODE_REL)) { - /* - * The device will not toggle the watchdog reset, - * thus shut down is only safe if the PowerPath controller - * has a long enough time-off before triggering a hardware - * power-off. - * - * Only sending a warning as the system will power-off anyway - */ - dev_err(data->dev, "unable to start the timer\n"); - } + hrtimer_start(&data->timer_wde, data->wde_interval, HRTIMER_MODE_REL); } static enum hrtimer_restart @@ -165,9 +154,8 @@ static irqreturn_t ltc2952_poweroff_handler(int irq, void *dev_id) } if (gpiod_get_value(data->gpio_trigger)) { - if (hrtimer_start(&data->timer_trigger, data->trigger_delay, - HRTIMER_MODE_REL)) - dev_err(data->dev, "unable to start the wait timer\n"); + hrtimer_start(&data->timer_trigger, data->trigger_delay, + HRTIMER_MODE_REL); } else { hrtimer_cancel(&data->timer_trigger); /* omitting return value check, timer should have been valid */ diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index 476171a768d6..8a029f9bc18c 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -16,6 +16,7 @@ #include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pwm.h> #include <linux/regmap.h> @@ -38,7 +39,22 @@ #define PERIP_PWM_PDM_CONTROL_CH_MASK 0x1 #define PERIP_PWM_PDM_CONTROL_CH_SHIFT(ch) ((ch) * 4) -#define MAX_TMBASE_STEPS 65536 +/* + * PWM period is specified with a timebase register, + * in number of step periods. The PWM duty cycle is also + * specified in step periods, in the [0, $timebase] range. + * In other words, the timebase imposes the duty cycle + * resolution. Therefore, let's constraint the timebase to + * a minimum value to allow a sane range of duty cycle values. + * Imposing a minimum timebase, will impose a maximum PWM frequency. + * + * The value chosen is completely arbitrary. + */ +#define MIN_TMBASE_STEPS 16 + +struct img_pwm_soc_data { + u32 max_timebase; +}; struct img_pwm_chip { struct device *dev; @@ -47,6 +63,9 @@ struct img_pwm_chip { struct clk *sys_clk; void __iomem *base; struct regmap *periph_regs; + int max_period_ns; + int min_period_ns; + const struct img_pwm_soc_data *data; }; static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip) @@ -72,24 +91,31 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, u32 val, div, duty, timebase; unsigned long mul, output_clk_hz, input_clk_hz; struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip); + unsigned int max_timebase = pwm_chip->data->max_timebase; + + if (period_ns < pwm_chip->min_period_ns || + period_ns > pwm_chip->max_period_ns) { + dev_err(chip->dev, "configured period not in range\n"); + return -ERANGE; + } input_clk_hz = clk_get_rate(pwm_chip->pwm_clk); output_clk_hz = DIV_ROUND_UP(NSEC_PER_SEC, period_ns); mul = DIV_ROUND_UP(input_clk_hz, output_clk_hz); - if (mul <= MAX_TMBASE_STEPS) { + if (mul <= max_timebase) { div = PWM_CTRL_CFG_NO_SUB_DIV; timebase = DIV_ROUND_UP(mul, 1); - } else if (mul <= MAX_TMBASE_STEPS * 8) { + } else if (mul <= max_timebase * 8) { div = PWM_CTRL_CFG_SUB_DIV0; timebase = DIV_ROUND_UP(mul, 8); - } else if (mul <= MAX_TMBASE_STEPS * 64) { + } else if (mul <= max_timebase * 64) { div = PWM_CTRL_CFG_SUB_DIV1; timebase = DIV_ROUND_UP(mul, 64); - } else if (mul <= MAX_TMBASE_STEPS * 512) { + } else if (mul <= max_timebase * 512) { div = PWM_CTRL_CFG_SUB_DIV0_DIV1; timebase = DIV_ROUND_UP(mul, 512); - } else if (mul > MAX_TMBASE_STEPS * 512) { + } else if (mul > max_timebase * 512) { dev_err(chip->dev, "failed to configure timebase steps/divider value\n"); return -EINVAL; @@ -143,11 +169,27 @@ static const struct pwm_ops img_pwm_ops = { .owner = THIS_MODULE, }; +static const struct img_pwm_soc_data pistachio_pwm = { + .max_timebase = 255, +}; + +static const struct of_device_id img_pwm_of_match[] = { + { + .compatible = "img,pistachio-pwm", + .data = &pistachio_pwm, + }, + { } +}; +MODULE_DEVICE_TABLE(of, img_pwm_of_match); + static int img_pwm_probe(struct platform_device *pdev) { int ret; + u64 val; + unsigned long clk_rate; struct resource *res; struct img_pwm_chip *pwm; + const struct of_device_id *of_dev_id; pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); if (!pwm) @@ -160,6 +202,11 @@ static int img_pwm_probe(struct platform_device *pdev) if (IS_ERR(pwm->base)) return PTR_ERR(pwm->base); + of_dev_id = of_match_device(img_pwm_of_match, &pdev->dev); + if (!of_dev_id) + return -ENODEV; + pwm->data = of_dev_id->data; + pwm->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "img,cr-periph"); if (IS_ERR(pwm->periph_regs)) @@ -189,6 +236,17 @@ static int img_pwm_probe(struct platform_device *pdev) goto disable_sysclk; } + clk_rate = clk_get_rate(pwm->pwm_clk); + + /* The maximum input clock divider is 512 */ + val = (u64)NSEC_PER_SEC * 512 * pwm->data->max_timebase; + do_div(val, clk_rate); + pwm->max_period_ns = val; + + val = (u64)NSEC_PER_SEC * MIN_TMBASE_STEPS; + do_div(val, clk_rate); + pwm->min_period_ns = val; + pwm->chip.dev = &pdev->dev; pwm->chip.ops = &img_pwm_ops; pwm->chip.base = -1; @@ -228,12 +286,6 @@ static int img_pwm_remove(struct platform_device *pdev) return pwmchip_remove(&pwm_chip->chip); } -static const struct of_device_id img_pwm_of_match[] = { - { .compatible = "img,pistachio-pwm", }, - { } -}; -MODULE_DEVICE_TABLE(of, img_pwm_of_match); - static struct platform_driver img_pwm_driver = { .driver = { .name = "img-pwm", diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 8a4df7a1f2ee..e628d4c2f2ae 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -394,6 +394,7 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, static int da9052_regulator_probe(struct platform_device *pdev) { + const struct mfd_cell *cell = mfd_get_cell(pdev); struct regulator_config config = { }; struct da9052_regulator *regulator; struct da9052 *da9052; @@ -409,7 +410,7 @@ static int da9052_regulator_probe(struct platform_device *pdev) regulator->da9052 = da9052; regulator->info = find_regulator_info(regulator->da9052->chip_id, - pdev->id); + cell->id); if (regulator->info == NULL) { dev_err(&pdev->dev, "invalid regulator ID specified\n"); return -EINVAL; @@ -419,7 +420,7 @@ static int da9052_regulator_probe(struct platform_device *pdev) config.driver_data = regulator; config.regmap = da9052->regmap; if (pdata && pdata->regulators) { - config.init_data = pdata->regulators[pdev->id]; + config.init_data = pdata->regulators[cell->id]; } else { #ifdef CONFIG_OF struct device_node *nproot = da9052->dev->of_node; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6149ae01e11f..0fe4ad8826b2 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -164,6 +164,16 @@ config RTC_DRV_ABB5ZES3 This driver can also be built as a module. If so, the module will be called rtc-ab-b5ze-s3. +config RTC_DRV_ABX80X + tristate "Abracon ABx80x" + help + If you say yes here you get support for Abracon AB080X and AB180X + families of ultra-low-power battery- and capacitor-backed real-time + clock chips. + + This driver can also be built as a module. If so, the module + will be called rtc-abx80x. + config RTC_DRV_AS3722 tristate "ams AS3722 RTC driver" depends on MFD_AS3722 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index c31731c29762..2b82e2b0311b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o +obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c new file mode 100644 index 000000000000..4337c3bc6ace --- /dev/null +++ b/drivers/rtc/rtc-abx80x.c @@ -0,0 +1,307 @@ +/* + * A driver for the I2C members of the Abracon AB x8xx RTC family, + * and compatible: AB 1805 and AB 0805 + * + * Copyright 2014-2015 Macq S.A. + * + * Author: Philippe De Muyter <phdm@macqel.be> + * Author: Alexandre Belloni <alexandre.belloni@free-electrons.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/bcd.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/rtc.h> + +#define ABX8XX_REG_HTH 0x00 +#define ABX8XX_REG_SC 0x01 +#define ABX8XX_REG_MN 0x02 +#define ABX8XX_REG_HR 0x03 +#define ABX8XX_REG_DA 0x04 +#define ABX8XX_REG_MO 0x05 +#define ABX8XX_REG_YR 0x06 +#define ABX8XX_REG_WD 0x07 + +#define ABX8XX_REG_CTRL1 0x10 +#define ABX8XX_CTRL_WRITE BIT(1) +#define ABX8XX_CTRL_12_24 BIT(6) + +#define ABX8XX_REG_CFG_KEY 0x1f +#define ABX8XX_CFG_KEY_MISC 0x9d + +#define ABX8XX_REG_ID0 0x28 + +#define ABX8XX_REG_TRICKLE 0x20 +#define ABX8XX_TRICKLE_CHARGE_ENABLE 0xa0 +#define ABX8XX_TRICKLE_STANDARD_DIODE 0x8 +#define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4 + +static u8 trickle_resistors[] = {0, 3, 6, 11}; + +enum abx80x_chip {AB0801, AB0803, AB0804, AB0805, + AB1801, AB1803, AB1804, AB1805, ABX80X}; + +struct abx80x_cap { + u16 pn; + bool has_tc; +}; + +static struct abx80x_cap abx80x_caps[] = { + [AB0801] = {.pn = 0x0801}, + [AB0803] = {.pn = 0x0803}, + [AB0804] = {.pn = 0x0804, .has_tc = true}, + [AB0805] = {.pn = 0x0805, .has_tc = true}, + [AB1801] = {.pn = 0x1801}, + [AB1803] = {.pn = 0x1803}, + [AB1804] = {.pn = 0x1804, .has_tc = true}, + [AB1805] = {.pn = 0x1805, .has_tc = true}, + [ABX80X] = {.pn = 0} +}; + +static struct i2c_driver abx80x_driver; + +static int abx80x_enable_trickle_charger(struct i2c_client *client, + u8 trickle_cfg) +{ + int err; + + /* + * Write the configuration key register to enable access to the Trickle + * register + */ + err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, + ABX8XX_CFG_KEY_MISC); + if (err < 0) { + dev_err(&client->dev, "Unable to write configuration key\n"); + return -EIO; + } + + err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE, + ABX8XX_TRICKLE_CHARGE_ENABLE | + trickle_cfg); + if (err < 0) { + dev_err(&client->dev, "Unable to write trickle register\n"); + return -EIO; + } + + return 0; +} + +static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + unsigned char buf[8]; + int err; + + err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, + sizeof(buf), buf); + if (err < 0) { + dev_err(&client->dev, "Unable to read date\n"); + return -EIO; + } + + tm->tm_sec = bcd2bin(buf[ABX8XX_REG_SC] & 0x7F); + tm->tm_min = bcd2bin(buf[ABX8XX_REG_MN] & 0x7F); + tm->tm_hour = bcd2bin(buf[ABX8XX_REG_HR] & 0x3F); + tm->tm_wday = buf[ABX8XX_REG_WD] & 0x7; + tm->tm_mday = bcd2bin(buf[ABX8XX_REG_DA] & 0x3F); + tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F) - 1; + tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 100; + + err = rtc_valid_tm(tm); + if (err < 0) + dev_err(&client->dev, "retrieved date/time is not valid.\n"); + + return err; +} + +static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + unsigned char buf[8]; + int err; + + if (tm->tm_year < 100) + return -EINVAL; + + buf[ABX8XX_REG_HTH] = 0; + buf[ABX8XX_REG_SC] = bin2bcd(tm->tm_sec); + buf[ABX8XX_REG_MN] = bin2bcd(tm->tm_min); + buf[ABX8XX_REG_HR] = bin2bcd(tm->tm_hour); + buf[ABX8XX_REG_DA] = bin2bcd(tm->tm_mday); + buf[ABX8XX_REG_MO] = bin2bcd(tm->tm_mon + 1); + buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 100); + buf[ABX8XX_REG_WD] = tm->tm_wday; + + err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_HTH, + sizeof(buf), buf); + if (err < 0) { + dev_err(&client->dev, "Unable to write to date registers\n"); + return -EIO; + } + + return 0; +} + +static const struct rtc_class_ops abx80x_rtc_ops = { + .read_time = abx80x_rtc_read_time, + .set_time = abx80x_rtc_set_time, +}; + +static int abx80x_dt_trickle_cfg(struct device_node *np) +{ + const char *diode; + int trickle_cfg = 0; + int i, ret; + u32 tmp; + + ret = of_property_read_string(np, "abracon,tc-diode", &diode); + if (ret) + return ret; + + if (!strcmp(diode, "standard")) + trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE; + else if (!strcmp(diode, "schottky")) + trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE; + else + return -EINVAL; + + ret = of_property_read_u32(np, "abracon,tc-resistor", &tmp); + if (ret) + return ret; + + for (i = 0; i < sizeof(trickle_resistors); i++) + if (trickle_resistors[i] == tmp) + break; + + if (i == sizeof(trickle_resistors)) + return -EINVAL; + + return (trickle_cfg | i); +} + +static int abx80x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct rtc_device *rtc; + int i, data, err, trickle_cfg = -EINVAL; + char buf[7]; + unsigned int part = id->driver_data; + unsigned int partnumber; + unsigned int majrev, minrev; + unsigned int lot; + unsigned int wafer; + unsigned int uid; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ID0, + sizeof(buf), buf); + if (err < 0) { + dev_err(&client->dev, "Unable to read partnumber\n"); + return -EIO; + } + + partnumber = (buf[0] << 8) | buf[1]; + majrev = buf[2] >> 3; + minrev = buf[2] & 0x7; + lot = ((buf[4] & 0x80) << 2) | ((buf[6] & 0x80) << 1) | buf[3]; + uid = ((buf[4] & 0x7f) << 8) | buf[5]; + wafer = (buf[6] & 0x7c) >> 2; + dev_info(&client->dev, "model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n", + partnumber, majrev, minrev, lot, wafer, uid); + + data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL1); + if (data < 0) { + dev_err(&client->dev, "Unable to read control register\n"); + return -EIO; + } + + err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1, + ((data & ~ABX8XX_CTRL_12_24) | + ABX8XX_CTRL_WRITE)); + if (err < 0) { + dev_err(&client->dev, "Unable to write control register\n"); + return -EIO; + } + + /* part autodetection */ + if (part == ABX80X) { + for (i = 0; abx80x_caps[i].pn; i++) + if (partnumber == abx80x_caps[i].pn) + break; + if (abx80x_caps[i].pn == 0) { + dev_err(&client->dev, "Unknown part: %04x\n", + partnumber); + return -EINVAL; + } + part = i; + } + + if (partnumber != abx80x_caps[part].pn) { + dev_err(&client->dev, "partnumber mismatch %04x != %04x\n", + partnumber, abx80x_caps[part].pn); + return -EINVAL; + } + + if (np && abx80x_caps[part].has_tc) + trickle_cfg = abx80x_dt_trickle_cfg(np); + + if (trickle_cfg > 0) { + dev_info(&client->dev, "Enabling trickle charger: %02x\n", + trickle_cfg); + abx80x_enable_trickle_charger(client, trickle_cfg); + } + + rtc = devm_rtc_device_register(&client->dev, abx80x_driver.driver.name, + &abx80x_rtc_ops, THIS_MODULE); + + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + i2c_set_clientdata(client, rtc); + + return 0; +} + +static int abx80x_remove(struct i2c_client *client) +{ + return 0; +} + +static const struct i2c_device_id abx80x_id[] = { + { "abx80x", ABX80X }, + { "ab0801", AB0801 }, + { "ab0803", AB0803 }, + { "ab0804", AB0804 }, + { "ab0805", AB0805 }, + { "ab1801", AB1801 }, + { "ab1803", AB1803 }, + { "ab1804", AB1804 }, + { "ab1805", AB1805 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, abx80x_id); + +static struct i2c_driver abx80x_driver = { + .driver = { + .name = "rtc-abx80x", + }, + .probe = abx80x_probe, + .remove = abx80x_remove, + .id_table = abx80x_id, +}; + +module_i2c_driver(abx80x_driver); + +MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>"); +MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); +MODULE_DESCRIPTION("Abracon ABX80X RTC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 43e04af39e09..4b62d1a875e4 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c @@ -40,6 +40,13 @@ struct armada38x_rtc { void __iomem *regs; void __iomem *regs_soc; spinlock_t lock; + /* + * While setting the time, the RTC TIME register should not be + * accessed. Setting the RTC time involves sleeping during + * 100ms, so a mutex instead of a spinlock is used to protect + * it + */ + struct mutex mutex_time; int irq; }; @@ -57,10 +64,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); - unsigned long time, time_check, flags; - - spin_lock_irqsave(&rtc->lock, flags); + unsigned long time, time_check; + mutex_lock(&rtc->mutex_time); time = readl(rtc->regs + RTC_TIME); /* * WA for failing time set attempts. As stated in HW ERRATA if @@ -71,7 +77,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) if ((time_check - time) > 1) time_check = readl(rtc->regs + RTC_TIME); - spin_unlock_irqrestore(&rtc->lock, flags); + mutex_unlock(&rtc->mutex_time); rtc_time_to_tm(time_check, tm); @@ -94,19 +100,12 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) * then wait for 100ms before writing to the time register to be * sure that the data will be taken into account. */ - spin_lock_irqsave(&rtc->lock, flags); - + mutex_lock(&rtc->mutex_time); rtc_delayed_write(0, rtc, RTC_STATUS); - - spin_unlock_irqrestore(&rtc->lock, flags); - msleep(100); - - spin_lock_irqsave(&rtc->lock, flags); - rtc_delayed_write(time, rtc, RTC_TIME); + mutex_unlock(&rtc->mutex_time); - spin_unlock_irqrestore(&rtc->lock, flags); out: return ret; } @@ -230,6 +229,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) return -ENOMEM; spin_lock_init(&rtc->lock); + mutex_init(&rtc->mutex_time); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); rtc->regs = devm_ioremap_resource(&pdev->dev, res); diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index f0b9871a4bbd..3ba611419759 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1158,11 +1158,12 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, poll_timeout = time; hr_time = ktime_set(0, poll_timeout); - if (!hrtimer_is_queued(&ap_poll_timer) || - !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) { - hrtimer_set_expires(&ap_poll_timer, hr_time); - hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS); - } + spin_lock_bh(&ap_poll_timer_lock); + hrtimer_cancel(&ap_poll_timer); + hrtimer_set_expires(&ap_poll_timer, hr_time); + hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS); + spin_unlock_bh(&ap_poll_timer_lock); + return count; } @@ -1528,14 +1529,11 @@ static inline void __ap_schedule_poll_timer(void) ktime_t hr_time; spin_lock_bh(&ap_poll_timer_lock); - if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag) - goto out; - if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) { + if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) { hr_time = ktime_set(0, poll_timeout); hrtimer_forward_now(&ap_poll_timer, hr_time); hrtimer_restart(&ap_poll_timer); } -out: spin_unlock_bh(&ap_poll_timer_lock); } @@ -1952,7 +1950,7 @@ static void ap_reset_domain(void) { int i; - if (ap_domain_index != -1) + if ((ap_domain_index != -1) && (ap_test_config_domain(ap_domain_index))) for (i = 0; i < AP_DEVICES; i++) ap_reset_queue(AP_MKQID(i, ap_domain_index)); } @@ -2097,7 +2095,6 @@ void ap_module_exit(void) hrtimer_cancel(&ap_poll_timer); destroy_workqueue(ap_work_queue); tasklet_kill(&ap_tasklet); - root_device_unregister(ap_root_device); while ((dev = bus_find_device(&ap_bus_type, NULL, NULL, __ap_match_all))) { @@ -2106,6 +2103,7 @@ void ap_module_exit(void) } for (i = 0; ap_bus_attrs[i]; i++) bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); + root_device_unregister(ap_root_device); bus_unregister(&ap_bus_type); unregister_reset_call(&ap_reset_call); if (ap_using_interrupts()) diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 81e83a65a193..32070099c333 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,9 +8,9 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 1028760b8a22..447cf7ce606e 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,9 +8,9 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 98897434bcb4..f11d325fe696 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,9 +8,9 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index b7391a3f9f0b..2f0700796842 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index e0b3b2d1f27a..0c84e1c0763a 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 923a2b5a2439..1f74760ce86c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ @@ -50,7 +50,7 @@ static unsigned int enable_msix = 1; MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); MODULE_VERSION(BUILD_STR); -MODULE_AUTHOR("Emulex Corporation"); +MODULE_AUTHOR("Avago Technologies"); MODULE_LICENSE("GPL"); module_param(be_iopoll_budget, int, 0); module_param(enable_msix, int, 0); @@ -552,7 +552,7 @@ MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); static struct scsi_host_template beiscsi_sht = { .module = THIS_MODULE, - .name = "Emulex 10Gbe open-iscsi Initiator Driver", + .name = "Avago Technologies 10Gbe open-iscsi Initiator Driver", .proc_name = DRV_NAME, .queuecommand = iscsi_queuecommand, .change_queue_depth = scsi_change_queue_depth, diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 7ee0ffc38514..e70ea26bbc2b 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ @@ -37,7 +37,7 @@ #define DRV_NAME "be2iscsi" #define BUILD_STR "10.4.114.0" -#define BE_NAME "Emulex OneConnect" \ +#define BE_NAME "Avago Technologies OneConnect" \ "Open-iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 681d4e8f003a..c2c4d6975fb7 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index bd81446936fc..9356b9a86b66 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2014 Emulex + * Copyright (C) 2005 - 2015 Avago Technologies * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,12 +7,12 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) * * Contact Information: - * linux-drivers@emulex.com + * linux-drivers@avagotech.com * - * Emulex + * Avago Technologies * 3333 Susan Street * Costa Mesa, CA 92626 */ diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index cb73cf9e9ba5..c140f99772ca 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1130,25 +1130,6 @@ lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) } /** - * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB - * @data: A pointer to the immediate command data portion of the IOCB. - * @fcp_cmnd: The FCP Command that is provided by the SCSI layer. - * - * The routine copies the entire FCP command from @fcp_cmnd to @data while - * byte swapping the data to big endian format for transmission on the wire. - **/ -static void -lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd) -{ - int i, j; - - for (i = 0, j = 0; i < sizeof(struct fcp_cmnd); - i += sizeof(uint32_t), j++) { - ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]); - } -} - -/** * lpfc_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec * @phba: The Hba for which this call is being executed. * @lpfc_cmd: The scsi buffer which is going to be mapped. @@ -1283,7 +1264,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) * we need to set word 4 of IOCB here */ iocb_cmd->un.fcpi.fcpi_parm = scsi_bufflen(scsi_cmnd); - lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd); return 0; } @@ -4147,6 +4127,24 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, } /** + * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB + * @data: A pointer to the immediate command data portion of the IOCB. + * @fcp_cmnd: The FCP Command that is provided by the SCSI layer. + * + * The routine copies the entire FCP command from @fcp_cmnd to @data while + * byte swapping the data to big endian format for transmission on the wire. + **/ +static void +lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd) +{ + int i, j; + for (i = 0, j = 0; i < sizeof(struct fcp_cmnd); + i += sizeof(uint32_t), j++) { + ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]); + } +} + +/** * lpfc_scsi_prep_cmnd - Wrapper func for convert scsi cmnd to FCP info unit * @vport: The virtual port for which this call is being executed. * @lpfc_cmd: The scsi command which needs to send. @@ -4225,6 +4223,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, fcp_cmnd->fcpCntl3 = 0; phba->fc4ControlRequests++; } + if (phba->sli_rev == 3 && + !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) + lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd); /* * Finish initializing those IOCB fields that are independent * of the scsi_cmnd request_buffer diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 68c2002e78bf..5c9e680aa375 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1020,8 +1020,7 @@ static void tcm_qla2xxx_depend_tpg(struct work_struct *work) struct se_portal_group *se_tpg = &base_tpg->se_tpg; struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; - if (!configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys, - &se_tpg->tpg_group.cg_item)) { + if (!target_depend_item(&se_tpg->tpg_group.cg_item)) { atomic_set(&base_tpg->lport_tpg_enabled, 1); qlt_enable_vha(base_vha); } @@ -1037,8 +1036,7 @@ static void tcm_qla2xxx_undepend_tpg(struct work_struct *work) if (!qlt_stop_phase1(base_vha->vha_tgt.qla_tgt)) { atomic_set(&base_tpg->lport_tpg_enabled, 0); - configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys, - &se_tpg->tpg_group.cg_item); + target_undepend_item(&se_tpg->tpg_group.cg_item); } complete(&base_tpg->tpg_base_comp); } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 79beebf53302..7f9d65fe4fd9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1600,6 +1600,7 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) { u64 start_lba = blk_rq_pos(scmd->request); u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512); + u64 factor = scmd->device->sector_size / 512; u64 bad_lba; int info_valid; /* @@ -1621,16 +1622,9 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) if (scsi_bufflen(scmd) <= scmd->device->sector_size) return 0; - if (scmd->device->sector_size < 512) { - /* only legitimate sector_size here is 256 */ - start_lba <<= 1; - end_lba <<= 1; - } else { - /* be careful ... don't want any overflows */ - unsigned int factor = scmd->device->sector_size / 512; - do_div(start_lba, factor); - do_div(end_lba, factor); - } + /* be careful ... don't want any overflows */ + do_div(start_lba, factor); + do_div(end_lba, factor); /* The bad lba was reported incorrectly, we have no idea where * the error is. @@ -2188,8 +2182,7 @@ got_data: if (sector_size != 512 && sector_size != 1024 && sector_size != 2048 && - sector_size != 4096 && - sector_size != 256) { + sector_size != 4096) { sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", sector_size); /* @@ -2244,8 +2237,6 @@ got_data: sdkp->capacity <<= 2; else if (sector_size == 1024) sdkp->capacity <<= 1; - else if (sector_size == 256) - sdkp->capacity >>= 1; blk_queue_physical_block_size(sdp->request_queue, sdkp->physical_block_size); diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index d9dad90344d5..3c6584ff65c1 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1600,8 +1600,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) break; default: vm_srb->data_in = UNKNOWN_TYPE; - vm_srb->win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN | - SRB_FLAGS_DATA_OUT); + vm_srb->win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER; break; } diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 198f96b7fb45..72b059081559 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -78,6 +78,7 @@ config SPI_ATMEL config SPI_BCM2835 tristate "BCM2835 SPI controller" depends on ARCH_BCM2835 || COMPILE_TEST + depends on GPIOLIB help This selects a driver for the Broadcom BCM2835 SPI master. @@ -302,7 +303,7 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" select REGMAP_MMIO - depends on SOC_VF610 || COMPILE_TEST + depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST help This enables support for the Freescale DSPI controller in master mode. VF610 platform uses the controller. diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index f63864a893c5..37875cf942f7 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, unsigned long xfer_time_us) { struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long timeout = jiffies + - max(4 * xfer_time_us * HZ / 1000000, 2uL); + /* set timeout to 1 second of maximum polling */ + unsigned long timeout = jiffies + HZ; /* enable HW block without interrupts */ bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); - /* set timeout to 4x the expected time, or 2 jiffies */ /* loop until finished the transfer */ while (bs->rx_len) { /* read from fifo as much as possible */ diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 5ef6638d5e8a..840a4984d365 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; - int retval; unsigned long flags; bitbang = spi_master_get_devdata(spi->master); @@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi) if (!cs->txrx_word) return -EINVAL; - retval = bitbang->setup_transfer(spi, NULL); - if (retval < 0) - return retval; + if (bitbang->setup_transfer) { + int retval = bitbang->setup_transfer(spi, NULL); + if (retval < 0) + return retval; + } dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); @@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master, /* init (-1) or override (1) transfer params */ if (do_setup != 0) { - status = bitbang->setup_transfer(spi, t); - if (status < 0) - break; + if (bitbang->setup_transfer) { + status = bitbang->setup_transfer(spi, t); + if (status < 0) + break; + } if (do_setup == -1) do_setup = 0; } diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 9c46a3058743..896add8cfd3b 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -24,6 +24,7 @@ #include <linux/of_address.h> #include <linux/spi/spi.h> #include <linux/types.h> +#include <linux/platform_device.h> #include "spi-fsl-cpm.h" #include "spi-fsl-lib.h" @@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) if (mspi->flags & SPI_CPM2) { pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); out_be16(spi_base, pram_ofs); - } else { - struct spi_pram __iomem *pram = spi_base; - u16 rpbase = in_be16(&pram->rpbase); - - /* Microcode relocation patch applied? */ - if (rpbase) { - pram_ofs = rpbase; - } else { - pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); - out_be16(spi_base, pram_ofs); - } } iounmap(spi_base); @@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) struct device_node *np = dev->of_node; const u32 *iprop; int size; - unsigned long pram_ofs; unsigned long bds_ofs; if (!(mspi->flags & SPI_CPM_MODE)) @@ -319,8 +308,26 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) } } - pram_ofs = fsl_spi_cpm_get_pram(mspi); - if (IS_ERR_VALUE(pram_ofs)) { + if (mspi->flags & SPI_CPM1) { + struct resource *res; + void *pram; + + res = platform_get_resource(to_platform_device(dev), + IORESOURCE_MEM, 1); + pram = devm_ioremap_resource(dev, res); + if (IS_ERR(pram)) + mspi->pram = NULL; + else + mspi->pram = pram; + } else { + unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi); + + if (IS_ERR_VALUE(pram_ofs)) + mspi->pram = NULL; + else + mspi->pram = cpm_muram_addr(pram_ofs); + } + if (mspi->pram == NULL) { dev_err(dev, "can't allocate spi parameter ram\n"); goto err_pram; } @@ -346,8 +353,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) goto err_dummy_rx; } - mspi->pram = cpm_muram_addr(pram_ofs); - mspi->tx_bd = cpm_muram_addr(bds_ofs); mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); @@ -375,7 +380,8 @@ err_dummy_rx: err_dummy_tx: cpm_muram_free(bds_ofs); err_bds: - cpm_muram_free(pram_ofs); + if (!(mspi->flags & SPI_CPM1)) + cpm_muram_free(cpm_muram_offset(mspi->pram)); err_pram: fsl_spi_free_dummy_rx(); return -ENOMEM; diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index d0a73a09a9bd..80d245ac846f 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -359,14 +359,16 @@ static void fsl_espi_rw_trans(struct spi_message *m, struct fsl_espi_transfer *trans, u8 *rx_buff) { struct fsl_espi_transfer *espi_trans = trans; - unsigned int n_tx = espi_trans->n_tx; - unsigned int n_rx = espi_trans->n_rx; + unsigned int total_len = espi_trans->len; struct spi_transfer *t; u8 *local_buf; u8 *rx_buf = rx_buff; unsigned int trans_len; unsigned int addr; - int i, pos, loop; + unsigned int tx_only; + unsigned int rx_pos = 0; + unsigned int pos; + int i, loop; local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); if (!local_buf) { @@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m, return; } - for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) { - trans_len = n_rx - pos; - if (trans_len > SPCOM_TRANLEN_MAX - n_tx) - trans_len = SPCOM_TRANLEN_MAX - n_tx; + for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) { + trans_len = total_len - pos; i = 0; + tx_only = 0; list_for_each_entry(t, &m->transfers, transfer_list) { if (t->tx_buf) { memcpy(local_buf + i, t->tx_buf, t->len); i += t->len; + if (!t->rx_buf) + tx_only += t->len; } } + /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */ + if (loop > 0) + trans_len += tx_only; + + if (trans_len > SPCOM_TRANLEN_MAX) + trans_len = SPCOM_TRANLEN_MAX; + + /* Update device offset */ if (pos > 0) { addr = fsl_espi_cmd2addr(local_buf); - addr += pos; + addr += rx_pos; fsl_espi_addr2cmd(addr, local_buf); } - espi_trans->n_tx = n_tx; - espi_trans->n_rx = trans_len; - espi_trans->len = trans_len + n_tx; + espi_trans->len = trans_len; espi_trans->tx_buf = local_buf; espi_trans->rx_buf = local_buf; fsl_espi_do_trans(m, espi_trans); - memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); + /* If there is at least one RX byte then copy it to rx_buf */ + if (tx_only < SPCOM_TRANLEN_MAX) + memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only, + trans_len - tx_only); + + rx_pos += trans_len - tx_only; if (loop > 0) - espi_trans->actual_length += espi_trans->len - n_tx; + espi_trans->actual_length += espi_trans->len - tx_only; else espi_trans->actual_length += espi_trans->len; } @@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master, u8 *rx_buf = NULL; unsigned int n_tx = 0; unsigned int n_rx = 0; + unsigned int xfer_len = 0; struct fsl_espi_transfer espi_trans; list_for_each_entry(t, &m->transfers, transfer_list) { @@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master, n_rx += t->len; rx_buf = t->rx_buf; } + if ((t->tx_buf) || (t->rx_buf)) + xfer_len += t->len; } espi_trans.n_tx = n_tx; espi_trans.n_rx = n_rx; - espi_trans.len = n_tx + n_rx; + espi_trans.len = xfer_len; espi_trans.actual_length = 0; espi_trans.status = 0; diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 4df8942058de..d1a5b9fc3eba 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; struct spi_transfer *t; + int status; spi = m->spi; mcspi = spi_master_get_devdata(master); @@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, tx_buf ? "tx" : "", rx_buf ? "rx" : "", t->bits_per_word); - return -EINVAL; + status = -EINVAL; + goto out; } if (m->is_dma_mapped || len < DMA_MIN_BYTES) @@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, if (dma_mapping_error(mcspi->dev, t->tx_dma)) { dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", 'T', len); - return -EINVAL; + status = -EINVAL; + goto out; } } if (mcspi_dma->dma_rx && rx_buf != NULL) { @@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, if (tx_buf != NULL) dma_unmap_single(mcspi->dev, t->tx_dma, len, DMA_TO_DEVICE); - return -EINVAL; + status = -EINVAL; + goto out; } } } omap2_mcspi_work(mcspi, m); + /* spi_finalize_current_message() changes the status inside the + * spi_message, save the status here. */ + status = m->status; +out: spi_finalize_current_message(master); - return 0; + return status; } static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d5d7d2235163..50910d85df5a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -583,6 +583,15 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) rx_dev = master->dma_rx->device->dev; list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* + * Restore the original value of tx_buf or rx_buf if they are + * NULL. + */ + if (xfer->tx_buf == master->dummy_tx) + xfer->tx_buf = NULL; + if (xfer->rx_buf == master->dummy_rx) + xfer->rx_buf = NULL; + if (!master->can_dma(master, msg->spi, xfer)) continue; diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 15a7ee3859dd..5fe1c22e289b 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -359,12 +359,13 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) /* * Accessing PCI config without a proper delay after devices reset (not - * GPIO reset) was causing reboots on WRT300N v1.0. + * GPIO reset) was causing reboots on WRT300N v1.0 (BCM4704). * Tested delay 850 us lowered reboot chance to 50-80%, 1000 us fixed it * completely. Flushing all writes was also tested but with no luck. + * The same problem was reported for WRT350N v1 (BCM4705), so we just + * sleep here unconditionally. */ - if (pc->dev->bus->chip_id == 0x4704) - usleep_range(1000, 2000); + usleep_range(1000, 2000); /* Enable PCI bridge BAR0 prefetch and burst */ val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index bfacf69f68f4..7f6cae5beb90 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -108,8 +108,8 @@ source "drivers/staging/clocking-wizard/Kconfig" source "drivers/staging/fbtft/Kconfig" -source "drivers/staging/i2o/Kconfig" - source "drivers/staging/fsl-mc/Kconfig" +source "drivers/staging/wilc1000/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a12221f086c2..347f6477aa3e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -46,5 +46,5 @@ obj-$(CONFIG_CRYPTO_SKEIN) += skein/ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ obj-$(CONFIG_FB_TFT) += fbtft/ -obj-$(CONFIG_I2O) += i2o/ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/ +obj-$(CONFIG_WILC1000) += wilc1000/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 8feb9048e62f..24d657b3ab99 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -22,11 +22,20 @@ config ANDROID_TIMED_GPIO tristate "Android timed gpio driver" depends on GPIOLIB && ANDROID_TIMED_OUTPUT default n + ---help--- + Unlike generic gpio is to allow programs to access and manipulate gpio + registers from user space, timed output/gpio is a system to allow changing + a gpio pin and restore it automatically after a specified timeout. config ANDROID_LOW_MEMORY_KILLER bool "Android Low Memory Killer" ---help--- - Registers processes to be killed when memory is low + Registers processes to be killed when low memory conditions, this is useful + as there is no particular swap space on android. + + The registered process will kills according to the priorities in android init + scripts (/init.rc), and it defines priority values with minimum free memory size + for each priority. config SYNC bool "Synchronization framework" diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index b0b96ab31954..6f4811263557 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1579,6 +1579,7 @@ struct ion_device *ion_device_create(long (*custom_ioctl) ret = misc_register(&idev->dev); if (ret) { pr_err("ion: failed to register misc device.\n"); + kfree(idev); return ERR_PTR(ret); } diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index feafa172b155..defddf5f80dd 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -156,20 +156,27 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) p->pid, p->comm, oom_score_adj, tasksize); } if (selected) { - lowmem_print(1, "send sigkill to %d (%s), adj %hd, size %d\n", - selected->pid, selected->comm, - selected_oom_score_adj, selected_tasksize); - lowmem_deathpending_timeout = jiffies + HZ; + task_lock(selected); + if (!selected->mm) { + /* Already exited, cannot do mark_tsk_oom_victim() */ + task_unlock(selected); + goto out; + } /* * FIXME: lowmemorykiller shouldn't abuse global OOM killer * infrastructure. There is no real reason why the selected * task should have access to the memory reserves. */ mark_tsk_oom_victim(selected); + task_unlock(selected); + lowmem_print(1, "send sigkill to %d (%s), adj %hd, size %d\n", + selected->pid, selected->comm, + selected_oom_score_adj, selected_tasksize); + lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); rem += selected_tasksize; } - +out: lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", sc->nr_to_scan, sc->gfp_mask, rem); rcu_read_unlock(); diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 61c6351f55ac..7dee73dfbf88 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1247,16 +1247,22 @@ config COMEDI_8254 tristate config COMEDI_8255 - tristate "Generic 8255 support" + tristate + +config COMEDI_8255_SA + tristate "Standalone 8255 support" + select COMEDI_8255 ---help--- - Enable generic 8255 support. + Enable support for 8255 digital I/O as a standalone driver. You should enable compilation this driver if you plan to use a board - that has an 8255 chip. For multifunction boards, the main driver will - configure the 8255 subdevice automatically. + that has an 8255 chip at a known I/O base address and there are no + other Comedi drivers for the board. - Note that most PCI based 8255 boards use the 8255_pci driver as a - wrapper around this driver. + Note that Comedi drivers for most multi-function boards incorporating + an 8255 chip use the 'comedi_8255' module. Most PCI-based 8255 + boards use the 8255_pci driver as a wrapper around the 'comedi_8255' + module. To compile this driver as a module, choose M here: the module will be called 8255. diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 745574077352..66edda190b75 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -217,7 +217,7 @@ #define SDF_RUNNING 0x08000000 /* subdevice is acquiring data */ #define SDF_LSAMPL 0x10000000 /* subdevice uses 32-bit samples */ #define SDF_PACKED 0x20000000 /* subdevice can do packed DIO */ -/* re recyle these flags for PWM */ +/* re recycle these flags for PWM */ #define SDF_PWM_COUNTER SDF_MODE0 /* PWM can automatically switch off */ #define SDF_PWM_HBRIDGE SDF_MODE1 /* PWM is signed (H-bridge) */ diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index ba89321df65d..b79d3764a8a0 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -53,221 +53,6 @@ #include "8255.h" -struct subdev_8255_private { - unsigned long regbase; - int (*io)(struct comedi_device *, int, int, int, unsigned long); -}; - -static int subdev_8255_io(struct comedi_device *dev, - int dir, int port, int data, unsigned long regbase) -{ - if (dir) { - outb(data, dev->iobase + regbase + port); - return 0; - } - return inb(dev->iobase + regbase + port); -} - -static int subdev_8255_mmio(struct comedi_device *dev, - int dir, int port, int data, unsigned long regbase) -{ - if (dir) { - writeb(data, dev->mmio + regbase + port); - return 0; - } - return readb(dev->mmio + regbase + port); -} - -static int subdev_8255_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct subdev_8255_private *spriv = s->private; - unsigned long regbase = spriv->regbase; - unsigned int mask; - unsigned int v; - - mask = comedi_dio_update_state(s, data); - if (mask) { - if (mask & 0xff) - spriv->io(dev, 1, I8255_DATA_A_REG, - s->state & 0xff, regbase); - if (mask & 0xff00) - spriv->io(dev, 1, I8255_DATA_B_REG, - (s->state >> 8) & 0xff, regbase); - if (mask & 0xff0000) - spriv->io(dev, 1, I8255_DATA_C_REG, - (s->state >> 16) & 0xff, regbase); - } - - v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase); - v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8); - v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16); - - data[1] = v; - - return insn->n; -} - -static void subdev_8255_do_config(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct subdev_8255_private *spriv = s->private; - unsigned long regbase = spriv->regbase; - int config; - - config = I8255_CTRL_CW; - /* 1 in io_bits indicates output, 1 in config indicates input */ - if (!(s->io_bits & 0x0000ff)) - config |= I8255_CTRL_A_IO; - if (!(s->io_bits & 0x00ff00)) - config |= I8255_CTRL_B_IO; - if (!(s->io_bits & 0x0f0000)) - config |= I8255_CTRL_C_LO_IO; - if (!(s->io_bits & 0xf00000)) - config |= I8255_CTRL_C_HI_IO; - - spriv->io(dev, 1, I8255_CTRL_REG, config, regbase); -} - -static int subdev_8255_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask; - int ret; - - if (chan < 8) - mask = 0x0000ff; - else if (chan < 16) - mask = 0x00ff00; - else if (chan < 20) - mask = 0x0f0000; - else - mask = 0xf00000; - - ret = comedi_dio_insn_config(dev, s, insn, data, mask); - if (ret) - return ret; - - subdev_8255_do_config(dev, s); - - return insn->n; -} - -static int __subdev_8255_init(struct comedi_device *dev, - struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase, - bool is_mmio) -{ - struct subdev_8255_private *spriv; - - spriv = comedi_alloc_spriv(s, sizeof(*spriv)); - if (!spriv) - return -ENOMEM; - - if (io) - spriv->io = io; - else if (is_mmio) - spriv->io = subdev_8255_mmio; - else - spriv->io = subdev_8255_io; - spriv->regbase = regbase; - - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 24; - s->range_table = &range_digital; - s->maxdata = 1; - s->insn_bits = subdev_8255_insn; - s->insn_config = subdev_8255_insn_config; - - subdev_8255_do_config(dev, s); - - return 0; -} - -/** - * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255 - * @dev: comedi device owning subdevice - * @s: comedi subdevice to initialize - * @io: (optional) register I/O call-back function - * @regbase: offset of 8255 registers from dev->iobase, or call-back context - * - * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. - * - * If the optional I/O call-back function is provided, its prototype is of - * the following form: - * - * int my_8255_callback(struct comedi_device *dev, - * struct comedi_subdevice *s, int dir, int port, - * int data, unsigned long regbase); - * - * where 'dev', 's', and 'regbase' match the values passed to this function, - * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' - * is the direction (0 for read, 1 for write) and 'data' is the value to be - * written. It should return 0 if writing or the value read if reading. - * - * If the optional I/O call-back function is not provided, an internal - * call-back function is used which uses consecutive I/O port addresses - * starting at dev->iobase + regbase. - * - * Return: -ENOMEM if failed to allocate memory, zero on success. - */ -int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase) -{ - return __subdev_8255_init(dev, s, io, regbase, false); -} -EXPORT_SYMBOL_GPL(subdev_8255_init); - -/** - * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255 - * @dev: comedi device owning subdevice - * @s: comedi subdevice to initialize - * @io: (optional) register I/O call-back function - * @regbase: offset of 8255 registers from dev->mmio, or call-back context - * - * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. - * - * If the optional I/O call-back function is provided, its prototype is of - * the following form: - * - * int my_8255_callback(struct comedi_device *dev, - * struct comedi_subdevice *s, int dir, int port, - * int data, unsigned long regbase); - * - * where 'dev', 's', and 'regbase' match the values passed to this function, - * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' - * is the direction (0 for read, 1 for write) and 'data' is the value to be - * written. It should return 0 if writing or the value read if reading. - * - * If the optional I/O call-back function is not provided, an internal - * call-back function is used which uses consecutive MMIO virtual addresses - * starting at dev->mmio + regbase. - * - * Return: -ENOMEM if failed to allocate memory, zero on success. - */ -int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase) -{ - return __subdev_8255_init(dev, s, io, regbase, true); -} -EXPORT_SYMBOL_GPL(subdev_8255_mm_init); - -/* - * Start of the 8255 standalone device - */ - static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -306,8 +91,15 @@ static int dev_8255_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } else { ret = subdev_8255_init(dev, s, NULL, iobase); - if (ret) + if (ret) { + /* + * Release the I/O port region here, as the + * "detach" handler cannot find it. + */ + release_region(iobase, I8255_SIZE); + s->type = COMEDI_SUBD_UNUSED; return ret; + } } } @@ -317,14 +109,14 @@ static int dev_8255_attach(struct comedi_device *dev, static void dev_8255_detach(struct comedi_device *dev) { struct comedi_subdevice *s; - struct subdev_8255_private *spriv; int i; for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; if (s->type != COMEDI_SUBD_UNUSED) { - spriv = s->private; - release_region(spriv->regbase, I8255_SIZE); + unsigned long regbase = subdev_8255_regbase(s); + + release_region(regbase, I8255_SIZE); } } } @@ -338,5 +130,5 @@ static struct comedi_driver dev_8255_driver = { module_comedi_driver(dev_8255_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for standalone 8255 devices"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 934b940ebd3c..41823de69b77 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -19,8 +19,6 @@ #ifndef _8255_H #define _8255_H -#include "../comedidev.h" - #define I8255_SIZE 0x04 #define I8255_DATA_A_REG 0x00 @@ -35,14 +33,19 @@ #define I8255_CTRL_A_MODE(x) ((x) << 5) #define I8255_CTRL_CW (1 << 7) -int subdev_8255_init(struct comedi_device *, struct comedi_subdevice *, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), +struct comedi_device; +struct comedi_subdevice; + +int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *dev, int dir, int port, + int data, unsigned long regbase), unsigned long regbase); -int subdev_8255_mm_init(struct comedi_device *, struct comedi_subdevice *, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), +int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *dev, int dir, int port, + int data, unsigned long regbase), unsigned long regbase); +unsigned long subdev_8255_regbase(struct comedi_subdevice *s); + #endif diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index d6d834006015..5764dc9a6893 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -139,7 +139,8 @@ obj-$(CONFIG_COMEDI_NI_TIOCMD) += ni_tiocmd.o obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc_common.o obj-$(CONFIG_COMEDI_NI_LABPC_ISADMA) += ni_labpc_isadma.o -obj-$(CONFIG_COMEDI_8255) += 8255.o +obj-$(CONFIG_COMEDI_8255) += comedi_8255.o +obj-$(CONFIG_COMEDI_8255_SA) += 8255.o obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200_common.o obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236_common.o obj-$(CONFIG_COMEDI_DAS08) += das08.o diff --git a/drivers/staging/comedi/drivers/addi_watchdog.h b/drivers/staging/comedi/drivers/addi_watchdog.h index 83b47befa4d1..3f8e7388bbca 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.h +++ b/drivers/staging/comedi/drivers/addi_watchdog.h @@ -1,7 +1,7 @@ #ifndef _ADDI_WATCHDOG_H #define _ADDI_WATCHDOG_H -#include "../comedidev.h" +struct comedi_subdevice; void addi_watchdog_reset(unsigned long iobase); int addi_watchdog_init(struct comedi_subdevice *, unsigned long iobase); diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index f7a7dab013db..9677111f9ab2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -180,11 +180,7 @@ static int adv_pci1724_auto_attach(struct comedi_device *dev, s->insn_write = adv_pci1724_insn_write; s->private = (void *)PCI1724_DAC_CTRL_MODE_GAIN; - ret = comedi_alloc_subdev_readback(s); - if (ret) - return ret; - - return 0; + return comedi_alloc_subdev_readback(s); } static struct comedi_driver adv_pci1724_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 4fe118380218..f5cfa71a90c6 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1,23 +1,24 @@ /* - comedi/drivers/amplc_dio200.c - - Driver for Amplicon PC212E, PC214E, PC215E, PC218E, PC272E. - - Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + * comedi/drivers/amplc_dio200.c + * + * Driver for Amplicon PC212E, PC214E, PC215E, PC218E, PC272E. + * + * Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* * Driver: amplc_dio200 * Description: Amplicon 200 Series ISA Digital I/O diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index d6d6a265c461..53fb86d59fc3 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -1,28 +1,32 @@ /* - comedi/drivers/amplc_dio.h - - Header for amplc_dio200.c, amplc_dio200_common.c and - amplc_dio200_pci.c. - - Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * comedi/drivers/amplc_dio.h + * + * Header for amplc_dio200.c, amplc_dio200_common.c and + * amplc_dio200_pci.c. + * + * Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef AMPLC_DIO200_H_INCLUDED #define AMPLC_DIO200_H_INCLUDED +#include <linux/types.h> + +struct comedi_device; + /* * Subdevice types. */ diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 3a8b3f27b525..d1539e798ffd 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -1,23 +1,23 @@ /* - comedi/drivers/amplc_dio200_common.c - - Common support code for "amplc_dio200" and "amplc_dio200_pci". - - Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * comedi/drivers/amplc_dio200_common.c + * + * Common support code for "amplc_dio200" and "amplc_dio200_pci". + * + * Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include <linux/module.h> #include <linux/interrupt.h> @@ -337,9 +337,10 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * interested in (just in case there's a race * condition). */ - if (triggered & subpriv->enabled_isns) + if (triggered & subpriv->enabled_isns) { /* Collect scan data. */ dio200_read_scan_intr(dev, s, triggered); + } } } spin_unlock_irqrestore(&subpriv->spinlock, flags); @@ -576,12 +577,13 @@ static int dio200_subdev_8254_init(struct comedi_device *dev, regshift = 0; } - if (dev->mmio) + if (dev->mmio) { i8254 = comedi_8254_mm_init(dev->mmio + offset, 0, I8254_IO8, regshift); - else + } else { i8254 = comedi_8254_init(dev->iobase + offset, 0, I8254_IO8, regshift); + } if (!i8254) return -ENOMEM; @@ -641,15 +643,18 @@ static int dio200_subdev_8255_bits(struct comedi_device *dev, mask = comedi_dio_update_state(s, data); if (mask) { - if (mask & 0xff) + if (mask & 0xff) { dio200_write8(dev, subpriv->ofs + I8255_DATA_A_REG, s->state & 0xff); - if (mask & 0xff00) + } + if (mask & 0xff00) { dio200_write8(dev, subpriv->ofs + I8255_DATA_B_REG, (s->state >> 8) & 0xff); - if (mask & 0xff0000) + } + if (mask & 0xff0000) { dio200_write8(dev, subpriv->ofs + I8255_DATA_C_REG, (s->state >> 16) & 0xff); + } } val = dio200_read8(dev, subpriv->ofs + I8255_DATA_A_REG); diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index d9850c917163..2598e6e7d47d 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -1,22 +1,23 @@ /* comedi/drivers/amplc_dio200_pci.c + * + * Driver for Amplicon PCI215, PCI272, PCIe215, PCIe236, PCIe296. + * + * Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - Driver for Amplicon PCI215, PCI272, PCIe215, PCIe236, PCIe296. - - Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/> - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* * Driver: amplc_dio200_pci * Description: Amplicon 200 Series PCI Digital I/O diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index a94c33c3d962..3d646c19f352 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -155,8 +155,10 @@ static inline unsigned int dac_msb_4020_reg(unsigned int channel) } enum read_only_registers { - /* hardware status register, - * reading this apparently clears pending interrupts as well */ + /* + * hardware status register, + * reading this apparently clears pending interrupts as well + */ HW_STATUS_REG = 0x0, PIPE1_READ_REG = 0x4, ADC_READ_PNTR_REG = 0x8, @@ -243,7 +245,8 @@ enum adc_control0_contents { ADC_SOFT_GATE_BITS = 0x1, /* software gate */ ADC_EXT_GATE_BITS = 0x2, /* external digital gate */ ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */ - ADC_GATE_LEVEL_BIT = 0x4, /* level-sensitive gate (for digital) */ + /* level-sensitive gate (for digital) */ + ADC_GATE_LEVEL_BIT = 0x4, ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */ ADC_START_TRIG_SOFT_BITS = 0x10, ADC_START_TRIG_EXT_BITS = 0x20, @@ -300,7 +303,8 @@ enum calibration_contents { CAL_GAIN_BIT = 0x800, }; -/* calibration sources for 6025 are: +/* + * calibration sources for 6025 are: * 0 : ground * 1 : 10V * 2 : 5V @@ -660,8 +664,10 @@ static const struct hw_fifo_info ai_fifo_60xx = { .fifo_size_reg_mask = 0x7f, }; -/* maximum number of dma transfers we will chain together into a ring - * (and the maximum number of dma buffers we maintain) */ +/* + * maximum number of dma transfers we will chain together into a ring + * (and the maximum number of dma buffers we maintain) + */ #define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE) #define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) #define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) @@ -1260,8 +1266,10 @@ static void enable_ai_interrupts(struct comedi_device *dev, bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; - /* Use pio transfer and interrupt on end of conversion - * if CMDF_WAKE_EOS flag is set. */ + /* + * Use pio transfer and interrupt on end of conversion + * if CMDF_WAKE_EOS flag is set. + */ if (cmd->flags & CMDF_WAKE_EOS) { /* 4020 doesn't support pio transfers except for fifo dregs */ if (thisboard->layout != LAYOUT_4020) @@ -1381,7 +1389,9 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, return devpriv->ai_fifo_segment_length; } -/* adjusts the size of hardware fifo (which determines block size for dma xfers) */ +/* + * adjusts the size of hardware fifo (which determines block size for dma xfers) + */ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) { const struct pcidas64_board *thisboard = dev->board_ptr; @@ -1422,8 +1432,10 @@ static void init_stc_registers(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); - /* bit should be set for 6025, - * although docs say boards with <= 16 chans should be cleared XXX */ + /* + * bit should be set for 6025, + * although docs say boards with <= 16 chans should be cleared XXX + */ if (1) devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; writew(devpriv->adc_control1_bits, @@ -1588,7 +1600,9 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n"); } -/* Their i2c requires a huge delay on setting clock or data high for some reason */ +/* + * their i2c requires a huge delay on setting clock or data high for some reason + */ static const int i2c_high_udelay = 1000; static const int i2c_low_udelay = 10; @@ -1684,8 +1698,10 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, uint8_t bitstream; static const int read_bit = 0x1; - /* XXX need mutex to prevent simultaneous attempts to access - * eeprom and i2c bus */ + /* + * XXX need mutex to prevent simultaneous attempts to access + * eeprom and i2c bus + */ /* make sure we dont send anything to eeprom */ devpriv->plx_control_bits &= ~CTL_EE_CS; @@ -1777,14 +1793,18 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, cal_en_bit = CAL_EN_60XX_BIT; else cal_en_bit = CAL_EN_64XX_BIT; - /* select internal reference source to connect - * to channel 0 */ + /* + * select internal reference source to connect + * to channel 0 + */ writew(cal_en_bit | adc_src_bits(devpriv->calibration_source), devpriv->main_iobase + CALIBRATION_REG); } else { - /* make sure internal calibration source - * is turned off */ + /* + * make sure internal calibration source + * is turned off + */ writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* load internal queue */ @@ -1816,8 +1836,10 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); - /* update calibration/range i2c register only if necessary, - * as it is very slow */ + /* + * update calibration/range i2c register only if necessary, + * as it is very slow + */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; @@ -1825,10 +1847,12 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, sizeof(i2c_data)); } - /* 4020 manual asks that sample interval register to be set + /* + * 4020 manual asks that sample interval register to be set * before writing to convert register. * Using somewhat arbitrary setting of 4 master clock ticks - * = 0.1 usec */ + * = 0.1 usec + */ writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); } @@ -1963,9 +1987,11 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, return -EINVAL; } -/* Gets nearest achievable timing given master clock speed, does not +/* + * Gets nearest achievable timing given master clock speed, does not * take into account possible minimum/maximum divisor values. Used - * by other timing checking functions. */ + * by other timing checking functions. + */ static unsigned int get_divisor(unsigned int ns, unsigned int flags) { unsigned int divisor; @@ -1985,9 +2011,11 @@ static unsigned int get_divisor(unsigned int ns, unsigned int flags) return divisor; } -/* utility function that rounds desired timing to an achievable time, and +/* + * utility function that rounds desired timing to an achievable time, and * sets cmd members appropriately. - * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number + * adc paces conversions from master clock by dividing by (x + 3) where x is + * 24 bit number */ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) { @@ -2468,8 +2496,10 @@ static int setup_channel_queue(struct comedi_device *dev, devpriv->main_iobase + ADC_QUEUE_FIFO_REG); } - /* doing a queue clear is not specified in board docs, - * but required for reliable operation */ + /* + * doing a queue clear is not specified in board docs, + * but required for reliable operation + */ writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); /* prime queue holding register */ writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); @@ -2492,8 +2522,10 @@ static int setup_channel_queue(struct comedi_device *dev, devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); } - /* update calibration/range i2c register only if necessary, - * as it is very slow */ + /* + * update calibration/range i2c register only if necessary, + * as it is very slow + */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; @@ -2510,11 +2542,13 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; - /* The transfer size, pci address, and local address registers + /* + * The transfer size, pci address, and local address registers * are supposedly unused during chained dma, * but I have found that left over values from last operation * occasionally cause problems with transfer of first dma - * block. Initializing them to zero seems to fix the problem. */ + * block. Initializing them to zero seems to fix the problem. + */ if (dma_channel) { writel(0, devpriv->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG); @@ -2669,15 +2703,19 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) 0x7fff; write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; - /* Get most significant bits (grey code). + /* + * Get most significant bits (grey code). * Different boards use different code so use a scheme * that doesn't depend on encoding. This read must * occur after reading least significant 15 bits to avoid race - * with fifo switching to next segment. */ + * with fifo switching to next segment. + */ prepost_bits = readw(devpriv->main_iobase + PREPOST_REG); - /* if read and write pointers are not on the same fifo segment, - * read to the end of the read segment */ + /* + * if read and write pointers are not on the same fifo segment, + * read to the end of the read segment + */ read_segment = adc_upper_read_ptr_code(prepost_bits); write_segment = adc_upper_write_ptr_code(prepost_bits); @@ -2706,7 +2744,8 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) } while (read_segment != write_segment); } -/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of +/* + * Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of * pointers. The pci-4020 hardware only supports dma transfers (it only * supports the use of pio for draining the last remaining points from the * fifo when a data acquisition operation has completed). @@ -2784,8 +2823,10 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % ai_dma_ring_count(thisboard); } - /* XXX check for dma ring buffer overrun - * (use end-of-chain bit to mark last unused buffer) */ + /* + * XXX check for dma ring buffer overrun + * (use end-of-chain bit to mark last unused buffer) + */ } static void handle_ai_interrupt(struct comedi_device *dev, @@ -2933,8 +2974,10 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); next_bits |= PLX_END_OF_CHAIN_BIT; devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); - /* clear end of chain bit on previous buffer now that we have set it - * for the last buffer */ + /* + * clear end of chain bit on previous buffer now that we have set it + * for the last buffer + */ next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); next_bits &= ~PLX_END_OF_CHAIN_BIT; devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); @@ -3027,9 +3070,11 @@ static irqreturn_t handle_interrupt(int irq, void *d) plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); status = readw(devpriv->main_iobase + HW_STATUS_REG); - /* an interrupt before all the postconfig stuff gets done could + /* + * an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the - * interrupt handler */ + * interrupt handler + */ if (!dev->attached) return IRQ_HANDLED; @@ -3189,8 +3234,10 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) unsigned int nbytes; int i; - /* clear queue pointer too, since external queue has - * weird interactions with ao fifo */ + /* + * clear queue pointer too, since external queue has + * weird interactions with ao fifo + */ writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); @@ -3459,7 +3506,8 @@ static int dio_60xx_wbits(struct comedi_device *dev, return insn->n; } -/* pci-6025 8800 caldac: +/* + * pci-6025 8800 caldac: * address 0 == dac channel 0 offset * address 1 == dac channel 0 gain * address 2 == dac channel 1 offset @@ -3469,7 +3517,8 @@ static int dio_60xx_wbits(struct comedi_device *dev, * address 6 == coarse adc gain * address 7 == fine adc gain */ -/* pci-6402/16 uses all 8 channels for dac: +/* + * pci-6402/16 uses all 8 channels for dac: * address 0 == dac channel 0 fine gain * address 1 == dac channel 0 coarse gain * address 2 == dac channel 0 coarse offset @@ -3478,7 +3527,7 @@ static int dio_60xx_wbits(struct comedi_device *dev, * address 5 == dac channel 1 coarse gain * address 6 == dac channel 0 fine offset * address 7 == dac channel 1 fine offset -*/ + */ static int caldac_8800_write(struct comedi_device *dev, unsigned int address, uint8_t value) @@ -3738,7 +3787,8 @@ static int eeprom_read_insn(struct comedi_device *dev, return 1; } -/* Allocate and initialize the subdevice structures. +/* + * Allocate and initialize the subdevice structures. */ static int setup_subdevices(struct comedi_device *dev) { @@ -3773,8 +3823,10 @@ static int setup_subdevices(struct comedi_device *dev) s->cancel = ai_cancel; if (thisboard->layout == LAYOUT_4020) { uint8_t data; - /* set adc to read from inputs - * (not internal calibration sources) */ + /* + * set adc to read from inputs + * (not internal calibration sources) + */ devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); /* set channels to +-5 volt input ranges */ for (i = 0; i < s->n_chan; i++) diff --git a/drivers/staging/comedi/drivers/comedi_8254.h b/drivers/staging/comedi/drivers/comedi_8254.h index d89f6d94f8aa..f4610ead6172 100644 --- a/drivers/staging/comedi/drivers/comedi_8254.h +++ b/drivers/staging/comedi/drivers/comedi_8254.h @@ -20,6 +20,12 @@ #ifndef _COMEDI_8254_H #define _COMEDI_8254_H +#include <linux/types.h> + +struct comedi_device; +struct comedi_insn; +struct comedi_subdevice; + /* * Common oscillator base values in nanoseconds */ diff --git a/drivers/staging/comedi/drivers/comedi_8255.c b/drivers/staging/comedi/drivers/comedi_8255.c new file mode 100644 index 000000000000..b2441efc61cc --- /dev/null +++ b/drivers/staging/comedi/drivers/comedi_8255.c @@ -0,0 +1,285 @@ +/* + * comedi_8255.c + * Generic 8255 digital I/O support + * + * Split from the Comedi "8255" driver module. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Module: comedi_8255 + * Description: Generic 8255 support + * Author: ds + * Updated: Fri, 22 May 2015 12:14:17 +0000 + * Status: works + * + * This module is not used directly by end-users. Rather, it is used by + * other drivers to provide support for an 8255 "Programmable Peripheral + * Interface" (PPI) chip. + * + * The classic in digital I/O. The 8255 appears in Comedi as a single + * digital I/O subdevice with 24 channels. The channel 0 corresponds to + * the 8255's port A, bit 0; channel 23 corresponds to port C, bit 7. + * Direction configuration is done in blocks, with channels 0-7, 8-15, + * 16-19, and 20-23 making up the 4 blocks. The only 8255 mode + * supported is mode 0. + */ + +#include <linux/module.h> +#include "../comedidev.h" + +#include "8255.h" + +struct subdev_8255_private { + unsigned long regbase; + int (*io)(struct comedi_device *dev, int dir, int port, int data, + unsigned long regbase); +}; + +static int subdev_8255_io(struct comedi_device *dev, + int dir, int port, int data, unsigned long regbase) +{ + if (dir) { + outb(data, dev->iobase + regbase + port); + return 0; + } + return inb(dev->iobase + regbase + port); +} + +static int subdev_8255_mmio(struct comedi_device *dev, + int dir, int port, int data, unsigned long regbase) +{ + if (dir) { + writeb(data, dev->mmio + regbase + port); + return 0; + } + return readb(dev->mmio + regbase + port); +} + +static int subdev_8255_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct subdev_8255_private *spriv = s->private; + unsigned long regbase = spriv->regbase; + unsigned int mask; + unsigned int v; + + mask = comedi_dio_update_state(s, data); + if (mask) { + if (mask & 0xff) + spriv->io(dev, 1, I8255_DATA_A_REG, + s->state & 0xff, regbase); + if (mask & 0xff00) + spriv->io(dev, 1, I8255_DATA_B_REG, + (s->state >> 8) & 0xff, regbase); + if (mask & 0xff0000) + spriv->io(dev, 1, I8255_DATA_C_REG, + (s->state >> 16) & 0xff, regbase); + } + + v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase); + v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8); + v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16); + + data[1] = v; + + return insn->n; +} + +static void subdev_8255_do_config(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct subdev_8255_private *spriv = s->private; + unsigned long regbase = spriv->regbase; + int config; + + config = I8255_CTRL_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(s->io_bits & 0x0000ff)) + config |= I8255_CTRL_A_IO; + if (!(s->io_bits & 0x00ff00)) + config |= I8255_CTRL_B_IO; + if (!(s->io_bits & 0x0f0000)) + config |= I8255_CTRL_C_LO_IO; + if (!(s->io_bits & 0xf00000)) + config |= I8255_CTRL_C_HI_IO; + + spriv->io(dev, 1, I8255_CTRL_REG, config, regbase); +} + +static int subdev_8255_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int mask; + int ret; + + if (chan < 8) + mask = 0x0000ff; + else if (chan < 16) + mask = 0x00ff00; + else if (chan < 20) + mask = 0x0f0000; + else + mask = 0xf00000; + + ret = comedi_dio_insn_config(dev, s, insn, data, mask); + if (ret) + return ret; + + subdev_8255_do_config(dev, s); + + return insn->n; +} + +static int __subdev_8255_init(struct comedi_device *dev, + struct comedi_subdevice *s, + int (*io)(struct comedi_device *dev, + int dir, int port, int data, + unsigned long regbase), + unsigned long regbase, + bool is_mmio) +{ + struct subdev_8255_private *spriv; + + spriv = comedi_alloc_spriv(s, sizeof(*spriv)); + if (!spriv) + return -ENOMEM; + + if (io) + spriv->io = io; + else if (is_mmio) + spriv->io = subdev_8255_mmio; + else + spriv->io = subdev_8255_io; + spriv->regbase = regbase; + + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_bits = subdev_8255_insn; + s->insn_config = subdev_8255_insn_config; + + subdev_8255_do_config(dev, s); + + return 0; +} + +/** + * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255 + * @dev: comedi device owning subdevice + * @s: comedi subdevice to initialize + * @io: (optional) register I/O call-back function + * @regbase: offset of 8255 registers from dev->iobase, or call-back context + * + * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. + * + * If the optional I/O call-back function is provided, its prototype is of + * the following form: + * + * int my_8255_callback(struct comedi_device *dev, int dir, int port, + * int data, unsigned long regbase); + * + * where 'dev', and 'regbase' match the values passed to this function, + * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' + * is the direction (0 for read, 1 for write) and 'data' is the value to be + * written. It should return 0 if writing or the value read if reading. + * + * If the optional I/O call-back function is not provided, an internal + * call-back function is used which uses consecutive I/O port addresses + * starting at dev->iobase + regbase. + * + * Return: -ENOMEM if failed to allocate memory, zero on success. + */ +int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *dev, int dir, int port, + int data, unsigned long regbase), + unsigned long regbase) +{ + return __subdev_8255_init(dev, s, io, regbase, false); +} +EXPORT_SYMBOL_GPL(subdev_8255_init); + +/** + * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255 + * @dev: comedi device owning subdevice + * @s: comedi subdevice to initialize + * @io: (optional) register I/O call-back function + * @regbase: offset of 8255 registers from dev->mmio, or call-back context + * + * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. + * + * If the optional I/O call-back function is provided, its prototype is of + * the following form: + * + * int my_8255_callback(struct comedi_device *dev, int dir, int port, + * int data, unsigned long regbase); + * + * where 'dev', and 'regbase' match the values passed to this function, + * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' + * is the direction (0 for read, 1 for write) and 'data' is the value to be + * written. It should return 0 if writing or the value read if reading. + * + * If the optional I/O call-back function is not provided, an internal + * call-back function is used which uses consecutive MMIO virtual addresses + * starting at dev->mmio + regbase. + * + * Return: -ENOMEM if failed to allocate memory, zero on success. + */ +int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *dev, int dir, int port, + int data, unsigned long regbase), + unsigned long regbase) +{ + return __subdev_8255_init(dev, s, io, regbase, true); +} +EXPORT_SYMBOL_GPL(subdev_8255_mm_init); + +/** + * subdev_8255_regbase - get offset of 8255 registers or call-back context + * @s: comedi subdevice + * + * Returns the 'regbase' parameter that was previously passed to to + * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice. + * Only valid if the subdevice was set up successfully. + */ +unsigned long subdev_8255_regbase(struct comedi_subdevice *s) +{ + struct subdev_8255_private *spriv = s->private; + + return spriv->regbase; +} +EXPORT_SYMBOL_GPL(subdev_8255_regbase); + +static int __init comedi_8255_module_init(void) +{ + return 0; +} +module_init(comedi_8255_module_init); + +static void __exit comedi_8255_module_exit(void) +{ +} +module_exit(comedi_8255_module_exit); + +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi: Generic 8255 digital I/O support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h index c7c524faf595..2fb6573ba9e4 100644 --- a/drivers/staging/comedi/drivers/comedi_isadma.h +++ b/drivers/staging/comedi/drivers/comedi_isadma.h @@ -16,6 +16,10 @@ #ifndef _COMEDI_ISADMA_H #define _COMEDI_ISADMA_H +#include <linux/types.h> + +struct comedi_device; + /* * These are used to avoid issues when <asm/dma.h> and the DMA_MODE_ * defines are not available. diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 2ca8d3eec742..611b0a3ef5d7 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -1,105 +1,105 @@ /* - comedi/drivers/daqboard2000.c - hardware driver for IOtech DAQboard/2000 - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + * comedi/drivers/daqboard2000.c + * hardware driver for IOtech DAQboard/2000 + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ /* -Driver: daqboard2000 -Description: IOTech DAQBoard/2000 -Author: Anders Blomdell <anders.blomdell@control.lth.se> -Status: works -Updated: Mon, 14 Apr 2008 15:28:52 +0100 -Devices: [IOTech] DAQBoard/2000 (daqboard2000) - -Much of the functionality of this driver was determined from reading -the source code for the Windows driver. - -The FPGA on the board requires fimware, which is available from -http://www.comedi.org in the comedi_nonfree_firmware tarball. - -Configuration options: not applicable, uses PCI auto config -*/ + * Driver: daqboard2000 + * Description: IOTech DAQBoard/2000 + * Author: Anders Blomdell <anders.blomdell@control.lth.se> + * Status: works + * Updated: Mon, 14 Apr 2008 15:28:52 +0100 + * Devices: [IOTech] DAQBoard/2000 (daqboard2000) + * + * Much of the functionality of this driver was determined from reading + * the source code for the Windows driver. + * + * The FPGA on the board requires fimware, which is available from + * http://www.comedi.org in the comedi_nonfree_firmware tarball. + * + * Configuration options: not applicable, uses PCI auto config + */ /* - This card was obviously never intended to leave the Windows world, - since it lacked all kind of hardware documentation (except for cable - pinouts, plug and pray has something to catch up with yet). - - With some help from our swedish distributor, we got the Windows sourcecode - for the card, and here are the findings so far. - - 1. A good document that describes the PCI interface chip is 9080db-106.pdf - available from http://www.plxtech.com/products/io/pci9080 - - 2. The initialization done so far is: - a. program the FPGA (windows code sans a lot of error messages) - b. - - 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled, - you have to output values to all enabled DAC's until result appears, I - guess that it has something to do with pacer clocks, but the source - gives me no clues. I'll keep it simple so far. - - 4. Analog in. - Each channel in the scanlist seems to be controlled by four - control words: - - Word0: - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! | | | ! | | | ! | | | ! | | | ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Word1: - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! | | | ! | | | ! | | | ! | | | ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | | | - +------+------+ | | | | +-- Digital input (??) - | | | | +---- 10 us settling time - | | | +------ Suspend acquisition (last to scan) - | | +-------- Simultaneous sample and hold - | +---------- Signed data format - +------------------------- Correction offset low - - Word2: - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! | | | ! | | | ! | | | ! | | | ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | | | | | | - +-----+ +--+--+ +++ +++ +--+--+ - | | | | +----- Expansion channel - | | | +----------- Expansion gain - | | +--------------- Channel (low) - | +--------------------- Correction offset high - +----------------------------- Correction gain low - Word3: - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! | | | ! | | | ! | | | ! | | | ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | | | | | - +------+------+ | | +-+-+ | | +-- Low bank enable - | | | | | +---- High bank enable - | | | | +------ Hi/low select - | | | +---------- Gain (1,?,2,4,8,16,32,64) - | | +-------------- differential/single ended - | +---------------- Unipolar - +------------------------- Correction gain high - - 999. The card seems to have an incredible amount of capabilities, but - trying to reverse engineer them from the Windows source is beyond my - patience. - + * This card was obviously never intended to leave the Windows world, + * since it lacked all kind of hardware documentation (except for cable + * pinouts, plug and pray has something to catch up with yet). + * + * With some help from our swedish distributor, we got the Windows sourcecode + * for the card, and here are the findings so far. + * + * 1. A good document that describes the PCI interface chip is 9080db-106.pdf + * available from http://www.plxtech.com/products/io/pci9080 + * + * 2. The initialization done so far is: + * a. program the FPGA (windows code sans a lot of error messages) + * b. + * + * 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled, + * you have to output values to all enabled DAC's until result appears, I + * guess that it has something to do with pacer clocks, but the source + * gives me no clues. I'll keep it simple so far. + * + * 4. Analog in. + * Each channel in the scanlist seems to be controlled by four + * control words: + * + * Word0: + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! | | | ! | | | ! | | | ! | | | ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Word1: + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! | | | ! | | | ! | | | ! | | | ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | + * +------+------+ | | | | +-- Digital input (??) + * | | | | +---- 10 us settling time + * | | | +------ Suspend acquisition (last to scan) + * | | +-------- Simultaneous sample and hold + * | +---------- Signed data format + * +------------------------- Correction offset low + * + * Word2: + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! | | | ! | | | ! | | | ! | | | ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | | | | + * +-----+ +--+--+ +++ +++ +--+--+ + * | | | | +----- Expansion channel + * | | | +----------- Expansion gain + * | | +--------------- Channel (low) + * | +--------------------- Correction offset high + * +----------------------------- Correction gain low + * Word3: + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! | | | ! | | | ! | | | ! | | | ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | | | + * +------+------+ | | +-+-+ | | +-- Low bank enable + * | | | | | +---- High bank enable + * | | | | +------ Hi/low select + * | | | +---------- Gain (1,?,2,4,8,16,32,64) + * | | +-------------- differential/single ended + * | +---------------- Unipolar + * +------------------------- Correction gain high + * + * 999. The card seems to have an incredible amount of capabilities, but + * trying to reverse engineer them from the Windows source is beyond my + * patience. + * */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 1adf6a71a9f3..a18a8878bdb8 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -46,8 +46,8 @@ list has 2 or more channels in it, then two conditions must be satisfied: (2) - the list must have an even number of entries. Options: - [0] - base io address - [1] - irq (optional, but you probably want it) + [0] - base io address + [1] - irq (optional, but you probably want it) irq can be omitted, although the cmd interface will not work without it. */ diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index d9715ea1e2da..e9296182236e 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -52,45 +52,45 @@ * PCI BAR2 Register map (dev->mmio) */ #define FIRMWARE_REV_REG 0x00 -#define FEATURES_REG_PRESENT_BIT (1 << 15) +#define FEATURES_REG_PRESENT_BIT BIT(15) #define BOARD_CONTROL_REG 0x04 -#define BOARD_RESET_BIT (1 << 0) -#define TX_FIFO_RESET_BIT (1 << 1) -#define RX_FIFO_RESET_BIT (1 << 2) -#define TX_ENABLE_BIT (1 << 4) -#define RX_ENABLE_BIT (1 << 5) -#define DEMAND_DMA_DIRECTION_TX_BIT (1 << 6) /* ch 0 only */ -#define LINE_VALID_ON_STATUS_VALID_BIT (1 << 7) -#define START_TX_BIT (1 << 8) -#define CABLE_THROTTLE_ENABLE_BIT (1 << 9) -#define TEST_MODE_ENABLE_BIT (1 << 31) +#define BOARD_RESET_BIT BIT(0) +#define TX_FIFO_RESET_BIT BIT(1) +#define RX_FIFO_RESET_BIT BIT(2) +#define TX_ENABLE_BIT BIT(4) +#define RX_ENABLE_BIT BIT(5) +#define DEMAND_DMA_DIRECTION_TX_BIT BIT(6) /* ch 0 only */ +#define LINE_VALID_ON_STATUS_VALID_BIT BIT(7) +#define START_TX_BIT BIT(8) +#define CABLE_THROTTLE_ENABLE_BIT BIT(9) +#define TEST_MODE_ENABLE_BIT BIT(31) #define BOARD_STATUS_REG 0x08 #define COMMAND_LINE_STATUS_MASK (0x7f << 0) -#define TX_IN_PROGRESS_BIT (1 << 7) -#define TX_NOT_EMPTY_BIT (1 << 8) -#define TX_NOT_ALMOST_EMPTY_BIT (1 << 9) -#define TX_NOT_ALMOST_FULL_BIT (1 << 10) -#define TX_NOT_FULL_BIT (1 << 11) -#define RX_NOT_EMPTY_BIT (1 << 12) -#define RX_NOT_ALMOST_EMPTY_BIT (1 << 13) -#define RX_NOT_ALMOST_FULL_BIT (1 << 14) -#define RX_NOT_FULL_BIT (1 << 15) -#define BOARD_JUMPER0_INSTALLED_BIT (1 << 16) -#define BOARD_JUMPER1_INSTALLED_BIT (1 << 17) -#define TX_OVERRUN_BIT (1 << 21) -#define RX_UNDERRUN_BIT (1 << 22) -#define RX_OVERRUN_BIT (1 << 23) +#define TX_IN_PROGRESS_BIT BIT(7) +#define TX_NOT_EMPTY_BIT BIT(8) +#define TX_NOT_ALMOST_EMPTY_BIT BIT(9) +#define TX_NOT_ALMOST_FULL_BIT BIT(10) +#define TX_NOT_FULL_BIT BIT(11) +#define RX_NOT_EMPTY_BIT BIT(12) +#define RX_NOT_ALMOST_EMPTY_BIT BIT(13) +#define RX_NOT_ALMOST_FULL_BIT BIT(14) +#define RX_NOT_FULL_BIT BIT(15) +#define BOARD_JUMPER0_INSTALLED_BIT BIT(16) +#define BOARD_JUMPER1_INSTALLED_BIT BIT(17) +#define TX_OVERRUN_BIT BIT(21) +#define RX_UNDERRUN_BIT BIT(22) +#define RX_OVERRUN_BIT BIT(23) #define TX_PROG_ALMOST_REG 0x0c #define RX_PROG_ALMOST_REG 0x10 #define ALMOST_EMPTY_BITS(x) (((x) & 0xffff) << 0) #define ALMOST_FULL_BITS(x) (((x) & 0xff) << 16) #define FEATURES_REG 0x14 -#define FIFO_SIZE_PRESENT_BIT (1 << 0) -#define FIFO_WORDS_PRESENT_BIT (1 << 1) -#define LEVEL_EDGE_INTERRUPTS_PRESENT_BIT (1 << 2) -#define GPIO_SUPPORTED_BIT (1 << 3) -#define PLX_DMA_CH1_SUPPORTED_BIT (1 << 4) -#define OVERRUN_UNDERRUN_SUPPORTED_BIT (1 << 5) +#define FIFO_SIZE_PRESENT_BIT BIT(0) +#define FIFO_WORDS_PRESENT_BIT BIT(1) +#define LEVEL_EDGE_INTERRUPTS_PRESENT_BIT BIT(2) +#define GPIO_SUPPORTED_BIT BIT(3) +#define PLX_DMA_CH1_SUPPORTED_BIT BIT(4) +#define OVERRUN_UNDERRUN_SUPPORTED_BIT BIT(5) #define FIFO_REG 0x18 #define TX_STATUS_COUNT_REG 0x1c #define TX_LINE_VALID_COUNT_REG 0x20, @@ -98,16 +98,16 @@ #define RX_STATUS_COUNT_REG 0x28 #define RX_LINE_COUNT_REG 0x2c #define INTERRUPT_CONTROL_REG 0x30 -#define FRAME_VALID_START_INTR (1 << 0) -#define FRAME_VALID_END_INTR (1 << 1) -#define TX_FIFO_EMPTY_INTR (1 << 8) -#define TX_FIFO_ALMOST_EMPTY_INTR (1 << 9) -#define TX_FIFO_ALMOST_FULL_INTR (1 << 10) -#define TX_FIFO_FULL_INTR (1 << 11) -#define RX_EMPTY_INTR (1 << 12) -#define RX_ALMOST_EMPTY_INTR (1 << 13) -#define RX_ALMOST_FULL_INTR (1 << 14) -#define RX_FULL_INTR (1 << 15) +#define FRAME_VALID_START_INTR BIT(0) +#define FRAME_VALID_END_INTR BIT(1) +#define TX_FIFO_EMPTY_INTR BIT(8) +#define TX_FIFO_ALMOST_EMPTY_INTR BIT(9) +#define TX_FIFO_ALMOST_FULL_INTR BIT(10) +#define TX_FIFO_FULL_INTR BIT(11) +#define RX_EMPTY_INTR BIT(12) +#define RX_ALMOST_EMPTY_INTR BIT(13) +#define RX_ALMOST_FULL_INTR BIT(14) +#define RX_FULL_INTR BIT(15) #define INTERRUPT_STATUS_REG 0x34 #define TX_CLOCK_DIVIDER_REG 0x38 #define TX_FIFO_SIZE_REG 0x40 @@ -123,27 +123,15 @@ #define NUM_DMA_BUFFERS 4 #define NUM_DMA_DESCRIPTORS 256 -struct hpdi_board { - const char *name; - int device_id; - int subdevice_id; -}; - -static const struct hpdi_board hpdi_boards[] = { - { - .name = "pci-hpdi32", - .device_id = PCI_DEVICE_ID_PLX_9080, - .subdevice_id = 0x2400, - }, -}; - struct hpdi_private { void __iomem *plx9080_mmio; - uint32_t *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */ + uint32_t *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */ /* physical addresses of dma buffers */ dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS]; - /* array of dma descriptors read by plx9080, allocated to get proper - * alignment */ + /* + * array of dma descriptors read by plx9080, allocated to get proper + * alignment + */ struct plx_dma_desc *dma_desc; /* physical address of dma descriptor array */ dma_addr_t dma_desc_phys_addr; @@ -195,7 +183,7 @@ static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel) devpriv->dma_desc_index = idx; } - /* XXX check for buffer overrun somehow */ + /* XXX check for buffer overrun somehow */ } static irqreturn_t gsc_hpdi_interrupt(int irq, void *d) @@ -223,10 +211,11 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d) if (hpdi_intr_status) writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG); - /* spin lock makes sure no one else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma0_status = readb(devpriv->plx9080_mmio + PLX_DMA0_CS_REG); - if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ + if (plx_status & ICS_DMA0_A) { + /* dma chan 0 interrupt */ writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_mmio + PLX_DMA0_CS_REG); @@ -235,17 +224,19 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d) } spin_unlock_irqrestore(&dev->spinlock, flags); - /* spin lock makes sure no one else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma1_status = readb(devpriv->plx9080_mmio + PLX_DMA1_CS_REG); - if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ + if (plx_status & ICS_DMA1_A) { + /* XXX */ /* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_mmio + PLX_DMA1_CS_REG); } spin_unlock_irqrestore(&dev->spinlock, flags); - /* clear possible plx9080 interrupt sources */ - if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ + /* clear possible plx9080 interrupt sources */ + if (plx_status & ICS_LDIA) { + /* clear local doorbell interrupt */ plx_bits = readl(devpriv->plx9080_mmio + PLX_DBR_OUT_REG); writel(plx_bits, devpriv->plx9080_mmio + PLX_DBR_OUT_REG); } @@ -273,7 +264,7 @@ static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel) struct hpdi_private *devpriv = dev->private; unsigned long flags; - /* spinlock for plx dma control/status reg */ + /* spinlock for plx dma control/status reg */ spin_lock_irqsave(&dev->spinlock, flags); plx9080_abort_dma(devpriv->plx9080_mmio, channel); @@ -529,7 +520,7 @@ static int gsc_hpdi_init(struct comedi_device *dev) /* wait 10usec after reset before accessing fifos */ writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG); - udelay(10); + usleep_range(10, 1000); writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32), dev->mmio + RX_PROG_ALMOST_REG); @@ -543,7 +534,7 @@ static int gsc_hpdi_init(struct comedi_device *dev) writel(0, dev->mmio + INTERRUPT_CONTROL_REG); - /* enable interrupts */ + /* enable interrupts */ plx_intcsr_bits = ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E; @@ -570,57 +561,42 @@ static void gsc_hpdi_init_plx9080(struct comedi_device *dev) gsc_hpdi_abort_dma(dev, 0); gsc_hpdi_abort_dma(dev, 1); - /* configure dma0 mode */ + /* configure dma0 mode */ bits = 0; - /* enable ready input */ + /* enable ready input */ bits |= PLX_DMA_EN_READYIN_BIT; - /* enable dma chaining */ + /* enable dma chaining */ bits |= PLX_EN_CHAIN_BIT; - /* enable interrupt on dma done - * (probably don't need this, since chain never finishes) */ + /* + * enable interrupt on dma done + * (probably don't need this, since chain never finishes) + */ bits |= PLX_EN_DMA_DONE_INTR_BIT; - /* don't increment local address during transfers - * (we are transferring from a fixed fifo register) */ + /* + * don't increment local address during transfers + * (we are transferring from a fixed fifo register) + */ bits |= PLX_LOCAL_ADDR_CONST_BIT; - /* route dma interrupt to pci bus */ + /* route dma interrupt to pci bus */ bits |= PLX_DMA_INTR_PCI_BIT; - /* enable demand mode */ + /* enable demand mode */ bits |= PLX_DEMAND_MODE_BIT; - /* enable local burst mode */ + /* enable local burst mode */ bits |= PLX_DMA_LOCAL_BURST_EN_BIT; bits |= PLX_LOCAL_BUS_32_WIDE_BITS; writel(bits, plx_iobase + PLX_DMA0_MODE_REG); } -static const struct hpdi_board *gsc_hpdi_find_board(struct pci_dev *pcidev) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++) - if (pcidev->device == hpdi_boards[i].device_id && - pcidev->subsystem_device == hpdi_boards[i].subdevice_id) - return &hpdi_boards[i]; - return NULL; -} - static int gsc_hpdi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct hpdi_board *thisboard; struct hpdi_private *devpriv; struct comedi_subdevice *s; int i; int retval; - thisboard = gsc_hpdi_find_board(pcidev); - if (!thisboard) { - dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n", - pci_name(pcidev)); - return -EINVAL; - } - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; + dev->board_name = "pci-hpdi32"; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -640,7 +616,7 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, gsc_hpdi_init_plx9080(dev); - /* get irq */ + /* get irq */ if (request_irq(pcidev->irq, gsc_hpdi_interrupt, IRQF_SHARED, dev->board_name, dev)) { dev_warn(dev->class_dev, @@ -651,13 +627,13 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, dev_dbg(dev->class_dev, " irq %u\n", dev->irq); - /* allocate pci dma buffers */ + /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { devpriv->dio_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->dio_buffer_phys_addr[i]); } - /* allocate dma descriptors */ + /* allocate dma descriptors */ devpriv->dma_desc = pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS, @@ -726,8 +702,8 @@ static int gsc_hpdi_pci_probe(struct pci_dev *dev, } static const struct pci_device_id gsc_hpdi_pci_table[] = { - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, - 0x2400, 0, 0, 0}, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, + PCI_VENDOR_ID_PLX, 0x2400) }, { 0 } }; MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table); @@ -741,5 +717,5 @@ static struct pci_driver gsc_hpdi_pci_driver = { module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for General Standards PCI-HPDI32/PMC-HPDI32"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index d78e9195fbce..9ea1ba4b1b6f 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -173,8 +173,7 @@ struct me_private_data { static inline void sleep(unsigned sec) { - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(sec * HZ); + schedule_timeout_interruptible(sec * HZ); } static int me_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 3a972d1538ab..60469bb77ee4 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -106,7 +106,7 @@ TRIG_WAKE_EOS #define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */ #define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */ #define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */ -#define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */ +#define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */ #define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */ #define I8253_BASE_REG 0x14 diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 69d71f328006..6cc304a4c59b 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -60,7 +60,6 @@ /* A timeout count */ #define NI_TIMEOUT 1000 -static const unsigned old_RTSI_clock_channel = 7; /* Note: this table must match the ai_gain_* definitions */ static const short ni_gainlkup[][16] = { @@ -308,262 +307,154 @@ static uint8_t ni_readb(struct comedi_device *dev, int reg) * windowed STC registers to the m series register offsets. */ -static void m_series_stc_writel(struct comedi_device *dev, - uint32_t data, int reg) +struct mio_regmap { + unsigned int mio_reg; + int size; +}; + +static const struct mio_regmap m_series_stc_write_regmap[] = { + [NISTC_INTA_ACK_REG] = { 0x104, 2 }, + [NISTC_INTB_ACK_REG] = { 0x106, 2 }, + [NISTC_AI_CMD2_REG] = { 0x108, 2 }, + [NISTC_AO_CMD2_REG] = { 0x10a, 2 }, + [NISTC_G0_CMD_REG] = { 0x10c, 2 }, + [NISTC_G1_CMD_REG] = { 0x10e, 2 }, + [NISTC_AI_CMD1_REG] = { 0x110, 2 }, + [NISTC_AO_CMD1_REG] = { 0x112, 2 }, + /* + * NISTC_DIO_OUT_REG maps to: + * { NI_M_DIO_REG, 4 } and { NI_M_SCXI_SER_DO_REG, 1 } + */ + [NISTC_DIO_OUT_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */ + [NISTC_DIO_CTRL_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */ + [NISTC_AI_MODE1_REG] = { 0x118, 2 }, + [NISTC_AI_MODE2_REG] = { 0x11a, 2 }, + [NISTC_AI_SI_LOADA_REG] = { 0x11c, 4 }, + [NISTC_AI_SI_LOADB_REG] = { 0x120, 4 }, + [NISTC_AI_SC_LOADA_REG] = { 0x124, 4 }, + [NISTC_AI_SC_LOADB_REG] = { 0x128, 4 }, + [NISTC_AI_SI2_LOADA_REG] = { 0x12c, 4 }, + [NISTC_AI_SI2_LOADB_REG] = { 0x130, 4 }, + [NISTC_G0_MODE_REG] = { 0x134, 2 }, + [NISTC_G1_MODE_REG] = { 0x136, 2 }, + [NISTC_G0_LOADA_REG] = { 0x138, 4 }, + [NISTC_G0_LOADB_REG] = { 0x13c, 4 }, + [NISTC_G1_LOADA_REG] = { 0x140, 4 }, + [NISTC_G1_LOADB_REG] = { 0x144, 4 }, + [NISTC_G0_INPUT_SEL_REG] = { 0x148, 2 }, + [NISTC_G1_INPUT_SEL_REG] = { 0x14a, 2 }, + [NISTC_AO_MODE1_REG] = { 0x14c, 2 }, + [NISTC_AO_MODE2_REG] = { 0x14e, 2 }, + [NISTC_AO_UI_LOADA_REG] = { 0x150, 4 }, + [NISTC_AO_UI_LOADB_REG] = { 0x154, 4 }, + [NISTC_AO_BC_LOADA_REG] = { 0x158, 4 }, + [NISTC_AO_BC_LOADB_REG] = { 0x15c, 4 }, + [NISTC_AO_UC_LOADA_REG] = { 0x160, 4 }, + [NISTC_AO_UC_LOADB_REG] = { 0x164, 4 }, + [NISTC_CLK_FOUT_REG] = { 0x170, 2 }, + [NISTC_IO_BIDIR_PIN_REG] = { 0x172, 2 }, + [NISTC_RTSI_TRIG_DIR_REG] = { 0x174, 2 }, + [NISTC_INT_CTRL_REG] = { 0x176, 2 }, + [NISTC_AI_OUT_CTRL_REG] = { 0x178, 2 }, + [NISTC_ATRIG_ETC_REG] = { 0x17a, 2 }, + [NISTC_AI_START_STOP_REG] = { 0x17c, 2 }, + [NISTC_AI_TRIG_SEL_REG] = { 0x17e, 2 }, + [NISTC_AI_DIV_LOADA_REG] = { 0x180, 4 }, + [NISTC_AO_START_SEL_REG] = { 0x184, 2 }, + [NISTC_AO_TRIG_SEL_REG] = { 0x186, 2 }, + [NISTC_G0_AUTOINC_REG] = { 0x188, 2 }, + [NISTC_G1_AUTOINC_REG] = { 0x18a, 2 }, + [NISTC_AO_MODE3_REG] = { 0x18c, 2 }, + [NISTC_RESET_REG] = { 0x190, 2 }, + [NISTC_INTA_ENA_REG] = { 0x192, 2 }, + [NISTC_INTA2_ENA_REG] = { 0, 0 }, /* E-Series only */ + [NISTC_INTB_ENA_REG] = { 0x196, 2 }, + [NISTC_INTB2_ENA_REG] = { 0, 0 }, /* E-Series only */ + [NISTC_AI_PERSONAL_REG] = { 0x19a, 2 }, + [NISTC_AO_PERSONAL_REG] = { 0x19c, 2 }, + [NISTC_RTSI_TRIGA_OUT_REG] = { 0x19e, 2 }, + [NISTC_RTSI_TRIGB_OUT_REG] = { 0x1a0, 2 }, + [NISTC_RTSI_BOARD_REG] = { 0, 0 }, /* Unknown */ + [NISTC_CFG_MEM_CLR_REG] = { 0x1a4, 2 }, + [NISTC_ADC_FIFO_CLR_REG] = { 0x1a6, 2 }, + [NISTC_DAC_FIFO_CLR_REG] = { 0x1a8, 2 }, + [NISTC_AO_OUT_CTRL_REG] = { 0x1ac, 2 }, + [NISTC_AI_MODE3_REG] = { 0x1ae, 2 }, +}; + +static void m_series_stc_write(struct comedi_device *dev, + unsigned int data, unsigned int reg) { - unsigned offset; + const struct mio_regmap *regmap; - switch (reg) { - case AI_SC_Load_A_Registers: - offset = M_Offset_AI_SC_Load_A; - break; - case AI_SI_Load_A_Registers: - offset = M_Offset_AI_SI_Load_A; - break; - case AO_BC_Load_A_Register: - offset = M_Offset_AO_BC_Load_A; - break; - case AO_UC_Load_A_Register: - offset = M_Offset_AO_UC_Load_A; - break; - case AO_UI_Load_A_Register: - offset = M_Offset_AO_UI_Load_A; - break; - case G_Load_A_Register(0): - offset = M_Offset_G0_Load_A; - break; - case G_Load_A_Register(1): - offset = M_Offset_G1_Load_A; - break; - case G_Load_B_Register(0): - offset = M_Offset_G0_Load_B; - break; - case G_Load_B_Register(1): - offset = M_Offset_G1_Load_B; - break; - default: - dev_warn(dev->class_dev, - "%s: bug! unhandled register=0x%x in switch\n", + if (reg < ARRAY_SIZE(m_series_stc_write_regmap)) { + regmap = &m_series_stc_write_regmap[reg]; + } else { + dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", __func__, reg); return; } - ni_writel(dev, data, offset); -} -static void m_series_stc_writew(struct comedi_device *dev, - uint16_t data, int reg) -{ - unsigned offset; - - switch (reg) { - case ADC_FIFO_Clear: - offset = M_Offset_AI_FIFO_Clear; - break; - case AI_Command_1_Register: - offset = M_Offset_AI_Command_1; - break; - case AI_Command_2_Register: - offset = M_Offset_AI_Command_2; - break; - case AI_Mode_1_Register: - offset = M_Offset_AI_Mode_1; - break; - case AI_Mode_2_Register: - offset = M_Offset_AI_Mode_2; - break; - case AI_Mode_3_Register: - offset = M_Offset_AI_Mode_3; - break; - case AI_Output_Control_Register: - offset = M_Offset_AI_Output_Control; - break; - case AI_Personal_Register: - offset = M_Offset_AI_Personal; - break; - case AI_SI2_Load_A_Register: - /* this is a 32 bit register on m series boards */ - ni_writel(dev, data, M_Offset_AI_SI2_Load_A); - return; - case AI_SI2_Load_B_Register: - /* this is a 32 bit register on m series boards */ - ni_writel(dev, data, M_Offset_AI_SI2_Load_B); - return; - case AI_START_STOP_Select_Register: - offset = M_Offset_AI_START_STOP_Select; - break; - case AI_Trigger_Select_Register: - offset = M_Offset_AI_Trigger_Select; - break; - case Analog_Trigger_Etc_Register: - offset = M_Offset_Analog_Trigger_Etc; - break; - case AO_Command_1_Register: - offset = M_Offset_AO_Command_1; - break; - case AO_Command_2_Register: - offset = M_Offset_AO_Command_2; - break; - case AO_Mode_1_Register: - offset = M_Offset_AO_Mode_1; - break; - case AO_Mode_2_Register: - offset = M_Offset_AO_Mode_2; - break; - case AO_Mode_3_Register: - offset = M_Offset_AO_Mode_3; - break; - case AO_Output_Control_Register: - offset = M_Offset_AO_Output_Control; - break; - case AO_Personal_Register: - offset = M_Offset_AO_Personal; - break; - case AO_Start_Select_Register: - offset = M_Offset_AO_Start_Select; - break; - case AO_Trigger_Select_Register: - offset = M_Offset_AO_Trigger_Select; - break; - case Clock_and_FOUT_Register: - offset = M_Offset_Clock_and_FOUT; - break; - case Configuration_Memory_Clear: - offset = M_Offset_Configuration_Memory_Clear; - break; - case DAC_FIFO_Clear: - offset = M_Offset_AO_FIFO_Clear; - break; - case DIO_Control_Register: - dev_dbg(dev->class_dev, - "%s: FIXME: register 0x%x does not map cleanly on to m-series boards\n", - __func__, reg); - return; - case G_Autoincrement_Register(0): - offset = M_Offset_G0_Autoincrement; - break; - case G_Autoincrement_Register(1): - offset = M_Offset_G1_Autoincrement; - break; - case G_Command_Register(0): - offset = M_Offset_G0_Command; - break; - case G_Command_Register(1): - offset = M_Offset_G1_Command; - break; - case G_Input_Select_Register(0): - offset = M_Offset_G0_Input_Select; - break; - case G_Input_Select_Register(1): - offset = M_Offset_G1_Input_Select; - break; - case G_Mode_Register(0): - offset = M_Offset_G0_Mode; - break; - case G_Mode_Register(1): - offset = M_Offset_G1_Mode; - break; - case Interrupt_A_Ack_Register: - offset = M_Offset_Interrupt_A_Ack; - break; - case Interrupt_A_Enable_Register: - offset = M_Offset_Interrupt_A_Enable; - break; - case Interrupt_B_Ack_Register: - offset = M_Offset_Interrupt_B_Ack; - break; - case Interrupt_B_Enable_Register: - offset = M_Offset_Interrupt_B_Enable; - break; - case Interrupt_Control_Register: - offset = M_Offset_Interrupt_Control; - break; - case IO_Bidirection_Pin_Register: - offset = M_Offset_IO_Bidirection_Pin; - break; - case Joint_Reset_Register: - offset = M_Offset_Joint_Reset; - break; - case RTSI_Trig_A_Output_Register: - offset = M_Offset_RTSI_Trig_A_Output; - break; - case RTSI_Trig_B_Output_Register: - offset = M_Offset_RTSI_Trig_B_Output; + switch (regmap->size) { + case 4: + ni_writel(dev, data, regmap->mio_reg); break; - case RTSI_Trig_Direction_Register: - offset = M_Offset_RTSI_Trig_Direction; + case 2: + ni_writew(dev, data, regmap->mio_reg); break; - /* - * FIXME: DIO_Output_Register (16 bit reg) is replaced by - * M_Offset_Static_Digital_Output (32 bit) and - * M_Offset_SCXI_Serial_Data_Out (8 bit) - */ default: - dev_warn(dev->class_dev, - "%s: bug! unhandled register=0x%x in switch\n", + dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n", __func__, reg); - return; + break; } - ni_writew(dev, data, offset); } -static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) +static const struct mio_regmap m_series_stc_read_regmap[] = { + [NISTC_AI_STATUS1_REG] = { 0x104, 2 }, + [NISTC_AO_STATUS1_REG] = { 0x106, 2 }, + [NISTC_G01_STATUS_REG] = { 0x108, 2 }, + [NISTC_AI_STATUS2_REG] = { 0, 0 }, /* Unknown */ + [NISTC_AO_STATUS2_REG] = { 0x10c, 2 }, + [NISTC_DIO_IN_REG] = { 0, 0 }, /* Unknown */ + [NISTC_G0_HW_SAVE_REG] = { 0x110, 4 }, + [NISTC_G1_HW_SAVE_REG] = { 0x114, 4 }, + [NISTC_G0_SAVE_REG] = { 0x118, 4 }, + [NISTC_G1_SAVE_REG] = { 0x11c, 4 }, + [NISTC_AO_UI_SAVE_REG] = { 0x120, 4 }, + [NISTC_AO_BC_SAVE_REG] = { 0x124, 4 }, + [NISTC_AO_UC_SAVE_REG] = { 0x128, 4 }, + [NISTC_STATUS1_REG] = { 0x136, 2 }, + [NISTC_DIO_SERIAL_IN_REG] = { 0x009, 1 }, + [NISTC_STATUS2_REG] = { 0x13a, 2 }, + [NISTC_AI_SI_SAVE_REG] = { 0x180, 4 }, + [NISTC_AI_SC_SAVE_REG] = { 0x184, 4 }, +}; + +static unsigned int m_series_stc_read(struct comedi_device *dev, + unsigned int reg) { - unsigned offset; + const struct mio_regmap *regmap; - switch (reg) { - case G_HW_Save_Register(0): - offset = M_Offset_G0_HW_Save; - break; - case G_HW_Save_Register(1): - offset = M_Offset_G1_HW_Save; - break; - case G_Save_Register(0): - offset = M_Offset_G0_Save; - break; - case G_Save_Register(1): - offset = M_Offset_G1_Save; - break; - default: - dev_warn(dev->class_dev, - "%s: bug! unhandled register=0x%x in switch\n", + if (reg < ARRAY_SIZE(m_series_stc_read_regmap)) { + regmap = &m_series_stc_read_regmap[reg]; + } else { + dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", __func__, reg); return 0; } - return ni_readl(dev, offset); -} -static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) -{ - unsigned offset; - - switch (reg) { - case AI_Status_1_Register: - offset = M_Offset_AI_Status_1; - break; - case AO_Status_1_Register: - offset = M_Offset_AO_Status_1; - break; - case AO_Status_2_Register: - offset = M_Offset_AO_Status_2; - break; - case DIO_Serial_Input_Register: - return ni_readb(dev, M_Offset_SCXI_Serial_Data_In); - case Joint_Status_1_Register: - offset = M_Offset_Joint_Status_1; - break; - case Joint_Status_2_Register: - offset = M_Offset_Joint_Status_2; - break; - case G_Status_Register: - offset = M_Offset_G01_Status; - break; + switch (regmap->size) { + case 4: + return ni_readl(dev, regmap->mio_reg); + case 2: + return ni_readw(dev, regmap->mio_reg); + case 1: + return ni_readb(dev, regmap->mio_reg); default: - dev_warn(dev->class_dev, - "%s: bug! unhandled register=0x%x in switch\n", + dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n", __func__, reg); return 0; } - return ni_readw(dev, offset); } static void ni_stc_writew(struct comedi_device *dev, uint16_t data, int reg) @@ -572,14 +463,14 @@ static void ni_stc_writew(struct comedi_device *dev, uint16_t data, int reg) unsigned long flags; if (devpriv->is_m_series) { - m_series_stc_writew(dev, data, reg); + m_series_stc_write(dev, data, reg); } else { spin_lock_irqsave(&devpriv->window_lock, flags); if (!devpriv->mite && reg < 8) { ni_writew(dev, data, reg * 2); } else { - ni_writew(dev, reg, Window_Address); - ni_writew(dev, data, Window_Data); + ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG); + ni_writew(dev, data, NI_E_STC_WINDOW_DATA_REG); } spin_unlock_irqrestore(&devpriv->window_lock, flags); } @@ -590,7 +481,7 @@ static void ni_stc_writel(struct comedi_device *dev, uint32_t data, int reg) struct ni_private *devpriv = dev->private; if (devpriv->is_m_series) { - m_series_stc_writel(dev, data, reg); + m_series_stc_write(dev, data, reg); } else { ni_stc_writew(dev, data >> 16, reg); ni_stc_writew(dev, data & 0xffff, reg + 1); @@ -604,14 +495,14 @@ static uint16_t ni_stc_readw(struct comedi_device *dev, int reg) uint16_t val; if (devpriv->is_m_series) { - val = m_series_stc_readw(dev, reg); + val = m_series_stc_read(dev, reg); } else { spin_lock_irqsave(&devpriv->window_lock, flags); if (!devpriv->mite && reg < 8) { val = ni_readw(dev, reg * 2); } else { - ni_writew(dev, reg, Window_Address); - val = ni_readw(dev, Window_Data); + ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG); + val = ni_readw(dev, NI_E_STC_WINDOW_DATA_REG); } spin_unlock_irqrestore(&devpriv->window_lock, flags); } @@ -624,7 +515,7 @@ static uint32_t ni_stc_readl(struct comedi_device *dev, int reg) uint32_t val; if (devpriv->is_m_series) { - val = m_series_stc_readl(dev, reg); + val = m_series_stc_read(dev, reg); } else { val = ni_stc_readw(dev, reg) << 16; val |= ni_stc_readw(dev, reg + 1); @@ -640,33 +531,30 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg, spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); switch (reg) { - case Interrupt_A_Enable_Register: + case NISTC_INTA_ENA_REG: devpriv->int_a_enable_reg &= ~bit_mask; devpriv->int_a_enable_reg |= bit_values & bit_mask; - ni_stc_writew(dev, devpriv->int_a_enable_reg, - Interrupt_A_Enable_Register); + ni_stc_writew(dev, devpriv->int_a_enable_reg, reg); break; - case Interrupt_B_Enable_Register: + case NISTC_INTB_ENA_REG: devpriv->int_b_enable_reg &= ~bit_mask; devpriv->int_b_enable_reg |= bit_values & bit_mask; - ni_stc_writew(dev, devpriv->int_b_enable_reg, - Interrupt_B_Enable_Register); + ni_stc_writew(dev, devpriv->int_b_enable_reg, reg); break; - case IO_Bidirection_Pin_Register: + case NISTC_IO_BIDIR_PIN_REG: devpriv->io_bidirection_pin_reg &= ~bit_mask; devpriv->io_bidirection_pin_reg |= bit_values & bit_mask; - ni_stc_writew(dev, devpriv->io_bidirection_pin_reg, - IO_Bidirection_Pin_Register); + ni_stc_writew(dev, devpriv->io_bidirection_pin_reg, reg); break; - case AI_AO_Select: + case NI_E_DMA_AI_AO_SEL_REG: devpriv->ai_ao_select_reg &= ~bit_mask; devpriv->ai_ao_select_reg |= bit_values & bit_mask; - ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select); + ni_writeb(dev, devpriv->ai_ao_select_reg, reg); break; - case G0_G1_Select: + case NI_E_DMA_G0_G1_SEL_REG: devpriv->g0_g1_select_reg &= ~bit_mask; devpriv->g0_g1_select_reg |= bit_values & bit_mask; - ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select); + ni_writeb(dev, devpriv->g0_g1_select_reg, reg); break; default: dev_err(dev->class_dev, "called with invalid register %d\n", @@ -679,48 +567,55 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg, #ifdef PCIDMA /* DMA channel setup */ +static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) +{ + if (channel < 4) + return 1 << channel; + if (channel == 4) + return 0x3; + if (channel == 5) + return 0x5; + BUG(); + return 0; +} /* negative channel means no channel */ static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel) { - unsigned bitfield; + unsigned bits = 0; if (channel >= 0) - bitfield = - (ni_stc_dma_channel_select_bitfield(channel) << - AI_DMA_Select_Shift) & AI_DMA_Select_Mask; - else - bitfield = 0; - ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield); + bits = ni_stc_dma_channel_select_bitfield(channel); + + ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, + NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits)); } /* negative channel means no channel */ static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel) { - unsigned bitfield; + unsigned bits = 0; if (channel >= 0) - bitfield = - (ni_stc_dma_channel_select_bitfield(channel) << - AO_DMA_Select_Shift) & AO_DMA_Select_Mask; - else - bitfield = 0; - ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield); + bits = ni_stc_dma_channel_select_bitfield(channel); + + ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG, + NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits)); } -/* negative mite_channel means no channel */ +/* negative channel means no channel */ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev, unsigned gpct_index, - int mite_channel) + int channel) { - unsigned bitfield; + unsigned bits = 0; - if (mite_channel >= 0) - bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel); - else - bitfield = 0; - ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index), - bitfield); + if (channel >= 0) + bits = ni_stc_dma_channel_select_bitfield(channel); + + ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG, + NI_E_DMA_G0_G1_SEL_MASK(gpct_index), + NI_E_DMA_G0_G1_SEL(gpct_index, bits)); } /* negative mite_channel means no channel */ @@ -729,18 +624,21 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, { struct ni_private *devpriv = dev->private; unsigned long flags; + unsigned bits; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); - devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask; + devpriv->cdio_dma_select_reg &= ~NI_M_CDIO_DMA_SEL_CDO_MASK; if (mite_channel >= 0) { - /*XXX just guessing ni_stc_dma_channel_select_bitfield() returns the right bits, - under the assumption the cdio dma selection works just like ai/ao/gpct. - Definitely works for dma channels 0 and 1. */ - devpriv->cdio_dma_select_reg |= - (ni_stc_dma_channel_select_bitfield(mite_channel) << - CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask; - } - ni_writeb(dev, devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select); + /* + * XXX just guessing ni_stc_dma_channel_select_bitfield() + * returns the right bits, under the assumption the cdio dma + * selection works just like ai/ao/gpct. + * Definitely works for dma channels 0 and 1. + */ + bits = ni_stc_dma_channel_select_bitfield(mite_channel); + devpriv->cdio_dma_select_reg |= NI_M_CDIO_DMA_SEL_CDO(bits); + } + ni_writeb(dev, devpriv->cdio_dma_select_reg, NI_M_CDIO_DMA_SEL_REG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -795,7 +693,6 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, unsigned long flags; struct mite_channel *mite_chan; - BUG_ON(gpct_index >= NUM_GPCT); spin_lock_irqsave(&devpriv->mite_channel_lock, flags); BUG_ON(devpriv->counter_dev->counters[gpct_index].mite_chan); mite_chan = @@ -879,7 +776,6 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev, struct ni_private *devpriv = dev->private; unsigned long flags; - BUG_ON(gpct_index >= NUM_GPCT); spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->counter_dev->counters[gpct_index].mite_chan) { struct mite_channel *mite_chan = @@ -927,13 +823,13 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev, * dma requests for their counters */ if (gpct_index == 0) { - reg = Second_IRQ_A_Enable_Register; + reg = NISTC_INTA2_ENA_REG; if (enable) - val = G0_Gate_Second_Irq_Enable; + val = NISTC_INTA_ENA_G0_GATE; } else { - reg = Second_IRQ_B_Enable_Register; + reg = NISTC_INTB2_ENA_REG; if (enable) - val = G1_Gate_Second_Irq_Enable; + val = NISTC_INTB_ENA_G1_GATE; } ni_stc_writew(dev, val, reg); } @@ -947,30 +843,30 @@ static void ni_clear_ai_fifo(struct comedi_device *dev) if (devpriv->is_6143) { /* Flush the 6143 data FIFO */ - ni_writel(dev, 0x10, AIFIFO_Control_6143); - ni_writel(dev, 0x00, AIFIFO_Control_6143); + ni_writel(dev, 0x10, NI6143_AI_FIFO_CTRL_REG); + ni_writel(dev, 0x00, NI6143_AI_FIFO_CTRL_REG); /* Wait for complete */ for (i = 0; i < timeout; i++) { - if (!(ni_readl(dev, AIFIFO_Status_6143) & 0x10)) + if (!(ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x10)) break; udelay(1); } if (i == timeout) dev_err(dev->class_dev, "FIFO flush timeout\n"); } else { - ni_stc_writew(dev, 1, ADC_FIFO_Clear); + ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG); if (devpriv->is_625x) { - ni_writeb(dev, 0, M_Offset_Static_AI_Control(0)); - ni_writeb(dev, 1, M_Offset_Static_AI_Control(0)); + ni_writeb(dev, 0, NI_M_STATIC_AI_CTRL_REG(0)); + ni_writeb(dev, 1, NI_M_STATIC_AI_CTRL_REG(0)); #if 0 /* the NI example code does 3 convert pulses for 625x boards, but that appears to be wrong in practice. */ - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); #endif } } @@ -983,8 +879,8 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); - ni_writew(dev, addr, AO_Window_Address_611x); - ni_writew(dev, data, AO_Window_Data_611x); + ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG); + ni_writew(dev, data, NI611X_AO_WINDOW_DATA_REG); spin_unlock_irqrestore(&devpriv->window_lock, flags); } @@ -995,8 +891,8 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); - ni_writew(dev, addr, AO_Window_Address_611x); - ni_writel(dev, data, AO_Window_Data_611x); + ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG); + ni_writel(dev, data, NI611X_AO_WINDOW_DATA_REG); spin_unlock_irqrestore(&devpriv->window_lock, flags); } @@ -1007,8 +903,8 @@ static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr) unsigned short data; spin_lock_irqsave(&devpriv->window_lock, flags); - ni_writew(dev, addr, AO_Window_Address_611x); - data = ni_readw(dev, AO_Window_Data_611x); + ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG); + data = ni_readw(dev, NI611X_AO_WINDOW_DATA_REG); spin_unlock_irqrestore(&devpriv->window_lock, flags); return data; } @@ -1059,8 +955,8 @@ static int ni_ai_drain_dma(struct comedi_device *dev) spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->ai_mite_chan) { for (i = 0; i < timeout; i++) { - if ((ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St) + if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E) && mite_bytes_in_transit(devpriv->ai_mite_chan) == 0) break; @@ -1071,7 +967,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) dev_err(dev->class_dev, "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n", mite_bytes_in_transit(devpriv->ai_mite_chan), - ni_stc_readw(dev, AI_Status_1_Register)); + ni_stc_readw(dev, NISTC_AI_STATUS1_REG)); retval = -1; } } @@ -1103,8 +999,8 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev) for (i = 0; i < timeout; i++) { unsigned short b_status; - b_status = ni_stc_readw(dev, AO_Status_1_Register); - if (b_status & AO_FIFO_Half_Full_St) + b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG); + if (b_status & NISTC_AO_STATUS1_FIFO_HF) break; /* if we poll too often, the pci bus activity seems to slow the dma transfer down */ @@ -1139,9 +1035,9 @@ static void ni_ao_fifo_load(struct comedi_device *dev, i++; packed_data |= (d << 16) & 0xffff0000; } - ni_writel(dev, packed_data, DAC_FIFO_Data_611x); + ni_writel(dev, packed_data, NI611X_AO_FIFO_DATA_REG); } else { - ni_writew(dev, d, DAC_FIFO_Data); + ni_writew(dev, d, NI_E_AO_FIFO_DATA_REG); } } } @@ -1193,9 +1089,9 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, unsigned int nsamples; /* reset fifo */ - ni_stc_writew(dev, 1, DAC_FIFO_Clear); + ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG); if (devpriv->is_6xxx) - ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); + ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG); /* load some data */ nbytes = comedi_buf_read_n_available(s); @@ -1222,7 +1118,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, if (devpriv->is_611x) { for (i = 0; i < n / 2; i++) { - dl = ni_readl(dev, ADC_FIFO_Data_611x); + dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG); /* This may get the hi/lo data in the wrong order */ data = (dl >> 16) & 0xffff; comedi_buf_write_samples(s, &data, 1); @@ -1231,14 +1127,14 @@ static void ni_ai_fifo_read(struct comedi_device *dev, } /* Check if there's a single sample stuck in the FIFO */ if (n % 2) { - dl = ni_readl(dev, ADC_FIFO_Data_611x); + dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG); data = dl & 0xffff; comedi_buf_write_samples(s, &data, 1); } } else if (devpriv->is_6143) { /* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */ for (i = 0; i < n / 2; i++) { - dl = ni_readl(dev, AIFIFO_Data_6143); + dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG); data = (dl >> 16) & 0xffff; comedi_buf_write_samples(s, &data, 1); @@ -1248,8 +1144,8 @@ static void ni_ai_fifo_read(struct comedi_device *dev, if (n % 2) { /* Assume there is a single sample stuck in the FIFO */ /* Get stranded sample into FIFO */ - ni_writel(dev, 0x01, AIFIFO_Control_6143); - dl = ni_readl(dev, AIFIFO_Data_6143); + ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG); + dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG); data = (dl >> 16) & 0xffff; comedi_buf_write_samples(s, &data, 1); } @@ -1263,7 +1159,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, } for (i = 0; i < n; i++) { devpriv->ai_fifo_buffer[i] = - ni_readw(dev, ADC_FIFO_Data_Register); + ni_readw(dev, NI_E_AI_FIFO_DATA_REG); } comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, n); } @@ -1294,9 +1190,9 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) int i; if (devpriv->is_611x) { - while ((ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St) == 0) { - dl = ni_readl(dev, ADC_FIFO_Data_611x); + while ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E) == 0) { + dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG); /* This may get the hi/lo data in the wrong order */ data = dl >> 16; @@ -1306,8 +1202,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) } } else if (devpriv->is_6143) { i = 0; - while (ni_readl(dev, AIFIFO_Status_6143) & 0x04) { - dl = ni_readl(dev, AIFIFO_Data_6143); + while (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x04) { + dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG); /* This may get the hi/lo data in the wrong order */ data = dl >> 16; @@ -1317,29 +1213,29 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) i += 2; } /* Check if stranded sample is present */ - if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) { + if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) { /* Get stranded sample into FIFO */ - ni_writel(dev, 0x01, AIFIFO_Control_6143); - dl = ni_readl(dev, AIFIFO_Data_6143); + ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG); + dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG); data = (dl >> 16) & 0xffff; comedi_buf_write_samples(s, &data, 1); } } else { - fifo_empty = ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St; + fifo_empty = ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E; while (fifo_empty == 0) { for (i = 0; i < sizeof(devpriv->ai_fifo_buffer) / sizeof(devpriv->ai_fifo_buffer[0]); i++) { fifo_empty = ni_stc_readw(dev, - AI_Status_1_Register) & - AI_FIFO_Empty_St; + NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E; if (fifo_empty) break; devpriv->ai_fifo_buffer[i] = - ni_readw(dev, ADC_FIFO_Data_Register); + ni_readw(dev, NI_E_AI_FIFO_DATA_REG); } comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, i); } @@ -1357,8 +1253,8 @@ static void get_last_sample_611x(struct comedi_device *dev) return; /* Check if there's a single sample stuck in the FIFO */ - if (ni_readb(dev, XXX_Status) & 0x80) { - dl = ni_readl(dev, ADC_FIFO_Data_611x); + if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) { + dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG); data = dl & 0xffff; comedi_buf_write_samples(s, &data, 1); } @@ -1375,10 +1271,10 @@ static void get_last_sample_6143(struct comedi_device *dev) return; /* Check if there's a single sample stuck in the FIFO */ - if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) { + if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) { /* Get stranded sample into FIFO */ - ni_writel(dev, 0x01, AIFIFO_Control_6143); - dl = ni_readl(dev, AIFIFO_Data_6143); + ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG); + dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG); /* This may get the hi/lo data in the wrong order */ data = (dl >> 16) & 0xffff; @@ -1420,8 +1316,8 @@ static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s) s->async->events |= COMEDI_CB_EOS; #endif } - /* handle special case of single scan using AI_End_On_End_Of_Scan */ - if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) + /* handle special case of single scan */ + if (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS) shutdown_ai_command(dev); } @@ -1444,17 +1340,16 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) { unsigned short ack = 0; - if (a_status & AI_SC_TC_St) - ack |= AI_SC_TC_Interrupt_Ack; - if (a_status & AI_START1_St) - ack |= AI_START1_Interrupt_Ack; - if (a_status & AI_START_St) - ack |= AI_START_Interrupt_Ack; - if (a_status & AI_STOP_St) - /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */ - ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */; + if (a_status & NISTC_AI_STATUS1_SC_TC) + ack |= NISTC_INTA_ACK_AI_SC_TC; + if (a_status & NISTC_AI_STATUS1_START1) + ack |= NISTC_INTA_ACK_AI_START1; + if (a_status & NISTC_AI_STATUS1_START) + ack |= NISTC_INTA_ACK_AI_START; + if (a_status & NISTC_AI_STATUS1_STOP) + ack |= NISTC_INTA_ACK_AI_STOP; if (ack) - ni_stc_writew(dev, ack, Interrupt_A_Ack_Register); + ni_stc_writew(dev, ack, NISTC_INTA_ACK_REG); } static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, @@ -1483,8 +1378,8 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, #endif /* test for all uncommon interrupt events at the same time */ - if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St | - AI_SC_TC_St | AI_START1_St)) { + if (status & (NISTC_AI_STATUS1_ERR | + NISTC_AI_STATUS1_SC_TC | NISTC_AI_STATUS1_START1)) { if (status == 0xffff) { dev_err(dev->class_dev, "Card removed?\n"); /* we probably aren't even running a command now, @@ -1495,41 +1390,40 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, } return; } - if (status & (AI_Overrun_St | AI_Overflow_St | - AI_SC_TC_Error_St)) { + if (status & NISTC_AI_STATUS1_ERR) { dev_err(dev->class_dev, "ai error a_status=%04x\n", status); shutdown_ai_command(dev); s->async->events |= COMEDI_CB_ERROR; - if (status & (AI_Overrun_St | AI_Overflow_St)) + if (status & NISTC_AI_STATUS1_OVER) s->async->events |= COMEDI_CB_OVERFLOW; comedi_handle_events(dev, s); return; } - if (status & AI_SC_TC_St) { + if (status & NISTC_AI_STATUS1_SC_TC) { if (cmd->stop_src == TRIG_COUNT) shutdown_ai_command(dev); } } #ifndef PCIDMA - if (status & AI_FIFO_Half_Full_St) { + if (status & NISTC_AI_STATUS1_FIFO_HF) { int i; static const int timeout = 10; /* pcmcia cards (at least 6036) seem to stop producing interrupts if we *fail to get the fifo less than half full, so loop to be sure.*/ for (i = 0; i < timeout; ++i) { ni_handle_fifo_half_full(dev); - if ((ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Half_Full_St) == 0) + if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_HF) == 0) break; } } #endif /* !PCIDMA */ - if ((status & AI_STOP_St)) + if (status & NISTC_AI_STATUS1_STOP) ni_handle_eos(dev, s); comedi_handle_events(dev, s); @@ -1539,22 +1433,22 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) { unsigned short ack = 0; - if (b_status & AO_BC_TC_St) - ack |= AO_BC_TC_Interrupt_Ack; - if (b_status & AO_Overrun_St) - ack |= AO_Error_Interrupt_Ack; - if (b_status & AO_START_St) - ack |= AO_START_Interrupt_Ack; - if (b_status & AO_START1_St) - ack |= AO_START1_Interrupt_Ack; - if (b_status & AO_UC_TC_St) - ack |= AO_UC_TC_Interrupt_Ack; - if (b_status & AO_UI2_TC_St) - ack |= AO_UI2_TC_Interrupt_Ack; - if (b_status & AO_UPDATE_St) - ack |= AO_UPDATE_Interrupt_Ack; + if (b_status & NISTC_AO_STATUS1_BC_TC) + ack |= NISTC_INTB_ACK_AO_BC_TC; + if (b_status & NISTC_AO_STATUS1_OVERRUN) + ack |= NISTC_INTB_ACK_AO_ERR; + if (b_status & NISTC_AO_STATUS1_START) + ack |= NISTC_INTB_ACK_AO_START; + if (b_status & NISTC_AO_STATUS1_START1) + ack |= NISTC_INTB_ACK_AO_START1; + if (b_status & NISTC_AO_STATUS1_UC_TC) + ack |= NISTC_INTB_ACK_AO_UC_TC; + if (b_status & NISTC_AO_STATUS1_UI2_TC) + ack |= NISTC_INTB_ACK_AO_UI2_TC; + if (b_status & NISTC_AO_STATUS1_UPDATE) + ack |= NISTC_INTB_ACK_AO_UPDATE; if (ack) - ni_stc_writew(dev, ack, Interrupt_B_Ack_Register); + ni_stc_writew(dev, ack, NISTC_INTB_ACK_REG); } static void handle_b_interrupt(struct comedi_device *dev, @@ -1583,26 +1477,26 @@ static void handle_b_interrupt(struct comedi_device *dev, if (b_status == 0xffff) return; - if (b_status & AO_Overrun_St) { + if (b_status & NISTC_AO_STATUS1_OVERRUN) { dev_err(dev->class_dev, "AO FIFO underrun status=0x%04x status2=0x%04x\n", - b_status, ni_stc_readw(dev, AO_Status_2_Register)); + b_status, ni_stc_readw(dev, NISTC_AO_STATUS2_REG)); s->async->events |= COMEDI_CB_OVERFLOW; } - if (b_status & AO_BC_TC_St) + if (b_status & NISTC_AO_STATUS1_BC_TC) s->async->events |= COMEDI_CB_EOA; #ifndef PCIDMA - if (b_status & AO_FIFO_Request_St) { + if (b_status & NISTC_AO_STATUS1_FIFO_REQ) { int ret; ret = ni_ao_fifo_half_empty(dev, s); if (!ret) { dev_err(dev->class_dev, "AO buffer underrun\n"); - ni_set_bits(dev, Interrupt_B_Enable_Register, - AO_FIFO_Interrupt_Enable | - AO_Error_Interrupt_Enable, 0); + ni_set_bits(dev, NISTC_INTB_ENA_REG, + NISTC_INTB_ENA_AO_FIFO | + NISTC_INTB_ENA_AO_ERR, 0); s->async->events |= COMEDI_CB_OVERFLOW; } } @@ -1718,101 +1612,65 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) { struct ni_private *devpriv = dev->private; + unsigned ai_personal; + unsigned ai_out_ctrl; ni_release_ai_mite_channel(dev); /* ai configuration */ - ni_stc_writew(dev, AI_Configuration_Start | AI_Reset, - Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AI_CFG_START | NISTC_RESET_AI, + NISTC_RESET_REG); - ni_set_bits(dev, Interrupt_A_Enable_Register, - AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable | - AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable | - AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable | - AI_FIFO_Interrupt_Enable, 0); + ni_set_bits(dev, NISTC_INTA_ENA_REG, NISTC_INTA_ENA_AI_MASK, 0); ni_clear_ai_fifo(dev); if (!devpriv->is_6143) - ni_writeb(dev, 0, Misc_Command); - - ni_stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */ - ni_stc_writew(dev, AI_Start_Stop | AI_Mode_1_Reserved - /*| AI_Trigger_Once */, - AI_Mode_1_Register); - ni_stc_writew(dev, 0x0000, AI_Mode_2_Register); + ni_writeb(dev, NI_E_MISC_CMD_EXT_ATRIG, NI_E_MISC_CMD_REG); + + ni_stc_writew(dev, NISTC_AI_CMD1_DISARM, NISTC_AI_CMD1_REG); + ni_stc_writew(dev, NISTC_AI_MODE1_START_STOP | + NISTC_AI_MODE1_RSVD + /*| NISTC_AI_MODE1_TRIGGER_ONCE */, + NISTC_AI_MODE1_REG); + ni_stc_writew(dev, 0, NISTC_AI_MODE2_REG); /* generate FIFO interrupts on non-empty */ - ni_stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE, + NISTC_AI_MODE3_REG); + + ai_personal = NISTC_AI_PERSONAL_SHIFTIN_PW | + NISTC_AI_PERSONAL_SOC_POLARITY | + NISTC_AI_PERSONAL_LOCALMUX_CLK_PW; + ai_out_ctrl = NISTC_AI_OUT_CTRL_SCAN_IN_PROG_SEL(3) | + NISTC_AI_OUT_CTRL_EXTMUX_CLK_SEL(0) | + NISTC_AI_OUT_CTRL_LOCALMUX_CLK_SEL(2) | + NISTC_AI_OUT_CTRL_SC_TC_SEL(3); if (devpriv->is_611x) { - ni_stc_writew(dev, - AI_SHIFTIN_Pulse_Width | - AI_SOC_Polarity | - AI_LOCALMUX_CLK_Pulse_Width, - AI_Personal_Register); - ni_stc_writew(dev, - AI_SCAN_IN_PROG_Output_Select(3) | - AI_EXTMUX_CLK_Output_Select(0) | - AI_LOCALMUX_CLK_Output_Select(2) | - AI_SC_TC_Output_Select(3) | - AI_CONVERT_Output_Select - (AI_CONVERT_Output_Enable_High), - AI_Output_Control_Register); + ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH; } else if (devpriv->is_6143) { - ni_stc_writew(dev, AI_SHIFTIN_Pulse_Width | - AI_SOC_Polarity | - AI_LOCALMUX_CLK_Pulse_Width, - AI_Personal_Register); - ni_stc_writew(dev, - AI_SCAN_IN_PROG_Output_Select(3) | - AI_EXTMUX_CLK_Output_Select(0) | - AI_LOCALMUX_CLK_Output_Select(2) | - AI_SC_TC_Output_Select(3) | - AI_CONVERT_Output_Select - (AI_CONVERT_Output_Enable_Low), - AI_Output_Control_Register); + ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW; } else { - unsigned ai_output_control_bits; - - ni_stc_writew(dev, - AI_SHIFTIN_Pulse_Width | - AI_SOC_Polarity | - AI_CONVERT_Pulse_Width | - AI_LOCALMUX_CLK_Pulse_Width, - AI_Personal_Register); - ai_output_control_bits = - AI_SCAN_IN_PROG_Output_Select(3) | - AI_EXTMUX_CLK_Output_Select(0) | - AI_LOCALMUX_CLK_Output_Select(2) | - AI_SC_TC_Output_Select(3); + ai_personal |= NISTC_AI_PERSONAL_CONVERT_PW; if (devpriv->is_622x) - ai_output_control_bits |= - AI_CONVERT_Output_Select - (AI_CONVERT_Output_Enable_High); + ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH; else - ai_output_control_bits |= - AI_CONVERT_Output_Select - (AI_CONVERT_Output_Enable_Low); - ni_stc_writew(dev, ai_output_control_bits, - AI_Output_Control_Register); + ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW; } + ni_stc_writew(dev, ai_personal, NISTC_AI_PERSONAL_REG); + ni_stc_writew(dev, ai_out_ctrl, NISTC_AI_OUT_CTRL_REG); + /* the following registers should not be changed, because there * are no backup registers in devpriv. If you want to change * any of these, add a backup register and other appropriate code: - * AI_Mode_1_Register - * AI_Mode_3_Register - * AI_Personal_Register - * AI_Output_Control_Register + * NISTC_AI_MODE1_REG + * NISTC_AI_MODE3_REG + * NISTC_AI_PERSONAL_REG + * NISTC_AI_OUT_CTRL_REG */ - ni_stc_writew(dev, - AI_SC_TC_Error_Confirm | - AI_START_Interrupt_Ack | - AI_START2_Interrupt_Ack | - AI_START1_Interrupt_Ack | - AI_SC_TC_Interrupt_Ack | - AI_Error_Interrupt_Ack | - AI_STOP_Interrupt_Ack, - Interrupt_A_Ack_Register); /* clear interrupts */ - - ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register); + + /* clear interrupts */ + ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG); + + ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG); return 0; } @@ -1839,11 +1697,11 @@ static void ni_prime_channelgain_list(struct comedi_device *dev) { int i; - ni_stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, NISTC_AI_CMD1_REG); for (i = 0; i < NI_TIMEOUT; ++i) { - if (!(ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St)) { - ni_stc_writew(dev, 1, ADC_FIFO_Clear); + if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E)) { + ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG); return; } udelay(1); @@ -1862,7 +1720,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, unsigned int dither; unsigned range_code; - ni_stc_writew(dev, 1, Configuration_Memory_Clear); + ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG); if ((list[0] & CR_ALT_SOURCE)) { unsigned bypass_bits; @@ -1871,22 +1729,17 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, range = CR_RANGE(list[0]); range_code = ni_gainlkup[board->gainlkup][range]; dither = (list[0] & CR_ALT_FILTER) != 0; - bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit; - bypass_bits |= chan; - bypass_bits |= - (devpriv->ai_calib_source) & - (MSeries_AI_Bypass_Cal_Sel_Pos_Mask | - MSeries_AI_Bypass_Cal_Sel_Neg_Mask | - MSeries_AI_Bypass_Mode_Mux_Mask | - MSeries_AO_Bypass_AO_Cal_Sel_Mask); - bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code); + bypass_bits = NI_M_CFG_BYPASS_FIFO | + NI_M_CFG_BYPASS_AI_CHAN(chan) | + NI_M_CFG_BYPASS_AI_GAIN(range_code) | + devpriv->ai_calib_source; if (dither) - bypass_bits |= MSeries_AI_Bypass_Dither_Bit; + bypass_bits |= NI_M_CFG_BYPASS_AI_DITHER; /* don't use 2's complement encoding */ - bypass_bits |= MSeries_AI_Bypass_Polarity_Bit; - ni_writel(dev, bypass_bits, M_Offset_AI_Config_FIFO_Bypass); + bypass_bits |= NI_M_CFG_BYPASS_AI_POLARITY; + ni_writel(dev, bypass_bits, NI_M_CFG_BYPASS_FIFO_REG); } else { - ni_writel(dev, 0, M_Offset_AI_Config_FIFO_Bypass); + ni_writel(dev, 0, NI_M_CFG_BYPASS_FIFO_REG); } for (i = 0; i < n_chan; i++) { unsigned config_bits = 0; @@ -1900,31 +1753,27 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, devpriv->ai_offset[i] = 0; switch (aref) { case AREF_DIFF: - config_bits |= - MSeries_AI_Config_Channel_Type_Differential_Bits; + config_bits |= NI_M_AI_CFG_CHAN_TYPE_DIFF; break; case AREF_COMMON: - config_bits |= - MSeries_AI_Config_Channel_Type_Common_Ref_Bits; + config_bits |= NI_M_AI_CFG_CHAN_TYPE_COMMON; break; case AREF_GROUND: - config_bits |= - MSeries_AI_Config_Channel_Type_Ground_Ref_Bits; + config_bits |= NI_M_AI_CFG_CHAN_TYPE_GROUND; break; case AREF_OTHER: break; } - config_bits |= MSeries_AI_Config_Channel_Bits(chan); - config_bits |= - MSeries_AI_Config_Bank_Bits(board->reg_type, chan); - config_bits |= MSeries_AI_Config_Gain_Bits(range_code); + config_bits |= NI_M_AI_CFG_CHAN_SEL(chan); + config_bits |= NI_M_AI_CFG_BANK_SEL(chan); + config_bits |= NI_M_AI_CFG_GAIN(range_code); if (i == n_chan - 1) - config_bits |= MSeries_AI_Config_Last_Channel_Bit; + config_bits |= NI_M_AI_CFG_LAST_CHAN; if (dither) - config_bits |= MSeries_AI_Config_Dither_Bit; + config_bits |= NI_M_AI_CFG_DITHER; /* don't use 2's complement encoding */ - config_bits |= MSeries_AI_Config_Polarity_Bit; - ni_writew(dev, config_bits, M_Offset_AI_Config_FIFO_Data); + config_bits |= NI_M_AI_CFG_POLARITY; + ni_writew(dev, config_bits, NI_M_AI_CFG_FIFO_DATA_REG); } ni_prime_channelgain_list(dev); } @@ -1986,7 +1835,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, devpriv->changain_state = 0; } - ni_stc_writew(dev, 1, Configuration_Memory_Clear); + ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG); /* Set up Calibration mode if required */ if (devpriv->is_6143) { @@ -1994,20 +1843,20 @@ static void ni_load_channelgain_list(struct comedi_device *dev, && !devpriv->ai_calib_source_enabled) { /* Strobe Relay enable bit */ ni_writew(dev, devpriv->ai_calib_source | - Calibration_Channel_6143_RelayOn, - Calibration_Channel_6143); + NI6143_CALIB_CHAN_RELAY_ON, + NI6143_CALIB_CHAN_REG); ni_writew(dev, devpriv->ai_calib_source, - Calibration_Channel_6143); + NI6143_CALIB_CHAN_REG); devpriv->ai_calib_source_enabled = 1; msleep_interruptible(100); /* Allow relays to change */ } else if (!(list[0] & CR_ALT_SOURCE) && devpriv->ai_calib_source_enabled) { /* Strobe Relay disable bit */ ni_writew(dev, devpriv->ai_calib_source | - Calibration_Channel_6143_RelayOff, - Calibration_Channel_6143); + NI6143_CALIB_CHAN_RELAY_OFF, + NI6143_CALIB_CHAN_REG); ni_writew(dev, devpriv->ai_calib_source, - Calibration_Channel_6143); + NI6143_CALIB_CHAN_REG); devpriv->ai_calib_source_enabled = 0; msleep_interruptible(100); /* Allow relays to change */ } @@ -2033,7 +1882,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, if ((list[i] & CR_ALT_SOURCE)) { if (devpriv->is_611x) ni_writew(dev, CR_CHAN(list[i]) & 0x0003, - Calibration_Channel_Select_611x); + NI611X_CALIB_CHAN_SEL_REG); } else { if (devpriv->is_611x) aref = AREF_DIFF; @@ -2041,30 +1890,31 @@ static void ni_load_channelgain_list(struct comedi_device *dev, aref = AREF_OTHER; switch (aref) { case AREF_DIFF: - hi |= AI_DIFFERENTIAL; + hi |= NI_E_AI_CFG_HI_TYPE_DIFF; break; case AREF_COMMON: - hi |= AI_COMMON; + hi |= NI_E_AI_CFG_HI_TYPE_COMMON; break; case AREF_GROUND: - hi |= AI_GROUND; + hi |= NI_E_AI_CFG_HI_TYPE_GROUND; break; case AREF_OTHER: break; } } - hi |= AI_CONFIG_CHANNEL(chan); + hi |= NI_E_AI_CFG_HI_CHAN(chan); - ni_writew(dev, hi, Configuration_Memory_High); + ni_writew(dev, hi, NI_E_AI_CFG_HI_REG); if (!devpriv->is_6143) { - lo = range; + lo = NI_E_AI_CFG_LO_GAIN(range); + if (i == n_chan - 1) - lo |= AI_LAST_CHANNEL; + lo |= NI_E_AI_CFG_LO_LAST_CHAN; if (dither) - lo |= AI_DITHER; + lo |= NI_E_AI_CFG_LO_DITHER; - ni_writew(dev, lo, Configuration_Memory_Low); + ni_writew(dev, lo, NI_E_AI_CFG_LO_REG); } } @@ -2092,25 +1942,27 @@ static int ni_ai_insn_read(struct comedi_device *dev, signbits = devpriv->ai_offset[0]; if (devpriv->is_611x) { for (n = 0; n < num_adc_stages_611x; n++) { - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); udelay(1); } for (n = 0; n < insn->n; n++) { - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); /* The 611x has screwy 32-bit FIFOs. */ d = 0; for (i = 0; i < NI_TIMEOUT; i++) { - if (ni_readb(dev, XXX_Status) & 0x80) { - d = ni_readl(dev, ADC_FIFO_Data_611x); + if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) { + d = ni_readl(dev, + NI611X_AI_FIFO_DATA_REG); d >>= 16; d &= 0xffff; break; } - if (!(ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St)) { - d = ni_readl(dev, ADC_FIFO_Data_611x); + if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E)) { + d = ni_readl(dev, + NI611X_AI_FIFO_DATA_REG); d &= 0xffff; break; } @@ -2124,17 +1976,19 @@ static int ni_ai_insn_read(struct comedi_device *dev, } } else if (devpriv->is_6143) { for (n = 0; n < insn->n; n++) { - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */ dl = 0; for (i = 0; i < NI_TIMEOUT; i++) { - if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) { + if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & + 0x01) { /* Get stranded sample into FIFO */ ni_writel(dev, 0x01, - AIFIFO_Control_6143); - dl = ni_readl(dev, AIFIFO_Data_6143); + NI6143_AI_FIFO_CTRL_REG); + dl = ni_readl(dev, + NI6143_AI_FIFO_DATA_REG); break; } } @@ -2146,11 +2000,11 @@ static int ni_ai_insn_read(struct comedi_device *dev, } } else { for (n = 0; n < insn->n; n++) { - ni_stc_writew(dev, AI_CONVERT_Pulse, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, + NISTC_AI_CMD1_REG); for (i = 0; i < NI_TIMEOUT; i++) { - if (!(ni_stc_readw(dev, AI_Status_1_Register) & - AI_FIFO_Empty_St)) + if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) & + NISTC_AI_STATUS1_FIFO_E)) break; } if (i == NI_TIMEOUT) { @@ -2158,11 +2012,11 @@ static int ni_ai_insn_read(struct comedi_device *dev, return -ETIME; } if (devpriv->is_m_series) { - dl = ni_readl(dev, M_Offset_AI_FIFO_Data); + dl = ni_readl(dev, NI_M_AI_FIFO_DATA_REG); dl &= mask; data[n] = dl; } else { - d = ni_readw(dev, ADC_FIFO_Data_Register); + d = ni_readw(dev, NI_E_AI_FIFO_DATA_REG); d += signbits; /* subtle: needs to be short addition */ data[n] = d; } @@ -2374,8 +2228,8 @@ static int ni_ai_inttrig(struct comedi_device *dev, if (trig_num != cmd->start_arg) return -EINVAL; - ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2, - AI_Command_2_Register); + ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE | devpriv->ai_cmd2, + NISTC_AI_CMD2_REG); s->async->inttrig = NULL; return 1; @@ -2391,6 +2245,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) int start_stop_select = 0; unsigned int stop_count; int interrupt_a_enable = 0; + unsigned ai_trig; if (dev->irq == 0) { dev_err(dev->class_dev, "cannot run command without an irq\n"); @@ -2401,51 +2256,47 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ni_load_channelgain_list(dev, s, cmd->chanlist_len, cmd->chanlist); /* start configuration */ - ni_stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AI_CFG_START, NISTC_RESET_REG); /* disable analog triggering for now, since it * interferes with the use of pfi0 */ - devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable; - ni_stc_writew(dev, devpriv->an_trig_etc_reg, - Analog_Trigger_Etc_Register); + devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_ENA; + ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG); + ai_trig = NISTC_AI_TRIG_START2_SEL(0) | NISTC_AI_TRIG_START1_SYNC; switch (cmd->start_src) { case TRIG_INT: case TRIG_NOW: - ni_stc_writew(dev, - AI_START2_Select(0) | - AI_START1_Sync | AI_START1_Edge | - AI_START1_Select(0), - AI_Trigger_Select_Register); + ai_trig |= NISTC_AI_TRIG_START1_EDGE | + NISTC_AI_TRIG_START1_SEL(0); break; case TRIG_EXT: - { - int chan = CR_CHAN(cmd->start_arg); - unsigned int bits = AI_START2_Select(0) | - AI_START1_Sync | AI_START1_Select(chan + 1); - - if (cmd->start_arg & CR_INVERT) - bits |= AI_START1_Polarity; - if (cmd->start_arg & CR_EDGE) - bits |= AI_START1_Edge; - ni_stc_writew(dev, bits, AI_Trigger_Select_Register); - break; - } + ai_trig |= NISTC_AI_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) + + 1); + + if (cmd->start_arg & CR_INVERT) + ai_trig |= NISTC_AI_TRIG_START1_POLARITY; + if (cmd->start_arg & CR_EDGE) + ai_trig |= NISTC_AI_TRIG_START1_EDGE; + break; } + ni_stc_writew(dev, ai_trig, NISTC_AI_TRIG_SEL_REG); - mode2 &= ~AI_Pre_Trigger; - mode2 &= ~AI_SC_Initial_Load_Source; - mode2 &= ~AI_SC_Reload_Mode; - ni_stc_writew(dev, mode2, AI_Mode_2_Register); + mode2 &= ~NISTC_AI_MODE2_PRE_TRIGGER; + mode2 &= ~NISTC_AI_MODE2_SC_INIT_LOAD_SRC; + mode2 &= ~NISTC_AI_MODE2_SC_RELOAD_MODE; + ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG); if (cmd->chanlist_len == 1 || devpriv->is_611x || devpriv->is_6143) { - start_stop_select |= AI_STOP_Polarity; - start_stop_select |= AI_STOP_Select(31); /* logic low */ - start_stop_select |= AI_STOP_Sync; + /* logic low */ + start_stop_select |= NISTC_AI_STOP_POLARITY | + NISTC_AI_STOP_SEL(31) | + NISTC_AI_STOP_SYNC; } else { - start_stop_select |= AI_STOP_Select(19); /* ai configuration memory */ + /* ai configuration memory */ + start_stop_select |= NISTC_AI_STOP_SEL(19); } - ni_stc_writew(dev, start_stop_select, AI_START_STOP_Select_Register); + ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG); devpriv->ai_cmd2 = 0; switch (cmd->stop_src) { @@ -2457,80 +2308,80 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) stop_count += num_adc_stages_611x; } /* stage number of scans */ - ni_stc_writel(dev, stop_count, AI_SC_Load_A_Registers); + ni_stc_writel(dev, stop_count, NISTC_AI_SC_LOADA_REG); - mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once; - ni_stc_writew(dev, mode1, AI_Mode_1_Register); + mode1 |= NISTC_AI_MODE1_START_STOP | + NISTC_AI_MODE1_RSVD | + NISTC_AI_MODE1_TRIGGER_ONCE; + ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG); /* load SC (Scan Count) */ - ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG); if (stop_count == 0) { - devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan; - interrupt_a_enable |= AI_STOP_Interrupt_Enable; + devpriv->ai_cmd2 |= NISTC_AI_CMD2_END_ON_EOS; + interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP; /* this is required to get the last sample for chanlist_len > 1, not sure why */ if (cmd->chanlist_len > 1) - start_stop_select |= - AI_STOP_Polarity | AI_STOP_Edge; + start_stop_select |= NISTC_AI_STOP_POLARITY | + NISTC_AI_STOP_EDGE; } break; case TRIG_NONE: /* stage number of scans */ - ni_stc_writel(dev, 0, AI_SC_Load_A_Registers); + ni_stc_writel(dev, 0, NISTC_AI_SC_LOADA_REG); - mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous; - ni_stc_writew(dev, mode1, AI_Mode_1_Register); + mode1 |= NISTC_AI_MODE1_START_STOP | + NISTC_AI_MODE1_RSVD | + NISTC_AI_MODE1_CONTINUOUS; + ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG); /* load SC (Scan Count) */ - ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG); break; } switch (cmd->scan_begin_src) { case TRIG_TIMER: /* - stop bits for non 611x boards - AI_SI_Special_Trigger_Delay=0 - AI_Pre_Trigger=0 - AI_START_STOP_Select_Register: - AI_START_Polarity=0 (?) rising edge - AI_START_Edge=1 edge triggered - AI_START_Sync=1 (?) - AI_START_Select=0 SI_TC - AI_STOP_Polarity=0 rising edge - AI_STOP_Edge=0 level - AI_STOP_Sync=1 - AI_STOP_Select=19 external pin (configuration mem) + * stop bits for non 611x boards + * NISTC_AI_MODE3_SI_TRIG_DELAY=0 + * NISTC_AI_MODE2_PRE_TRIGGER=0 + * NISTC_AI_START_STOP_REG: + * NISTC_AI_START_POLARITY=0 (?) rising edge + * NISTC_AI_START_EDGE=1 edge triggered + * NISTC_AI_START_SYNC=1 (?) + * NISTC_AI_START_SEL=0 SI_TC + * NISTC_AI_STOP_POLARITY=0 rising edge + * NISTC_AI_STOP_EDGE=0 level + * NISTC_AI_STOP_SYNC=1 + * NISTC_AI_STOP_SEL=19 external pin (configuration mem) */ - start_stop_select |= AI_START_Edge | AI_START_Sync; - ni_stc_writew(dev, start_stop_select, - AI_START_STOP_Select_Register); + start_stop_select |= NISTC_AI_START_EDGE | NISTC_AI_START_SYNC; + ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG); - mode2 |= AI_SI_Reload_Mode(0); - /* AI_SI_Initial_Load_Source=A */ - mode2 &= ~AI_SI_Initial_Load_Source; - /* mode2 |= AI_SC_Reload_Mode; */ - ni_stc_writew(dev, mode2, AI_Mode_2_Register); + mode2 &= ~NISTC_AI_MODE2_SI_INIT_LOAD_SRC; /* A */ + mode2 |= NISTC_AI_MODE2_SI_RELOAD_MODE(0); + /* mode2 |= NISTC_AI_MODE2_SC_RELOAD_MODE; */ + ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG); /* load SI */ timer = ni_ns_to_timer(dev, cmd->scan_begin_arg, CMDF_ROUND_NEAREST); - ni_stc_writel(dev, timer, AI_SI_Load_A_Registers); - ni_stc_writew(dev, AI_SI_Load, AI_Command_1_Register); + ni_stc_writel(dev, timer, NISTC_AI_SI_LOADA_REG); + ni_stc_writew(dev, NISTC_AI_CMD1_SI_LOAD, NISTC_AI_CMD1_REG); break; case TRIG_EXT: if (cmd->scan_begin_arg & CR_EDGE) - start_stop_select |= AI_START_Edge; - /* AI_START_Polarity==1 is falling edge */ - if (cmd->scan_begin_arg & CR_INVERT) - start_stop_select |= AI_START_Polarity; + start_stop_select |= NISTC_AI_START_EDGE; + if (cmd->scan_begin_arg & CR_INVERT) /* falling edge */ + start_stop_select |= NISTC_AI_START_POLARITY; if (cmd->scan_begin_src != cmd->convert_src || (cmd->scan_begin_arg & ~CR_EDGE) != (cmd->convert_arg & ~CR_EDGE)) - start_stop_select |= AI_START_Sync; + start_stop_select |= NISTC_AI_START_SYNC; start_stop_select |= - AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg)); - ni_stc_writew(dev, start_stop_select, - AI_START_STOP_Select_Register); + NISTC_AI_START_SEL(1 + CR_CHAN(cmd->scan_begin_arg)); + ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG); break; } @@ -2543,46 +2394,43 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) timer = ni_ns_to_timer(dev, cmd->convert_arg, CMDF_ROUND_NEAREST); /* 0,0 does not work */ - ni_stc_writew(dev, 1, AI_SI2_Load_A_Register); - ni_stc_writew(dev, timer, AI_SI2_Load_B_Register); - - /* AI_SI2_Reload_Mode = alternate */ - /* AI_SI2_Initial_Load_Source = A */ - mode2 &= ~AI_SI2_Initial_Load_Source; - mode2 |= AI_SI2_Reload_Mode; - ni_stc_writew(dev, mode2, AI_Mode_2_Register); + ni_stc_writew(dev, 1, NISTC_AI_SI2_LOADA_REG); + ni_stc_writew(dev, timer, NISTC_AI_SI2_LOADB_REG); - /* AI_SI2_Load */ - ni_stc_writew(dev, AI_SI2_Load, AI_Command_1_Register); + mode2 &= ~NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* A */ + mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */ + ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG); - mode2 |= AI_SI2_Reload_Mode; /* alternate */ - mode2 |= AI_SI2_Initial_Load_Source; /* B */ + ni_stc_writew(dev, NISTC_AI_CMD1_SI2_LOAD, NISTC_AI_CMD1_REG); - ni_stc_writew(dev, mode2, AI_Mode_2_Register); + mode2 |= NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* B */ + mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */ + ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG); break; case TRIG_EXT: - mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg); + mode1 |= NISTC_AI_MODE1_CONVERT_SRC(1 + cmd->convert_arg); if ((cmd->convert_arg & CR_INVERT) == 0) - mode1 |= AI_CONVERT_Source_Polarity; - ni_stc_writew(dev, mode1, AI_Mode_1_Register); + mode1 |= NISTC_AI_MODE1_CONVERT_POLARITY; + ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG); - mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable; - ni_stc_writew(dev, mode2, AI_Mode_2_Register); + mode2 |= NISTC_AI_MODE2_SC_GATE_ENA | + NISTC_AI_MODE2_START_STOP_GATE_ENA; + ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG); break; } if (dev->irq) { /* interrupt on FIFO, errors, SC_TC */ - interrupt_a_enable |= AI_Error_Interrupt_Enable | - AI_SC_TC_Interrupt_Enable; + interrupt_a_enable |= NISTC_INTA_ENA_AI_ERR | + NISTC_INTA_ENA_AI_SC_TC; #ifndef PCIDMA - interrupt_a_enable |= AI_FIFO_Interrupt_Enable; + interrupt_a_enable |= NISTC_INTA_ENA_AI_FIFO; #endif - if (cmd->flags & CMDF_WAKE_EOS - || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) { + if ((cmd->flags & CMDF_WAKE_EOS) || + (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS)) { /* wake on end-of-scan */ devpriv->aimode = AIMODE_SCAN; } else { @@ -2593,66 +2441,60 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case AIMODE_HALF_FULL: /*generate FIFO interrupts and DMA requests on half-full */ #ifdef PCIDMA - ni_stc_writew(dev, AI_FIFO_Mode_HF_to_E, - AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF_E, + NISTC_AI_MODE3_REG); #else - ni_stc_writew(dev, AI_FIFO_Mode_HF, - AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF, + NISTC_AI_MODE3_REG); #endif break; case AIMODE_SAMPLE: /*generate FIFO interrupts on non-empty */ - ni_stc_writew(dev, AI_FIFO_Mode_NE, - AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE, + NISTC_AI_MODE3_REG); break; case AIMODE_SCAN: #ifdef PCIDMA - ni_stc_writew(dev, AI_FIFO_Mode_NE, - AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE, + NISTC_AI_MODE3_REG); #else - ni_stc_writew(dev, AI_FIFO_Mode_HF, - AI_Mode_3_Register); + ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF, + NISTC_AI_MODE3_REG); #endif - interrupt_a_enable |= AI_STOP_Interrupt_Enable; + interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP; break; default: break; } /* clear interrupts */ - ni_stc_writew(dev, - AI_Error_Interrupt_Ack | - AI_STOP_Interrupt_Ack | - AI_START_Interrupt_Ack | - AI_START2_Interrupt_Ack | - AI_START1_Interrupt_Ack | - AI_SC_TC_Interrupt_Ack | - AI_SC_TC_Error_Confirm, - Interrupt_A_Ack_Register); - - ni_set_bits(dev, Interrupt_A_Enable_Register, - interrupt_a_enable, 1); + ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG); + + ni_set_bits(dev, NISTC_INTA_ENA_REG, interrupt_a_enable, 1); } else { /* interrupt on nothing */ - ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0); + ni_set_bits(dev, NISTC_INTA_ENA_REG, ~0, 0); /* XXX start polling if necessary */ } /* end configuration */ - ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG); switch (cmd->scan_begin_src) { case TRIG_TIMER: - ni_stc_writew(dev, - AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM | + NISTC_AI_CMD1_SI_ARM | + NISTC_AI_CMD1_DIV_ARM | + NISTC_AI_CMD1_SC_ARM, + NISTC_AI_CMD1_REG); break; case TRIG_EXT: - /* XXX AI_SI_Arm? */ - ni_stc_writew(dev, - AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm, - AI_Command_1_Register); + ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM | + NISTC_AI_CMD1_SI_ARM | /* XXX ? */ + NISTC_AI_CMD1_DIV_ARM | + NISTC_AI_CMD1_SC_ARM, + NISTC_AI_CMD1_REG); break; } @@ -2666,9 +2508,9 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) #endif if (cmd->start_src == TRIG_NOW) { - /* AI_START1_Pulse */ - ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2, - AI_Command_2_Register); + ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE | + devpriv->ai_cmd2, + NISTC_AI_CMD2_REG); s->async->inttrig = NULL; } else if (cmd->start_src == TRIG_EXT) { s->async->inttrig = NULL; @@ -2691,12 +2533,8 @@ static int ni_ai_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_ALT_SOURCE: if (devpriv->is_m_series) { - if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask | - MSeries_AI_Bypass_Cal_Sel_Neg_Mask | - MSeries_AI_Bypass_Mode_Mux_Mask | - MSeries_AO_Bypass_AO_Cal_Sel_Mask)) { + if (data[1] & ~NI_M_CFG_BYPASS_AI_CAL_MASK) return -EINVAL; - } devpriv->ai_calib_source = data[1]; } else if (devpriv->is_6143) { unsigned int calib_source; @@ -2704,7 +2542,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, calib_source = data[1] & 0xf; devpriv->ai_calib_source = calib_source; - ni_writew(dev, calib_source, Calibration_Channel_6143); + ni_writew(dev, calib_source, NI6143_CALIB_CHAN_REG); } else { unsigned int calib_source; unsigned int calib_source_adjust; @@ -2717,7 +2555,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, devpriv->ai_calib_source = calib_source; if (devpriv->is_611x) { ni_writeb(dev, calib_source_adjust, - Cal_Gain_Select_611x); + NI611X_CAL_GAIN_SEL_REG); } } return 2; @@ -2771,10 +2609,10 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, if (timed) { for (i = 0; i < s->n_chan; ++i) { - devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit; + devpriv->ao_conf[i] &= ~NI_M_AO_CFG_BANK_UPDATE_TIMED; ni_writeb(dev, devpriv->ao_conf[i], - M_Offset_AO_Config_Bank(i)); - ni_writeb(dev, 0xf, M_Offset_AO_Waveform_Order(i)); + NI_M_AO_CFG_BANK_REG(i)); + ni_writeb(dev, 0xf, NI_M_AO_WAVEFORM_ORDER_REG(i)); } } for (i = 0; i < n_chans; i++) { @@ -2787,24 +2625,22 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, conf = 0; switch (krange->max - krange->min) { case 20000000: - conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits; - ni_writeb(dev, 0, - M_Offset_AO_Reference_Attenuation(chan)); + conf |= NI_M_AO_CFG_BANK_REF_INT_10V; + ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan)); break; case 10000000: - conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits; - ni_writeb(dev, 0, - M_Offset_AO_Reference_Attenuation(chan)); + conf |= NI_M_AO_CFG_BANK_REF_INT_5V; + ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan)); break; case 4000000: - conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits; - ni_writeb(dev, MSeries_Attenuate_x5_Bit, - M_Offset_AO_Reference_Attenuation(chan)); + conf |= NI_M_AO_CFG_BANK_REF_INT_10V; + ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5, + NI_M_AO_REF_ATTENUATION_REG(chan)); break; case 2000000: - conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits; - ni_writeb(dev, MSeries_Attenuate_x5_Bit, - M_Offset_AO_Reference_Attenuation(chan)); + conf |= NI_M_AO_CFG_BANK_REF_INT_5V; + ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5, + NI_M_AO_REF_ATTENUATION_REG(chan)); break; default: dev_err(dev->class_dev, @@ -2813,10 +2649,10 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, } switch (krange->max + krange->min) { case 0: - conf |= MSeries_AO_DAC_Offset_0V_Bits; + conf |= NI_M_AO_CFG_BANK_OFFSET_0V; break; case 10000000: - conf |= MSeries_AO_DAC_Offset_5V_Bits; + conf |= NI_M_AO_CFG_BANK_OFFSET_5V; break; default: dev_err(dev->class_dev, @@ -2824,10 +2660,10 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, break; } if (timed) - conf |= MSeries_AO_Update_Timed_Bit; - ni_writeb(dev, conf, M_Offset_AO_Config_Bank(chan)); + conf |= NI_M_AO_CFG_BANK_UPDATE_TIMED; + ni_writeb(dev, conf, NI_M_AO_CFG_BANK_REG(chan)); devpriv->ao_conf[chan] = conf; - ni_writeb(dev, i, M_Offset_AO_Waveform_Order(chan)); + ni_writeb(dev, i, NI_M_AO_WAVEFORM_ORDER_REG(chan)); } return invert; } @@ -2847,27 +2683,27 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, for (i = 0; i < n_chans; i++) { chan = CR_CHAN(chanspec[i]); range = CR_RANGE(chanspec[i]); - conf = AO_Channel(chan); + conf = NI_E_AO_DACSEL(chan); if (comedi_range_is_bipolar(s, range)) { - conf |= AO_Bipolar; + conf |= NI_E_AO_CFG_BIP; invert = (s->maxdata + 1) >> 1; } else { invert = 0; } if (comedi_range_is_external(s, range)) - conf |= AO_Ext_Ref; + conf |= NI_E_AO_EXT_REF; /* not all boards can deglitch, but this shouldn't hurt */ if (chanspec[i] & CR_DEGLITCH) - conf |= AO_Deglitch; + conf |= NI_E_AO_DEGLITCH; /* analog reference */ /* AREF_OTHER connects AO ground to AI ground, i think */ - conf |= (CR_AREF(chanspec[i]) == - AREF_OTHER) ? AO_Ground_Ref : 0; + if (CR_AREF(chanspec[i]) == AREF_OTHER) + conf |= NI_E_AO_GROUND_REF; - ni_writew(dev, conf, AO_Configuration); + ni_writew(dev, conf, NI_E_AO_CFG_REG); devpriv->ao_conf[chan] = conf; } return invert; @@ -2899,13 +2735,13 @@ static int ni_ao_insn_write(struct comedi_device *dev, int i; if (devpriv->is_6xxx) { - ni_ao_win_outw(dev, 1 << chan, AO_Immediate_671x); + ni_ao_win_outw(dev, 1 << chan, NI671X_AO_IMMEDIATE_REG); - reg = DACx_Direct_Data_671x(chan); + reg = NI671X_DAC_DIRECT_DATA_REG(chan); } else if (devpriv->is_m_series) { - reg = M_Offset_DAC_Direct_Data(chan); + reg = NI_M_DAC_DIRECT_DATA_REG(chan); } else { - reg = (chan) ? DAC1_Direct_Data : DAC0_Direct_Data; + reg = NI_E_DAC_DIRECT_DATA_REG(chan); } ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0); @@ -2995,13 +2831,13 @@ static int ni_ao_inttrig(struct comedi_device *dev, multiple times) */ s->async->inttrig = NULL; - ni_set_bits(dev, Interrupt_B_Enable_Register, - AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0); - interrupt_b_bits = AO_Error_Interrupt_Enable; + ni_set_bits(dev, NISTC_INTB_ENA_REG, + NISTC_INTB_ENA_AO_FIFO | NISTC_INTB_ENA_AO_ERR, 0); + interrupt_b_bits = NISTC_INTB_ENA_AO_ERR; #ifdef PCIDMA - ni_stc_writew(dev, 1, DAC_FIFO_Clear); + ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG); if (devpriv->is_6xxx) - ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); + ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG); ret = ni_ao_setup_MITE_dma(dev); if (ret) return ret; @@ -3013,17 +2849,17 @@ static int ni_ao_inttrig(struct comedi_device *dev, if (ret == 0) return -EPIPE; - interrupt_b_bits |= AO_FIFO_Interrupt_Enable; + interrupt_b_bits |= NISTC_INTB_ENA_AO_FIFO; #endif - ni_stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE, - AO_Mode_3_Register); - ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + ni_stc_writew(dev, devpriv->ao_mode3 | NISTC_AO_MODE3_NOT_AN_UPDATE, + NISTC_AO_MODE3_REG); + ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG); /* wait for DACs to be loaded */ for (i = 0; i < timeout; i++) { udelay(1); - if ((ni_stc_readw(dev, Joint_Status_2_Register) & - AO_TMRDACWRs_In_Progress_St) == 0) + if ((ni_stc_readw(dev, NISTC_STATUS2_REG) & + NISTC_STATUS2_AO_TMRDACWRS_IN_PROGRESS) == 0) break; } if (i == timeout) { @@ -3035,17 +2871,20 @@ static int ni_ao_inttrig(struct comedi_device *dev, * stc manual says we are need to clear error interrupt after * AO_TMRDACWRs_In_Progress_St clears */ - ni_stc_writew(dev, AO_Error_Interrupt_Ack, Interrupt_B_Ack_Register); + ni_stc_writew(dev, NISTC_INTB_ACK_AO_ERR, NISTC_INTB_ACK_REG); - ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1); + ni_set_bits(dev, NISTC_INTB_ENA_REG, interrupt_b_bits, 1); - ni_stc_writew(dev, devpriv->ao_cmd1 | - AO_UI_Arm | AO_UC_Arm | AO_BC_Arm | - AO_DAC1_Update_Mode | AO_DAC0_Update_Mode, - AO_Command_1_Register); + ni_stc_writew(dev, NISTC_AO_CMD1_UI_ARM | + NISTC_AO_CMD1_UC_ARM | + NISTC_AO_CMD1_BC_ARM | + NISTC_AO_CMD1_DAC1_UPDATE_MODE | + NISTC_AO_CMD1_DAC0_UPDATE_MODE | + devpriv->ao_cmd1, + NISTC_AO_CMD1_REG); - ni_stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse, - AO_Command_2_Register); + ni_stc_writew(dev, NISTC_AO_CMD2_START1_PULSE | devpriv->ao_cmd2, + NISTC_AO_CMD2_REG); return 0; } @@ -3058,18 +2897,20 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) int bits; int i; unsigned trigvar; + unsigned val; if (dev->irq == 0) { dev_err(dev->class_dev, "cannot run command without an irq\n"); return -EIO; } - ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG); - ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register); + ni_stc_writew(dev, NISTC_AO_CMD1_DISARM, NISTC_AO_CMD1_REG); if (devpriv->is_6xxx) { - ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x); + ni_ao_win_outw(dev, NI611X_AO_MISC_CLEAR_WG, + NI611X_AO_MISC_REG); bits = 0; for (i = 0; i < cmd->chanlist_len; i++) { @@ -3077,172 +2918,186 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) chan = CR_CHAN(cmd->chanlist[i]); bits |= 1 << chan; - ni_ao_win_outw(dev, chan, AO_Waveform_Generation_611x); + ni_ao_win_outw(dev, chan, NI611X_AO_WAVEFORM_GEN_REG); } - ni_ao_win_outw(dev, bits, AO_Timed_611x); + ni_ao_win_outw(dev, bits, NI611X_AO_TIMED_REG); } ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1); if (cmd->stop_src == TRIG_NONE) { - devpriv->ao_mode1 |= AO_Continuous; - devpriv->ao_mode1 &= ~AO_Trigger_Once; + devpriv->ao_mode1 |= NISTC_AO_MODE1_CONTINUOUS; + devpriv->ao_mode1 &= ~NISTC_AO_MODE1_TRIGGER_ONCE; } else { - devpriv->ao_mode1 &= ~AO_Continuous; - devpriv->ao_mode1 |= AO_Trigger_Once; + devpriv->ao_mode1 &= ~NISTC_AO_MODE1_CONTINUOUS; + devpriv->ao_mode1 |= NISTC_AO_MODE1_TRIGGER_ONCE; } - ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG); + + val = devpriv->ao_trigger_select; switch (cmd->start_src) { case TRIG_INT: case TRIG_NOW: - devpriv->ao_trigger_select &= - ~(AO_START1_Polarity | AO_START1_Select(-1)); - devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync; - ni_stc_writew(dev, devpriv->ao_trigger_select, - AO_Trigger_Select_Register); + val &= ~(NISTC_AO_TRIG_START1_POLARITY | + NISTC_AO_TRIG_START1_SEL_MASK); + val |= NISTC_AO_TRIG_START1_EDGE | + NISTC_AO_TRIG_START1_SYNC; break; case TRIG_EXT: - devpriv->ao_trigger_select = - AO_START1_Select(CR_CHAN(cmd->start_arg) + 1); - if (cmd->start_arg & CR_INVERT) - devpriv->ao_trigger_select |= AO_START1_Polarity; /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */ - if (cmd->start_arg & CR_EDGE) - devpriv->ao_trigger_select |= AO_START1_Edge; /* 0=edge detection disabled, 1=enabled */ + val = NISTC_AO_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) + 1); + if (cmd->start_arg & CR_INVERT) { + /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */ + val |= NISTC_AO_TRIG_START1_POLARITY; + } + if (cmd->start_arg & CR_EDGE) { + /* 0=edge detection disabled, 1=enabled */ + val |= NISTC_AO_TRIG_START1_EDGE; + } ni_stc_writew(dev, devpriv->ao_trigger_select, - AO_Trigger_Select_Register); + NISTC_AO_TRIG_SEL_REG); break; default: BUG(); break; } - devpriv->ao_mode3 &= ~AO_Trigger_Length; - ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + devpriv->ao_trigger_select = val; + ni_stc_writew(dev, devpriv->ao_trigger_select, NISTC_AO_TRIG_SEL_REG); - ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); - devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source; - ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + devpriv->ao_mode3 &= ~NISTC_AO_MODE3_TRIG_LEN; + ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG); + + ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG); + devpriv->ao_mode2 &= ~NISTC_AO_MODE2_BC_INIT_LOAD_SRC; + ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG); if (cmd->stop_src == TRIG_NONE) - ni_stc_writel(dev, 0xffffff, AO_BC_Load_A_Register); + ni_stc_writel(dev, 0xffffff, NISTC_AO_BC_LOADA_REG); else - ni_stc_writel(dev, 0, AO_BC_Load_A_Register); - ni_stc_writew(dev, AO_BC_Load, AO_Command_1_Register); - devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source; - ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + ni_stc_writel(dev, 0, NISTC_AO_BC_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_BC_LOAD, NISTC_AO_CMD1_REG); + devpriv->ao_mode2 &= ~NISTC_AO_MODE2_UC_INIT_LOAD_SRC; + ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG); switch (cmd->stop_src) { case TRIG_COUNT: if (devpriv->is_m_series) { /* this is how the NI example code does it for m-series boards, verified correct with 6259 */ ni_stc_writel(dev, cmd->stop_arg - 1, - AO_UC_Load_A_Register); - ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register); + NISTC_AO_UC_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD, + NISTC_AO_CMD1_REG); } else { ni_stc_writel(dev, cmd->stop_arg, - AO_UC_Load_A_Register); - ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register); + NISTC_AO_UC_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD, + NISTC_AO_CMD1_REG); ni_stc_writel(dev, cmd->stop_arg - 1, - AO_UC_Load_A_Register); + NISTC_AO_UC_LOADA_REG); } break; case TRIG_NONE: - ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register); - ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register); - ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register); + ni_stc_writel(dev, 0xffffff, NISTC_AO_UC_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD, NISTC_AO_CMD1_REG); + ni_stc_writel(dev, 0xffffff, NISTC_AO_UC_LOADA_REG); break; default: - ni_stc_writel(dev, 0, AO_UC_Load_A_Register); - ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register); - ni_stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register); + ni_stc_writel(dev, 0, NISTC_AO_UC_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD, NISTC_AO_CMD1_REG); + ni_stc_writel(dev, cmd->stop_arg, NISTC_AO_UC_LOADA_REG); } - devpriv->ao_mode1 &= - ~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity | - AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity); + devpriv->ao_mode1 &= ~(NISTC_AO_MODE1_UPDATE_SRC_MASK | + NISTC_AO_MODE1_UI_SRC_MASK | + NISTC_AO_MODE1_UPDATE_SRC_POLARITY | + NISTC_AO_MODE1_UI_SRC_POLARITY); switch (cmd->scan_begin_src) { case TRIG_TIMER: - devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable; + devpriv->ao_cmd2 &= ~NISTC_AO_CMD2_BC_GATE_ENA; trigvar = ni_ns_to_timer(dev, cmd->scan_begin_arg, CMDF_ROUND_NEAREST); - ni_stc_writel(dev, 1, AO_UI_Load_A_Register); - ni_stc_writew(dev, AO_UI_Load, AO_Command_1_Register); - ni_stc_writel(dev, trigvar, AO_UI_Load_A_Register); + ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG); + ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG); break; case TRIG_EXT: devpriv->ao_mode1 |= - AO_UPDATE_Source_Select(cmd->scan_begin_arg); + NISTC_AO_MODE1_UPDATE_SRC(cmd->scan_begin_arg); if (cmd->scan_begin_arg & CR_INVERT) - devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity; - devpriv->ao_cmd2 |= AO_BC_Gate_Enable; + devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC_POLARITY; + devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA; break; default: BUG(); break; } - ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register); - ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); - devpriv->ao_mode2 &= - ~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source); - ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + ni_stc_writew(dev, devpriv->ao_cmd2, NISTC_AO_CMD2_REG); + ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG); + devpriv->ao_mode2 &= ~(NISTC_AO_MODE2_UI_RELOAD_MODE(3) | + NISTC_AO_MODE2_UI_INIT_LOAD_SRC); + ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG); if (cmd->scan_end_arg > 1) { - devpriv->ao_mode1 |= AO_Multiple_Channels; + devpriv->ao_mode1 |= NISTC_AO_MODE1_MULTI_CHAN; ni_stc_writew(dev, - AO_Number_Of_Channels(cmd->scan_end_arg - 1) | - AO_UPDATE_Output_Select(AO_Update_Output_High_Z), - AO_Output_Control_Register); + NISTC_AO_OUT_CTRL_CHANS(cmd->scan_end_arg - 1) | + NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ, + NISTC_AO_OUT_CTRL_REG); } else { unsigned bits; - devpriv->ao_mode1 &= ~AO_Multiple_Channels; - bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z); + devpriv->ao_mode1 &= ~NISTC_AO_MODE1_MULTI_CHAN; + bits = NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ; if (devpriv->is_m_series || devpriv->is_6xxx) { - bits |= AO_Number_Of_Channels(0); + bits |= NISTC_AO_OUT_CTRL_CHANS(0); } else { bits |= - AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0])); + NISTC_AO_OUT_CTRL_CHANS(CR_CHAN(cmd->chanlist[0])); } - ni_stc_writew(dev, bits, AO_Output_Control_Register); + ni_stc_writew(dev, bits, NISTC_AO_OUT_CTRL_REG); } - ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG); - ni_stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode, - AO_Command_1_Register); + ni_stc_writew(dev, NISTC_AO_CMD1_DAC1_UPDATE_MODE | + NISTC_AO_CMD1_DAC0_UPDATE_MODE, + NISTC_AO_CMD1_REG); - devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error; - ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + devpriv->ao_mode3 |= NISTC_AO_MODE3_STOP_ON_OVERRUN_ERR; + ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG); - devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask; + devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_MODE_MASK; #ifdef PCIDMA - devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F; + devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF_F; #else - devpriv->ao_mode2 |= AO_FIFO_Mode_HF; + devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF; #endif - devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable; - ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_REXMIT_ENA; + ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG); - bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width | - AO_TMRDACWR_Pulse_Width; + bits = NISTC_AO_PERSONAL_BC_SRC_SEL | + NISTC_AO_PERSONAL_UPDATE_PW | + NISTC_AO_PERSONAL_TMRDACWR_PW; if (board->ao_fifo_depth) - bits |= AO_FIFO_Enable; + bits |= NISTC_AO_PERSONAL_FIFO_ENA; else - bits |= AO_DMA_PIO_Control; + bits |= NISTC_AO_PERSONAL_DMA_PIO_CTRL; #if 0 - /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281, - verified with bus analyzer. */ + /* + * F Hess: windows driver does not set NISTC_AO_PERSONAL_NUM_DAC bit + * for 6281, verified with bus analyzer. + */ if (devpriv->is_m_series) - bits |= AO_Number_Of_DAC_Packages; + bits |= NISTC_AO_PERSONAL_NUM_DAC; #endif - ni_stc_writew(dev, bits, AO_Personal_Register); + ni_stc_writew(dev, bits, NISTC_AO_PERSONAL_REG); /* enable sending of ao dma requests */ - ni_stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register); + ni_stc_writew(dev, NISTC_AO_START_AOFREQ_ENA, NISTC_AO_START_SEL_REG); - ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG); if (cmd->stop_src == TRIG_COUNT) { - ni_stc_writew(dev, AO_BC_TC_Interrupt_Ack, - Interrupt_B_Ack_Register); - ni_set_bits(dev, Interrupt_B_Enable_Register, - AO_BC_TC_Interrupt_Enable, 1); + ni_stc_writew(dev, NISTC_INTB_ACK_AO_BC_TC, + NISTC_INTB_ACK_REG); + ni_set_bits(dev, NISTC_INTB_ENA_REG, + NISTC_INTB_ENA_AO_BC_TC, 1); } s->async->inttrig = ni_ao_inttrig; @@ -3339,41 +3194,44 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) ni_release_ao_mite_channel(dev); - ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register); - ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register); - ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0); - ni_stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register); - ni_stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register); - ni_stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width | - AO_TMRDACWR_Pulse_Width, AO_Personal_Register); - ni_stc_writew(dev, 0, AO_Output_Control_Register); - ni_stc_writew(dev, 0, AO_Start_Select_Register); + ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG); + ni_stc_writew(dev, NISTC_AO_CMD1_DISARM, NISTC_AO_CMD1_REG); + ni_set_bits(dev, NISTC_INTB_ENA_REG, ~0, 0); + ni_stc_writew(dev, NISTC_AO_PERSONAL_BC_SRC_SEL, NISTC_AO_PERSONAL_REG); + ni_stc_writew(dev, NISTC_INTB_ACK_AO_ALL, NISTC_INTB_ACK_REG); + ni_stc_writew(dev, NISTC_AO_PERSONAL_BC_SRC_SEL | + NISTC_AO_PERSONAL_UPDATE_PW | + NISTC_AO_PERSONAL_TMRDACWR_PW, + NISTC_AO_PERSONAL_REG); + ni_stc_writew(dev, 0, NISTC_AO_OUT_CTRL_REG); + ni_stc_writew(dev, 0, NISTC_AO_START_SEL_REG); devpriv->ao_cmd1 = 0; - ni_stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register); + ni_stc_writew(dev, devpriv->ao_cmd1, NISTC_AO_CMD1_REG); devpriv->ao_cmd2 = 0; - ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register); + ni_stc_writew(dev, devpriv->ao_cmd2, NISTC_AO_CMD2_REG); devpriv->ao_mode1 = 0; - ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG); devpriv->ao_mode2 = 0; - ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG); if (devpriv->is_m_series) - devpriv->ao_mode3 = AO_Last_Gate_Disable; + devpriv->ao_mode3 = NISTC_AO_MODE3_LAST_GATE_DISABLE; else devpriv->ao_mode3 = 0; - ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG); devpriv->ao_trigger_select = 0; ni_stc_writew(dev, devpriv->ao_trigger_select, - AO_Trigger_Select_Register); + NISTC_AO_TRIG_SEL_REG); if (devpriv->is_6xxx) { unsigned immediate_bits = 0; unsigned i; for (i = 0; i < s->n_chan; ++i) immediate_bits |= 1 << i; - ni_ao_win_outw(dev, immediate_bits, AO_Immediate_671x); - ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x); + ni_ao_win_outw(dev, immediate_bits, NI671X_AO_IMMEDIATE_REG); + ni_ao_win_outw(dev, NI611X_AO_MISC_CLEAR_WG, + NI611X_AO_MISC_REG); } - ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register); + ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG); return 0; } @@ -3392,9 +3250,9 @@ static int ni_dio_insn_config(struct comedi_device *dev, if (ret) return ret; - devpriv->dio_control &= ~DIO_Pins_Dir_Mask; - devpriv->dio_control |= DIO_Pins_Dir(s->io_bits); - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + devpriv->dio_control &= ~NISTC_DIO_CTRL_DIR_MASK; + devpriv->dio_control |= NISTC_DIO_CTRL_DIR(s->io_bits); + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); return insn->n; } @@ -3407,16 +3265,17 @@ static int ni_dio_insn_bits(struct comedi_device *dev, struct ni_private *devpriv = dev->private; /* Make sure we're not using the serial part of the dio */ - if ((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns) + if ((data[0] & (NISTC_DIO_SDIN | NISTC_DIO_SDOUT)) && + devpriv->serial_interval_ns) return -EBUSY; if (comedi_dio_update_state(s, data)) { - devpriv->dio_output &= ~DIO_Parallel_Data_Mask; - devpriv->dio_output |= DIO_Parallel_Data_Out(s->state); - ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register); + devpriv->dio_output &= ~NISTC_DIO_OUT_PARALLEL_MASK; + devpriv->dio_output |= NISTC_DIO_OUT_PARALLEL(s->state); + ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG); } - data[1] = ni_stc_readw(dev, DIO_Parallel_Input_Register); + data[1] = ni_stc_readw(dev, NISTC_DIO_IN_REG); return insn->n; } @@ -3432,7 +3291,7 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev, if (ret) return ret; - ni_writel(dev, s->io_bits, M_Offset_DIO_Direction); + ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG); return insn->n; } @@ -3443,9 +3302,9 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, unsigned int *data) { if (comedi_dio_update_state(s, data)) - ni_writel(dev, s->state, M_Offset_Static_Digital_Output); + ni_writel(dev, s->state, NI_M_DIO_REG); - data[1] = ni_readl(dev, M_Offset_Static_Digital_Input); + data[1] = ni_readl(dev, NI_M_DIO_REG); return insn->n; } @@ -3491,7 +3350,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); tmp = cmd->scan_begin_arg; - tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, CR_INVERT); + tmp &= CR_PACK_FLAGS(NI_M_CDO_MODE_SAMPLE_SRC_MASK, 0, 0, CR_INVERT); if (tmp != cmd->scan_begin_arg) err |= -EINVAL; @@ -3550,13 +3409,14 @@ static int ni_cdo_inttrig(struct comedi_device *dev, if (retval < 0) return retval; #endif -/* -* XXX not sure what interrupt C group does -* ni_writeb(dev, Interrupt_Group_C_Enable_Bit, -* M_Offset_Interrupt_C_Enable); wait for dma to fill output fifo -*/ + /* + * XXX not sure what interrupt C group does + * wait for dma to fill output fifo + * ni_writeb(dev, NI_M_INTC_ENA, NI_M_INTC_ENA_REG); + */ for (i = 0; i < timeout; ++i) { - if (ni_readl(dev, M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit) + if (ni_readl(dev, NI_M_CDIO_STATUS_REG) & + NI_M_CDIO_STATUS_CDO_FIFO_FULL) break; udelay(10); } @@ -3565,36 +3425,30 @@ static int ni_cdo_inttrig(struct comedi_device *dev, s->cancel(dev, s); return -EIO; } - ni_writel(dev, CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit | - CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, - M_Offset_CDIO_Command); + ni_writel(dev, NI_M_CDO_CMD_ARM | + NI_M_CDO_CMD_ERR_INT_ENA_SET | + NI_M_CDO_CMD_F_E_INT_ENA_SET, + NI_M_CDIO_CMD_REG); return retval; } static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct comedi_cmd *cmd = &s->async->cmd; - unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit; + unsigned cdo_mode_bits; int retval; - ni_writel(dev, CDO_Reset_Bit, M_Offset_CDIO_Command); - switch (cmd->scan_begin_src) { - case TRIG_EXT: - cdo_mode_bits |= - CR_CHAN(cmd->scan_begin_arg) & - CDO_Sample_Source_Select_Mask; - break; - default: - BUG(); - break; - } + ni_writel(dev, NI_M_CDO_CMD_RESET, NI_M_CDIO_CMD_REG); + cdo_mode_bits = NI_M_CDO_MODE_FIFO_MODE | + NI_M_CDO_MODE_HALT_ON_ERROR | + NI_M_CDO_MODE_SAMPLE_SRC(CR_CHAN(cmd->scan_begin_arg)); if (cmd->scan_begin_arg & CR_INVERT) - cdo_mode_bits |= CDO_Polarity_Bit; - ni_writel(dev, cdo_mode_bits, M_Offset_CDO_Mode); + cdo_mode_bits |= NI_M_CDO_MODE_POLARITY; + ni_writel(dev, cdo_mode_bits, NI_M_CDO_MODE_REG); if (s->io_bits) { - ni_writel(dev, s->state, M_Offset_CDO_FIFO_Data); - ni_writel(dev, CDO_SW_Update_Bit, M_Offset_CDIO_Command); - ni_writel(dev, s->io_bits, M_Offset_CDO_Mask_Enable); + ni_writel(dev, s->state, NI_M_CDO_FIFO_DATA_REG); + ni_writel(dev, NI_M_CDO_CMD_SW_UPDATE, NI_M_CDIO_CMD_REG); + ni_writel(dev, s->io_bits, NI_M_CDO_MASK_ENA_REG); } else { dev_err(dev->class_dev, "attempted to run digital output command with no lines configured as outputs\n"); @@ -3611,15 +3465,16 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - ni_writel(dev, CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit | - CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit | - CDO_FIFO_Request_Interrupt_Enable_Clear_Bit, - M_Offset_CDIO_Command); -/* -* XXX not sure what interrupt C group does ni_writeb(dev, 0, -* M_Offset_Interrupt_C_Enable); -*/ - ni_writel(dev, 0, M_Offset_CDO_Mask_Enable); + ni_writel(dev, NI_M_CDO_CMD_DISARM | + NI_M_CDO_CMD_ERR_INT_ENA_CLR | + NI_M_CDO_CMD_F_E_INT_ENA_CLR | + NI_M_CDO_CMD_F_REQ_INT_ENA_CLR, + NI_M_CDIO_CMD_REG); + /* + * XXX not sure what interrupt C group does + * ni_writeb(dev, 0, NI_M_INTC_ENA_REG); + */ + ni_writel(dev, 0, NI_M_CDO_MASK_ENA_REG); ni_release_cdo_mite_channel(dev); return 0; } @@ -3650,16 +3505,16 @@ static void handle_cdio_interrupt(struct comedi_device *dev) spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); #endif - cdio_status = ni_readl(dev, M_Offset_CDIO_Status); - if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) { + cdio_status = ni_readl(dev, NI_M_CDIO_STATUS_REG); + if (cdio_status & NI_M_CDIO_STATUS_CDO_ERROR) { /* XXX just guessing this is needed and does something useful */ - ni_writel(dev, CDO_Error_Interrupt_Confirm_Bit, - M_Offset_CDIO_Command); + ni_writel(dev, NI_M_CDO_CMD_ERR_INT_CONFIRM, + NI_M_CDIO_CMD_REG); s->async->events |= COMEDI_CB_OVERFLOW; } - if (cdio_status & CDO_FIFO_Empty_Bit) { - ni_writel(dev, CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit, - M_Offset_CDIO_Command); + if (cdio_status & NI_M_CDIO_STATUS_CDO_FIFO_EMPTY) { + ni_writel(dev, NI_M_CDO_CMD_F_E_INT_ENA_CLR, + NI_M_CDIO_CMD_REG); /* s->async->events |= COMEDI_CB_EOA; */ } comedi_handle_events(dev, s); @@ -3674,23 +3529,23 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, unsigned int status1; int err = 0, count = 20; - devpriv->dio_output &= ~DIO_Serial_Data_Mask; - devpriv->dio_output |= DIO_Serial_Data_Out(data_out); - ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register); + devpriv->dio_output &= ~NISTC_DIO_OUT_SERIAL_MASK; + devpriv->dio_output |= NISTC_DIO_OUT_SERIAL(data_out); + ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG); - status1 = ni_stc_readw(dev, Joint_Status_1_Register); - if (status1 & DIO_Serial_IO_In_Progress_St) { + status1 = ni_stc_readw(dev, NISTC_STATUS1_REG); + if (status1 & NISTC_STATUS1_SERIO_IN_PROG) { err = -EBUSY; goto Error; } - devpriv->dio_control |= DIO_HW_Serial_Start; - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); - devpriv->dio_control &= ~DIO_HW_Serial_Start; + devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_START; + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); + devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_START; /* Wait until STC says we're done, but don't loop infinitely. */ - while ((status1 = ni_stc_readw(dev, Joint_Status_1_Register)) & - DIO_Serial_IO_In_Progress_St) { + while ((status1 = ni_stc_readw(dev, NISTC_STATUS1_REG)) & + NISTC_STATUS1_SERIO_IN_PROG) { /* Delay one bit per loop */ udelay((devpriv->serial_interval_ns + 999) / 1000); if (--count < 0) { @@ -3701,15 +3556,17 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, } } - /* Delay for last bit. This delay is absolutely necessary, because - DIO_Serial_IO_In_Progress_St goes high one bit too early. */ + /* + * Delay for last bit. This delay is absolutely necessary, because + * NISTC_STATUS1_SERIO_IN_PROG goes high one bit too early. + */ udelay((devpriv->serial_interval_ns + 999) / 1000); if (data_in) - *data_in = ni_stc_readw(dev, DIO_Serial_Input_Register); + *data_in = ni_stc_readw(dev, NISTC_DIO_SERIAL_IN_REG); Error: - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); return err; } @@ -3729,25 +3586,25 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, /* Output current bit; note that we cannot touch s->state because it is a per-subdevice field, and serial is a separate subdevice from DIO. */ - devpriv->dio_output &= ~DIO_SDOUT; + devpriv->dio_output &= ~NISTC_DIO_SDOUT; if (data_out & mask) - devpriv->dio_output |= DIO_SDOUT; - ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register); + devpriv->dio_output |= NISTC_DIO_SDOUT; + ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG); /* Assert SDCLK (active low, inverted), wait for half of the delay, deassert SDCLK, and wait for the other half. */ - devpriv->dio_control |= DIO_Software_Serial_Control; - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + devpriv->dio_control |= NISTC_DIO_SDCLK; + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); udelay((devpriv->serial_interval_ns + 999) / 2000); - devpriv->dio_control &= ~DIO_Software_Serial_Control; - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + devpriv->dio_control &= ~NISTC_DIO_SDCLK; + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); udelay((devpriv->serial_interval_ns + 999) / 2000); /* Input current bit */ - if (ni_stc_readw(dev, DIO_Parallel_Input_Register) & DIO_SDIN) + if (ni_stc_readw(dev, NISTC_DIO_IN_REG) & NISTC_DIO_SDIN) input |= mask; } @@ -3763,6 +3620,7 @@ static int ni_serial_insn_config(struct comedi_device *dev, unsigned int *data) { struct ni_private *devpriv = dev->private; + unsigned clk_fout = devpriv->clock_and_fout; int err = insn->n; unsigned char byte_out, byte_in = 0; @@ -3772,49 +3630,49 @@ static int ni_serial_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_SERIAL_CLOCK: devpriv->serial_hw_mode = 1; - devpriv->dio_control |= DIO_HW_Serial_Enable; + devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_ENA; if (data[1] == SERIAL_DISABLED) { devpriv->serial_hw_mode = 0; - devpriv->dio_control &= ~(DIO_HW_Serial_Enable | - DIO_Software_Serial_Control); + devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA | + NISTC_DIO_SDCLK); data[1] = SERIAL_DISABLED; devpriv->serial_interval_ns = data[1]; } else if (data[1] <= SERIAL_600NS) { /* Warning: this clock speed is too fast to reliably control SCXI. */ - devpriv->dio_control &= ~DIO_HW_Serial_Timebase; - devpriv->clock_and_fout |= Slow_Internal_Timebase; - devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2; + devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE; + clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE; + clk_fout &= ~NISTC_CLK_FOUT_DIO_SER_OUT_DIV2; data[1] = SERIAL_600NS; devpriv->serial_interval_ns = data[1]; } else if (data[1] <= SERIAL_1_2US) { - devpriv->dio_control &= ~DIO_HW_Serial_Timebase; - devpriv->clock_and_fout |= Slow_Internal_Timebase | - DIO_Serial_Out_Divide_By_2; + devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE; + clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE | + NISTC_CLK_FOUT_DIO_SER_OUT_DIV2; data[1] = SERIAL_1_2US; devpriv->serial_interval_ns = data[1]; } else if (data[1] <= SERIAL_10US) { - devpriv->dio_control |= DIO_HW_Serial_Timebase; - devpriv->clock_and_fout |= Slow_Internal_Timebase | - DIO_Serial_Out_Divide_By_2; - /* Note: DIO_Serial_Out_Divide_By_2 only affects + devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_TIMEBASE; + clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE | + NISTC_CLK_FOUT_DIO_SER_OUT_DIV2; + /* Note: NISTC_CLK_FOUT_DIO_SER_OUT_DIV2 only affects 600ns/1.2us. If you turn divide_by_2 off with the slow clock, you will still get 10us, except then all your delays are wrong. */ data[1] = SERIAL_10US; devpriv->serial_interval_ns = data[1]; } else { - devpriv->dio_control &= ~(DIO_HW_Serial_Enable | - DIO_Software_Serial_Control); + devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA | + NISTC_DIO_SDCLK); devpriv->serial_hw_mode = 0; data[1] = (data[1] / 1000) * 1000; devpriv->serial_interval_ns = data[1]; } + devpriv->clock_and_fout = clk_fout; - ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register); - ni_stc_writew(dev, devpriv->clock_and_fout, - Clock_and_FOUT_Register); + ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); + ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG); return 1; case INSN_CONFIG_BIDIRECTIONAL_DATA: @@ -3850,141 +3708,91 @@ static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s) int i; for (i = 0; i < s->n_chan; i++) { - ni_ao_win_outw(dev, AO_Channel(i) | 0x0, - AO_Configuration_2_67xx); - } - ni_ao_win_outw(dev, 0x0, AO_Later_Single_Point_Updates); -} + ni_ao_win_outw(dev, NI_E_AO_DACSEL(i) | 0x0, + NI67XX_AO_CFG2_REG); + } + ni_ao_win_outw(dev, 0x0, NI67XX_AO_SP_UPDATES_REG); +} + +static const struct mio_regmap ni_gpct_to_stc_regmap[] = { + [NITIO_G0_AUTO_INC] = { NISTC_G0_AUTOINC_REG, 2 }, + [NITIO_G1_AUTO_INC] = { NISTC_G1_AUTOINC_REG, 2 }, + [NITIO_G0_CMD] = { NISTC_G0_CMD_REG, 2 }, + [NITIO_G1_CMD] = { NISTC_G1_CMD_REG, 2 }, + [NITIO_G0_HW_SAVE] = { NISTC_G0_HW_SAVE_REG, 4 }, + [NITIO_G1_HW_SAVE] = { NISTC_G1_HW_SAVE_REG, 4 }, + [NITIO_G0_SW_SAVE] = { NISTC_G0_SAVE_REG, 4 }, + [NITIO_G1_SW_SAVE] = { NISTC_G1_SAVE_REG, 4 }, + [NITIO_G0_MODE] = { NISTC_G0_MODE_REG, 2 }, + [NITIO_G1_MODE] = { NISTC_G1_MODE_REG, 2 }, + [NITIO_G0_LOADA] = { NISTC_G0_LOADA_REG, 4 }, + [NITIO_G1_LOADA] = { NISTC_G1_LOADA_REG, 4 }, + [NITIO_G0_LOADB] = { NISTC_G0_LOADB_REG, 4 }, + [NITIO_G1_LOADB] = { NISTC_G1_LOADB_REG, 4 }, + [NITIO_G0_INPUT_SEL] = { NISTC_G0_INPUT_SEL_REG, 2 }, + [NITIO_G1_INPUT_SEL] = { NISTC_G1_INPUT_SEL_REG, 2 }, + [NITIO_G0_CNT_MODE] = { 0x1b0, 2 }, /* M-Series only */ + [NITIO_G1_CNT_MODE] = { 0x1b2, 2 }, /* M-Series only */ + [NITIO_G0_GATE2] = { 0x1b4, 2 }, /* M-Series only */ + [NITIO_G1_GATE2] = { 0x1b6, 2 }, /* M-Series only */ + [NITIO_G01_STATUS] = { NISTC_G01_STATUS_REG, 2 }, + [NITIO_G01_RESET] = { NISTC_RESET_REG, 2 }, + [NITIO_G01_STATUS1] = { NISTC_STATUS1_REG, 2 }, + [NITIO_G01_STATUS2] = { NISTC_STATUS2_REG, 2 }, + [NITIO_G0_DMA_CFG] = { 0x1b8, 2 }, /* M-Series only */ + [NITIO_G1_DMA_CFG] = { 0x1ba, 2 }, /* M-Series only */ + [NITIO_G0_DMA_STATUS] = { 0x1b8, 2 }, /* M-Series only */ + [NITIO_G1_DMA_STATUS] = { 0x1ba, 2 }, /* M-Series only */ + [NITIO_G0_ABZ] = { 0x1c0, 2 }, /* M-Series only */ + [NITIO_G1_ABZ] = { 0x1c2, 2 }, /* M-Series only */ + [NITIO_G0_INT_ACK] = { NISTC_INTA_ACK_REG, 2 }, + [NITIO_G1_INT_ACK] = { NISTC_INTB_ACK_REG, 2 }, + [NITIO_G0_STATUS] = { NISTC_AI_STATUS1_REG, 2 }, + [NITIO_G1_STATUS] = { NISTC_AO_STATUS1_REG, 2 }, + [NITIO_G0_INT_ENA] = { NISTC_INTA_ENA_REG, 2 }, + [NITIO_G1_INT_ENA] = { NISTC_INTB_ENA_REG, 2 }, +}; -static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg) +static unsigned int ni_gpct_to_stc_register(struct comedi_device *dev, + enum ni_gpct_register reg) { - unsigned stc_register; + const struct mio_regmap *regmap; - switch (reg) { - case NITIO_G0_AUTO_INC: - stc_register = G_Autoincrement_Register(0); - break; - case NITIO_G1_AUTO_INC: - stc_register = G_Autoincrement_Register(1); - break; - case NITIO_G0_CMD: - stc_register = G_Command_Register(0); - break; - case NITIO_G1_CMD: - stc_register = G_Command_Register(1); - break; - case NITIO_G0_HW_SAVE: - stc_register = G_HW_Save_Register(0); - break; - case NITIO_G1_HW_SAVE: - stc_register = G_HW_Save_Register(1); - break; - case NITIO_G0_SW_SAVE: - stc_register = G_Save_Register(0); - break; - case NITIO_G1_SW_SAVE: - stc_register = G_Save_Register(1); - break; - case NITIO_G0_MODE: - stc_register = G_Mode_Register(0); - break; - case NITIO_G1_MODE: - stc_register = G_Mode_Register(1); - break; - case NITIO_G0_LOADA: - stc_register = G_Load_A_Register(0); - break; - case NITIO_G1_LOADA: - stc_register = G_Load_A_Register(1); - break; - case NITIO_G0_LOADB: - stc_register = G_Load_B_Register(0); - break; - case NITIO_G1_LOADB: - stc_register = G_Load_B_Register(1); - break; - case NITIO_G0_INPUT_SEL: - stc_register = G_Input_Select_Register(0); - break; - case NITIO_G1_INPUT_SEL: - stc_register = G_Input_Select_Register(1); - break; - case NITIO_G01_STATUS: - stc_register = G_Status_Register; - break; - case NITIO_G01_RESET: - stc_register = Joint_Reset_Register; - break; - case NITIO_G01_STATUS1: - stc_register = Joint_Status_1_Register; - break; - case NITIO_G01_STATUS2: - stc_register = Joint_Status_2_Register; - break; - case NITIO_G0_INT_ACK: - stc_register = Interrupt_A_Ack_Register; - break; - case NITIO_G1_INT_ACK: - stc_register = Interrupt_B_Ack_Register; - break; - case NITIO_G0_STATUS: - stc_register = AI_Status_1_Register; - break; - case NITIO_G1_STATUS: - stc_register = AO_Status_1_Register; - break; - case NITIO_G0_INT_ENA: - stc_register = Interrupt_A_Enable_Register; - break; - case NITIO_G1_INT_ENA: - stc_register = Interrupt_B_Enable_Register; - break; - default: - pr_err("%s: unhandled register 0x%x in switch.\n", - __func__, reg); - BUG(); + if (reg < ARRAY_SIZE(ni_gpct_to_stc_regmap)) { + regmap = &ni_gpct_to_stc_regmap[reg]; + } else { + dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", + __func__, reg); return 0; } - return stc_register; + + return regmap->mio_reg; } static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - unsigned stc_register; - /* bits in the join reset register which are relevant to counters */ - static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset; + unsigned int stc_register = ni_gpct_to_stc_register(dev, reg); static const unsigned gpct_interrupt_a_enable_mask = - G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable; + NISTC_INTA_ENA_G0_GATE | NISTC_INTA_ENA_G0_TC; static const unsigned gpct_interrupt_b_enable_mask = - G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable; + NISTC_INTB_ENA_G1_GATE | NISTC_INTB_ENA_G1_TC; + + if (stc_register == 0) + return; switch (reg) { - /* m-series-only registers */ + /* m-series only registers */ case NITIO_G0_CNT_MODE: - ni_writew(dev, bits, M_Offset_G0_Counting_Mode); - break; case NITIO_G1_CNT_MODE: - ni_writew(dev, bits, M_Offset_G1_Counting_Mode); - break; case NITIO_G0_GATE2: - ni_writew(dev, bits, M_Offset_G0_Second_Gate); - break; case NITIO_G1_GATE2: - ni_writew(dev, bits, M_Offset_G1_Second_Gate); - break; case NITIO_G0_DMA_CFG: - ni_writew(dev, bits, M_Offset_G0_DMA_Config); - break; case NITIO_G1_DMA_CFG: - ni_writew(dev, bits, M_Offset_G1_DMA_Config); - break; case NITIO_G0_ABZ: - ni_writew(dev, bits, M_Offset_G0_MSeries_ABZ); - break; case NITIO_G1_ABZ: - ni_writew(dev, bits, M_Offset_G1_MSeries_ABZ); + ni_writew(dev, bits, stc_register); break; /* 32 bit registers */ @@ -3992,26 +3800,24 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, case NITIO_G1_LOADA: case NITIO_G0_LOADB: case NITIO_G1_LOADB: - stc_register = ni_gpct_to_stc_register(reg); ni_stc_writel(dev, bits, stc_register); break; /* 16 bit registers */ case NITIO_G0_INT_ENA: BUG_ON(bits & ~gpct_interrupt_a_enable_mask); - ni_set_bitfield(dev, Interrupt_A_Enable_Register, + ni_set_bitfield(dev, stc_register, gpct_interrupt_a_enable_mask, bits); break; case NITIO_G1_INT_ENA: BUG_ON(bits & ~gpct_interrupt_b_enable_mask); - ni_set_bitfield(dev, Interrupt_B_Enable_Register, + ni_set_bitfield(dev, stc_register, gpct_interrupt_b_enable_mask, bits); break; case NITIO_G01_RESET: - BUG_ON(bits & ~gpct_joint_reset_mask); + BUG_ON(bits & ~(NISTC_RESET_G0 | NISTC_RESET_G1)); /* fall-through */ default: - stc_register = ni_gpct_to_stc_register(reg); ni_stc_writew(dev, bits, stc_register); } } @@ -4020,29 +3826,28 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - unsigned stc_register; + unsigned int stc_register = ni_gpct_to_stc_register(dev, reg); + + if (stc_register == 0) + return 0; switch (reg) { /* m-series only registers */ case NITIO_G0_DMA_STATUS: - return ni_readw(dev, M_Offset_G0_DMA_Status); case NITIO_G1_DMA_STATUS: - return ni_readw(dev, M_Offset_G1_DMA_Status); + return ni_readw(dev, stc_register); /* 32 bit registers */ case NITIO_G0_HW_SAVE: case NITIO_G1_HW_SAVE: case NITIO_G0_SW_SAVE: case NITIO_G1_SW_SAVE: - stc_register = ni_gpct_to_stc_register(reg); return ni_stc_readl(dev, stc_register); /* 16 bit registers */ default: - stc_register = ni_gpct_to_stc_register(reg); return ni_stc_readw(dev, stc_register); } - return 0; } static int ni_freq_out_insn_read(struct comedi_device *dev, @@ -4051,7 +3856,7 @@ static int ni_freq_out_insn_read(struct comedi_device *dev, unsigned int *data) { struct ni_private *devpriv = dev->private; - unsigned int val = devpriv->clock_and_fout & FOUT_Divider_mask; + unsigned int val = NISTC_CLK_FOUT_TO_DIVIDER(devpriv->clock_and_fout); int i; for (i = 0; i < insn->n; i++) @@ -4068,17 +3873,17 @@ static int ni_freq_out_insn_write(struct comedi_device *dev, struct ni_private *devpriv = dev->private; if (insn->n) { - devpriv->clock_and_fout &= ~FOUT_Enable; - ni_stc_writew(dev, devpriv->clock_and_fout, - Clock_and_FOUT_Register); - devpriv->clock_and_fout &= ~FOUT_Divider_mask; + unsigned int val = data[insn->n - 1]; + + devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_ENA; + ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG); + devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_DIVIDER_MASK; /* use the last data value to set the fout divider */ - devpriv->clock_and_fout |= FOUT_Divider(data[insn->n - 1]); + devpriv->clock_and_fout |= NISTC_CLK_FOUT_DIVIDER(val); - devpriv->clock_and_fout |= FOUT_Enable; - ni_stc_writew(dev, devpriv->clock_and_fout, - Clock_and_FOUT_Register); + devpriv->clock_and_fout |= NISTC_CLK_FOUT_ENA; + ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG); } return insn->n; } @@ -4094,19 +3899,18 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, case INSN_CONFIG_SET_CLOCK_SRC: switch (data[1]) { case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC: - devpriv->clock_and_fout &= ~FOUT_Timebase_Select; + devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_TIMEBASE_SEL; break; case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC: - devpriv->clock_and_fout |= FOUT_Timebase_Select; + devpriv->clock_and_fout |= NISTC_CLK_FOUT_TIMEBASE_SEL; break; default: return -EINVAL; } - ni_stc_writew(dev, devpriv->clock_and_fout, - Clock_and_FOUT_Register); + ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG); break; case INSN_CONFIG_GET_CLOCK_SRC: - if (devpriv->clock_and_fout & FOUT_Timebase_Select) { + if (devpriv->clock_and_fout & NISTC_CLK_FOUT_TIMEBASE_SEL) { data[1] = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC; data[2] = TIMEBASE_2_NS; } else { @@ -4190,9 +3994,9 @@ static int ni_m_series_pwm_config(struct comedi_device *dev, data[4] = down_count * devpriv->clock_ns; return -EAGAIN; } - ni_writel(dev, MSeries_Cal_PWM_High_Time_Bits(up_count) | - MSeries_Cal_PWM_Low_Time_Bits(down_count), - M_Offset_Cal_PWM); + ni_writel(dev, NI_M_CAL_PWM_HIGH_TIME(up_count) | + NI_M_CAL_PWM_LOW_TIME(down_count), + NI_M_CAL_PWM_REG); devpriv->pwm_up_count = up_count; devpriv->pwm_down_count = down_count; return 5; @@ -4254,9 +4058,9 @@ static int ni_6143_pwm_config(struct comedi_device *dev, data[4] = down_count * devpriv->clock_ns; return -EAGAIN; } - ni_writel(dev, up_count, Calibration_HighTime_6143); + ni_writel(dev, up_count, NI6143_CALIB_HI_TIME_REG); devpriv->pwm_up_count = up_count; - ni_writel(dev, down_count, Calibration_LowTime_6143); + ni_writel(dev, down_count, NI6143_CALIB_LO_TIME_REG); devpriv->pwm_down_count = down_count; return 5; case INSN_CONFIG_GET_PWM_OUTPUT: @@ -4336,6 +4140,7 @@ static void ni_write_caldac(struct comedi_device *dev, int addr, int val) const struct ni_board_struct *board = dev->board_ptr; struct ni_private *devpriv = dev->private; unsigned int loadbit = 0, bits = 0, bit, bitstring = 0; + unsigned int cmd; int i; int type; @@ -4349,7 +4154,7 @@ static void ni_write_caldac(struct comedi_device *dev, int addr, int val) break; if (addr < caldacs[type].n_chans) { bits = caldacs[type].packbits(addr, val, &bitstring); - loadbit = SerDacLd(i); + loadbit = NI_E_SERIAL_CMD_DAC_LD(i); break; } addr -= caldacs[type].n_chans; @@ -4360,15 +4165,15 @@ static void ni_write_caldac(struct comedi_device *dev, int addr, int val) return; for (bit = 1 << (bits - 1); bit; bit >>= 1) { - ni_writeb(dev, ((bit & bitstring) ? 0x02 : 0), Serial_Command); + cmd = (bit & bitstring) ? NI_E_SERIAL_CMD_SDATA : 0; + ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG); udelay(1); - ni_writeb(dev, 1 | ((bit & bitstring) ? 0x02 : 0), - Serial_Command); + ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG); udelay(1); } - ni_writeb(dev, loadbit, Serial_Command); + ni_writeb(dev, loadbit, NI_E_SERIAL_CMD_REG); udelay(1); - ni_writeb(dev, 0, Serial_Command); + ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG); } static int ni_calib_insn_write(struct comedi_device *dev, @@ -4450,24 +4255,30 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_read_eeprom(struct comedi_device *dev, int addr) { + unsigned int cmd = NI_E_SERIAL_CMD_EEPROM_CS; int bit; int bitstring; bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff); - ni_writeb(dev, 0x04, Serial_Command); + ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG); for (bit = 0x8000; bit; bit >>= 1) { - ni_writeb(dev, 0x04 | ((bit & bitstring) ? 0x02 : 0), - Serial_Command); - ni_writeb(dev, 0x05 | ((bit & bitstring) ? 0x02 : 0), - Serial_Command); + if (bit & bitstring) + cmd |= NI_E_SERIAL_CMD_SDATA; + else + cmd &= ~NI_E_SERIAL_CMD_SDATA; + + ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG); + ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG); } + cmd = NI_E_SERIAL_CMD_EEPROM_CS; bitstring = 0; for (bit = 0x80; bit; bit >>= 1) { - ni_writeb(dev, 0x04, Serial_Command); - ni_writeb(dev, 0x05, Serial_Command); - bitstring |= ((ni_readb(dev, XXX_Status) & PROMOUT) ? bit : 0); + ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG); + ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG); + if (ni_readb(dev, NI_E_STATUS_REG) & NI_E_STATUS_PROMOUT) + bitstring |= bit; } - ni_writeb(dev, 0x00, Serial_Command); + ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG); return bitstring; } @@ -4541,7 +4352,7 @@ static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev, struct ni_private *devpriv = dev->private; const unsigned array_offset = chan / 3; - return MSeries_PFI_Output_Select_Source(chan, + return NI_M_PFI_OUT_SEL_TO_SRC(chan, devpriv->pfi_output_select_reg[array_offset]); } @@ -4549,19 +4360,17 @@ static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { struct ni_private *devpriv = dev->private; - unsigned pfi_reg_index; - unsigned array_offset; + unsigned index = chan / 3; + unsigned short val = devpriv->pfi_output_select_reg[index]; if ((source & 0x1f) != source) return -EINVAL; - pfi_reg_index = 1 + chan / 3; - array_offset = pfi_reg_index - 1; - devpriv->pfi_output_select_reg[array_offset] &= - ~MSeries_PFI_Output_Select_Mask(chan); - devpriv->pfi_output_select_reg[array_offset] |= - MSeries_PFI_Output_Select_Bits(chan, source); - ni_writew(dev, devpriv->pfi_output_select_reg[array_offset], - M_Offset_PFI_Output_Select(pfi_reg_index)); + + val &= ~NI_M_PFI_OUT_SEL_MASK(chan); + val |= NI_M_PFI_OUT_SEL(chan, source); + ni_writew(dev, val, NI_M_PFI_OUT_SEL_REG(index)); + devpriv->pfi_output_select_reg[index] = val; + return 2; } @@ -4594,10 +4403,10 @@ static int ni_config_filter(struct comedi_device *dev, if (!devpriv->is_m_series) return -ENOTSUPP; - bits = ni_readl(dev, M_Offset_PFI_Filter); - bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel); - bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter); - ni_writel(dev, bits, M_Offset_PFI_Filter); + bits = ni_readl(dev, NI_M_PFI_FILTER_REG); + bits &= ~NI_M_PFI_FILTER_SEL_MASK(pfi_channel); + bits |= NI_M_PFI_FILTER_SEL(pfi_channel, filter); + ni_writel(dev, bits, NI_M_PFI_FILTER_REG); return 0; } @@ -4616,10 +4425,10 @@ static int ni_pfi_insn_config(struct comedi_device *dev, switch (data[0]) { case COMEDI_OUTPUT: - ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1); + ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 1); break; case COMEDI_INPUT: - ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0); + ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 0); break; case INSN_CONFIG_DIO_QUERY: data[1] = @@ -4650,9 +4459,9 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, return -ENOTSUPP; if (comedi_dio_update_state(s, data)) - ni_writew(dev, s->state, M_Offset_PFI_DO); + ni_writew(dev, s->state, NI_M_PFI_DO_REG); - data[1] = ni_readw(dev, M_Offset_PFI_DI); + data[1] = ni_readw(dev, NI_M_PFI_DI_REG); return insn->n; } @@ -4664,8 +4473,8 @@ static int cs5529_wait_for_idle(struct comedi_device *dev) int i; for (i = 0; i < timeout; i++) { - status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); - if ((status & CSS_ADC_BUSY) == 0) + status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG); + if ((status & NI67XX_CAL_STATUS_BUSY) == 0) break; set_current_state(TASK_INTERRUPTIBLE); if (schedule_timeout(1)) @@ -4683,13 +4492,14 @@ static void cs5529_command(struct comedi_device *dev, unsigned short value) static const int timeout = 100; int i; - ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx); + ni_ao_win_outw(dev, value, NI67XX_CAL_CMD_REG); /* give time for command to start being serially clocked into cs5529. - * this insures that the CSS_ADC_BUSY bit will get properly + * this insures that the NI67XX_CAL_STATUS_BUSY bit will get properly * set before we exit this function. */ for (i = 0; i < timeout; i++) { - if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY)) + if (ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG) & + NI67XX_CAL_STATUS_BUSY) break; udelay(1); } @@ -4704,25 +4514,25 @@ static int cs5529_do_conversion(struct comedi_device *dev, int retval; unsigned short status; - cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION); + cs5529_command(dev, CS5529_CMD_CB | CS5529_CMD_SINGLE_CONV); retval = cs5529_wait_for_idle(dev); if (retval) { dev_err(dev->class_dev, "timeout or signal in cs5529_do_conversion()\n"); return -ETIME; } - status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); - if (status & CSS_OSC_DETECT) { + status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG); + if (status & NI67XX_CAL_STATUS_OSC_DETECT) { dev_err(dev->class_dev, "cs5529 conversion error, status CSS_OSC_DETECT\n"); return -EIO; } - if (status & CSS_OVERRANGE) { + if (status & NI67XX_CAL_STATUS_OVERRANGE) { dev_err(dev->class_dev, "cs5529 conversion error, overrange (ignoring)\n"); } if (data) { - *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx); + *data = ni_ao_win_inw(dev, NI67XX_CAL_DATA_REG); /* cs5529 returns 16 bit signed data in bipolar mode */ *data ^= (1 << 15); } @@ -4746,7 +4556,7 @@ static int cs5529_ai_insn_read(struct comedi_device *dev, channel_select = INTERNAL_REF; else channel_select = CR_CHAN(insn->chanspec); - ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx); + ni_ao_win_outw(dev, channel_select, NI67XX_AO_CAL_CHAN_SEL_REG); for (n = 0; n < insn->n; n++) { retval = cs5529_do_conversion(dev, &sample); @@ -4760,12 +4570,10 @@ static int cs5529_ai_insn_read(struct comedi_device *dev, static void cs5529_config_write(struct comedi_device *dev, unsigned int value, unsigned int reg_select_bits) { - ni_ao_win_outw(dev, ((value >> 16) & 0xff), - CAL_ADC_Config_Data_High_Word_67xx); - ni_ao_win_outw(dev, (value & 0xffff), - CAL_ADC_Config_Data_Low_Word_67xx); - reg_select_bits &= CSCMD_REGISTER_SELECT_MASK; - cs5529_command(dev, CSCMD_COMMAND | reg_select_bits); + ni_ao_win_outw(dev, (value >> 16) & 0xff, NI67XX_CAL_CFG_HI_REG); + ni_ao_win_outw(dev, value & 0xffff, NI67XX_CAL_CFG_LO_REG); + reg_select_bits &= CS5529_CMD_REG_MASK; + cs5529_command(dev, CS5529_CMD_CB | reg_select_bits); if (cs5529_wait_for_idle(dev)) dev_err(dev->class_dev, "timeout or signal in %s\n", __func__); @@ -4773,20 +4581,20 @@ static void cs5529_config_write(struct comedi_device *dev, unsigned int value, static int init_cs5529(struct comedi_device *dev) { - unsigned int config_bits = - CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES; + unsigned int config_bits = CS5529_CFG_PORT_FLAG | + CS5529_CFG_WORD_RATE_2180; #if 1 /* do self-calibration */ - cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN, - CSCMD_CONFIG_REGISTER); + cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_BOTH_SELF, + CS5529_CFG_REG); /* need to force a conversion for calibration to run */ cs5529_do_conversion(dev, NULL); #else /* force gain calibration to 1 */ - cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER); - cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET, - CSCMD_CONFIG_REGISTER); + cs5529_config_write(dev, 0x400000, CS5529_GAIN_REG); + cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_OFFSET_SELF, + CS5529_CFG_REG); if (cs5529_wait_for_idle(dev)) dev_err(dev->class_dev, "timeout or signal in %s\n", __func__); @@ -4805,10 +4613,8 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns, { unsigned div; unsigned best_div = 1; - static const unsigned max_div = 0x10; unsigned mult; unsigned best_mult = 1; - static const unsigned max_mult = 0x100; static const unsigned pico_per_nano = 1000; const unsigned reference_picosec = reference_period_ns * pico_per_nano; @@ -4818,8 +4624,8 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns, static const unsigned fudge_factor_80_to_20Mhz = 4; int best_period_picosec = 0; - for (div = 1; div <= max_div; ++div) { - for (mult = 1; mult <= max_mult; ++mult) { + for (div = 1; div <= NI_M_PLL_MAX_DIVISOR; ++div) { + for (mult = 1; mult <= NI_M_PLL_MAX_MULTIPLIER; ++mult) { unsigned new_period_ps = (reference_picosec * div) / mult; if (abs(new_period_ps - target_picosec) < @@ -4851,6 +4657,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned pll_control_bits; unsigned freq_divider; unsigned freq_multiplier; + unsigned rtsi; unsigned i; int retval; @@ -4863,42 +4670,31 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, __func__, min_period_ns, max_period_ns); return -EINVAL; } - devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; + devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK; ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg, - RTSI_Trig_Direction_Register); - pll_control_bits = - MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits; - devpriv->clock_and_fout2 |= - MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit; - devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask; + NISTC_RTSI_TRIG_DIR_REG); + pll_control_bits = NI_M_PLL_CTRL_ENA | NI_M_PLL_CTRL_VCO_MODE_75_150MHZ; + devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_TIMEBASE1_PLL | + NI_M_CLK_FOUT2_TIMEBASE3_PLL; + devpriv->clock_and_fout2 &= ~NI_M_CLK_FOUT2_PLL_SRC_MASK; switch (source) { case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK: - devpriv->clock_and_fout2 |= - MSeries_PLL_In_Source_Select_Star_Trigger_Bits; + devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_STAR; break; case NI_MIO_PLL_PXI10_CLOCK: /* pxi clock is 10MHz */ - devpriv->clock_and_fout2 |= - MSeries_PLL_In_Source_Select_PXI_Clock10; + devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_PXI10; break; default: - { - unsigned rtsi_channel; - static const unsigned max_rtsi_channel = 7; - - for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel; - ++rtsi_channel) { - if (source == - NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) { - devpriv->clock_and_fout2 |= - MSeries_PLL_In_Source_Select_RTSI_Bits - (rtsi_channel); - break; - } + for (rtsi = 0; rtsi <= NI_M_MAX_RTSI_CHAN; ++rtsi) { + if (source == NI_MIO_PLL_RTSI_CLOCK(rtsi)) { + devpriv->clock_and_fout2 |= + NI_M_CLK_FOUT2_PLL_SRC_RTSI(rtsi); + break; } - if (rtsi_channel > max_rtsi_channel) - return -EINVAL; } + if (rtsi > NI_M_MAX_RTSI_CHAN) + return -EINVAL; break; } retval = ni_mseries_get_pll_parameters(period_ns, @@ -4911,16 +4707,15 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, return retval; } - ni_writew(dev, devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2); - pll_control_bits |= - MSeries_PLL_Divisor_Bits(freq_divider) | - MSeries_PLL_Multiplier_Bits(freq_multiplier); + ni_writew(dev, devpriv->clock_and_fout2, NI_M_CLK_FOUT2_REG); + pll_control_bits |= NI_M_PLL_CTRL_DIVISOR(freq_divider) | + NI_M_PLL_CTRL_MULTIPLIER(freq_multiplier); - ni_writew(dev, pll_control_bits, M_Offset_PLL_Control); + ni_writew(dev, pll_control_bits, NI_M_PLL_CTRL_REG); devpriv->clock_source = source; /* it seems to typically take a few hundred microseconds for PLL to lock */ for (i = 0; i < timeout; ++i) { - if (ni_readw(dev, M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) + if (ni_readw(dev, NI_M_PLL_STATUS_REG) & NI_M_PLL_STATUS_LOCKED) break; udelay(1); } @@ -4939,17 +4734,17 @@ static int ni_set_master_clock(struct comedi_device *dev, struct ni_private *devpriv = dev->private; if (source == NI_MIO_INTERNAL_CLOCK) { - devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; + devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK; ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg, - RTSI_Trig_Direction_Register); + NISTC_RTSI_TRIG_DIR_REG); devpriv->clock_ns = TIMEBASE_1_NS; if (devpriv->is_m_series) { devpriv->clock_and_fout2 &= - ~(MSeries_Timebase1_Select_Bit | - MSeries_Timebase3_Select_Bit); + ~(NI_M_CLK_FOUT2_TIMEBASE1_PLL | + NI_M_CLK_FOUT2_TIMEBASE3_PLL); ni_writew(dev, devpriv->clock_and_fout2, - M_Offset_Clock_and_Fout2); - ni_writew(dev, 0, M_Offset_PLL_Control); + NI_M_CLK_FOUT2_REG); + ni_writew(dev, 0, NI_M_PLL_CTRL_REG); } devpriv->clock_source = source; } else { @@ -4959,10 +4754,10 @@ static int ni_set_master_clock(struct comedi_device *dev, } else { if (source == NI_MIO_RTSI_CLOCK) { devpriv->rtsi_trig_direction_reg |= - Use_RTSI_Clock_Bit; + NISTC_RTSI_TRIG_USE_CLK; ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg, - RTSI_Trig_Direction_Register); + NISTC_RTSI_TRIG_DIR_REG); if (period_ns == 0) { dev_err(dev->class_dev, "we don't handle an unspecified clock period correctly yet, returning error\n"); @@ -4978,26 +4773,19 @@ static int ni_set_master_clock(struct comedi_device *dev, return 3; } -static unsigned num_configurable_rtsi_channels(struct comedi_device *dev) -{ - struct ni_private *devpriv = dev->private; - - return (devpriv->is_m_series) ? 8 : 7; -} - static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan, unsigned source) { struct ni_private *devpriv = dev->private; - if (chan >= num_configurable_rtsi_channels(dev)) { - if (chan == old_RTSI_clock_channel) { + if (chan >= NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) { + if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) { if (source == NI_RTSI_OUTPUT_RTSI_OSC) return 1; dev_err(dev->class_dev, "%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards\n", - __func__, chan, old_RTSI_clock_channel); + __func__, chan, NISTC_RTSI_TRIG_OLD_CLK_CHAN); return 0; } return 0; @@ -5021,24 +4809,22 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, } static int ni_set_rtsi_routing(struct comedi_device *dev, - unsigned chan, unsigned source) + unsigned chan, unsigned src) { struct ni_private *devpriv = dev->private; - if (ni_valid_rtsi_output_source(dev, chan, source) == 0) + if (ni_valid_rtsi_output_source(dev, chan, src) == 0) return -EINVAL; if (chan < 4) { - devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan); - devpriv->rtsi_trig_a_output_reg |= - RTSI_Trig_Output_Bits(chan, source); + devpriv->rtsi_trig_a_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan); + devpriv->rtsi_trig_a_output_reg |= NISTC_RTSI_TRIG(chan, src); ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg, - RTSI_Trig_A_Output_Register); + NISTC_RTSI_TRIGA_OUT_REG); } else if (chan < 8) { - devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan); - devpriv->rtsi_trig_b_output_reg |= - RTSI_Trig_Output_Bits(chan, source); + devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan); + devpriv->rtsi_trig_b_output_reg |= NISTC_RTSI_TRIG(chan, src); ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg, - RTSI_Trig_B_Output_Register); + NISTC_RTSI_TRIGB_OUT_REG); } return 2; } @@ -5048,13 +4834,13 @@ static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan) struct ni_private *devpriv = dev->private; if (chan < 4) { - return RTSI_Trig_Output_Source(chan, - devpriv->rtsi_trig_a_output_reg); - } else if (chan < num_configurable_rtsi_channels(dev)) { - return RTSI_Trig_Output_Source(chan, - devpriv->rtsi_trig_b_output_reg); + return NISTC_RTSI_TRIG_TO_SRC(chan, + devpriv->rtsi_trig_a_output_reg); + } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) { + return NISTC_RTSI_TRIG_TO_SRC(chan, + devpriv->rtsi_trig_b_output_reg); } else { - if (chan == old_RTSI_clock_channel) + if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) return NI_RTSI_OUTPUT_RTSI_OSC; dev_err(dev->class_dev, "bug! should never get here?\n"); return 0; @@ -5068,42 +4854,43 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, { struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series); switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - if (chan < num_configurable_rtsi_channels(dev)) { + if (chan < max_chan) { devpriv->rtsi_trig_direction_reg |= - RTSI_Output_Bit(chan, devpriv->is_m_series); - } else if (chan == old_RTSI_clock_channel) { + NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series); + } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) { devpriv->rtsi_trig_direction_reg |= - Drive_RTSI_Clock_Bit; + NISTC_RTSI_TRIG_DRV_CLK; } ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg, - RTSI_Trig_Direction_Register); + NISTC_RTSI_TRIG_DIR_REG); break; case INSN_CONFIG_DIO_INPUT: - if (chan < num_configurable_rtsi_channels(dev)) { + if (chan < max_chan) { devpriv->rtsi_trig_direction_reg &= - ~RTSI_Output_Bit(chan, devpriv->is_m_series); - } else if (chan == old_RTSI_clock_channel) { + ~NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series); + } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) { devpriv->rtsi_trig_direction_reg &= - ~Drive_RTSI_Clock_Bit; + ~NISTC_RTSI_TRIG_DRV_CLK; } ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg, - RTSI_Trig_Direction_Register); + NISTC_RTSI_TRIG_DIR_REG); break; case INSN_CONFIG_DIO_QUERY: - if (chan < num_configurable_rtsi_channels(dev)) { + if (chan < max_chan) { data[1] = (devpriv->rtsi_trig_direction_reg & - RTSI_Output_Bit(chan, devpriv->is_m_series)) + NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series)) ? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT; - } else if (chan == old_RTSI_clock_channel) { - data[1] = - (devpriv->rtsi_trig_direction_reg & - Drive_RTSI_Clock_Bit) - ? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT; + } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) { + data[1] = (devpriv->rtsi_trig_direction_reg & + NISTC_RTSI_TRIG_DRV_CLK) + ? INSN_CONFIG_DIO_OUTPUT + : INSN_CONFIG_DIO_INPUT; } return 2; case INSN_CONFIG_SET_CLOCK_SRC: @@ -5139,37 +4926,37 @@ static void ni_rtsi_init(struct comedi_device *dev) /* Initialises the RTSI bus signal switch to a default state */ + /* + * Use 10MHz instead of 20MHz for RTSI clock frequency. Appears + * to have no effect, at least on pxi-6281, which always uses + * 20MHz rtsi clock frequency + */ + devpriv->clock_and_fout2 = NI_M_CLK_FOUT2_RTSI_10MHZ; /* Set clock mode to internal */ - devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit; if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n"); /* default internal lines routing to RTSI bus lines */ devpriv->rtsi_trig_a_output_reg = - RTSI_Trig_Output_Bits(0, - NI_RTSI_OUTPUT_ADR_START1) | - RTSI_Trig_Output_Bits(1, - NI_RTSI_OUTPUT_ADR_START2) | - RTSI_Trig_Output_Bits(2, - NI_RTSI_OUTPUT_SCLKG) | - RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN); + NISTC_RTSI_TRIG(0, NI_RTSI_OUTPUT_ADR_START1) | + NISTC_RTSI_TRIG(1, NI_RTSI_OUTPUT_ADR_START2) | + NISTC_RTSI_TRIG(2, NI_RTSI_OUTPUT_SCLKG) | + NISTC_RTSI_TRIG(3, NI_RTSI_OUTPUT_DACUPDN); ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg, - RTSI_Trig_A_Output_Register); + NISTC_RTSI_TRIGA_OUT_REG); devpriv->rtsi_trig_b_output_reg = - RTSI_Trig_Output_Bits(4, - NI_RTSI_OUTPUT_DA_START1) | - RTSI_Trig_Output_Bits(5, - NI_RTSI_OUTPUT_G_SRC0) | - RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0); + NISTC_RTSI_TRIG(4, NI_RTSI_OUTPUT_DA_START1) | + NISTC_RTSI_TRIG(5, NI_RTSI_OUTPUT_G_SRC0) | + NISTC_RTSI_TRIG(6, NI_RTSI_OUTPUT_G_GATE0); if (devpriv->is_m_series) devpriv->rtsi_trig_b_output_reg |= - RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC); + NISTC_RTSI_TRIG(7, NI_RTSI_OUTPUT_RTSI_OSC); ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg, - RTSI_Trig_B_Output_Register); + NISTC_RTSI_TRIGB_OUT_REG); -/* -* Sets the source and direction of the 4 on board lines -* ni_stc_writew(dev, 0x0000, RTSI_Board_Register); -*/ + /* + * Sets the source and direction of the 4 on board lines + * ni_stc_writew(dev, 0, NISTC_RTSI_BOARD_REG); + */ } #ifdef PCIDMA @@ -5203,88 +4990,6 @@ static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s) } #endif -#if 0 -/* - * Read the GPCTs current value. - */ -static int GPCT_G_Watch(struct comedi_device *dev, int chan) -{ - unsigned int hi1, hi2, lo; - - devpriv->gpct_command[chan] &= ~G_Save_Trace; - ni_stc_writew(dev, devpriv->gpct_command[chan], - G_Command_Register(chan)); - - devpriv->gpct_command[chan] |= G_Save_Trace; - ni_stc_writew(dev, devpriv->gpct_command[chan], - G_Command_Register(chan)); - - /* This procedure is used because the two registers cannot - * be read atomically. */ - do { - hi1 = ni_stc_readw(dev, G_Save_Register_High(chan)); - lo = ni_stc_readw(dev, G_Save_Register_Low(chan)); - hi2 = ni_stc_readw(dev, G_Save_Register_High(chan)); - } while (hi1 != hi2); - - return (hi1 << 16) | lo; -} - -static void GPCT_Reset(struct comedi_device *dev, int chan) -{ - int temp_ack_reg = 0; - - devpriv->gpct_cur_operation[chan] = GPCT_RESET; - - switch (chan) { - case 0: - ni_stc_writew(dev, G0_Reset, Joint_Reset_Register); - ni_set_bits(dev, Interrupt_A_Enable_Register, - G0_TC_Interrupt_Enable, 0); - ni_set_bits(dev, Interrupt_A_Enable_Register, - G0_Gate_Interrupt_Enable, 0); - temp_ack_reg |= G0_Gate_Error_Confirm; - temp_ack_reg |= G0_TC_Error_Confirm; - temp_ack_reg |= G0_TC_Interrupt_Ack; - temp_ack_reg |= G0_Gate_Interrupt_Ack; - ni_stc_writew(dev, temp_ack_reg, Interrupt_A_Ack_Register); - - /* problem...this interferes with the other ctr... */ - devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable; - ni_stc_writew(dev, devpriv->an_trig_etc_reg, - Analog_Trigger_Etc_Register); - break; - case 1: - ni_stc_writew(dev, G1_Reset, Joint_Reset_Register); - ni_set_bits(dev, Interrupt_B_Enable_Register, - G1_TC_Interrupt_Enable, 0); - ni_set_bits(dev, Interrupt_B_Enable_Register, - G0_Gate_Interrupt_Enable, 0); - temp_ack_reg |= G1_Gate_Error_Confirm; - temp_ack_reg |= G1_TC_Error_Confirm; - temp_ack_reg |= G1_TC_Interrupt_Ack; - temp_ack_reg |= G1_Gate_Interrupt_Ack; - ni_stc_writew(dev, temp_ack_reg, Interrupt_B_Ack_Register); - - devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable; - ni_stc_writew(dev, devpriv->an_trig_etc_reg, - Analog_Trigger_Etc_Register); - break; - } - - devpriv->gpct_mode[chan] = 0; - devpriv->gpct_input_select[chan] = 0; - devpriv->gpct_command[chan] = 0; - - devpriv->gpct_command[chan] |= G_Synchronized_Gate; - - ni_stc_writew(dev, devpriv->gpct_mode[chan], G_Mode_Register(chan)); - ni_stc_writew(dev, devpriv->gpct_input_select[chan], - G_Input_Select_Register(chan)); - ni_stc_writew(dev, 0, G_Autoincrement_Register(chan)); -} -#endif - static irqreturn_t ni_E_interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -5304,8 +5009,8 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&dev->spinlock, flags); - a_status = ni_stc_readw(dev, AI_Status_1_Register); - b_status = ni_stc_readw(dev, AO_Status_1_Register); + a_status = ni_stc_readw(dev, NISTC_AI_STATUS1_REG); + b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG); #ifdef PCIDMA if (mite) { struct ni_private *devpriv = dev->private; @@ -5333,9 +5038,9 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) #endif ack_a_interrupt(dev, a_status); ack_b_interrupt(dev, b_status); - if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT)) + if ((a_status & NISTC_AI_STATUS1_INTA) || (ai_mite_status & CHSR_INT)) handle_a_interrupt(dev, a_status, ai_mite_status); - if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT)) + if ((b_status & NISTC_AO_STATUS1_INTB) || (ao_mite_status & CHSR_INT)) handle_b_interrupt(dev, b_status, ao_mite_status); handle_gpct_interrupt(dev, 0); handle_gpct_interrupt(dev, 1); @@ -5375,16 +5080,16 @@ static int ni_E_init(struct comedi_device *dev, } /* initialize clock dividers */ - devpriv->clock_and_fout = Slow_Internal_Time_Divide_By_2 | - Slow_Internal_Timebase | - Clock_To_Board_Divide_By_2 | - Clock_To_Board; + devpriv->clock_and_fout = NISTC_CLK_FOUT_SLOW_DIV2 | + NISTC_CLK_FOUT_SLOW_TIMEBASE | + NISTC_CLK_FOUT_TO_BOARD_DIV2 | + NISTC_CLK_FOUT_TO_BOARD; if (!devpriv->is_6xxx) { /* BEAM is this needed for PCI-6143 ?? */ - devpriv->clock_and_fout |= (AI_Output_Divide_By_2 | - AO_Output_Divide_By_2); + devpriv->clock_and_fout |= (NISTC_CLK_FOUT_AI_OUT_DIV2 | + NISTC_CLK_FOUT_AO_OUT_DIV2); } - ni_stc_writew(dev, devpriv->clock_and_fout, Clock_and_FOUT_Register); + ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG); ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES); if (ret) @@ -5493,22 +5198,24 @@ static int ni_E_init(struct comedi_device *dev, } /* reset DIO and set all channels to inputs */ - ni_writel(dev, CDO_Reset_Bit | CDI_Reset_Bit, - M_Offset_CDIO_Command); - ni_writel(dev, s->io_bits, M_Offset_DIO_Direction); + ni_writel(dev, NI_M_CDO_CMD_RESET | + NI_M_CDI_CMD_RESET, + NI_M_CDIO_CMD_REG); + ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG); } else { s->insn_bits = ni_dio_insn_bits; s->insn_config = ni_dio_insn_config; /* set all channels to inputs */ - devpriv->dio_control = DIO_Pins_Dir(s->io_bits); - ni_writew(dev, devpriv->dio_control, DIO_Control_Register); + devpriv->dio_control = NISTC_DIO_CTRL_DIR(s->io_bits); + ni_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG); } /* 8255 device */ s = &dev->subdevices[NI_8255_DIO_SUBDEV]; if (board->has_8255) { - ret = subdev_8255_init(dev, s, ni_8255_callback, Port_A); + ret = subdev_8255_init(dev, s, ni_8255_callback, + NI_E_8255_BASE); if (ret) return ret; } else { @@ -5529,7 +5236,7 @@ static int ni_E_init(struct comedi_device *dev, /* internal PWM output used for AI nonlinearity calibration */ s->insn_config = ni_m_series_pwm_config; - ni_writel(dev, 0x0, M_Offset_Cal_PWM); + ni_writel(dev, 0x0, NI_M_CAL_PWM_REG); } else if (devpriv->is_6143) { /* internal PWM output used for AI nonlinearity calibration */ s->insn_config = ni_6143_pwm_config; @@ -5564,17 +5271,17 @@ static int ni_E_init(struct comedi_device *dev, s->n_chan = 16; s->insn_bits = ni_pfi_insn_bits; - ni_writew(dev, s->state, M_Offset_PFI_DO); + ni_writew(dev, s->state, NI_M_PFI_DO_REG); for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) { ni_writew(dev, devpriv->pfi_output_select_reg[i], - M_Offset_PFI_Output_Select(i + 1)); + NI_M_PFI_OUT_SEL_REG(i)); } } else { s->n_chan = 10; } s->insn_config = ni_pfi_insn_config; - ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0); + ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, ~0, 0); /* cs5529 calibration adc */ s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV]; @@ -5667,30 +5374,31 @@ static int ni_E_init(struct comedi_device *dev, if (dev->irq) { ni_stc_writew(dev, - (irq_polarity ? Interrupt_Output_Polarity : 0) | - (Interrupt_Output_On_3_Pins & 0) | - Interrupt_A_Enable | Interrupt_B_Enable | - Interrupt_A_Output_Select(interrupt_pin) | - Interrupt_B_Output_Select(interrupt_pin), - Interrupt_Control_Register); + (irq_polarity ? NISTC_INT_CTRL_INT_POL : 0) | + (NISTC_INT_CTRL_3PIN_INT & 0) | + NISTC_INT_CTRL_INTA_ENA | + NISTC_INT_CTRL_INTB_ENA | + NISTC_INT_CTRL_INTA_SEL(interrupt_pin) | + NISTC_INT_CTRL_INTB_SEL(interrupt_pin), + NISTC_INT_CTRL_REG); } /* DMA setup */ - ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select); - ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select); + ni_writeb(dev, devpriv->ai_ao_select_reg, NI_E_DMA_AI_AO_SEL_REG); + ni_writeb(dev, devpriv->g0_g1_select_reg, NI_E_DMA_G0_G1_SEL_REG); if (devpriv->is_6xxx) { - ni_writeb(dev, 0, Magic_611x); + ni_writeb(dev, 0, NI611X_MAGIC_REG); } else if (devpriv->is_m_series) { int channel; for (channel = 0; channel < board->n_aochan; ++channel) { ni_writeb(dev, 0xf, - M_Offset_AO_Waveform_Order(channel)); + NI_M_AO_WAVEFORM_ORDER_REG(channel)); ni_writeb(dev, 0x0, - M_Offset_AO_Reference_Attenuation(channel)); + NI_M_AO_REF_ATTENUATION_REG(channel)); } - ni_writeb(dev, 0x0, M_Offset_AO_Calibration); + ni_writeb(dev, 0x0, NI_M_AO_CALIB_REG); } return 0; diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 1481f71a31b1..30a5a75d1fe7 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1085,26 +1085,25 @@ static void init_6143(struct comedi_device *dev) struct ni_private *devpriv = dev->private; /* Disable interrupts */ - ni_stc_writew(dev, 0, Interrupt_Control_Register); + ni_stc_writew(dev, 0, NISTC_INT_CTRL_REG); /* Initialise 6143 AI specific bits */ /* Set G0,G1 DMA mode to E series version */ - ni_writeb(dev, 0x00, Magic_6143); + ni_writeb(dev, 0x00, NI6143_MAGIC_REG); /* Set EOCMode, ADCMode and pipelinedelay */ - ni_writeb(dev, 0x80, PipelineDelay_6143); + ni_writeb(dev, 0x80, NI6143_PIPELINE_DELAY_REG); /* Set EOC Delay */ - ni_writeb(dev, 0x00, EOC_Set_6143); + ni_writeb(dev, 0x00, NI6143_EOC_SET_REG); /* Set the FIFO half full level */ - ni_writel(dev, board->ai_fifo_depth / 2, AIFIFO_Flag_6143); + ni_writel(dev, board->ai_fifo_depth / 2, NI6143_AI_FIFO_FLAG_REG); /* Strobe Relay disable bit */ devpriv->ai_calib_source_enabled = 0; - ni_writew(dev, devpriv->ai_calib_source | - Calibration_Channel_6143_RelayOff, - Calibration_Channel_6143); - ni_writew(dev, devpriv->ai_calib_source, Calibration_Channel_6143); + ni_writew(dev, devpriv->ai_calib_source | NI6143_CALIB_CHAN_RELAY_OFF, + NI6143_CALIB_CHAN_REG); + ni_writew(dev, devpriv->ai_calib_source, NI6143_CALIB_CHAN_REG); } static void pcimio_detach(struct comedi_device *dev) diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index bd69c3f0acdc..1d5af25b92a8 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -26,884 +26,907 @@ #include "ni_tio.h" -#define _bit15 0x8000 -#define _bit14 0x4000 -#define _bit13 0x2000 -#define _bit12 0x1000 -#define _bit11 0x0800 -#define _bit10 0x0400 -#define _bit9 0x0200 -#define _bit8 0x0100 -#define _bit7 0x0080 -#define _bit6 0x0040 -#define _bit5 0x0020 -#define _bit4 0x0010 -#define _bit3 0x0008 -#define _bit2 0x0004 -#define _bit1 0x0002 -#define _bit0 0x0001 - -#define NUM_PFI_OUTPUT_SELECT_REGS 6 - -/* Registers in the National Instruments DAQ-STC chip */ - -#define Interrupt_A_Ack_Register 2 -#define G0_Gate_Interrupt_Ack _bit15 -#define G0_TC_Interrupt_Ack _bit14 -#define AI_Error_Interrupt_Ack _bit13 -#define AI_STOP_Interrupt_Ack _bit12 -#define AI_START_Interrupt_Ack _bit11 -#define AI_START2_Interrupt_Ack _bit10 -#define AI_START1_Interrupt_Ack _bit9 -#define AI_SC_TC_Interrupt_Ack _bit8 -#define AI_SC_TC_Error_Confirm _bit7 -#define G0_TC_Error_Confirm _bit6 -#define G0_Gate_Error_Confirm _bit5 - -#define AI_Status_1_Register 2 -#define Interrupt_A_St 0x8000 -#define AI_FIFO_Full_St 0x4000 -#define AI_FIFO_Half_Full_St 0x2000 -#define AI_FIFO_Empty_St 0x1000 -#define AI_Overrun_St 0x0800 -#define AI_Overflow_St 0x0400 -#define AI_SC_TC_Error_St 0x0200 -#define AI_START2_St 0x0100 -#define AI_START1_St 0x0080 -#define AI_SC_TC_St 0x0040 -#define AI_START_St 0x0020 -#define AI_STOP_St 0x0010 -#define G0_TC_St 0x0008 -#define G0_Gate_Interrupt_St 0x0004 -#define AI_FIFO_Request_St 0x0002 -#define Pass_Thru_0_Interrupt_St 0x0001 - -#define AI_Status_2_Register 5 - -#define Interrupt_B_Ack_Register 3 -enum Interrupt_B_Ack_Bits { - G1_Gate_Error_Confirm = _bit1, - G1_TC_Error_Confirm = _bit2, - AO_BC_TC_Trigger_Error_Confirm = _bit3, - AO_BC_TC_Error_Confirm = _bit4, - AO_UI2_TC_Error_Confrim = _bit5, - AO_UI2_TC_Interrupt_Ack = _bit6, - AO_UC_TC_Interrupt_Ack = _bit7, - AO_BC_TC_Interrupt_Ack = _bit8, - AO_START1_Interrupt_Ack = _bit9, - AO_UPDATE_Interrupt_Ack = _bit10, - AO_START_Interrupt_Ack = _bit11, - AO_STOP_Interrupt_Ack = _bit12, - AO_Error_Interrupt_Ack = _bit13, - G1_TC_Interrupt_Ack = _bit14, - G1_Gate_Interrupt_Ack = _bit15 -}; - -#define AO_Status_1_Register 3 -#define Interrupt_B_St _bit15 -#define AO_FIFO_Full_St _bit14 -#define AO_FIFO_Half_Full_St _bit13 -#define AO_FIFO_Empty_St _bit12 -#define AO_BC_TC_Error_St _bit11 -#define AO_START_St _bit10 -#define AO_Overrun_St _bit9 -#define AO_START1_St _bit8 -#define AO_BC_TC_St _bit7 -#define AO_UC_TC_St _bit6 -#define AO_UPDATE_St _bit5 -#define AO_UI2_TC_St _bit4 -#define G1_TC_St _bit3 -#define G1_Gate_Interrupt_St _bit2 -#define AO_FIFO_Request_St _bit1 -#define Pass_Thru_1_Interrupt_St _bit0 - -#define AI_Command_2_Register 4 -#define AI_End_On_SC_TC _bit15 -#define AI_End_On_End_Of_Scan _bit14 -#define AI_START1_Disable _bit11 -#define AI_SC_Save_Trace _bit10 -#define AI_SI_Switch_Load_On_SC_TC _bit9 -#define AI_SI_Switch_Load_On_STOP _bit8 -#define AI_SI_Switch_Load_On_TC _bit7 -#define AI_SC_Switch_Load_On_TC _bit4 -#define AI_STOP_Pulse _bit3 -#define AI_START_Pulse _bit2 -#define AI_START2_Pulse _bit1 -#define AI_START1_Pulse _bit0 - -#define AO_Command_2_Register 5 -#define AO_End_On_BC_TC(x) (((x) & 0x3) << 14) -#define AO_Start_Stop_Gate_Enable _bit13 -#define AO_UC_Save_Trace _bit12 -#define AO_BC_Gate_Enable _bit11 -#define AO_BC_Save_Trace _bit10 -#define AO_UI_Switch_Load_On_BC_TC _bit9 -#define AO_UI_Switch_Load_On_Stop _bit8 -#define AO_UI_Switch_Load_On_TC _bit7 -#define AO_UC_Switch_Load_On_BC_TC _bit6 -#define AO_UC_Switch_Load_On_TC _bit5 -#define AO_BC_Switch_Load_On_TC _bit4 -#define AO_Mute_B _bit3 -#define AO_Mute_A _bit2 -#define AO_UPDATE2_Pulse _bit1 -#define AO_START1_Pulse _bit0 - -#define AO_Status_2_Register 6 - -#define DIO_Parallel_Input_Register 7 - -#define AI_Command_1_Register 8 -#define AI_Analog_Trigger_Reset _bit14 -#define AI_Disarm _bit13 -#define AI_SI2_Arm _bit12 -#define AI_SI2_Load _bit11 -#define AI_SI_Arm _bit10 -#define AI_SI_Load _bit9 -#define AI_DIV_Arm _bit8 -#define AI_DIV_Load _bit7 -#define AI_SC_Arm _bit6 -#define AI_SC_Load _bit5 -#define AI_SCAN_IN_PROG_Pulse _bit4 -#define AI_EXTMUX_CLK_Pulse _bit3 -#define AI_LOCALMUX_CLK_Pulse _bit2 -#define AI_SC_TC_Pulse _bit1 -#define AI_CONVERT_Pulse _bit0 - -#define AO_Command_1_Register 9 -#define AO_Analog_Trigger_Reset _bit15 -#define AO_START_Pulse _bit14 -#define AO_Disarm _bit13 -#define AO_UI2_Arm_Disarm _bit12 -#define AO_UI2_Load _bit11 -#define AO_UI_Arm _bit10 -#define AO_UI_Load _bit9 -#define AO_UC_Arm _bit8 -#define AO_UC_Load _bit7 -#define AO_BC_Arm _bit6 -#define AO_BC_Load _bit5 -#define AO_DAC1_Update_Mode _bit4 -#define AO_LDAC1_Source_Select _bit3 -#define AO_DAC0_Update_Mode _bit2 -#define AO_LDAC0_Source_Select _bit1 -#define AO_UPDATE_Pulse _bit0 - -#define DIO_Output_Register 10 -#define DIO_Parallel_Data_Out(a) ((a)&0xff) -#define DIO_Parallel_Data_Mask 0xff -#define DIO_SDOUT _bit0 -#define DIO_SDIN _bit4 -#define DIO_Serial_Data_Out(a) (((a)&0xff)<<8) -#define DIO_Serial_Data_Mask 0xff00 - -#define DIO_Control_Register 11 -#define DIO_Software_Serial_Control _bit11 -#define DIO_HW_Serial_Timebase _bit10 -#define DIO_HW_Serial_Enable _bit9 -#define DIO_HW_Serial_Start _bit8 -#define DIO_Pins_Dir(a) ((a)&0xff) -#define DIO_Pins_Dir_Mask 0xff - -#define AI_Mode_1_Register 12 -#define AI_CONVERT_Source_Select(a) (((a) & 0x1f) << 11) -#define AI_SI_Source_select(a) (((a) & 0x1f) << 6) -#define AI_CONVERT_Source_Polarity _bit5 -#define AI_SI_Source_Polarity _bit4 -#define AI_Start_Stop _bit3 -#define AI_Mode_1_Reserved _bit2 -#define AI_Continuous _bit1 -#define AI_Trigger_Once _bit0 - -#define AI_Mode_2_Register 13 -#define AI_SC_Gate_Enable _bit15 -#define AI_Start_Stop_Gate_Enable _bit14 -#define AI_Pre_Trigger _bit13 -#define AI_External_MUX_Present _bit12 -#define AI_SI2_Initial_Load_Source _bit9 -#define AI_SI2_Reload_Mode _bit8 -#define AI_SI_Initial_Load_Source _bit7 -#define AI_SI_Reload_Mode(a) (((a) & 0x7)<<4) -#define AI_SI_Write_Switch _bit3 -#define AI_SC_Initial_Load_Source _bit2 -#define AI_SC_Reload_Mode _bit1 -#define AI_SC_Write_Switch _bit0 - -#define AI_SI_Load_A_Registers 14 -#define AI_SI_Load_B_Registers 16 -#define AI_SC_Load_A_Registers 18 -#define AI_SC_Load_B_Registers 20 -#define AI_SI_Save_Registers 64 -#define AI_SC_Save_Registers 66 - -#define AI_SI2_Load_A_Register 23 -#define AI_SI2_Load_B_Register 25 - -#define Joint_Status_1_Register 27 -#define DIO_Serial_IO_In_Progress_St _bit12 - -#define DIO_Serial_Input_Register 28 -#define Joint_Status_2_Register 29 -enum Joint_Status_2_Bits { - AO_TMRDACWRs_In_Progress_St = 0x20, -}; - -#define AO_Mode_1_Register 38 -#define AO_UPDATE_Source_Select(x) (((x)&0x1f)<<11) -#define AO_UI_Source_Select(x) (((x)&0x1f)<<6) -#define AO_Multiple_Channels _bit5 -#define AO_UPDATE_Source_Polarity _bit4 -#define AO_UI_Source_Polarity _bit3 -#define AO_UC_Switch_Load_Every_TC _bit2 -#define AO_Continuous _bit1 -#define AO_Trigger_Once _bit0 - -#define AO_Mode_2_Register 39 -#define AO_FIFO_Mode_Mask (0x3 << 14) -enum AO_FIFO_Mode_Bits { - AO_FIFO_Mode_HF_to_F = (3 << 14), - AO_FIFO_Mode_F = (2 << 14), - AO_FIFO_Mode_HF = (1 << 14), - AO_FIFO_Mode_E = (0 << 14), -}; -#define AO_FIFO_Retransmit_Enable _bit13 -#define AO_START1_Disable _bit12 -#define AO_UC_Initial_Load_Source _bit11 -#define AO_UC_Write_Switch _bit10 -#define AO_UI2_Initial_Load_Source _bit9 -#define AO_UI2_Reload_Mode _bit8 -#define AO_UI_Initial_Load_Source _bit7 -#define AO_UI_Reload_Mode(x) (((x) & 0x7) << 4) -#define AO_UI_Write_Switch _bit3 -#define AO_BC_Initial_Load_Source _bit2 -#define AO_BC_Reload_Mode _bit1 -#define AO_BC_Write_Switch _bit0 - -#define AO_UI_Load_A_Register 40 -#define AO_UI_Load_A_Register_High 40 -#define AO_UI_Load_A_Register_Low 41 -#define AO_UI_Load_B_Register 42 -#define AO_UI_Save_Registers 16 -#define AO_BC_Load_A_Register 44 -#define AO_BC_Load_A_Register_High 44 -#define AO_BC_Load_A_Register_Low 45 -#define AO_BC_Load_B_Register 46 -#define AO_BC_Load_B_Register_High 46 -#define AO_BC_Load_B_Register_Low 47 -#define AO_BC_Save_Registers 18 -#define AO_UC_Load_A_Register 48 -#define AO_UC_Load_A_Register_High 48 -#define AO_UC_Load_A_Register_Low 49 -#define AO_UC_Load_B_Register 50 -#define AO_UC_Save_Registers 20 - -#define Clock_and_FOUT_Register 56 -enum Clock_and_FOUT_bits { - FOUT_Enable = _bit15, - FOUT_Timebase_Select = _bit14, - DIO_Serial_Out_Divide_By_2 = _bit13, - Slow_Internal_Time_Divide_By_2 = _bit12, - Slow_Internal_Timebase = _bit11, - G_Source_Divide_By_2 = _bit10, - Clock_To_Board_Divide_By_2 = _bit9, - Clock_To_Board = _bit8, - AI_Output_Divide_By_2 = _bit7, - AI_Source_Divide_By_2 = _bit6, - AO_Output_Divide_By_2 = _bit5, - AO_Source_Divide_By_2 = _bit4, - FOUT_Divider_mask = 0xf -}; -static inline unsigned FOUT_Divider(unsigned divider) -{ - return divider & FOUT_Divider_mask; -} - -#define IO_Bidirection_Pin_Register 57 -#define RTSI_Trig_Direction_Register 58 -enum RTSI_Trig_Direction_Bits { - Drive_RTSI_Clock_Bit = 0x1, - Use_RTSI_Clock_Bit = 0x2, -}; -static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries) -{ - unsigned max_channel; - unsigned base_bit_shift; - if (is_mseries) { - base_bit_shift = 8; - max_channel = 7; - } else { - base_bit_shift = 9; - max_channel = 6; - } - if (channel > max_channel) { - pr_err("%s: bug, invalid RTSI_channel=%i\n", __func__, channel); - return 0; - } - return 1 << (base_bit_shift + channel); -} - -#define Interrupt_Control_Register 59 -#define Interrupt_B_Enable _bit15 -#define Interrupt_B_Output_Select(x) ((x)<<12) -#define Interrupt_A_Enable _bit11 -#define Interrupt_A_Output_Select(x) ((x)<<8) -#define Pass_Thru_0_Interrupt_Polarity _bit3 -#define Pass_Thru_1_Interrupt_Polarity _bit2 -#define Interrupt_Output_On_3_Pins _bit1 -#define Interrupt_Output_Polarity _bit0 - -#define AI_Output_Control_Register 60 -#define AI_START_Output_Select _bit10 -#define AI_SCAN_IN_PROG_Output_Select(x) (((x) & 0x3) << 8) -#define AI_EXTMUX_CLK_Output_Select(x) (((x) & 0x3) << 6) -#define AI_LOCALMUX_CLK_Output_Select(x) ((x)<<4) -#define AI_SC_TC_Output_Select(x) ((x)<<2) -enum ai_convert_output_selection { - AI_CONVERT_Output_High_Z = 0, - AI_CONVERT_Output_Ground = 1, - AI_CONVERT_Output_Enable_Low = 2, - AI_CONVERT_Output_Enable_High = 3 -}; -static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection - selection) -{ - return selection & 0x3; -} - -#define AI_START_STOP_Select_Register 62 -#define AI_START_Polarity _bit15 -#define AI_STOP_Polarity _bit14 -#define AI_STOP_Sync _bit13 -#define AI_STOP_Edge _bit12 -#define AI_STOP_Select(a) (((a) & 0x1f)<<7) -#define AI_START_Sync _bit6 -#define AI_START_Edge _bit5 -#define AI_START_Select(a) ((a) & 0x1f) - -#define AI_Trigger_Select_Register 63 -#define AI_START1_Polarity _bit15 -#define AI_START2_Polarity _bit14 -#define AI_START2_Sync _bit13 -#define AI_START2_Edge _bit12 -#define AI_START2_Select(a) (((a) & 0x1f) << 7) -#define AI_START1_Sync _bit6 -#define AI_START1_Edge _bit5 -#define AI_START1_Select(a) ((a) & 0x1f) - -#define AI_DIV_Load_A_Register 64 - -#define AO_Start_Select_Register 66 -#define AO_UI2_Software_Gate _bit15 -#define AO_UI2_External_Gate_Polarity _bit14 -#define AO_START_Polarity _bit13 -#define AO_AOFREQ_Enable _bit12 -#define AO_UI2_External_Gate_Select(a) (((a) & 0x1f) << 7) -#define AO_START_Sync _bit6 -#define AO_START_Edge _bit5 -#define AO_START_Select(a) ((a) & 0x1f) - -#define AO_Trigger_Select_Register 67 -#define AO_UI2_External_Gate_Enable _bit15 -#define AO_Delayed_START1 _bit14 -#define AO_START1_Polarity _bit13 -#define AO_UI2_Source_Polarity _bit12 -#define AO_UI2_Source_Select(x) (((x)&0x1f)<<7) -#define AO_START1_Sync _bit6 -#define AO_START1_Edge _bit5 -#define AO_START1_Select(x) (((x)&0x1f)<<0) - -#define AO_Mode_3_Register 70 -#define AO_UI2_Switch_Load_Next_TC _bit13 -#define AO_UC_Switch_Load_Every_BC_TC _bit12 -#define AO_Trigger_Length _bit11 -#define AO_Stop_On_Overrun_Error _bit5 -#define AO_Stop_On_BC_TC_Trigger_Error _bit4 -#define AO_Stop_On_BC_TC_Error _bit3 -#define AO_Not_An_UPDATE _bit2 -#define AO_Software_Gate _bit1 -#define AO_Last_Gate_Disable _bit0 /* M Series only */ - -#define Joint_Reset_Register 72 -#define Software_Reset _bit11 -#define AO_Configuration_End _bit9 -#define AI_Configuration_End _bit8 -#define AO_Configuration_Start _bit5 -#define AI_Configuration_Start _bit4 -#define G1_Reset _bit3 -#define G0_Reset _bit2 -#define AO_Reset _bit1 -#define AI_Reset _bit0 - -#define Interrupt_A_Enable_Register 73 -#define Pass_Thru_0_Interrupt_Enable _bit9 -#define G0_Gate_Interrupt_Enable _bit8 -#define AI_FIFO_Interrupt_Enable _bit7 -#define G0_TC_Interrupt_Enable _bit6 -#define AI_Error_Interrupt_Enable _bit5 -#define AI_STOP_Interrupt_Enable _bit4 -#define AI_START_Interrupt_Enable _bit3 -#define AI_START2_Interrupt_Enable _bit2 -#define AI_START1_Interrupt_Enable _bit1 -#define AI_SC_TC_Interrupt_Enable _bit0 - -#define Interrupt_B_Enable_Register 75 -#define Pass_Thru_1_Interrupt_Enable _bit11 -#define G1_Gate_Interrupt_Enable _bit10 -#define G1_TC_Interrupt_Enable _bit9 -#define AO_FIFO_Interrupt_Enable _bit8 -#define AO_UI2_TC_Interrupt_Enable _bit7 -#define AO_UC_TC_Interrupt_Enable _bit6 -#define AO_Error_Interrupt_Enable _bit5 -#define AO_STOP_Interrupt_Enable _bit4 -#define AO_START_Interrupt_Enable _bit3 -#define AO_UPDATE_Interrupt_Enable _bit2 -#define AO_START1_Interrupt_Enable _bit1 -#define AO_BC_TC_Interrupt_Enable _bit0 - -#define Second_IRQ_A_Enable_Register 74 -enum Second_IRQ_A_Enable_Bits { - AI_SC_TC_Second_Irq_Enable = _bit0, - AI_START1_Second_Irq_Enable = _bit1, - AI_START2_Second_Irq_Enable = _bit2, - AI_START_Second_Irq_Enable = _bit3, - AI_STOP_Second_Irq_Enable = _bit4, - AI_Error_Second_Irq_Enable = _bit5, - G0_TC_Second_Irq_Enable = _bit6, - AI_FIFO_Second_Irq_Enable = _bit7, - G0_Gate_Second_Irq_Enable = _bit8, - Pass_Thru_0_Second_Irq_Enable = _bit9 -}; +/* + * Registers in the National Instruments DAQ-STC chip + */ + +#define NISTC_INTA_ACK_REG 2 +#define NISTC_INTA_ACK_G0_GATE BIT(15) +#define NISTC_INTA_ACK_G0_TC BIT(14) +#define NISTC_INTA_ACK_AI_ERR BIT(13) +#define NISTC_INTA_ACK_AI_STOP BIT(12) +#define NISTC_INTA_ACK_AI_START BIT(11) +#define NISTC_INTA_ACK_AI_START2 BIT(10) +#define NISTC_INTA_ACK_AI_START1 BIT(9) +#define NISTC_INTA_ACK_AI_SC_TC BIT(8) +#define NISTC_INTA_ACK_AI_SC_TC_ERR BIT(7) +#define NISTC_INTA_ACK_G0_TC_ERR BIT(6) +#define NISTC_INTA_ACK_G0_GATE_ERR BIT(5) +#define NISTC_INTA_ACK_AI_ALL (NISTC_INTA_ACK_AI_ERR | \ + NISTC_INTA_ACK_AI_STOP | \ + NISTC_INTA_ACK_AI_START | \ + NISTC_INTA_ACK_AI_START2 | \ + NISTC_INTA_ACK_AI_START1 | \ + NISTC_INTA_ACK_AI_SC_TC | \ + NISTC_INTA_ACK_AI_SC_TC_ERR) + +#define NISTC_INTB_ACK_REG 3 +#define NISTC_INTB_ACK_G1_GATE BIT(15) +#define NISTC_INTB_ACK_G1_TC BIT(14) +#define NISTC_INTB_ACK_AO_ERR BIT(13) +#define NISTC_INTB_ACK_AO_STOP BIT(12) +#define NISTC_INTB_ACK_AO_START BIT(11) +#define NISTC_INTB_ACK_AO_UPDATE BIT(10) +#define NISTC_INTB_ACK_AO_START1 BIT(9) +#define NISTC_INTB_ACK_AO_BC_TC BIT(8) +#define NISTC_INTB_ACK_AO_UC_TC BIT(7) +#define NISTC_INTB_ACK_AO_UI2_TC BIT(6) +#define NISTC_INTB_ACK_AO_UI2_TC_ERR BIT(5) +#define NISTC_INTB_ACK_AO_BC_TC_ERR BIT(4) +#define NISTC_INTB_ACK_AO_BC_TC_TRIG_ERR BIT(3) +#define NISTC_INTB_ACK_G1_TC_ERR BIT(2) +#define NISTC_INTB_ACK_G1_GATE_ERR BIT(1) +#define NISTC_INTB_ACK_AO_ALL (NISTC_INTB_ACK_AO_ERR | \ + NISTC_INTB_ACK_AO_STOP | \ + NISTC_INTB_ACK_AO_START | \ + NISTC_INTB_ACK_AO_UPDATE | \ + NISTC_INTB_ACK_AO_START1 | \ + NISTC_INTB_ACK_AO_BC_TC | \ + NISTC_INTB_ACK_AO_UC_TC | \ + NISTC_INTB_ACK_AO_BC_TC_ERR | \ + NISTC_INTB_ACK_AO_BC_TC_TRIG_ERR) + +#define NISTC_AI_CMD2_REG 4 +#define NISTC_AI_CMD2_END_ON_SC_TC BIT(15) +#define NISTC_AI_CMD2_END_ON_EOS BIT(14) +#define NISTC_AI_CMD2_START1_DISABLE BIT(11) +#define NISTC_AI_CMD2_SC_SAVE_TRACE BIT(10) +#define NISTC_AI_CMD2_SI_SW_ON_SC_TC BIT(9) +#define NISTC_AI_CMD2_SI_SW_ON_STOP BIT(8) +#define NISTC_AI_CMD2_SI_SW_ON_TC BIT(7) +#define NISTC_AI_CMD2_SC_SW_ON_TC BIT(4) +#define NISTC_AI_CMD2_STOP_PULSE BIT(3) +#define NISTC_AI_CMD2_START_PULSE BIT(2) +#define NISTC_AI_CMD2_START2_PULSE BIT(1) +#define NISTC_AI_CMD2_START1_PULSE BIT(0) + +#define NISTC_AO_CMD2_REG 5 +#define NISTC_AO_CMD2_END_ON_BC_TC(x) (((x) & 0x3) << 14) +#define NISTC_AO_CMD2_START_STOP_GATE_ENA BIT(13) +#define NISTC_AO_CMD2_UC_SAVE_TRACE BIT(12) +#define NISTC_AO_CMD2_BC_GATE_ENA BIT(11) +#define NISTC_AO_CMD2_BC_SAVE_TRACE BIT(10) +#define NISTC_AO_CMD2_UI_SW_ON_BC_TC BIT(9) +#define NISTC_AO_CMD2_UI_SW_ON_STOP BIT(8) +#define NISTC_AO_CMD2_UI_SW_ON_TC BIT(7) +#define NISTC_AO_CMD2_UC_SW_ON_BC_TC BIT(6) +#define NISTC_AO_CMD2_UC_SW_ON_TC BIT(5) +#define NISTC_AO_CMD2_BC_SW_ON_TC BIT(4) +#define NISTC_AO_CMD2_MUTE_B BIT(3) +#define NISTC_AO_CMD2_MUTE_A BIT(2) +#define NISTC_AO_CMD2_UPDATE2_PULSE BIT(1) +#define NISTC_AO_CMD2_START1_PULSE BIT(0) + +#define NISTC_G0_CMD_REG 6 +#define NISTC_G1_CMD_REG 7 + +#define NISTC_AI_CMD1_REG 8 +#define NISTC_AI_CMD1_ATRIG_RESET BIT(14) +#define NISTC_AI_CMD1_DISARM BIT(13) +#define NISTC_AI_CMD1_SI2_ARM BIT(12) +#define NISTC_AI_CMD1_SI2_LOAD BIT(11) +#define NISTC_AI_CMD1_SI_ARM BIT(10) +#define NISTC_AI_CMD1_SI_LOAD BIT(9) +#define NISTC_AI_CMD1_DIV_ARM BIT(8) +#define NISTC_AI_CMD1_DIV_LOAD BIT(7) +#define NISTC_AI_CMD1_SC_ARM BIT(6) +#define NISTC_AI_CMD1_SC_LOAD BIT(5) +#define NISTC_AI_CMD1_SCAN_IN_PROG_PULSE BIT(4) +#define NISTC_AI_CMD1_EXTMUX_CLK_PULSE BIT(3) +#define NISTC_AI_CMD1_LOCALMUX_CLK_PULSE BIT(2) +#define NISTC_AI_CMD1_SC_TC_PULSE BIT(1) +#define NISTC_AI_CMD1_CONVERT_PULSE BIT(0) + +#define NISTC_AO_CMD1_REG 9 +#define NISTC_AO_CMD1_ATRIG_RESET BIT(15) +#define NISTC_AO_CMD1_START_PULSE BIT(14) +#define NISTC_AO_CMD1_DISARM BIT(13) +#define NISTC_AO_CMD1_UI2_ARM_DISARM BIT(12) +#define NISTC_AO_CMD1_UI2_LOAD BIT(11) +#define NISTC_AO_CMD1_UI_ARM BIT(10) +#define NISTC_AO_CMD1_UI_LOAD BIT(9) +#define NISTC_AO_CMD1_UC_ARM BIT(8) +#define NISTC_AO_CMD1_UC_LOAD BIT(7) +#define NISTC_AO_CMD1_BC_ARM BIT(6) +#define NISTC_AO_CMD1_BC_LOAD BIT(5) +#define NISTC_AO_CMD1_DAC1_UPDATE_MODE BIT(4) +#define NISTC_AO_CMD1_LDAC1_SRC_SEL BIT(3) +#define NISTC_AO_CMD1_DAC0_UPDATE_MODE BIT(2) +#define NISTC_AO_CMD1_LDAC0_SRC_SEL BIT(1) +#define NISTC_AO_CMD1_UPDATE_PULSE BIT(0) + +#define NISTC_DIO_OUT_REG 10 +#define NISTC_DIO_OUT_SERIAL(x) (((x) & 0xff) << 8) +#define NISTC_DIO_OUT_SERIAL_MASK NISTC_DIO_OUT_SERIAL(0xff) +#define NISTC_DIO_OUT_PARALLEL(x) ((x) & 0xff) +#define NISTC_DIO_OUT_PARALLEL_MASK NISTC_DIO_OUT_PARALLEL(0xff) +#define NISTC_DIO_SDIN BIT(4) +#define NISTC_DIO_SDOUT BIT(0) + +#define NISTC_DIO_CTRL_REG 11 +#define NISTC_DIO_SDCLK BIT(11) +#define NISTC_DIO_CTRL_HW_SER_TIMEBASE BIT(10) +#define NISTC_DIO_CTRL_HW_SER_ENA BIT(9) +#define NISTC_DIO_CTRL_HW_SER_START BIT(8) +#define NISTC_DIO_CTRL_DIR(x) ((x) & 0xff) +#define NISTC_DIO_CTRL_DIR_MASK NISTC_DIO_CTRL_DIR(0xff) + +#define NISTC_AI_MODE1_REG 12 +#define NISTC_AI_MODE1_CONVERT_SRC(x) (((x) & 0x1f) << 11) +#define NISTC_AI_MODE1_SI_SRC(x) (((x) & 0x1f) << 6) +#define NISTC_AI_MODE1_CONVERT_POLARITY BIT(5) +#define NISTC_AI_MODE1_SI_POLARITY BIT(4) +#define NISTC_AI_MODE1_START_STOP BIT(3) +#define NISTC_AI_MODE1_RSVD BIT(2) +#define NISTC_AI_MODE1_CONTINUOUS BIT(1) +#define NISTC_AI_MODE1_TRIGGER_ONCE BIT(0) + +#define NISTC_AI_MODE2_REG 13 +#define NISTC_AI_MODE2_SC_GATE_ENA BIT(15) +#define NISTC_AI_MODE2_START_STOP_GATE_ENA BIT(14) +#define NISTC_AI_MODE2_PRE_TRIGGER BIT(13) +#define NISTC_AI_MODE2_EXTMUX_PRESENT BIT(12) +#define NISTC_AI_MODE2_SI2_INIT_LOAD_SRC BIT(9) +#define NISTC_AI_MODE2_SI2_RELOAD_MODE BIT(8) +#define NISTC_AI_MODE2_SI_INIT_LOAD_SRC BIT(7) +#define NISTC_AI_MODE2_SI_RELOAD_MODE(x) (((x) & 0x7) << 4) +#define NISTC_AI_MODE2_SI_WR_SWITCH BIT(3) +#define NISTC_AI_MODE2_SC_INIT_LOAD_SRC BIT(2) +#define NISTC_AI_MODE2_SC_RELOAD_MODE BIT(1) +#define NISTC_AI_MODE2_SC_WR_SWITCH BIT(0) + +#define NISTC_AI_SI_LOADA_REG 14 +#define NISTC_AI_SI_LOADB_REG 16 +#define NISTC_AI_SC_LOADA_REG 18 +#define NISTC_AI_SC_LOADB_REG 20 +#define NISTC_AI_SI2_LOADA_REG 23 +#define NISTC_AI_SI2_LOADB_REG 25 + +#define NISTC_G0_MODE_REG 26 +#define NISTC_G1_MODE_REG 27 +#define NISTC_G0_LOADA_REG 28 +#define NISTC_G0_LOADB_REG 30 +#define NISTC_G1_LOADA_REG 32 +#define NISTC_G1_LOADB_REG 34 +#define NISTC_G0_INPUT_SEL_REG 36 +#define NISTC_G1_INPUT_SEL_REG 37 + +#define NISTC_AO_MODE1_REG 38 +#define NISTC_AO_MODE1_UPDATE_SRC(x) (((x) & 0x1f) << 11) +#define NISTC_AO_MODE1_UPDATE_SRC_MASK NISTC_AO_MODE1_UPDATE_SRC(0x1f) +#define NISTC_AO_MODE1_UI_SRC(x) (((x) & 0x1f) << 6) +#define NISTC_AO_MODE1_UI_SRC_MASK NISTC_AO_MODE1_UI_SRC(0x1f) +#define NISTC_AO_MODE1_MULTI_CHAN BIT(5) +#define NISTC_AO_MODE1_UPDATE_SRC_POLARITY BIT(4) +#define NISTC_AO_MODE1_UI_SRC_POLARITY BIT(3) +#define NISTC_AO_MODE1_UC_SW_EVERY_TC BIT(2) +#define NISTC_AO_MODE1_CONTINUOUS BIT(1) +#define NISTC_AO_MODE1_TRIGGER_ONCE BIT(0) + +#define NISTC_AO_MODE2_REG 39 +#define NISTC_AO_MODE2_FIFO_MODE(x) (((x) & 0x3) << 14) +#define NISTC_AO_MODE2_FIFO_MODE_MASK NISTC_AO_MODE2_FIFO_MODE(3) +#define NISTC_AO_MODE2_FIFO_MODE_E NISTC_AO_MODE2_FIFO_MODE(0) +#define NISTC_AO_MODE2_FIFO_MODE_HF NISTC_AO_MODE2_FIFO_MODE(1) +#define NISTC_AO_MODE2_FIFO_MODE_F NISTC_AO_MODE2_FIFO_MODE(2) +#define NISTC_AO_MODE2_FIFO_MODE_HF_F NISTC_AO_MODE2_FIFO_MODE(3) +#define NISTC_AO_MODE2_FIFO_REXMIT_ENA BIT(13) +#define NISTC_AO_MODE2_START1_DISABLE BIT(12) +#define NISTC_AO_MODE2_UC_INIT_LOAD_SRC BIT(11) +#define NISTC_AO_MODE2_UC_WR_SWITCH BIT(10) +#define NISTC_AO_MODE2_UI2_INIT_LOAD_SRC BIT(9) +#define NISTC_AO_MODE2_UI2_RELOAD_MODE BIT(8) +#define NISTC_AO_MODE2_UI_INIT_LOAD_SRC BIT(7) +#define NISTC_AO_MODE2_UI_RELOAD_MODE(x) (((x) & 0x7) << 4) +#define NISTC_AO_MODE2_UI_WR_SWITCH BIT(3) +#define NISTC_AO_MODE2_BC_INIT_LOAD_SRC BIT(2) +#define NISTC_AO_MODE2_BC_RELOAD_MODE BIT(1) +#define NISTC_AO_MODE2_BC_WR_SWITCH BIT(0) + +#define NISTC_AO_UI_LOADA_REG 40 +#define NISTC_AO_UI_LOADB_REG 42 +#define NISTC_AO_BC_LOADA_REG 44 +#define NISTC_AO_BC_LOADB_REG 46 +#define NISTC_AO_UC_LOADA_REG 48 +#define NISTC_AO_UC_LOADB_REG 50 + +#define NISTC_CLK_FOUT_REG 56 +#define NISTC_CLK_FOUT_ENA BIT(15) +#define NISTC_CLK_FOUT_TIMEBASE_SEL BIT(14) +#define NISTC_CLK_FOUT_DIO_SER_OUT_DIV2 BIT(13) +#define NISTC_CLK_FOUT_SLOW_DIV2 BIT(12) +#define NISTC_CLK_FOUT_SLOW_TIMEBASE BIT(11) +#define NISTC_CLK_FOUT_G_SRC_DIV2 BIT(10) +#define NISTC_CLK_FOUT_TO_BOARD_DIV2 BIT(9) +#define NISTC_CLK_FOUT_TO_BOARD BIT(8) +#define NISTC_CLK_FOUT_AI_OUT_DIV2 BIT(7) +#define NISTC_CLK_FOUT_AI_SRC_DIV2 BIT(6) +#define NISTC_CLK_FOUT_AO_OUT_DIV2 BIT(5) +#define NISTC_CLK_FOUT_AO_SRC_DIV2 BIT(4) +#define NISTC_CLK_FOUT_DIVIDER(x) (((x) & 0xf) << 0) +#define NISTC_CLK_FOUT_TO_DIVIDER(x) (((x) >> 0) & 0xf) +#define NISTC_CLK_FOUT_DIVIDER_MASK NISTC_CLK_FOUT_DIVIDER(0xf) + +#define NISTC_IO_BIDIR_PIN_REG 57 + +#define NISTC_RTSI_TRIG_DIR_REG 58 +#define NISTC_RTSI_TRIG_OLD_CLK_CHAN 7 +#define NISTC_RTSI_TRIG_NUM_CHAN(_m) ((_m) ? 8 : 7) +#define NISTC_RTSI_TRIG_DIR(_c, _m) ((_m) ? BIT(8 + (_c)) : BIT(7 + (_c))) +#define NISTC_RTSI_TRIG_USE_CLK BIT(1) +#define NISTC_RTSI_TRIG_DRV_CLK BIT(0) + +#define NISTC_INT_CTRL_REG 59 +#define NISTC_INT_CTRL_INTB_ENA BIT(15) +#define NISTC_INT_CTRL_INTB_SEL(x) (((x) & 0x7) << 12) +#define NISTC_INT_CTRL_INTA_ENA BIT(11) +#define NISTC_INT_CTRL_INTA_SEL(x) (((x) & 0x7) << 8) +#define NISTC_INT_CTRL_PASSTHRU0_POL BIT(3) +#define NISTC_INT_CTRL_PASSTHRU1_POL BIT(2) +#define NISTC_INT_CTRL_3PIN_INT BIT(1) +#define NISTC_INT_CTRL_INT_POL BIT(0) + +#define NISTC_AI_OUT_CTRL_REG 60 +#define NISTC_AI_OUT_CTRL_START_SEL BIT(10) +#define NISTC_AI_OUT_CTRL_SCAN_IN_PROG_SEL(x) (((x) & 0x3) << 8) +#define NISTC_AI_OUT_CTRL_EXTMUX_CLK_SEL(x) (((x) & 0x3) << 6) +#define NISTC_AI_OUT_CTRL_LOCALMUX_CLK_SEL(x) (((x) & 0x3) << 4) +#define NISTC_AI_OUT_CTRL_SC_TC_SEL(x) (((x) & 0x3) << 2) +#define NISTC_AI_OUT_CTRL_CONVERT_SEL(x) (((x) & 0x3) << 0) +#define NISTC_AI_OUT_CTRL_CONVERT_HIGH_Z NISTC_AI_OUT_CTRL_CONVERT_SEL(0) +#define NISTC_AI_OUT_CTRL_CONVERT_GND NISTC_AI_OUT_CTRL_CONVERT_SEL(1) +#define NISTC_AI_OUT_CTRL_CONVERT_LOW NISTC_AI_OUT_CTRL_CONVERT_SEL(2) +#define NISTC_AI_OUT_CTRL_CONVERT_HIGH NISTC_AI_OUT_CTRL_CONVERT_SEL(3) + +#define NISTC_ATRIG_ETC_REG 61 +#define NISTC_ATRIG_ETC_GPFO_1_ENA BIT(15) +#define NISTC_ATRIG_ETC_GPFO_0_ENA BIT(14) +#define NISTC_ATRIG_ETC_GPFO_0_SEL(x) (((x) & 0x3) << 11) +#define NISTC_ATRIG_ETC_GPFO_1_SEL BIT(7) +#define NISTC_ATRIG_ETC_DRV BIT(4) +#define NISTC_ATRIG_ETC_ENA BIT(3) +#define NISTC_ATRIG_ETC_MODE(x) (((x) & 0x7) << 0) + +#define NISTC_AI_START_STOP_REG 62 +#define NISTC_AI_START_POLARITY BIT(15) +#define NISTC_AI_STOP_POLARITY BIT(14) +#define NISTC_AI_STOP_SYNC BIT(13) +#define NISTC_AI_STOP_EDGE BIT(12) +#define NISTC_AI_STOP_SEL(x) (((x) & 0x1f) << 7) +#define NISTC_AI_START_SYNC BIT(6) +#define NISTC_AI_START_EDGE BIT(5) +#define NISTC_AI_START_SEL(x) (((x) & 0x1f) << 0) + +#define NISTC_AI_TRIG_SEL_REG 63 +#define NISTC_AI_TRIG_START1_POLARITY BIT(15) +#define NISTC_AI_TRIG_START2_POLARITY BIT(14) +#define NISTC_AI_TRIG_START2_SYNC BIT(13) +#define NISTC_AI_TRIG_START2_EDGE BIT(12) +#define NISTC_AI_TRIG_START2_SEL(x) (((x) & 0x1f) << 7) +#define NISTC_AI_TRIG_START1_SYNC BIT(6) +#define NISTC_AI_TRIG_START1_EDGE BIT(5) +#define NISTC_AI_TRIG_START1_SEL(x) (((x) & 0x1f) << 0) + +#define NISTC_AI_DIV_LOADA_REG 64 + +#define NISTC_AO_START_SEL_REG 66 +#define NISTC_AO_START_UI2_SW_GATE BIT(15) +#define NISTC_AO_START_UI2_EXT_GATE_POL BIT(14) +#define NISTC_AO_START_POLARITY BIT(13) +#define NISTC_AO_START_AOFREQ_ENA BIT(12) +#define NISTC_AO_START_UI2_EXT_GATE_SEL(x) (((x) & 0x1f) << 7) +#define NISTC_AO_START_SYNC BIT(6) +#define NISTC_AO_START_EDGE BIT(5) +#define NISTC_AO_START_SEL(x) (((x) & 0x1f) << 0) + +#define NISTC_AO_TRIG_SEL_REG 67 +#define NISTC_AO_TRIG_UI2_EXT_GATE_ENA BIT(15) +#define NISTC_AO_TRIG_DELAYED_START1 BIT(14) +#define NISTC_AO_TRIG_START1_POLARITY BIT(13) +#define NISTC_AO_TRIG_UI2_SRC_POLARITY BIT(12) +#define NISTC_AO_TRIG_UI2_SRC_SEL(x) (((x) & 0x1f) << 7) +#define NISTC_AO_TRIG_START1_SYNC BIT(6) +#define NISTC_AO_TRIG_START1_EDGE BIT(5) +#define NISTC_AO_TRIG_START1_SEL(x) (((x) & 0x1f) << 0) +#define NISTC_AO_TRIG_START1_SEL_MASK NISTC_AO_TRIG_START1_SEL(0x1f) + +#define NISTC_G0_AUTOINC_REG 68 +#define NISTC_G1_AUTOINC_REG 69 + +#define NISTC_AO_MODE3_REG 70 +#define NISTC_AO_MODE3_UI2_SW_NEXT_TC BIT(13) +#define NISTC_AO_MODE3_UC_SW_EVERY_BC_TC BIT(12) +#define NISTC_AO_MODE3_TRIG_LEN BIT(11) +#define NISTC_AO_MODE3_STOP_ON_OVERRUN_ERR BIT(5) +#define NISTC_AO_MODE3_STOP_ON_BC_TC_TRIG_ERR BIT(4) +#define NISTC_AO_MODE3_STOP_ON_BC_TC_ERR BIT(3) +#define NISTC_AO_MODE3_NOT_AN_UPDATE BIT(2) +#define NISTC_AO_MODE3_SW_GATE BIT(1) +#define NISTC_AO_MODE3_LAST_GATE_DISABLE BIT(0) /* M-Series only */ + +#define NISTC_RESET_REG 72 +#define NISTC_RESET_SOFTWARE BIT(11) +#define NISTC_RESET_AO_CFG_END BIT(9) +#define NISTC_RESET_AI_CFG_END BIT(8) +#define NISTC_RESET_AO_CFG_START BIT(5) +#define NISTC_RESET_AI_CFG_START BIT(4) +#define NISTC_RESET_G1 BIT(3) +#define NISTC_RESET_G0 BIT(2) +#define NISTC_RESET_AO BIT(1) +#define NISTC_RESET_AI BIT(0) + +#define NISTC_INTA_ENA_REG 73 +#define NISTC_INTA2_ENA_REG 74 +#define NISTC_INTA_ENA_PASSTHRU0 BIT(9) +#define NISTC_INTA_ENA_G0_GATE BIT(8) +#define NISTC_INTA_ENA_AI_FIFO BIT(7) +#define NISTC_INTA_ENA_G0_TC BIT(6) +#define NISTC_INTA_ENA_AI_ERR BIT(5) +#define NISTC_INTA_ENA_AI_STOP BIT(4) +#define NISTC_INTA_ENA_AI_START BIT(3) +#define NISTC_INTA_ENA_AI_START2 BIT(2) +#define NISTC_INTA_ENA_AI_START1 BIT(1) +#define NISTC_INTA_ENA_AI_SC_TC BIT(0) +#define NISTC_INTA_ENA_AI_MASK (NISTC_INTA_ENA_AI_FIFO | \ + NISTC_INTA_ENA_AI_ERR | \ + NISTC_INTA_ENA_AI_STOP | \ + NISTC_INTA_ENA_AI_START | \ + NISTC_INTA_ENA_AI_START2 | \ + NISTC_INTA_ENA_AI_START1 | \ + NISTC_INTA_ENA_AI_SC_TC) + +#define NISTC_INTB_ENA_REG 75 +#define NISTC_INTB2_ENA_REG 76 +#define NISTC_INTB_ENA_PASSTHRU1 BIT(11) +#define NISTC_INTB_ENA_G1_GATE BIT(10) +#define NISTC_INTB_ENA_G1_TC BIT(9) +#define NISTC_INTB_ENA_AO_FIFO BIT(8) +#define NISTC_INTB_ENA_AO_UI2_TC BIT(7) +#define NISTC_INTB_ENA_AO_UC_TC BIT(6) +#define NISTC_INTB_ENA_AO_ERR BIT(5) +#define NISTC_INTB_ENA_AO_STOP BIT(4) +#define NISTC_INTB_ENA_AO_START BIT(3) +#define NISTC_INTB_ENA_AO_UPDATE BIT(2) +#define NISTC_INTB_ENA_AO_START1 BIT(1) +#define NISTC_INTB_ENA_AO_BC_TC BIT(0) + +#define NISTC_AI_PERSONAL_REG 77 +#define NISTC_AI_PERSONAL_SHIFTIN_PW BIT(15) +#define NISTC_AI_PERSONAL_EOC_POLARITY BIT(14) +#define NISTC_AI_PERSONAL_SOC_POLARITY BIT(13) +#define NISTC_AI_PERSONAL_SHIFTIN_POL BIT(12) +#define NISTC_AI_PERSONAL_CONVERT_TIMEBASE BIT(11) +#define NISTC_AI_PERSONAL_CONVERT_PW BIT(10) +#define NISTC_AI_PERSONAL_CONVERT_ORIG_PULSE BIT(9) +#define NISTC_AI_PERSONAL_FIFO_FLAGS_POL BIT(8) +#define NISTC_AI_PERSONAL_OVERRUN_MODE BIT(7) +#define NISTC_AI_PERSONAL_EXTMUX_CLK_PW BIT(6) +#define NISTC_AI_PERSONAL_LOCALMUX_CLK_PW BIT(5) +#define NISTC_AI_PERSONAL_AIFREQ_POL BIT(4) + +#define NISTC_AO_PERSONAL_REG 78 +#define NISTC_AO_PERSONAL_MULTI_DACS BIT(15) /* M-Series only */ +#define NISTC_AO_PERSONAL_NUM_DAC BIT(14) /* 1:single; 0:dual */ +#define NISTC_AO_PERSONAL_FAST_CPU BIT(13) /* M-Series reserved */ +#define NISTC_AO_PERSONAL_TMRDACWR_PW BIT(12) +#define NISTC_AO_PERSONAL_FIFO_FLAGS_POL BIT(11) /* M-Series reserved */ +#define NISTC_AO_PERSONAL_FIFO_ENA BIT(10) +#define NISTC_AO_PERSONAL_AOFREQ_POL BIT(9) /* M-Series reserved */ +#define NISTC_AO_PERSONAL_DMA_PIO_CTRL BIT(8) /* M-Series reserved */ +#define NISTC_AO_PERSONAL_UPDATE_ORIG_PULSE BIT(7) +#define NISTC_AO_PERSONAL_UPDATE_TIMEBASE BIT(6) +#define NISTC_AO_PERSONAL_UPDATE_PW BIT(5) +#define NISTC_AO_PERSONAL_BC_SRC_SEL BIT(4) +#define NISTC_AO_PERSONAL_INTERVAL_BUFFER_MODE BIT(3) + +#define NISTC_RTSI_TRIGA_OUT_REG 79 +#define NISTC_RTSI_TRIGB_OUT_REG 80 +#define NISTC_RTSI_TRIGB_SUB_SEL1 BIT(15) /* not for M-Series */ +#define NISTC_RTSI_TRIG(_c, _s) (((_s) & 0xf) << (((_c) % 4) * 4)) +#define NISTC_RTSI_TRIG_MASK(_c) NISTC_RTSI_TRIG((_c), 0xf) +#define NISTC_RTSI_TRIG_TO_SRC(_c, _b) (((_b) >> (((_c) % 4) * 4)) & 0xf) + +#define NISTC_RTSI_BOARD_REG 81 + +#define NISTC_CFG_MEM_CLR_REG 82 +#define NISTC_ADC_FIFO_CLR_REG 83 +#define NISTC_DAC_FIFO_CLR_REG 84 +#define NISTC_WR_STROBE3_REG 85 + +#define NISTC_AO_OUT_CTRL_REG 86 +#define NISTC_AO_OUT_CTRL_EXT_GATE_ENA BIT(15) +#define NISTC_AO_OUT_CTRL_EXT_GATE_SEL(x) (((x) & 0x1f) << 10) +#define NISTC_AO_OUT_CTRL_CHANS(x) (((x) & 0xf) << 6) +#define NISTC_AO_OUT_CTRL_UPDATE2_SEL(x) (((x) & 0x3) << 4) +#define NISTC_AO_OUT_CTRL_EXT_GATE_POL BIT(3) +#define NISTC_AO_OUT_CTRL_UPDATE2_TOGGLE BIT(2) +#define NISTC_AO_OUT_CTRL_UPDATE_SEL(x) (((x) & 0x3) << 0) +#define NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ NISTC_AO_OUT_CTRL_UPDATE_SEL(0) +#define NISTC_AO_OUT_CTRL_UPDATE_SEL_GND NISTC_AO_OUT_CTRL_UPDATE_SEL(1) +#define NISTC_AO_OUT_CTRL_UPDATE_SEL_LOW NISTC_AO_OUT_CTRL_UPDATE_SEL(2) +#define NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGH NISTC_AO_OUT_CTRL_UPDATE_SEL(3) + +#define NISTC_AI_MODE3_REG 87 +#define NISTC_AI_MODE3_TRIG_LEN BIT(15) +#define NISTC_AI_MODE3_DELAY_START BIT(14) +#define NISTC_AI_MODE3_SOFTWARE_GATE BIT(13) +#define NISTC_AI_MODE3_SI_TRIG_DELAY BIT(12) +#define NISTC_AI_MODE3_SI2_SRC_SEL BIT(11) +#define NISTC_AI_MODE3_DELAYED_START2 BIT(10) +#define NISTC_AI_MODE3_DELAYED_START1 BIT(9) +#define NISTC_AI_MODE3_EXT_GATE_MODE BIT(8) +#define NISTC_AI_MODE3_FIFO_MODE(x) (((x) & 0x3) << 6) +#define NISTC_AI_MODE3_FIFO_MODE_NE NISTC_AI_MODE3_FIFO_MODE(0) +#define NISTC_AI_MODE3_FIFO_MODE_HF NISTC_AI_MODE3_FIFO_MODE(1) +#define NISTC_AI_MODE3_FIFO_MODE_F NISTC_AI_MODE3_FIFO_MODE(2) +#define NISTC_AI_MODE3_FIFO_MODE_HF_E NISTC_AI_MODE3_FIFO_MODE(3) +#define NISTC_AI_MODE3_EXT_GATE_POL BIT(5) +#define NISTC_AI_MODE3_EXT_GATE_SEL(x) (((x) & 0x1f) << 0) + +#define NISTC_AI_STATUS1_REG 2 +#define NISTC_AI_STATUS1_INTA BIT(15) +#define NISTC_AI_STATUS1_FIFO_F BIT(14) +#define NISTC_AI_STATUS1_FIFO_HF BIT(13) +#define NISTC_AI_STATUS1_FIFO_E BIT(12) +#define NISTC_AI_STATUS1_OVERRUN BIT(11) +#define NISTC_AI_STATUS1_OVERFLOW BIT(10) +#define NISTC_AI_STATUS1_SC_TC_ERR BIT(9) +#define NISTC_AI_STATUS1_OVER (NISTC_AI_STATUS1_OVERRUN | \ + NISTC_AI_STATUS1_OVERFLOW) +#define NISTC_AI_STATUS1_ERR (NISTC_AI_STATUS1_OVER | \ + NISTC_AI_STATUS1_SC_TC_ERR) +#define NISTC_AI_STATUS1_START2 BIT(8) +#define NISTC_AI_STATUS1_START1 BIT(7) +#define NISTC_AI_STATUS1_SC_TC BIT(6) +#define NISTC_AI_STATUS1_START BIT(5) +#define NISTC_AI_STATUS1_STOP BIT(4) +#define NISTC_AI_STATUS1_G0_TC BIT(3) +#define NISTC_AI_STATUS1_G0_GATE BIT(2) +#define NISTC_AI_STATUS1_FIFO_REQ BIT(1) +#define NISTC_AI_STATUS1_PASSTHRU0 BIT(0) + +#define NISTC_AO_STATUS1_REG 3 +#define NISTC_AO_STATUS1_INTB BIT(15) +#define NISTC_AO_STATUS1_FIFO_F BIT(14) +#define NISTC_AO_STATUS1_FIFO_HF BIT(13) +#define NISTC_AO_STATUS1_FIFO_E BIT(12) +#define NISTC_AO_STATUS1_BC_TC_ERR BIT(11) +#define NISTC_AO_STATUS1_START BIT(10) +#define NISTC_AO_STATUS1_OVERRUN BIT(9) +#define NISTC_AO_STATUS1_START1 BIT(8) +#define NISTC_AO_STATUS1_BC_TC BIT(7) +#define NISTC_AO_STATUS1_UC_TC BIT(6) +#define NISTC_AO_STATUS1_UPDATE BIT(5) +#define NISTC_AO_STATUS1_UI2_TC BIT(4) +#define NISTC_AO_STATUS1_G1_TC BIT(3) +#define NISTC_AO_STATUS1_G1_GATE BIT(2) +#define NISTC_AO_STATUS1_FIFO_REQ BIT(1) +#define NISTC_AO_STATUS1_PASSTHRU1 BIT(0) + +#define NISTC_G01_STATUS_REG 4 + +#define NISTC_AI_STATUS2_REG 5 + +#define NISTC_AO_STATUS2_REG 6 + +#define NISTC_DIO_IN_REG 7 + +#define NISTC_G0_HW_SAVE_REG 8 +#define NISTC_G1_HW_SAVE_REG 10 + +#define NISTC_G0_SAVE_REG 12 +#define NISTC_G1_SAVE_REG 14 + +#define NISTC_AO_UI_SAVE_REG 16 +#define NISTC_AO_BC_SAVE_REG 18 +#define NISTC_AO_UC_SAVE_REG 20 + +#define NISTC_STATUS1_REG 27 +#define NISTC_STATUS1_SERIO_IN_PROG BIT(12) + +#define NISTC_DIO_SERIAL_IN_REG 28 + +#define NISTC_STATUS2_REG 29 +#define NISTC_STATUS2_AO_TMRDACWRS_IN_PROGRESS BIT(5) + +#define NISTC_AI_SI_SAVE_REG 64 +#define NISTC_AI_SC_SAVE_REG 66 -#define Second_IRQ_B_Enable_Register 76 -enum Second_IRQ_B_Enable_Bits { - AO_BC_TC_Second_Irq_Enable = _bit0, - AO_START1_Second_Irq_Enable = _bit1, - AO_UPDATE_Second_Irq_Enable = _bit2, - AO_START_Second_Irq_Enable = _bit3, - AO_STOP_Second_Irq_Enable = _bit4, - AO_Error_Second_Irq_Enable = _bit5, - AO_UC_TC_Second_Irq_Enable = _bit6, - AO_UI2_TC_Second_Irq_Enable = _bit7, - AO_FIFO_Second_Irq_Enable = _bit8, - G1_TC_Second_Irq_Enable = _bit9, - G1_Gate_Second_Irq_Enable = _bit10, - Pass_Thru_1_Second_Irq_Enable = _bit11 -}; +/* + * PCI E Series Registers + */ +#define NI_E_STC_WINDOW_ADDR_REG 0x00 /* rw16 */ +#define NI_E_STC_WINDOW_DATA_REG 0x02 /* rw16 */ + +#define NI_E_STATUS_REG 0x01 /* r8 */ +#define NI_E_STATUS_AI_FIFO_LOWER_NE BIT(3) +#define NI_E_STATUS_PROMOUT BIT(0) + +#define NI_E_DMA_AI_AO_SEL_REG 0x09 /* w8 */ +#define NI_E_DMA_AI_SEL(x) (((x) & 0xf) << 0) +#define NI_E_DMA_AI_SEL_MASK NI_E_DMA_AI_SEL(0xf) +#define NI_E_DMA_AO_SEL(x) (((x) & 0xf) << 4) +#define NI_E_DMA_AO_SEL_MASK NI_E_DMA_AO_SEL(0xf) + +#define NI_E_DMA_G0_G1_SEL_REG 0x0b /* w8 */ +#define NI_E_DMA_G0_G1_SEL(_g, _c) (((_c) & 0xf) << ((_g) * 4)) +#define NI_E_DMA_G0_G1_SEL_MASK(_g) NI_E_DMA_G0_G1_SEL((_g), 0xf) + +#define NI_E_SERIAL_CMD_REG 0x0d /* w8 */ +#define NI_E_SERIAL_CMD_DAC_LD(x) BIT(3 + (x)) +#define NI_E_SERIAL_CMD_EEPROM_CS BIT(2) +#define NI_E_SERIAL_CMD_SDATA BIT(1) +#define NI_E_SERIAL_CMD_SCLK BIT(0) + +#define NI_E_MISC_CMD_REG 0x0f /* w8 */ +#define NI_E_MISC_CMD_INTEXT_ATRIG(x) (((x) & 0x1) << 7) +#define NI_E_MISC_CMD_EXT_ATRIG NI_E_MISC_CMD_INTEXT_ATRIG(0) +#define NI_E_MISC_CMD_INT_ATRIG NI_E_MISC_CMD_INTEXT_ATRIG(1) + +#define NI_E_AI_CFG_LO_REG 0x10 /* w16 */ +#define NI_E_AI_CFG_LO_LAST_CHAN BIT(15) +#define NI_E_AI_CFG_LO_GEN_TRIG BIT(12) +#define NI_E_AI_CFG_LO_DITHER BIT(9) +#define NI_E_AI_CFG_LO_UNI BIT(8) +#define NI_E_AI_CFG_LO_GAIN(x) ((x) << 0) + +#define NI_E_AI_CFG_HI_REG 0x12 /* w16 */ +#define NI_E_AI_CFG_HI_TYPE(x) (((x) & 0x7) << 12) +#define NI_E_AI_CFG_HI_TYPE_DIFF NI_E_AI_CFG_HI_TYPE(1) +#define NI_E_AI_CFG_HI_TYPE_COMMON NI_E_AI_CFG_HI_TYPE(2) +#define NI_E_AI_CFG_HI_TYPE_GROUND NI_E_AI_CFG_HI_TYPE(3) +#define NI_E_AI_CFG_HI_AC_COUPLE BIT(11) +#define NI_E_AI_CFG_HI_CHAN(x) (((x) & 0x3f) << 0) + +#define NI_E_AO_CFG_REG 0x16 /* w16 */ +#define NI_E_AO_DACSEL(x) ((x) << 8) +#define NI_E_AO_GROUND_REF BIT(3) +#define NI_E_AO_EXT_REF BIT(2) +#define NI_E_AO_DEGLITCH BIT(1) +#define NI_E_AO_CFG_BIP BIT(0) + +#define NI_E_DAC_DIRECT_DATA_REG(x) (0x18 + ((x) * 2)) /* w16 */ + +#define NI_E_8255_BASE 0x19 /* rw8 */ + +#define NI_E_AI_FIFO_DATA_REG 0x1c /* r16 */ + +#define NI_E_AO_FIFO_DATA_REG 0x1e /* w16 */ -#define AI_Personal_Register 77 -#define AI_SHIFTIN_Pulse_Width _bit15 -#define AI_EOC_Polarity _bit14 -#define AI_SOC_Polarity _bit13 -#define AI_SHIFTIN_Polarity _bit12 -#define AI_CONVERT_Pulse_Timebase _bit11 -#define AI_CONVERT_Pulse_Width _bit10 -#define AI_CONVERT_Original_Pulse _bit9 -#define AI_FIFO_Flags_Polarity _bit8 -#define AI_Overrun_Mode _bit7 -#define AI_EXTMUX_CLK_Pulse_Width _bit6 -#define AI_LOCALMUX_CLK_Pulse_Width _bit5 -#define AI_AIFREQ_Polarity _bit4 - -#define AO_Personal_Register 78 -enum AO_Personal_Bits { - AO_Interval_Buffer_Mode = 1 << 3, - AO_BC_Source_Select = 1 << 4, - AO_UPDATE_Pulse_Width = 1 << 5, - AO_UPDATE_Pulse_Timebase = 1 << 6, - AO_UPDATE_Original_Pulse = 1 << 7, - AO_DMA_PIO_Control = 1 << 8, /* M Series: reserved */ - AO_AOFREQ_Polarity = 1 << 9, /* M Series: reserved */ - AO_FIFO_Enable = 1 << 10, - AO_FIFO_Flags_Polarity = 1 << 11, /* M Series: reserved */ - AO_TMRDACWR_Pulse_Width = 1 << 12, - AO_Fast_CPU = 1 << 13, /* M Series: reserved */ - AO_Number_Of_DAC_Packages = 1 << 14, /* 1 for "single" mode, 0 for "dual" */ - AO_Multiple_DACS_Per_Package = 1 << 15 /* m-series only */ -}; -#define RTSI_Trig_A_Output_Register 79 -#define RTSI_Trig_B_Output_Register 80 -enum RTSI_Trig_B_Output_Bits { - RTSI_Sub_Selection_1_Bit = 0x8000 /* not for m-series */ -}; -static inline unsigned RTSI_Trig_Output_Bits(unsigned rtsi_channel, - unsigned source) -{ - return (source & 0xf) << ((rtsi_channel % 4) * 4); -}; +/* + * 611x registers (these boards differ from the e-series) + */ +#define NI611X_MAGIC_REG 0x19 /* w8 (new) */ +#define NI611X_CALIB_CHAN_SEL_REG 0x1a /* w16 (new) */ +#define NI611X_AI_FIFO_DATA_REG 0x1c /* r32 (incompatible) */ +#define NI611X_AI_FIFO_OFFSET_LOAD_REG 0x05 /* r8 (new) */ +#define NI611X_AO_FIFO_DATA_REG 0x14 /* w32 (incompatible) */ +#define NI611X_CAL_GAIN_SEL_REG 0x05 /* w8 (new) */ + +#define NI611X_AO_WINDOW_ADDR_REG 0x18 +#define NI611X_AO_WINDOW_DATA_REG 0x1e -static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel) -{ - return 0xf << ((rtsi_channel % 4) * 4); -}; +/* + * 6143 registers + */ +#define NI6143_MAGIC_REG 0x19 /* w8 */ +#define NI6143_DMA_G0_G1_SEL_REG 0x0b /* w8 */ +#define NI6143_PIPELINE_DELAY_REG 0x1f /* w8 */ +#define NI6143_EOC_SET_REG 0x1d /* w8 */ +#define NI6143_DMA_AI_SEL_REG 0x09 /* w8 */ +#define NI6143_AI_FIFO_DATA_REG 0x8c /* r32 */ +#define NI6143_AI_FIFO_FLAG_REG 0x84 /* w32 */ +#define NI6143_AI_FIFO_CTRL_REG 0x88 /* w32 */ +#define NI6143_AI_FIFO_STATUS_REG 0x88 /* r32 */ +#define NI6143_AI_FIFO_DMA_THRESH_REG 0x90 /* w32 */ +#define NI6143_AI_FIFO_WORDS_AVAIL_REG 0x94 /* w32 */ + +#define NI6143_CALIB_CHAN_REG 0x42 /* w16 */ +#define NI6143_CALIB_CHAN_RELAY_ON BIT(15) +#define NI6143_CALIB_CHAN_RELAY_OFF BIT(14) +#define NI6143_CALIB_CHAN(x) (((x) & 0xf) << 0) +#define NI6143_CALIB_CHAN_GND_GND NI6143_CALIB_CHAN(0) /* Offset Cal */ +#define NI6143_CALIB_CHAN_2V5_GND NI6143_CALIB_CHAN(2) /* 2.5V ref */ +#define NI6143_CALIB_CHAN_PWM_GND NI6143_CALIB_CHAN(5) /* +-5V Self Cal */ +#define NI6143_CALIB_CHAN_2V5_PWM NI6143_CALIB_CHAN(10) /* PWM Cal */ +#define NI6143_CALIB_CHAN_PWM_PWM NI6143_CALIB_CHAN(13) /* CMRR */ +#define NI6143_CALIB_CHAN_GND_PWM NI6143_CALIB_CHAN(14) /* PWM Cal */ +#define NI6143_CALIB_LO_TIME_REG 0x20 /* w16 */ +#define NI6143_CALIB_HI_TIME_REG 0x22 /* w16 */ +#define NI6143_RELAY_COUNTER_LOAD_REG 0x4c /* w32 */ +#define NI6143_SIGNATURE_REG 0x50 /* w32 */ +#define NI6143_RELEASE_DATE_REG 0x54 /* w32 */ +#define NI6143_RELEASE_OLDEST_DATE_REG 0x58 /* w32 */ -/* inverse to RTSI_Trig_Output_Bits() */ -static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel, - unsigned bits) -{ - return (bits >> ((rtsi_channel % 4) * 4)) & 0xf; -}; +/* + * 671x, 611x windowed ao registers + */ +#define NI671X_DAC_DIRECT_DATA_REG(x) (0x00 + (x)) /* w16 */ +#define NI611X_AO_TIMED_REG 0x10 /* w16 */ +#define NI671X_AO_IMMEDIATE_REG 0x11 /* w16 */ +#define NI611X_AO_FIFO_OFFSET_LOAD_REG 0x13 /* w32 */ +#define NI67XX_AO_SP_UPDATES_REG 0x14 /* w16 */ +#define NI611X_AO_WAVEFORM_GEN_REG 0x15 /* w16 */ +#define NI611X_AO_MISC_REG 0x16 /* w16 */ +#define NI611X_AO_MISC_CLEAR_WG BIT(0) +#define NI67XX_AO_CAL_CHAN_SEL_REG 0x17 /* w16 */ +#define NI67XX_AO_CFG2_REG 0x18 /* w16 */ +#define NI67XX_CAL_CMD_REG 0x19 /* w16 */ +#define NI67XX_CAL_STATUS_REG 0x1a /* r8 */ +#define NI67XX_CAL_STATUS_BUSY BIT(0) +#define NI67XX_CAL_STATUS_OSC_DETECT BIT(1) +#define NI67XX_CAL_STATUS_OVERRANGE BIT(2) +#define NI67XX_CAL_DATA_REG 0x1b /* r16 */ +#define NI67XX_CAL_CFG_HI_REG 0x1c /* rw16 */ +#define NI67XX_CAL_CFG_LO_REG 0x1d /* rw16 */ + +#define CS5529_CMD_CB BIT(7) +#define CS5529_CMD_SINGLE_CONV BIT(6) +#define CS5529_CMD_CONT_CONV BIT(5) +#define CS5529_CMD_READ BIT(4) +#define CS5529_CMD_REG(x) (((x) & 0x7) << 1) +#define CS5529_CMD_REG_MASK CS5529_CMD_REG(7) +#define CS5529_CMD_PWR_SAVE BIT(0) + +#define CS5529_OFFSET_REG CS5529_CMD_REG(0) +#define CS5529_GAIN_REG CS5529_CMD_REG(1) +#define CS5529_CONV_DATA_REG CS5529_CMD_REG(3) +#define CS5529_SETUP_REG CS5529_CMD_REG(4) + +#define CS5529_CFG_REG CS5529_CMD_REG(2) +#define CS5529_CFG_AOUT(x) BIT(22 + (x)) +#define CS5529_CFG_DOUT(x) BIT(18 + (x)) +#define CS5529_CFG_LOW_PWR_MODE BIT(16) +#define CS5529_CFG_WORD_RATE(x) (((x) & 0x7) << 13) +#define CS5529_CFG_WORD_RATE_MASK CS5529_CFG_WORD_RATE(0x7) +#define CS5529_CFG_WORD_RATE_2180 CS5529_CFG_WORD_RATE(0) +#define CS5529_CFG_WORD_RATE_1092 CS5529_CFG_WORD_RATE(1) +#define CS5529_CFG_WORD_RATE_532 CS5529_CFG_WORD_RATE(2) +#define CS5529_CFG_WORD_RATE_388 CS5529_CFG_WORD_RATE(3) +#define CS5529_CFG_WORD_RATE_324 CS5529_CFG_WORD_RATE(4) +#define CS5529_CFG_WORD_RATE_17444 CS5529_CFG_WORD_RATE(5) +#define CS5529_CFG_WORD_RATE_8724 CS5529_CFG_WORD_RATE(6) +#define CS5529_CFG_WORD_RATE_4364 CS5529_CFG_WORD_RATE(7) +#define CS5529_CFG_UNIPOLAR BIT(12) +#define CS5529_CFG_RESET BIT(7) +#define CS5529_CFG_RESET_VALID BIT(6) +#define CS5529_CFG_PORT_FLAG BIT(5) +#define CS5529_CFG_PWR_SAVE_SEL BIT(4) +#define CS5529_CFG_DONE_FLAG BIT(3) +#define CS5529_CFG_CALIB(x) (((x) & 0x7) << 0) +#define CS5529_CFG_CALIB_NONE CS5529_CFG_CALIB(0) +#define CS5529_CFG_CALIB_OFFSET_SELF CS5529_CFG_CALIB(1) +#define CS5529_CFG_CALIB_GAIN_SELF CS5529_CFG_CALIB(2) +#define CS5529_CFG_CALIB_BOTH_SELF CS5529_CFG_CALIB(3) +#define CS5529_CFG_CALIB_OFFSET_SYS CS5529_CFG_CALIB(5) +#define CS5529_CFG_CALIB_GAIN_SYS CS5529_CFG_CALIB(6) -#define RTSI_Board_Register 81 -#define Write_Strobe_0_Register 82 -#define Write_Strobe_1_Register 83 -#define Write_Strobe_2_Register 84 -#define Write_Strobe_3_Register 85 - -#define AO_Output_Control_Register 86 -#define AO_External_Gate_Enable _bit15 -#define AO_External_Gate_Select(x) (((x)&0x1f)<<10) -#define AO_Number_Of_Channels(x) (((x)&0xf)<<6) -#define AO_UPDATE2_Output_Select(x) (((x)&0x3)<<4) -#define AO_External_Gate_Polarity _bit3 -#define AO_UPDATE2_Output_Toggle _bit2 -enum ao_update_output_selection { - AO_Update_Output_High_Z = 0, - AO_Update_Output_Ground = 1, - AO_Update_Output_Enable_Low = 2, - AO_Update_Output_Enable_High = 3 -}; -static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection - selection) -{ - return selection & 0x3; -} - -#define AI_Mode_3_Register 87 -#define AI_Trigger_Length _bit15 -#define AI_Delay_START _bit14 -#define AI_Software_Gate _bit13 -#define AI_SI_Special_Trigger_Delay _bit12 -#define AI_SI2_Source_Select _bit11 -#define AI_Delayed_START2 _bit10 -#define AI_Delayed_START1 _bit9 -#define AI_External_Gate_Mode _bit8 -#define AI_FIFO_Mode_HF_to_E (3<<6) -#define AI_FIFO_Mode_F (2<<6) -#define AI_FIFO_Mode_HF (1<<6) -#define AI_FIFO_Mode_NE (0<<6) -#define AI_External_Gate_Polarity _bit5 -#define AI_External_Gate_Select(a) ((a) & 0x1f) - -#define G_Autoincrement_Register(a) (68+(a)) -#define G_Command_Register(a) (6+(a)) -#define G_HW_Save_Register(a) (8+(a)*2) -#define G_HW_Save_Register_High(a) (8+(a)*2) -#define G_HW_Save_Register_Low(a) (9+(a)*2) -#define G_Input_Select_Register(a) (36+(a)) -#define G_Load_A_Register(a) (28+(a)*4) -#define G_Load_A_Register_High(a) (28+(a)*4) -#define G_Load_A_Register_Low(a) (29+(a)*4) -#define G_Load_B_Register(a) (30+(a)*4) -#define G_Load_B_Register_High(a) (30+(a)*4) -#define G_Load_B_Register_Low(a) (31+(a)*4) -#define G_Mode_Register(a) (26+(a)) -#define G_Save_Register(a) (12+(a)*2) -#define G_Save_Register_High(a) (12+(a)*2) -#define G_Save_Register_Low(a) (13+(a)*2) -#define G_Status_Register 4 -#define Analog_Trigger_Etc_Register 61 - -/* command register */ -#define G_Disarm_Copy _bit15 /* strobe */ -#define G_Save_Trace_Copy _bit14 -#define G_Arm_Copy _bit13 /* strobe */ -#define G_Bank_Switch_Start _bit10 /* strobe */ -#define G_Little_Big_Endian _bit9 -#define G_Synchronized_Gate _bit8 -#define G_Write_Switch _bit7 -#define G_Up_Down(a) (((a)&0x03)<<5) -#define G_Disarm _bit4 /* strobe */ -#define G_Analog_Trigger_Reset _bit3 /* strobe */ -#define G_Save_Trace _bit1 -#define G_Arm _bit0 /* strobe */ - -/*channel agnostic names for the command register #defines */ -#define G_Bank_Switch_Enable _bit12 -#define G_Bank_Switch_Mode _bit11 -#define G_Load _bit2 /* strobe */ - -/* input select register */ -#define G_Gate_Select(a) (((a)&0x1f)<<7) -#define G_Source_Select(a) (((a)&0x1f)<<2) -#define G_Write_Acknowledges_Irq _bit1 -#define G_Read_Acknowledges_Irq _bit0 - -/* same input select register, but with channel agnostic names */ -#define G_Source_Polarity _bit15 -#define G_Output_Polarity _bit14 -#define G_OR_Gate _bit13 -#define G_Gate_Select_Load_Source _bit12 - -/* mode register */ -#define G_Loading_On_TC _bit12 -#define G_Output_Mode(a) (((a)&0x03)<<8) -#define G_Trigger_Mode_For_Edge_Gate(a) (((a)&0x03)<<3) -#define G_Gating_Mode(a) (((a)&0x03)<<0) - -/* same input mode register, but with channel agnostic names */ -#define G_Load_Source_Select _bit7 -#define G_Reload_Source_Switching _bit15 -#define G_Loading_On_Gate _bit14 -#define G_Gate_Polarity _bit13 - -#define G_Counting_Once(a) (((a)&0x03)<<10) -#define G_Stop_Mode(a) (((a)&0x03)<<5) -#define G_Gate_On_Both_Edges _bit2 - -/* G_Status_Register */ -#define G1_Gate_Error_St _bit15 -#define G0_Gate_Error_St _bit14 -#define G1_TC_Error_St _bit13 -#define G0_TC_Error_St _bit12 -#define G1_No_Load_Between_Gates_St _bit11 -#define G0_No_Load_Between_Gates_St _bit10 -#define G1_Armed_St _bit9 -#define G0_Armed_St _bit8 -#define G1_Stale_Data_St _bit7 -#define G0_Stale_Data_St _bit6 -#define G1_Next_Load_Source_St _bit5 -#define G0_Next_Load_Source_St _bit4 -#define G1_Counting_St _bit3 -#define G0_Counting_St _bit2 -#define G1_Save_St _bit1 -#define G0_Save_St _bit0 - -/* general purpose counter timer */ -#define G_Autoincrement(a) ((a)<<0) - -/*Analog_Trigger_Etc_Register*/ -#define Analog_Trigger_Mode(x) ((x) & 0x7) -#define Analog_Trigger_Enable _bit3 -#define Analog_Trigger_Drive _bit4 -#define GPFO_1_Output_Select _bit7 -#define GPFO_0_Output_Select(a) ((a)<<11) -#define GPFO_0_Output_Enable _bit14 -#define GPFO_1_Output_Enable _bit15 - -/* Additional windowed registers unique to E series */ - -/* 16 bit registers shadowed from DAQ-STC */ -#define Window_Address 0x00 -#define Window_Data 0x02 - -#define Configuration_Memory_Clear 82 -#define ADC_FIFO_Clear 83 -#define DAC_FIFO_Clear 84 - -/* i/o port offsets */ - -/* 8 bit registers */ -#define XXX_Status 0x01 -enum XXX_Status_Bits { - PROMOUT = 0x1, - AI_FIFO_LOWER_NOT_EMPTY = 0x8, -}; -#define Serial_Command 0x0d -#define Misc_Command 0x0f -#define Port_A 0x19 -#define Port_B 0x1b -#define Port_C 0x1d -#define Configuration 0x1f -#define Strobes 0x01 -#define Channel_A_Mode 0x03 -#define Channel_B_Mode 0x05 -#define Channel_C_Mode 0x07 -#define AI_AO_Select 0x09 -enum AI_AO_Select_Bits { - AI_DMA_Select_Shift = 0, - AI_DMA_Select_Mask = 0xf, - AO_DMA_Select_Shift = 4, - AO_DMA_Select_Mask = 0xf << AO_DMA_Select_Shift -}; -#define G0_G1_Select 0x0b -static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) -{ - if (channel < 4) - return 1 << channel; - if (channel == 4) - return 0x3; - if (channel == 5) - return 0x5; - BUG(); - return 0; -} - -static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index, - unsigned mite_channel) -{ - BUG_ON(gpct_index > 1); - return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 * - gpct_index); -} - -static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index) -{ - BUG_ON(gpct_index > 1); - return 0xf << (4 * gpct_index); -} - -/* 16 bit registers */ - -#define Configuration_Memory_Low 0x10 -enum Configuration_Memory_Low_Bits { - AI_DITHER = 0x200, - AI_LAST_CHANNEL = 0x8000, -}; -#define Configuration_Memory_High 0x12 -enum Configuration_Memory_High_Bits { - AI_AC_COUPLE = 0x800, - AI_DIFFERENTIAL = 0x1000, - AI_COMMON = 0x2000, - AI_GROUND = 0x3000, -}; -static inline unsigned int AI_CONFIG_CHANNEL(unsigned int channel) -{ - return channel & 0x3f; -} - -#define ADC_FIFO_Data_Register 0x1c - -#define AO_Configuration 0x16 -#define AO_Bipolar _bit0 -#define AO_Deglitch _bit1 -#define AO_Ext_Ref _bit2 -#define AO_Ground_Ref _bit3 -#define AO_Channel(x) ((x) << 8) - -#define DAC_FIFO_Data 0x1e -#define DAC0_Direct_Data 0x18 -#define DAC1_Direct_Data 0x1a - -/* 611x registers (these boards differ from the e-series) */ - -#define Magic_611x 0x19 /* w8 (new) */ -#define Calibration_Channel_Select_611x 0x1a /* w16 (new) */ -#define ADC_FIFO_Data_611x 0x1c /* r32 (incompatible) */ -#define AI_FIFO_Offset_Load_611x 0x05 /* r8 (new) */ -#define DAC_FIFO_Data_611x 0x14 /* w32 (incompatible) */ -#define Cal_Gain_Select_611x 0x05 /* w8 (new) */ - -#define AO_Window_Address_611x 0x18 -#define AO_Window_Data_611x 0x1e - -/* 6143 registers */ -#define Magic_6143 0x19 /* w8 */ -#define G0G1_DMA_Select_6143 0x0B /* w8 */ -#define PipelineDelay_6143 0x1f /* w8 */ -#define EOC_Set_6143 0x1D /* w8 */ -#define AIDMA_Select_6143 0x09 /* w8 */ -#define AIFIFO_Data_6143 0x8C /* w32 */ -#define AIFIFO_Flag_6143 0x84 /* w32 */ -#define AIFIFO_Control_6143 0x88 /* w32 */ -#define AIFIFO_Status_6143 0x88 /* w32 */ -#define AIFIFO_DMAThreshold_6143 0x90 /* w32 */ -#define AIFIFO_Words_Available_6143 0x94 /* w32 */ - -#define Calibration_Channel_6143 0x42 /* w16 */ -#define Calibration_LowTime_6143 0x20 /* w16 */ -#define Calibration_HighTime_6143 0x22 /* w16 */ -#define Relay_Counter_Load_Val__6143 0x4C /* w32 */ -#define Signature_6143 0x50 /* w32 */ -#define Release_Date_6143 0x54 /* w32 */ -#define Release_Oldest_Date_6143 0x58 /* w32 */ - -#define Calibration_Channel_6143_RelayOn 0x8000 /* Calibration relay switch On */ -#define Calibration_Channel_6143_RelayOff 0x4000 /* Calibration relay switch Off */ -#define Calibration_Channel_Gnd_Gnd 0x00 /* Offset Calibration */ -#define Calibration_Channel_2v5_Gnd 0x02 /* 2.5V Reference */ -#define Calibration_Channel_Pwm_Gnd 0x05 /* +/- 5V Self Cal */ -#define Calibration_Channel_2v5_Pwm 0x0a /* PWM Calibration */ -#define Calibration_Channel_Pwm_Pwm 0x0d /* CMRR */ -#define Calibration_Channel_Gnd_Pwm 0x0e /* PWM Calibration */ - -/* 671x, 611x registers */ - -/* 671xi, 611x windowed ao registers */ -enum windowed_regs_67xx_61xx { - AO_Immediate_671x = 0x11, /* W 16 */ - AO_Timed_611x = 0x10, /* W 16 */ - AO_FIFO_Offset_Load_611x = 0x13, /* W32 */ - AO_Later_Single_Point_Updates = 0x14, /* W 16 */ - AO_Waveform_Generation_611x = 0x15, /* W 16 */ - AO_Misc_611x = 0x16, /* W 16 */ - AO_Calibration_Channel_Select_67xx = 0x17, /* W 16 */ - AO_Configuration_2_67xx = 0x18, /* W 16 */ - CAL_ADC_Command_67xx = 0x19, /* W 8 */ - CAL_ADC_Status_67xx = 0x1a, /* R 8 */ - CAL_ADC_Data_67xx = 0x1b, /* R 16 */ - CAL_ADC_Config_Data_High_Word_67xx = 0x1c, /* RW 16 */ - CAL_ADC_Config_Data_Low_Word_67xx = 0x1d, /* RW 16 */ +/* + * M-Series specific registers not handled by the DAQ-STC and GPCT register + * remapping. + */ +#define NI_M_CDIO_DMA_SEL_REG 0x007 +#define NI_M_CDIO_DMA_SEL_CDO(x) (((x) & 0xf) << 4) +#define NI_M_CDIO_DMA_SEL_CDO_MASK NI_M_CDIO_DMA_SEL_CDO(0xf) +#define NI_M_CDIO_DMA_SEL_CDI(x) (((x) & 0xf) << 0) +#define NI_M_CDIO_DMA_SEL_CDI_MASK NI_M_CDIO_DMA_SEL_CDI(0xf) +#define NI_M_SCXI_STATUS_REG 0x007 +#define NI_M_AI_AO_SEL_REG 0x009 +#define NI_M_G0_G1_SEL_REG 0x00b +#define NI_M_MISC_CMD_REG 0x00f +#define NI_M_SCXI_SER_DO_REG 0x011 +#define NI_M_SCXI_CTRL_REG 0x013 +#define NI_M_SCXI_OUT_ENA_REG 0x015 +#define NI_M_AI_FIFO_DATA_REG 0x01c +#define NI_M_DIO_REG 0x024 +#define NI_M_DIO_DIR_REG 0x028 +#define NI_M_CAL_PWM_REG 0x040 +#define NI_M_CAL_PWM_HIGH_TIME(x) (((x) & 0xffff) << 16) +#define NI_M_CAL_PWM_LOW_TIME(x) (((x) & 0xffff) << 0) +#define NI_M_GEN_PWM_REG(x) (0x044 + ((x) * 2)) +#define NI_M_AI_CFG_FIFO_DATA_REG 0x05e +#define NI_M_AI_CFG_LAST_CHAN BIT(14) +#define NI_M_AI_CFG_DITHER BIT(13) +#define NI_M_AI_CFG_POLARITY BIT(12) +#define NI_M_AI_CFG_GAIN(x) (((x) & 0x7) << 9) +#define NI_M_AI_CFG_CHAN_TYPE(x) (((x) & 0x7) << 6) +#define NI_M_AI_CFG_CHAN_TYPE_MASK NI_M_AI_CFG_CHAN_TYPE(7) +#define NI_M_AI_CFG_CHAN_TYPE_CALIB NI_M_AI_CFG_CHAN_TYPE(0) +#define NI_M_AI_CFG_CHAN_TYPE_DIFF NI_M_AI_CFG_CHAN_TYPE(1) +#define NI_M_AI_CFG_CHAN_TYPE_COMMON NI_M_AI_CFG_CHAN_TYPE(2) +#define NI_M_AI_CFG_CHAN_TYPE_GROUND NI_M_AI_CFG_CHAN_TYPE(3) +#define NI_M_AI_CFG_CHAN_TYPE_AUX NI_M_AI_CFG_CHAN_TYPE(5) +#define NI_M_AI_CFG_CHAN_TYPE_GHOST NI_M_AI_CFG_CHAN_TYPE(7) +#define NI_M_AI_CFG_BANK_SEL(x) ((((x) & 0x40) << 4) | ((x) & 0x30)) +#define NI_M_AI_CFG_CHAN_SEL(x) (((x) & 0xf) << 0) +#define NI_M_INTC_ENA_REG 0x088 +#define NI_M_INTC_ENA BIT(0) +#define NI_M_INTC_STATUS_REG 0x088 +#define NI_M_INTC_STATUS BIT(0) +#define NI_M_ATRIG_CTRL_REG 0x08c +#define NI_M_AO_SER_INT_ENA_REG 0x0a0 +#define NI_M_AO_SER_INT_ACK_REG 0x0a1 +#define NI_M_AO_SER_INT_STATUS_REG 0x0a1 +#define NI_M_AO_CALIB_REG 0x0a3 +#define NI_M_AO_FIFO_DATA_REG 0x0a4 +#define NI_M_PFI_FILTER_REG 0x0b0 +#define NI_M_PFI_FILTER_SEL(_c, _f) (((_f) & 0x3) << ((_c) * 2)) +#define NI_M_PFI_FILTER_SEL_MASK(_c) NI_M_PFI_FILTER_SEL((_c), 0x3) +#define NI_M_RTSI_FILTER_REG 0x0b4 +#define NI_M_SCXI_LEGACY_COMPAT_REG 0x0bc +#define NI_M_DAC_DIRECT_DATA_REG(x) (0x0c0 + ((x) * 4)) +#define NI_M_AO_WAVEFORM_ORDER_REG(x) (0x0c2 + ((x) * 4)) +#define NI_M_AO_CFG_BANK_REG(x) (0x0c3 + ((x) * 4)) +#define NI_M_AO_CFG_BANK_BIPOLAR BIT(7) +#define NI_M_AO_CFG_BANK_UPDATE_TIMED BIT(6) +#define NI_M_AO_CFG_BANK_REF(x) (((x) & 0x7) << 3) +#define NI_M_AO_CFG_BANK_REF_MASK NI_M_AO_CFG_BANK_REF(7) +#define NI_M_AO_CFG_BANK_REF_INT_10V NI_M_AO_CFG_BANK_REF(0) +#define NI_M_AO_CFG_BANK_REF_INT_5V NI_M_AO_CFG_BANK_REF(1) +#define NI_M_AO_CFG_BANK_OFFSET(x) (((x) & 0x7) << 0) +#define NI_M_AO_CFG_BANK_OFFSET_MASK NI_M_AO_CFG_BANK_OFFSET(7) +#define NI_M_AO_CFG_BANK_OFFSET_0V NI_M_AO_CFG_BANK_OFFSET(0) +#define NI_M_AO_CFG_BANK_OFFSET_5V NI_M_AO_CFG_BANK_OFFSET(1) +#define NI_M_RTSI_SHARED_MUX_REG 0x1a2 +#define NI_M_CLK_FOUT2_REG 0x1c4 +#define NI_M_CLK_FOUT2_RTSI_10MHZ BIT(7) +#define NI_M_CLK_FOUT2_TIMEBASE3_PLL BIT(6) +#define NI_M_CLK_FOUT2_TIMEBASE1_PLL BIT(5) +#define NI_M_CLK_FOUT2_PLL_SRC(x) (((x) & 0x1f) << 0) +#define NI_M_CLK_FOUT2_PLL_SRC_MASK NI_M_CLK_FOUT2_PLL_SRC(0x1f) +#define NI_M_MAX_RTSI_CHAN 7 +#define NI_M_CLK_FOUT2_PLL_SRC_RTSI(x) (((x) == NI_M_MAX_RTSI_CHAN) \ + ? NI_M_CLK_FOUT2_PLL_SRC(0x1b) \ + : NI_M_CLK_FOUT2_PLL_SRC(0xb + (x))) +#define NI_M_CLK_FOUT2_PLL_SRC_STAR NI_M_CLK_FOUT2_PLL_SRC(0x14) +#define NI_M_CLK_FOUT2_PLL_SRC_PXI10 NI_M_CLK_FOUT2_PLL_SRC(0x1d) +#define NI_M_PLL_CTRL_REG 0x1c6 +#define NI_M_PLL_CTRL_VCO_MODE(x) (((x) & 0x3) << 13) +#define NI_M_PLL_CTRL_VCO_MODE_200_325MHZ NI_M_PLL_CTRL_VCO_MODE(0) +#define NI_M_PLL_CTRL_VCO_MODE_175_225MHZ NI_M_PLL_CTRL_VCO_MODE(1) +#define NI_M_PLL_CTRL_VCO_MODE_100_225MHZ NI_M_PLL_CTRL_VCO_MODE(2) +#define NI_M_PLL_CTRL_VCO_MODE_75_150MHZ NI_M_PLL_CTRL_VCO_MODE(3) +#define NI_M_PLL_CTRL_ENA BIT(12) +#define NI_M_PLL_MAX_DIVISOR 0x10 +#define NI_M_PLL_CTRL_DIVISOR(x) (((x) & 0xf) << 8) +#define NI_M_PLL_MAX_MULTIPLIER 0x100 +#define NI_M_PLL_CTRL_MULTIPLIER(x) (((x) & 0xff) << 0) +#define NI_M_PLL_STATUS_REG 0x1c8 +#define NI_M_PLL_STATUS_LOCKED BIT(0) +#define NI_M_PFI_OUT_SEL_REG(x) (0x1d0 + ((x) * 2)) +#define NI_M_PFI_CHAN(_c) (((_c) % 3) * 5) +#define NI_M_PFI_OUT_SEL(_c, _s) (((_s) & 0x1f) << NI_M_PFI_CHAN(_c)) +#define NI_M_PFI_OUT_SEL_MASK(_c) (0x1f << NI_M_PFI_CHAN(_c)) +#define NI_M_PFI_OUT_SEL_TO_SRC(_c, _b) (((_b) >> NI_M_PFI_CHAN(_c)) & 0x1f) +#define NI_M_PFI_DI_REG 0x1dc +#define NI_M_PFI_DO_REG 0x1de +#define NI_M_CFG_BYPASS_FIFO_REG 0x218 +#define NI_M_CFG_BYPASS_FIFO BIT(31) +#define NI_M_CFG_BYPASS_AI_POLARITY BIT(22) +#define NI_M_CFG_BYPASS_AI_DITHER BIT(21) +#define NI_M_CFG_BYPASS_AI_GAIN(x) (((x) & 0x7) << 18) +#define NI_M_CFG_BYPASS_AO_CAL(x) (((x) & 0xf) << 15) +#define NI_M_CFG_BYPASS_AO_CAL_MASK NI_M_CFG_BYPASS_AO_CAL(0xf) +#define NI_M_CFG_BYPASS_AI_MODE_MUX(x) (((x) & 0x3) << 13) +#define NI_M_CFG_BYPASS_AI_MODE_MUX_MASK NI_M_CFG_BYPASS_AI_MODE_MUX(3) +#define NI_M_CFG_BYPASS_AI_CAL_NEG(x) (((x) & 0x7) << 10) +#define NI_M_CFG_BYPASS_AI_CAL_NEG_MASK NI_M_CFG_BYPASS_AI_CAL_NEG(7) +#define NI_M_CFG_BYPASS_AI_CAL_POS(x) (((x) & 0x7) << 7) +#define NI_M_CFG_BYPASS_AI_CAL_POS_MASK NI_M_CFG_BYPASS_AI_CAL_POS(7) +#define NI_M_CFG_BYPASS_AI_CAL_MASK (NI_M_CFG_BYPASS_AI_CAL_POS_MASK | \ + NI_M_CFG_BYPASS_AI_CAL_NEG_MASK | \ + NI_M_CFG_BYPASS_AI_MODE_MUX_MASK | \ + NI_M_CFG_BYPASS_AO_CAL_MASK) +#define NI_M_CFG_BYPASS_AI_BANK(x) (((x) & 0xf) << 3) +#define NI_M_CFG_BYPASS_AI_BANK_MASK NI_M_CFG_BYPASS_AI_BANK(0xf) +#define NI_M_CFG_BYPASS_AI_CHAN(x) (((x) & 0x7) << 0) +#define NI_M_CFG_BYPASS_AI_CHAN_MASK NI_M_CFG_BYPASS_AI_CHAN(7) +#define NI_M_SCXI_DIO_ENA_REG 0x21c +#define NI_M_CDI_FIFO_DATA_REG 0x220 +#define NI_M_CDO_FIFO_DATA_REG 0x220 +#define NI_M_CDIO_STATUS_REG 0x224 +#define NI_M_CDIO_STATUS_CDI_OVERFLOW BIT(20) +#define NI_M_CDIO_STATUS_CDI_OVERRUN BIT(19) +#define NI_M_CDIO_STATUS_CDI_ERROR (NI_M_CDIO_STATUS_CDI_OVERFLOW | \ + NI_M_CDIO_STATUS_CDI_OVERRUN) +#define NI_M_CDIO_STATUS_CDI_FIFO_REQ BIT(18) +#define NI_M_CDIO_STATUS_CDI_FIFO_FULL BIT(17) +#define NI_M_CDIO_STATUS_CDI_FIFO_EMPTY BIT(16) +#define NI_M_CDIO_STATUS_CDO_UNDERFLOW BIT(4) +#define NI_M_CDIO_STATUS_CDO_OVERRUN BIT(3) +#define NI_M_CDIO_STATUS_CDO_ERROR (NI_M_CDIO_STATUS_CDO_UNDERFLOW | \ + NI_M_CDIO_STATUS_CDO_OVERRUN) +#define NI_M_CDIO_STATUS_CDO_FIFO_REQ BIT(2) +#define NI_M_CDIO_STATUS_CDO_FIFO_FULL BIT(1) +#define NI_M_CDIO_STATUS_CDO_FIFO_EMPTY BIT(0) +#define NI_M_CDIO_CMD_REG 0x224 +#define NI_M_CDI_CMD_SW_UPDATE BIT(20) +#define NI_M_CDO_CMD_SW_UPDATE BIT(19) +#define NI_M_CDO_CMD_F_E_INT_ENA_CLR BIT(17) +#define NI_M_CDO_CMD_F_E_INT_ENA_SET BIT(16) +#define NI_M_CDI_CMD_ERR_INT_CONFIRM BIT(15) +#define NI_M_CDO_CMD_ERR_INT_CONFIRM BIT(14) +#define NI_M_CDI_CMD_F_REQ_INT_ENA_CLR BIT(13) +#define NI_M_CDI_CMD_F_REQ_INT_ENA_SET BIT(12) +#define NI_M_CDO_CMD_F_REQ_INT_ENA_CLR BIT(11) +#define NI_M_CDO_CMD_F_REQ_INT_ENA_SET BIT(10) +#define NI_M_CDI_CMD_ERR_INT_ENA_CLR BIT(9) +#define NI_M_CDI_CMD_ERR_INT_ENA_SET BIT(8) +#define NI_M_CDO_CMD_ERR_INT_ENA_CLR BIT(7) +#define NI_M_CDO_CMD_ERR_INT_ENA_SET BIT(6) +#define NI_M_CDI_CMD_RESET BIT(5) +#define NI_M_CDO_CMD_RESET BIT(4) +#define NI_M_CDI_CMD_ARM BIT(3) +#define NI_M_CDI_CMD_DISARM BIT(2) +#define NI_M_CDO_CMD_ARM BIT(1) +#define NI_M_CDO_CMD_DISARM BIT(0) +#define NI_M_CDI_MODE_REG 0x228 +#define NI_M_CDI_MODE_DATA_LANE(x) (((x) & 0x3) << 12) +#define NI_M_CDI_MODE_DATA_LANE_MASK NI_M_CDI_MODE_DATA_LANE(3) +#define NI_M_CDI_MODE_DATA_LANE_0_15 NI_M_CDI_MODE_DATA_LANE(0) +#define NI_M_CDI_MODE_DATA_LANE_16_31 NI_M_CDI_MODE_DATA_LANE(1) +#define NI_M_CDI_MODE_DATA_LANE_0_7 NI_M_CDI_MODE_DATA_LANE(0) +#define NI_M_CDI_MODE_DATA_LANE_8_15 NI_M_CDI_MODE_DATA_LANE(1) +#define NI_M_CDI_MODE_DATA_LANE_16_23 NI_M_CDI_MODE_DATA_LANE(2) +#define NI_M_CDI_MODE_DATA_LANE_24_31 NI_M_CDI_MODE_DATA_LANE(3) +#define NI_M_CDI_MODE_FIFO_MODE BIT(11) +#define NI_M_CDI_MODE_POLARITY BIT(10) +#define NI_M_CDI_MODE_HALT_ON_ERROR BIT(9) +#define NI_M_CDI_MODE_SAMPLE_SRC(x) (((x) & 0x3f) << 0) +#define NI_M_CDI_MODE_SAMPLE_SRC_MASK NI_M_CDI_MODE_SAMPLE_SRC(0x3f) +#define NI_M_CDO_MODE_REG 0x22c +#define NI_M_CDO_MODE_DATA_LANE(x) (((x) & 0x3) << 12) +#define NI_M_CDO_MODE_DATA_LANE_MASK NI_M_CDO_MODE_DATA_LANE(3) +#define NI_M_CDO_MODE_DATA_LANE_0_15 NI_M_CDO_MODE_DATA_LANE(0) +#define NI_M_CDO_MODE_DATA_LANE_16_31 NI_M_CDO_MODE_DATA_LANE(1) +#define NI_M_CDO_MODE_DATA_LANE_0_7 NI_M_CDO_MODE_DATA_LANE(0) +#define NI_M_CDO_MODE_DATA_LANE_8_15 NI_M_CDO_MODE_DATA_LANE(1) +#define NI_M_CDO_MODE_DATA_LANE_16_23 NI_M_CDO_MODE_DATA_LANE(2) +#define NI_M_CDO_MODE_DATA_LANE_24_31 NI_M_CDO_MODE_DATA_LANE(3) +#define NI_M_CDO_MODE_FIFO_MODE BIT(11) +#define NI_M_CDO_MODE_POLARITY BIT(10) +#define NI_M_CDO_MODE_HALT_ON_ERROR BIT(9) +#define NI_M_CDO_MODE_RETRANSMIT BIT(8) +#define NI_M_CDO_MODE_SAMPLE_SRC(x) (((x) & 0x3f) << 0) +#define NI_M_CDO_MODE_SAMPLE_SRC_MASK NI_M_CDO_MODE_SAMPLE_SRC(0x3f) +#define NI_M_CDI_MASK_ENA_REG 0x230 +#define NI_M_CDO_MASK_ENA_REG 0x234 +#define NI_M_STATIC_AI_CTRL_REG(x) ((x) ? (0x260 + (x)) : 0x064) +#define NI_M_AO_REF_ATTENUATION_REG(x) (0x264 + (x)) +#define NI_M_AO_REF_ATTENUATION_X5 BIT(0) + +enum { + ai_gain_16 = 0, + ai_gain_8, + ai_gain_14, + ai_gain_4, + ai_gain_611x, + ai_gain_622x, + ai_gain_628x, + ai_gain_6143 }; -static inline unsigned int DACx_Direct_Data_671x(int channel) -{ - return channel; -} -enum AO_Misc_611x_Bits { - CLEAR_WG = 1, +enum caldac_enum { + caldac_none = 0, + mb88341, + dac8800, + dac8043, + ad8522, + ad8804, + ad8842, + ad8804_debug }; -enum cs5529_configuration_bits { - CSCFG_CAL_CONTROL_MASK = 0x7, - CSCFG_SELF_CAL_OFFSET = 0x1, - CSCFG_SELF_CAL_GAIN = 0x2, - CSCFG_SELF_CAL_OFFSET_GAIN = 0x3, - CSCFG_SYSTEM_CAL_OFFSET = 0x5, - CSCFG_SYSTEM_CAL_GAIN = 0x6, - CSCFG_DONE = 1 << 3, - CSCFG_POWER_SAVE_SELECT = 1 << 4, - CSCFG_PORT_MODE = 1 << 5, - CSCFG_RESET_VALID = 1 << 6, - CSCFG_RESET = 1 << 7, - CSCFG_UNIPOLAR = 1 << 12, - CSCFG_WORD_RATE_2180_CYCLES = 0x0 << 13, - CSCFG_WORD_RATE_1092_CYCLES = 0x1 << 13, - CSCFG_WORD_RATE_532_CYCLES = 0x2 << 13, - CSCFG_WORD_RATE_388_CYCLES = 0x3 << 13, - CSCFG_WORD_RATE_324_CYCLES = 0x4 << 13, - CSCFG_WORD_RATE_17444_CYCLES = 0x5 << 13, - CSCFG_WORD_RATE_8724_CYCLES = 0x6 << 13, - CSCFG_WORD_RATE_4364_CYCLES = 0x7 << 13, - CSCFG_WORD_RATE_MASK = 0x7 << 13, - CSCFG_LOW_POWER = 1 << 16, -}; -static inline unsigned int CS5529_CONFIG_DOUT(int output) -{ - return 1 << (18 + output); -} - -static inline unsigned int CS5529_CONFIG_AOUT(int output) -{ - return 1 << (22 + output); -} - -enum cs5529_command_bits { - CSCMD_POWER_SAVE = 0x1, - CSCMD_REGISTER_SELECT_MASK = 0xe, - CSCMD_OFFSET_REGISTER = 0x0, - CSCMD_GAIN_REGISTER = 0x2, - CSCMD_CONFIG_REGISTER = 0x4, - CSCMD_READ = 0x10, - CSCMD_CONTINUOUS_CONVERSIONS = 0x20, - CSCMD_SINGLE_CONVERSION = 0x40, - CSCMD_COMMAND = 0x80, -}; -enum cs5529_status_bits { - CSS_ADC_BUSY = 0x1, - CSS_OSC_DETECT = 0x2, /* indicates adc error */ - CSS_OVERRANGE = 0x4, -}; -#define SerDacLd(x) (0x08<<(x)) - -/* - This is stuff unique to the NI E series drivers, - but I thought I'd put it here anyway. -*/ -enum { ai_gain_16 = - 0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x, - ai_gain_628x, ai_gain_6143 -}; -enum caldac_enum { caldac_none = 0, mb88341, dac8800, dac8043, ad8522, - ad8804, ad8842, ad8804_debug -}; enum ni_reg_type { ni_reg_normal = 0x0, ni_reg_611x = 0x1, @@ -918,467 +941,6 @@ enum ni_reg_type { ni_reg_6143 = 0x20 }; -static const struct comedi_lrange range_ni_E_ao_ext; - -enum m_series_register_offsets { - M_Offset_CDIO_DMA_Select = 0x7, /* write */ - M_Offset_SCXI_Status = 0x7, /* read */ - M_Offset_AI_AO_Select = 0x9, /* write, same offset as e-series */ - M_Offset_SCXI_Serial_Data_In = 0x9, /* read */ - M_Offset_G0_G1_Select = 0xb, /* write, same offset as e-series */ - M_Offset_Misc_Command = 0xf, - M_Offset_SCXI_Serial_Data_Out = 0x11, - M_Offset_SCXI_Control = 0x13, - M_Offset_SCXI_Output_Enable = 0x15, - M_Offset_AI_FIFO_Data = 0x1c, - M_Offset_Static_Digital_Output = 0x24, /* write */ - M_Offset_Static_Digital_Input = 0x24, /* read */ - M_Offset_DIO_Direction = 0x28, - M_Offset_Cal_PWM = 0x40, - M_Offset_AI_Config_FIFO_Data = 0x5e, - M_Offset_Interrupt_C_Enable = 0x88, /* write */ - M_Offset_Interrupt_C_Status = 0x88, /* read */ - M_Offset_Analog_Trigger_Control = 0x8c, - M_Offset_AO_Serial_Interrupt_Enable = 0xa0, - M_Offset_AO_Serial_Interrupt_Ack = 0xa1, /* write */ - M_Offset_AO_Serial_Interrupt_Status = 0xa1, /* read */ - M_Offset_AO_Calibration = 0xa3, - M_Offset_AO_FIFO_Data = 0xa4, - M_Offset_PFI_Filter = 0xb0, - M_Offset_RTSI_Filter = 0xb4, - M_Offset_SCXI_Legacy_Compatibility = 0xbc, - M_Offset_Interrupt_A_Ack = 0x104, /* write */ - M_Offset_AI_Status_1 = 0x104, /* read */ - M_Offset_Interrupt_B_Ack = 0x106, /* write */ - M_Offset_AO_Status_1 = 0x106, /* read */ - M_Offset_AI_Command_2 = 0x108, /* write */ - M_Offset_G01_Status = 0x108, /* read */ - M_Offset_AO_Command_2 = 0x10a, - M_Offset_AO_Status_2 = 0x10c, /* read */ - M_Offset_G0_Command = 0x10c, /* write */ - M_Offset_G1_Command = 0x10e, /* write */ - M_Offset_G0_HW_Save = 0x110, - M_Offset_G0_HW_Save_High = 0x110, - M_Offset_AI_Command_1 = 0x110, - M_Offset_G0_HW_Save_Low = 0x112, - M_Offset_AO_Command_1 = 0x112, - M_Offset_G1_HW_Save = 0x114, - M_Offset_G1_HW_Save_High = 0x114, - M_Offset_G1_HW_Save_Low = 0x116, - M_Offset_AI_Mode_1 = 0x118, - M_Offset_G0_Save = 0x118, - M_Offset_G0_Save_High = 0x118, - M_Offset_AI_Mode_2 = 0x11a, - M_Offset_G0_Save_Low = 0x11a, - M_Offset_AI_SI_Load_A = 0x11c, - M_Offset_G1_Save = 0x11c, - M_Offset_G1_Save_High = 0x11c, - M_Offset_G1_Save_Low = 0x11e, - M_Offset_AI_SI_Load_B = 0x120, /* write */ - M_Offset_AO_UI_Save = 0x120, /* read */ - M_Offset_AI_SC_Load_A = 0x124, /* write */ - M_Offset_AO_BC_Save = 0x124, /* read */ - M_Offset_AI_SC_Load_B = 0x128, /* write */ - M_Offset_AO_UC_Save = 0x128, /* read */ - M_Offset_AI_SI2_Load_A = 0x12c, - M_Offset_AI_SI2_Load_B = 0x130, - M_Offset_G0_Mode = 0x134, - M_Offset_G1_Mode = 0x136, /* write */ - M_Offset_Joint_Status_1 = 0x136, /* read */ - M_Offset_G0_Load_A = 0x138, - M_Offset_Joint_Status_2 = 0x13a, - M_Offset_G0_Load_B = 0x13c, - M_Offset_G1_Load_A = 0x140, - M_Offset_G1_Load_B = 0x144, - M_Offset_G0_Input_Select = 0x148, - M_Offset_G1_Input_Select = 0x14a, - M_Offset_AO_Mode_1 = 0x14c, - M_Offset_AO_Mode_2 = 0x14e, - M_Offset_AO_UI_Load_A = 0x150, - M_Offset_AO_UI_Load_B = 0x154, - M_Offset_AO_BC_Load_A = 0x158, - M_Offset_AO_BC_Load_B = 0x15c, - M_Offset_AO_UC_Load_A = 0x160, - M_Offset_AO_UC_Load_B = 0x164, - M_Offset_Clock_and_FOUT = 0x170, - M_Offset_IO_Bidirection_Pin = 0x172, - M_Offset_RTSI_Trig_Direction = 0x174, - M_Offset_Interrupt_Control = 0x176, - M_Offset_AI_Output_Control = 0x178, - M_Offset_Analog_Trigger_Etc = 0x17a, - M_Offset_AI_START_STOP_Select = 0x17c, - M_Offset_AI_Trigger_Select = 0x17e, - M_Offset_AI_SI_Save = 0x180, /* read */ - M_Offset_AI_DIV_Load_A = 0x180, /* write */ - M_Offset_AI_SC_Save = 0x184, /* read */ - M_Offset_AO_Start_Select = 0x184, /* write */ - M_Offset_AO_Trigger_Select = 0x186, - M_Offset_AO_Mode_3 = 0x18c, - M_Offset_G0_Autoincrement = 0x188, - M_Offset_G1_Autoincrement = 0x18a, - M_Offset_Joint_Reset = 0x190, - M_Offset_Interrupt_A_Enable = 0x192, - M_Offset_Interrupt_B_Enable = 0x196, - M_Offset_AI_Personal = 0x19a, - M_Offset_AO_Personal = 0x19c, - M_Offset_RTSI_Trig_A_Output = 0x19e, - M_Offset_RTSI_Trig_B_Output = 0x1a0, - M_Offset_RTSI_Shared_MUX = 0x1a2, - M_Offset_AO_Output_Control = 0x1ac, - M_Offset_AI_Mode_3 = 0x1ae, - M_Offset_Configuration_Memory_Clear = 0x1a4, - M_Offset_AI_FIFO_Clear = 0x1a6, - M_Offset_AO_FIFO_Clear = 0x1a8, - M_Offset_G0_Counting_Mode = 0x1b0, - M_Offset_G1_Counting_Mode = 0x1b2, - M_Offset_G0_Second_Gate = 0x1b4, - M_Offset_G1_Second_Gate = 0x1b6, - M_Offset_G0_DMA_Config = 0x1b8, /* write */ - M_Offset_G0_DMA_Status = 0x1b8, /* read */ - M_Offset_G1_DMA_Config = 0x1ba, /* write */ - M_Offset_G1_DMA_Status = 0x1ba, /* read */ - M_Offset_G0_MSeries_ABZ = 0x1c0, - M_Offset_G1_MSeries_ABZ = 0x1c2, - M_Offset_Clock_and_Fout2 = 0x1c4, - M_Offset_PLL_Control = 0x1c6, - M_Offset_PLL_Status = 0x1c8, - M_Offset_PFI_Output_Select_1 = 0x1d0, - M_Offset_PFI_Output_Select_2 = 0x1d2, - M_Offset_PFI_Output_Select_3 = 0x1d4, - M_Offset_PFI_Output_Select_4 = 0x1d6, - M_Offset_PFI_Output_Select_5 = 0x1d8, - M_Offset_PFI_Output_Select_6 = 0x1da, - M_Offset_PFI_DI = 0x1dc, - M_Offset_PFI_DO = 0x1de, - M_Offset_AI_Config_FIFO_Bypass = 0x218, - M_Offset_SCXI_DIO_Enable = 0x21c, - M_Offset_CDI_FIFO_Data = 0x220, /* read */ - M_Offset_CDO_FIFO_Data = 0x220, /* write */ - M_Offset_CDIO_Status = 0x224, /* read */ - M_Offset_CDIO_Command = 0x224, /* write */ - M_Offset_CDI_Mode = 0x228, - M_Offset_CDO_Mode = 0x22c, - M_Offset_CDI_Mask_Enable = 0x230, - M_Offset_CDO_Mask_Enable = 0x234, -}; -static inline int M_Offset_AO_Waveform_Order(int channel) -{ - return 0xc2 + 0x4 * channel; -}; - -static inline int M_Offset_AO_Config_Bank(int channel) -{ - return 0xc3 + 0x4 * channel; -}; - -static inline int M_Offset_DAC_Direct_Data(int channel) -{ - return 0xc0 + 0x4 * channel; -} - -static inline int M_Offset_Gen_PWM(int channel) -{ - return 0x44 + 0x2 * channel; -} - -static inline int M_Offset_Static_AI_Control(int i) -{ - int offset[] = { - 0x64, - 0x261, - 0x262, - 0x263, - }; - if (((unsigned)i) >= ARRAY_SIZE(offset)) { - pr_err("%s: invalid channel=%i\n", __func__, i); - return offset[0]; - } - return offset[i]; -}; - -static inline int M_Offset_AO_Reference_Attenuation(int channel) -{ - int offset[] = { - 0x264, - 0x265, - 0x266, - 0x267 - }; - if (((unsigned)channel) >= ARRAY_SIZE(offset)) { - pr_err("%s: invalid channel=%i\n", __func__, channel); - return offset[0]; - } - return offset[channel]; -}; - -static inline unsigned M_Offset_PFI_Output_Select(unsigned n) -{ - if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) { - pr_err("%s: invalid pfi output select register=%i\n", - __func__, n); - return M_Offset_PFI_Output_Select_1; - } - return M_Offset_PFI_Output_Select_1 + (n - 1) * 2; -} - -enum MSeries_AI_Config_FIFO_Data_Bits { - MSeries_AI_Config_Channel_Type_Mask = 0x7 << 6, - MSeries_AI_Config_Channel_Type_Calibration_Bits = 0x0, - MSeries_AI_Config_Channel_Type_Differential_Bits = 0x1 << 6, - MSeries_AI_Config_Channel_Type_Common_Ref_Bits = 0x2 << 6, - MSeries_AI_Config_Channel_Type_Ground_Ref_Bits = 0x3 << 6, - MSeries_AI_Config_Channel_Type_Aux_Bits = 0x5 << 6, - MSeries_AI_Config_Channel_Type_Ghost_Bits = 0x7 << 6, - MSeries_AI_Config_Polarity_Bit = 0x1000, /* 0 for 2's complement encoding */ - MSeries_AI_Config_Dither_Bit = 0x2000, - MSeries_AI_Config_Last_Channel_Bit = 0x4000, -}; -static inline unsigned MSeries_AI_Config_Channel_Bits(unsigned channel) -{ - return channel & 0xf; -} - -static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type, - unsigned channel) -{ - unsigned bits = channel & 0x30; - if (reg_type == ni_reg_622x) { - if (channel & 0x40) - bits |= 0x400; - } - return bits; -} - -static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range) -{ - return (range & 0x7) << 9; -} - -enum MSeries_Clock_and_Fout2_Bits { - MSeries_PLL_In_Source_Select_RTSI0_Bits = 0xb, - MSeries_PLL_In_Source_Select_Star_Trigger_Bits = 0x14, - MSeries_PLL_In_Source_Select_RTSI7_Bits = 0x1b, - MSeries_PLL_In_Source_Select_PXI_Clock10 = 0x1d, - MSeries_PLL_In_Source_Select_Mask = 0x1f, - MSeries_Timebase1_Select_Bit = 0x20, /* use PLL for timebase 1 */ - MSeries_Timebase3_Select_Bit = 0x40, /* use PLL for timebase 3 */ - /* use 10MHz instead of 20MHz for RTSI clock frequency. Appears - to have no effect, at least on pxi-6281, which always uses - 20MHz rtsi clock frequency */ - MSeries_RTSI_10MHz_Bit = 0x80 -}; -static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned - RTSI_channel) -{ - if (RTSI_channel > 7) { - pr_err("%s: bug, invalid RTSI_channel=%i\n", __func__, - RTSI_channel); - return 0; - } - if (RTSI_channel == 7) - return MSeries_PLL_In_Source_Select_RTSI7_Bits; - else - return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel; -} - -enum MSeries_PLL_Control_Bits { - MSeries_PLL_Enable_Bit = 0x1000, - MSeries_PLL_VCO_Mode_200_325MHz_Bits = 0x0, - MSeries_PLL_VCO_Mode_175_225MHz_Bits = 0x2000, - MSeries_PLL_VCO_Mode_100_225MHz_Bits = 0x4000, - MSeries_PLL_VCO_Mode_75_150MHz_Bits = 0x6000, -}; -static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor) -{ - static const unsigned max_divisor = 0x10; - if (divisor < 1 || divisor > max_divisor) { - pr_err("%s: bug, invalid divisor=%i\n", __func__, divisor); - return 0; - } - return (divisor & 0xf) << 8; -} - -static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier) -{ - static const unsigned max_multiplier = 0x100; - if (multiplier < 1 || multiplier > max_multiplier) { - pr_err("%s: bug, invalid multiplier=%i\n", __func__, - multiplier); - return 0; - } - return multiplier & 0xff; -} - -enum MSeries_PLL_Status { - MSeries_PLL_Locked_Bit = 0x1 -}; - -enum MSeries_AI_Config_FIFO_Bypass_Bits { - MSeries_AI_Bypass_Channel_Mask = 0x7, - MSeries_AI_Bypass_Bank_Mask = 0x78, - MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380, - MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00, - MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000, - MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000, - MSeries_AI_Bypass_Gain_Mask = 0x1c0000, - MSeries_AI_Bypass_Dither_Bit = 0x200000, - MSeries_AI_Bypass_Polarity_Bit = 0x400000, /* 0 for 2's complement encoding */ - MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000 -}; -static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int - calibration_source) -{ - return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask; -} - -static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int - calibration_source) -{ - return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask; -} - -static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain) -{ - return (gain << 18) & MSeries_AI_Bypass_Gain_Mask; -} - -enum MSeries_AO_Config_Bank_Bits { - MSeries_AO_DAC_Offset_Select_Mask = 0x7, - MSeries_AO_DAC_Offset_0V_Bits = 0x0, - MSeries_AO_DAC_Offset_5V_Bits = 0x1, - MSeries_AO_DAC_Reference_Mask = 0x38, - MSeries_AO_DAC_Reference_10V_Internal_Bits = 0x0, - MSeries_AO_DAC_Reference_5V_Internal_Bits = 0x8, - MSeries_AO_Update_Timed_Bit = 0x40, - MSeries_AO_Bipolar_Bit = 0x80 /* turns on 2's complement encoding */ -}; - -enum MSeries_AO_Reference_Attenuation_Bits { - MSeries_Attenuate_x5_Bit = 0x1 -}; - -static inline unsigned MSeries_Cal_PWM_High_Time_Bits(unsigned count) -{ - return (count << 16) & 0xffff0000; -} - -static inline unsigned MSeries_Cal_PWM_Low_Time_Bits(unsigned count) -{ - return count & 0xffff; -} - -static inline unsigned MSeries_PFI_Output_Select_Mask(unsigned channel) -{ - return 0x1f << (channel % 3) * 5; -}; - -static inline unsigned MSeries_PFI_Output_Select_Bits(unsigned channel, - unsigned source) -{ - return (source & 0x1f) << ((channel % 3) * 5); -}; - -/* inverse to MSeries_PFI_Output_Select_Bits */ -static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel, - unsigned bits) -{ - return (bits >> ((channel % 3) * 5)) & 0x1f; -}; - -static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel) -{ - return 0x3 << (channel * 2); -} - -static inline unsigned MSeries_PFI_Filter_Select_Bits(unsigned channel, - unsigned filter) -{ - return (filter << (channel * - 2)) & MSeries_PFI_Filter_Select_Mask(channel); -} - -enum CDIO_DMA_Select_Bits { - CDI_DMA_Select_Shift = 0, - CDI_DMA_Select_Mask = 0xf, - CDO_DMA_Select_Shift = 4, - CDO_DMA_Select_Mask = 0xf << CDO_DMA_Select_Shift -}; - -enum CDIO_Status_Bits { - CDO_FIFO_Empty_Bit = 0x1, - CDO_FIFO_Full_Bit = 0x2, - CDO_FIFO_Request_Bit = 0x4, - CDO_Overrun_Bit = 0x8, - CDO_Underflow_Bit = 0x10, - CDI_FIFO_Empty_Bit = 0x10000, - CDI_FIFO_Full_Bit = 0x20000, - CDI_FIFO_Request_Bit = 0x40000, - CDI_Overrun_Bit = 0x80000, - CDI_Overflow_Bit = 0x100000 -}; - -enum CDIO_Command_Bits { - CDO_Disarm_Bit = 0x1, - CDO_Arm_Bit = 0x2, - CDI_Disarm_Bit = 0x4, - CDI_Arm_Bit = 0x8, - CDO_Reset_Bit = 0x10, - CDI_Reset_Bit = 0x20, - CDO_Error_Interrupt_Enable_Set_Bit = 0x40, - CDO_Error_Interrupt_Enable_Clear_Bit = 0x80, - CDI_Error_Interrupt_Enable_Set_Bit = 0x100, - CDI_Error_Interrupt_Enable_Clear_Bit = 0x200, - CDO_FIFO_Request_Interrupt_Enable_Set_Bit = 0x400, - CDO_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x800, - CDI_FIFO_Request_Interrupt_Enable_Set_Bit = 0x1000, - CDI_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x2000, - CDO_Error_Interrupt_Confirm_Bit = 0x4000, - CDI_Error_Interrupt_Confirm_Bit = 0x8000, - CDO_Empty_FIFO_Interrupt_Enable_Set_Bit = 0x10000, - CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit = 0x20000, - CDO_SW_Update_Bit = 0x80000, - CDI_SW_Update_Bit = 0x100000 -}; - -enum CDI_Mode_Bits { - CDI_Sample_Source_Select_Mask = 0x3f, - CDI_Halt_On_Error_Bit = 0x200, - CDI_Polarity_Bit = 0x400, /* sample clock on falling edge */ - CDI_FIFO_Mode_Bit = 0x800, /* set for half full mode, clear for not empty mode */ - CDI_Data_Lane_Mask = 0x3000, /* data lanes specify which dio channels map to byte or word accesses to the dio fifos */ - CDI_Data_Lane_0_15_Bits = 0x0, - CDI_Data_Lane_16_31_Bits = 0x1000, - CDI_Data_Lane_0_7_Bits = 0x0, - CDI_Data_Lane_8_15_Bits = 0x1000, - CDI_Data_Lane_16_23_Bits = 0x2000, - CDI_Data_Lane_24_31_Bits = 0x3000 -}; - -enum CDO_Mode_Bits { - CDO_Sample_Source_Select_Mask = 0x3f, - CDO_Retransmit_Bit = 0x100, - CDO_Halt_On_Error_Bit = 0x200, - CDO_Polarity_Bit = 0x400, /* sample clock on falling edge */ - CDO_FIFO_Mode_Bit = 0x800, /* set for half full mode, clear for not full mode */ - CDO_Data_Lane_Mask = 0x3000, /* data lanes specify which dio channels map to byte or word accesses to the dio fifos */ - CDO_Data_Lane_0_15_Bits = 0x0, - CDO_Data_Lane_16_31_Bits = 0x1000, - CDO_Data_Lane_0_7_Bits = 0x0, - CDO_Data_Lane_8_15_Bits = 0x1000, - CDO_Data_Lane_16_23_Bits = 0x2000, - CDO_Data_Lane_24_31_Bits = 0x3000 -}; - -enum Interrupt_C_Enable_Bits { - Interrupt_Group_C_Enable_Bit = 0x1 -}; - -enum Interrupt_C_Status_Bits { - Interrupt_Group_C_Status_Bit = 0x1 -}; - -#define M_SERIES_EEPROM_SIZE 1024 - struct ni_board_struct { const char *name; int device_id; @@ -1405,9 +967,13 @@ struct ni_board_struct { enum caldac_enum caldac[3]; }; -#define MAX_N_CALDACS 34 -#define MAX_N_AO_CHAN 8 -#define NUM_GPCT 2 +#define MAX_N_CALDACS 34 +#define MAX_N_AO_CHAN 8 +#define NUM_GPCT 2 + +#define NUM_PFI_OUTPUT_SELECT_REGS 6 + +#define M_SERIES_EEPROM_SIZE 1024 struct ni_private { unsigned short dio_output; @@ -1415,8 +981,11 @@ struct ni_private { int aimode; unsigned int ai_calib_source; unsigned int ai_calib_source_enabled; + /* protects access to windowed registers */ spinlock_t window_lock; + /* protects interrupt/dma register access */ spinlock_t soft_reg_copy_lock; + /* protects mite DMA channel request/release */ spinlock_t mite_channel_lock; int changain_state; @@ -1488,4 +1057,6 @@ struct ni_private { unsigned int is_6713:1; }; +static const struct comedi_lrange range_ni_E_ao_ext; + #endif /* _COMEDI_NI_STC_H */ diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 03a3fd6cd918..48f6cdf440b9 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -507,11 +507,11 @@ static const struct pcl812_board boardtypes[] = { struct pcl812_private { struct comedi_isadma *dma; - unsigned char range_correction; /* =1 we must add 1 to range number */ + unsigned char range_correction; /* =1 we must add 1 to range number */ unsigned int last_ai_chanspec; - unsigned char mode_reg_int; /* there is stored INT number for some card */ - unsigned int ai_poll_ptr; /* how many sampes transfer poll */ - unsigned int max_812_ai_mode0_rangewait; /* setling time for gain */ + unsigned char mode_reg_int; /* stored INT number for some cards */ + unsigned int ai_poll_ptr; /* how many samples transfer poll */ + unsigned int max_812_ai_mode0_rangewait; /* settling time for gain */ unsigned int use_diff:1; unsigned int use_mpc508:1; unsigned int use_ext_trg:1; @@ -1155,7 +1155,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* we need an IRQ to do DMA on channel 3 or 1 */ if (dev->irq && board->has_dma) - pcl812_alloc_dma(dev, it->options[2]); + pcl812_alloc_dma(dev, it->options[2]); /* differential analog inputs? */ switch (board->board_type) { diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 1ccb2f19f4be..781b321587dc 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -323,7 +323,7 @@ static int check_channel_list(struct comedi_device *dev, /* check whole chanlist */ for (i = 0, segpos = 0; i < chanlen; i++) { - if (chanlist[i] != chansegment[i % seglen]) { + if (chanlist[i] != chansegment[i % seglen]) { dev_dbg(dev->class_dev, "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", i, CR_CHAN(chansegment[i]), diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 6766d5a91a90..26b0446d943a 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -290,8 +290,7 @@ static struct toklist dgap_tlist[] = { /* * dgap_sindex: much like index(), but it looks for a match of any character in - * the group, and returns that position. If the first character is a ^, then - * this will match the first occurrence not in that group. + * the group, and returns that position. */ static char *dgap_sindex(char *string, char *group) { @@ -300,23 +299,11 @@ static char *dgap_sindex(char *string, char *group) if (!string || !group) return NULL; - if (*group == '^') { - group++; - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - break; - } - if (*ptr == '\0') + for (; *string; string++) { + for (ptr = group; *ptr; ptr++) { + if (*ptr == *string) return string; } - } else { - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - return string; - } - } } return NULL; @@ -2658,7 +2645,7 @@ static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) * dgap_wmove - Write data to FEP buffer. * * ch - Pointer to channel structure. - * buf - Poiter to characters to be moved. + * buf - Pointer to characters to be moved. * cnt - Number of characters to move. * *=======================================================================*/ @@ -6987,9 +6974,62 @@ cleanup_brd: return rc; } +/* + * dgap_cleanup_board() + * + * Free all the memory associated with a board + */ +static void dgap_cleanup_board(struct board_t *brd) +{ + unsigned int i; + + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return; + + dgap_free_irq(brd); + + tasklet_kill(&brd->helper_tasklet); + + dgap_unmap(brd); + + /* Free all allocated channels structs */ + for (i = 0; i < MAXPORTS ; i++) + kfree(brd->channels[i]); + + kfree(brd->flipbuf); + kfree(brd->flipflagbuf); + + dgap_board[brd->boardnum] = NULL; + + kfree(brd); +} + static void dgap_remove_one(struct pci_dev *dev) { - /* Do Nothing */ + unsigned int i; + ulong lock_flags; + struct pci_driver *drv = to_pci_driver(dev->dev.driver); + + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); + + /* Turn off poller right away. */ + del_timer_sync(&dgap_poll_timer); + + dgap_remove_driver_sysfiles(drv); + + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + + for (i = 0; i < dgap_numboards; ++i) { + dgap_remove_ports_sysfiles(dgap_board[i]); + dgap_cleanup_tty(dgap_board[i]); + dgap_cleanup_board(dgap_board[i]); + } + + dgap_cleanup_nodes(); } static struct pci_driver dgap_driver = { @@ -7071,37 +7111,6 @@ static void dgap_stop(void) unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); } -/* - * dgap_cleanup_board() - * - * Free all the memory associated with a board - */ -static void dgap_cleanup_board(struct board_t *brd) -{ - unsigned int i; - - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return; - - dgap_free_irq(brd); - - tasklet_kill(&brd->helper_tasklet); - - dgap_unmap(brd); - - /* Free all allocated channels structs */ - for (i = 0; i < MAXPORTS ; i++) - kfree(brd->channels[i]); - - kfree(brd->flipbuf); - kfree(brd->flipflagbuf); - - dgap_board[brd->boardnum] = NULL; - - kfree(brd); -} - - /************************************************************************ * * Driver load/unload functions @@ -7150,30 +7159,6 @@ err_stop: */ static void dgap_cleanup_module(void) { - unsigned int i; - ulong lock_flags; - - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_stop = 1; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgap_poll_timer); - - dgap_remove_driver_sysfiles(&dgap_driver); - - device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); - class_destroy(dgap_class); - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); - - for (i = 0; i < dgap_numboards; ++i) { - dgap_remove_ports_sysfiles(dgap_board[i]); - dgap_cleanup_tty(dgap_board[i]); - dgap_cleanup_board(dgap_board[i]); - } - - dgap_cleanup_nodes(); - if (dgap_numboards) pci_unregister_driver(&dgap_driver); } diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index a2e5b26c673a..e707ed5fe949 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -172,7 +172,7 @@ /* * Define a local default termios struct. All ports will be created * with this termios initially. This is the same structure that is defined - * as the default in tty_io.c with the same settings overriden as in serial.c + * as the default in tty_io.c with the same settings overridden as in serial.c * * In short, this should match the internal serial ports' defaults. */ diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 805dc617e3a7..7546aff65002 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -355,7 +355,6 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) } } - kfree(brd->flipbuf); dgnc_Board[brd->boardnum] = NULL; @@ -581,14 +580,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->msgbuf_head = NULL; spin_unlock_irqrestore(&dgnc_global_lock, flags); - /* - * allocate flip buffer for board. - * - * Okay to malloc with GFP_KERNEL, we are not at interrupt - * context, and there are no locks held. - */ - brd->flipbuf = kzalloc(MYFLIPLEN, GFP_KERNEL); - wake_up_interruptible(&brd->state_wait); return 0; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index f77fed57b873..ebb34398885d 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -66,7 +66,6 @@ /* 4 extra for alignment play space */ #define WRITEBUFLEN ((4096) + 4) -#define MYFLIPLEN N_TTY_BUF_SIZE #define dgnc_jiffies_from_ms(a) (((a) * HZ) / 1000) @@ -212,8 +211,6 @@ struct dgnc_board { uint TtyRefCnt; - char *flipbuf; /* Our flip buffer, alloced if board is found */ - u16 dpatype; /* The board "type", as defined by DPA */ u16 dpastatus; /* The board "status", as defined by DPA */ @@ -288,7 +285,6 @@ struct un_t { #define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */ #define CH_BREAK_SENDING 0x1000 /* Break is being sent */ #define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ -#define CH_FLIPBUF_IN_USE 0x4000 /* Channel's flipbuf is in use */ #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ #define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */ #define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */ diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 65551d190515..44db8703eba4 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -53,7 +53,8 @@ static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf) return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick); } -static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, const char *buf, size_t count) +static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, + const char *buf, size_t count) { int ret; @@ -62,7 +63,8 @@ static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, const char return -EINVAL; return count; } -static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, dgnc_driver_pollrate_store); +static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, + dgnc_driver_pollrate_store); void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) @@ -104,7 +106,8 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) -static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, + char *buf) { struct dgnc_board *bd; int count = 0; @@ -112,7 +115,8 @@ static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, ch DGNC_VERIFY_BOARD(p, bd); - count += sprintf(buf + count, "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F"); + count += sprintf(buf + count, + "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for (i = 0; i < 0x40 * 2; i++) { if (!(i % 16)) count += sprintf(buf + count, "\n%04X ", i * 2); @@ -124,7 +128,8 @@ static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, ch } static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL); -static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_serial_number_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -141,7 +146,8 @@ static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL); -static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_state_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -159,7 +165,8 @@ static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute * static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL); -static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_baud_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -169,14 +176,17 @@ static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *a for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, - "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud); + "%d %d\n", bd->channels[i]->ch_portnum, + bd->channels[i]->ch_old_baud); } return count; } static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL); -static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_msignals_show(struct device *p, + struct device_attribute *attr, + char *buf) { struct dgnc_board *bd; int count = 0; @@ -187,7 +197,8 @@ static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribut for (i = 0; i < bd->nasync; i++) { if (bd->channels[i]->ch_open_count) { count += snprintf(buf + count, PAGE_SIZE - count, - "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum, + "%d %s %s %s %s %s %s\n", + bd->channels[i]->ch_portnum, (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "", (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "", (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "", @@ -204,7 +215,8 @@ static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribut static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL); -static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_iflag_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -214,14 +226,16 @@ static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute * for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_c_iflag); } return count; } static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL); -static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_cflag_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -231,14 +245,16 @@ static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute * for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_c_cflag); } return count; } static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL); -static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_oflag_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -248,14 +264,16 @@ static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute * for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_oflag); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_c_oflag); } return count; } static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL); -static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_lflag_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -265,14 +283,17 @@ static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute * for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_c_lflag); } return count; } static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL); -static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_digi_flag_show(struct device *p, + struct device_attribute *attr, + char *buf) { struct dgnc_board *bd; int count = 0; @@ -282,14 +303,16 @@ static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribu for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_digi.digi_flags); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_digi.digi_flags); } return count; } static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL); -static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_rxcount_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -299,14 +322,16 @@ static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_rxcount); } return count; } static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL); -static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf) +static ssize_t dgnc_ports_txcount_show(struct device *p, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; int count = 0; @@ -316,7 +341,8 @@ static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute for (i = 0; i < bd->nasync; i++) { count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n", - bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount); + bd->channels[i]->ch_portnum, + bd->channels[i]->ch_txcount); } return count; } @@ -366,7 +392,8 @@ void dgnc_remove_ports_sysfiles(struct dgnc_board *bd) } -static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_state_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -386,12 +413,14 @@ static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *at if (bd->state != BOARD_READY) return 0; - return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed"); + return snprintf(buf, PAGE_SIZE, "%s", + un->un_open_count ? "Open" : "Closed"); } static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL); -static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_baud_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -416,7 +445,8 @@ static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *att static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL); -static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_msignals_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -450,7 +480,8 @@ static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL); -static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_iflag_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -475,7 +506,8 @@ static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *at static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL); -static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_cflag_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -500,7 +532,8 @@ static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *at static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL); -static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_oflag_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -525,7 +558,8 @@ static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *at static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL); -static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_lflag_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -550,7 +584,8 @@ static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *at static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL); -static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_digi_flag_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -575,7 +610,8 @@ static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL); -static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_rxcount_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -600,7 +636,8 @@ static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute * static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL); -static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_txcount_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; @@ -625,7 +662,8 @@ static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute * static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL); -static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t dgnc_tty_name_show(struct device *d, + struct device_attribute *attr, char *buf) { struct dgnc_board *bd; struct channel_t *ch; diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h index d637a7802168..cf9dcae7cc3f 100644 --- a/drivers/staging/dgnc/digi.h +++ b/drivers/staging/dgnc/digi.h @@ -130,19 +130,19 @@ struct digi_getcounter { #define BD_RUNNING 0x0 #define BD_NOFEP 0x5 -#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */ -#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */ +#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */ +#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */ #define DIGI_REALPORT_GETBUFFERS (('e'<<8) | 108) #define DIGI_REALPORT_SENDIMMEDIATE (('e'<<8) | 109) #define DIGI_REALPORT_GETCOUNTERS (('e'<<8) | 110) #define DIGI_REALPORT_GETEVENTS (('e'<<8) | 111) -#define EV_OPU 0x0001 /* !<Output paused by client */ -#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */ -#define EV_IPU 0x0010 /* !<Input paused unconditionally by user */ -#define EV_IPS 0x0020 /* !<Input paused by high/low water marks */ -#define EV_TXB 0x0040 /* !<Transmit break pending */ +#define EV_OPU 0x0001 /* !<Output paused by client */ +#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */ +#define EV_IPU 0x0010 /* !<Input paused unconditionally by user */ +#define EV_IPS 0x0020 /* !<Input paused by high/low water marks */ +#define EV_TXB 0x0040 /* !<Transmit break pending */ /* * This structure holds data needed for the intelligent <--> nonintelligent diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 163ca56a11ab..4178d96f94cf 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2249,8 +2249,6 @@ static int _nbu2ss_pullup(struct nbu2ss_udc *udc, int is_on) if (is_on) { /* D+ Pullup */ -/* INFO(" --- D+ Pullup\n"); */ - if (udc->driver) { reg_dt = (_nbu2ss_readl(&udc->p_regs->USB_CONTROL) | PUE2) & ~(u32)CONNECTB; @@ -2260,8 +2258,6 @@ static int _nbu2ss_pullup(struct nbu2ss_udc *udc, int is_on) } else { /* D+ Pulldown */ -/* INFO(" --- D+ Pulldown\n"); */ - reg_dt = (_nbu2ss_readl(&udc->p_regs->USB_CONTROL) | CONNECTB) & ~(u32)PUE2; @@ -2731,8 +2727,6 @@ static int nbu2ss_ep_queue( ep = container_of(_ep, struct nbu2ss_ep, ep); udc = ep->udc; -/* INFO("=== %s(ep%d), zero=%d\n", __func__, ep->epnum, _req->zero); */ - if (udc->vbus_active == 0) { dev_info(udc->dev, "Can't ep_queue (VBUS OFF)\n"); return -ESHUTDOWN; @@ -2808,8 +2802,6 @@ static int nbu2ss_ep_dequeue( struct nbu2ss_udc *udc; unsigned long flags; - /*INFO("=== %s()\n", __func__);*/ - /* catch various bogus parameters */ if ((_ep == NULL) || (_req == NULL)) { /* pr_err("%s, bad param(1)\n", __func__); */ @@ -2855,8 +2847,6 @@ static int nbu2ss_ep_set_halt(struct usb_ep *_ep, int value) struct nbu2ss_ep *ep; struct nbu2ss_udc *udc; -/* INFO("=== %s()\n", __func__); */ - if (!_ep) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -2909,8 +2899,6 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) unsigned long flags; struct fc_regs *preg; -/* INFO("=== %s()\n", __func__); */ - if (!_ep) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -2957,8 +2945,6 @@ static void nbu2ss_ep_fifo_flush(struct usb_ep *_ep) struct nbu2ss_udc *udc; unsigned long flags; -/* INFO("=== %s()\n", __func__); */ - if (!_ep) { pr_err("udc: %s, bad param\n", __func__); return; @@ -3013,8 +2999,6 @@ static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget) u32 data; struct nbu2ss_udc *udc; -/* INFO("=== %s()\n", __func__); */ - if (pgadget == NULL) { pr_err("udc: %s, bad param\n", __func__); return -EINVAL; @@ -3043,8 +3027,6 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget) struct nbu2ss_udc *udc; -/* INFO("=== %s()\n", __func__); */ - if (pgadget == NULL) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -3083,8 +3065,6 @@ static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, struct nbu2ss_udc *udc; unsigned long flags; -/* INFO("=== %s()\n", __func__); */ - if (pgadget == NULL) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -3102,7 +3082,6 @@ static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, /*-------------------------------------------------------------------------*/ static int nbu2ss_gad_vbus_session(struct usb_gadget *pgadget, int is_active) { -/* INFO("=== %s()\n", __func__); */ return 0; } @@ -3112,8 +3091,6 @@ static int nbu2ss_gad_vbus_draw(struct usb_gadget *pgadget, unsigned mA) struct nbu2ss_udc *udc; unsigned long flags; -/* INFO("=== %s()\n", __func__); */ - if (pgadget == NULL) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -3134,8 +3111,6 @@ static int nbu2ss_gad_pullup(struct usb_gadget *pgadget, int is_on) struct nbu2ss_udc *udc; unsigned long flags; -/* INFO("=== %s()\n", __func__); */ - if (pgadget == NULL) { pr_err("%s, bad param\n", __func__); return -EINVAL; @@ -3164,7 +3139,6 @@ static int nbu2ss_gad_ioctl( unsigned code, unsigned long param) { -/* INFO("=== %s()\n", __func__); */ return 0; } diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig index 346f189d871a..d4018780ce58 100644 --- a/drivers/staging/fbtft/Kconfig +++ b/drivers/staging/fbtft/Kconfig @@ -38,6 +38,12 @@ config FB_TFT_HX8353D help Generic Framebuffer support for HX8353D +config FB_TFT_HX8357D + tristate "FB driver for the HX8357D LCD Controller" + depends on FB_TFT + help + Generic Framebuffer support for HX8357D + config FB_TFT_ILI9163 tristate "FB driver for the ILI9163 LCD Controller" depends on FB_TFT diff --git a/drivers/staging/fbtft/Makefile b/drivers/staging/fbtft/Makefile index 9e73beee23f4..554b5260b0ee 100644 --- a/drivers/staging/fbtft/Makefile +++ b/drivers/staging/fbtft/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_FB_TFT_BD663474) += fb_bd663474.o obj-$(CONFIG_FB_TFT_HX8340BN) += fb_hx8340bn.o obj-$(CONFIG_FB_TFT_HX8347D) += fb_hx8347d.o obj-$(CONFIG_FB_TFT_HX8353D) += fb_hx8353d.o +obj-$(CONFIG_FB_TFT_HX8357D) += fb_hx8357d.o obj-$(CONFIG_FB_TFT_ILI9163) += fb_ili9163.o obj-$(CONFIG_FB_TFT_ILI9320) += fb_ili9320.o obj-$(CONFIG_FB_TFT_ILI9325) += fb_ili9325.o diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index 8f5af1db852c..94dd49ce18de 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -94,7 +94,7 @@ static void reset(struct fbtft_par *par) if (par->gpio.reset == -1) return; - fbtft_dev_dbg(DEBUG_RESET, par, par->info->device, "%s()\n", __func__); + dev_dbg(par->info->device, "%s()\n", __func__); gpio_set_value(par->gpio.reset, 0); udelay(20); @@ -107,7 +107,7 @@ static int verify_gpios(struct fbtft_par *par) { int i; - fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par, par->info->device, + dev_dbg(par->info->device, "%s()\n", __func__); if (par->EPIN < 0) { @@ -145,7 +145,7 @@ static int verify_gpios(struct fbtft_par *par) static unsigned long request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio) { - fbtft_dev_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, par->info->device, + dev_dbg(par->info->device, "%s('%s')\n", __func__, gpio->name); if (strcasecmp(gpio->name, "wr") == 0) { diff --git a/drivers/staging/fbtft/fb_hx8357d.c b/drivers/staging/fbtft/fb_hx8357d.c new file mode 100644 index 000000000000..8c7bb3ac8030 --- /dev/null +++ b/drivers/staging/fbtft/fb_hx8357d.c @@ -0,0 +1,222 @@ +/* + * FB driver for the HX8357D LCD Controller + * Copyright (C) 2015 Adafruit Industries + * + * Based on the HX8347D FB driver + * Copyright (C) 2013 Christian Vogelgsang + * + * Based on driver code found here: https://github.com/watterott/r61505u-Adapter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> + +#include "fbtft.h" +#include "fb_hx8357d.h" + +#define DRVNAME "fb_hx8357d" +#define WIDTH 320 +#define HEIGHT 480 + + +static int init_display(struct fbtft_par *par) +{ + fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); + + par->fbtftops.reset(par); + + /* Reset things like Gamma */ + write_reg(par, HX8357B_SWRESET); + usleep_range(5000, 7000); + + /* setextc */ + write_reg(par, HX8357D_SETC, 0xFF, 0x83, 0x57); + msleep(150); + + /* setRGB which also enables SDO */ + write_reg(par, HX8357_SETRGB, 0x00, 0x00, 0x06, 0x06); + + /* -1.52V */ + write_reg(par, HX8357D_SETCOM, 0x25); + + /* Normal mode 70Hz, Idle mode 55 Hz */ + write_reg(par, HX8357_SETOSC, 0x68); + + /* Set Panel - BGR, Gate direction swapped */ + write_reg(par, HX8357_SETPANEL, 0x05); + + write_reg(par, HX8357_SETPWR1, + 0x00, /* Not deep standby */ + 0x15, /* BT */ + 0x1C, /* VSPR */ + 0x1C, /* VSNR */ + 0x83, /* AP */ + 0xAA); /* FS */ + + write_reg(par, HX8357D_SETSTBA, + 0x50, /* OPON normal */ + 0x50, /* OPON idle */ + 0x01, /* STBA */ + 0x3C, /* STBA */ + 0x1E, /* STBA */ + 0x08); /* GEN */ + + write_reg(par, HX8357D_SETCYC, + 0x02, /* NW 0x02 */ + 0x40, /* RTN */ + 0x00, /* DIV */ + 0x2A, /* DUM */ + 0x2A, /* DUM */ + 0x0D, /* GDON */ + 0x78); /* GDOFF */ + + write_reg(par, HX8357D_SETGAMMA, + 0x02, + 0x0A, + 0x11, + 0x1d, + 0x23, + 0x35, + 0x41, + 0x4b, + 0x4b, + 0x42, + 0x3A, + 0x27, + 0x1B, + 0x08, + 0x09, + 0x03, + 0x02, + 0x0A, + 0x11, + 0x1d, + 0x23, + 0x35, + 0x41, + 0x4b, + 0x4b, + 0x42, + 0x3A, + 0x27, + 0x1B, + 0x08, + 0x09, + 0x03, + 0x00, + 0x01); + + /* 16 bit */ + write_reg(par, HX8357_COLMOD, 0x55); + + write_reg(par, HX8357_MADCTL, 0xC0); + + /* TE off */ + write_reg(par, HX8357_TEON, 0x00); + + /* tear line */ + write_reg(par, HX8357_TEARLINE, 0x00, 0x02); + + /* Exit Sleep */ + write_reg(par, HX8357_SLPOUT); + msleep(150); + + /* display on */ + write_reg(par, HX8357_DISPON); + usleep_range(5000, 7000); + + return 0; +} + +static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) +{ + fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, + "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye); + + /* Column addr set */ + write_reg(par, HX8357_CASET, + xs >> 8, xs & 0xff, /* XSTART */ + xe >> 8, xe & 0xff); /* XEND */ + + /* Row addr set */ + write_reg(par, HX8357_PASET, + ys >> 8, ys & 0xff, /* YSTART */ + ye >> 8, ye & 0xff); /* YEND */ + + /* write to RAM */ + write_reg(par, HX8357_RAMWR); +} + +#define HX8357D_MADCTL_MY 0x80 +#define HX8357D_MADCTL_MX 0x40 +#define HX8357D_MADCTL_MV 0x20 +#define HX8357D_MADCTL_ML 0x10 +#define HX8357D_MADCTL_RGB 0x00 +#define HX8357D_MADCTL_BGR 0x08 +#define HX8357D_MADCTL_MH 0x04 +static int set_var(struct fbtft_par *par) +{ + u8 val; + + fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); + + switch (par->info->var.rotate) { + case 270: + val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MX; + break; + case 180: + val = 0; + break; + case 90: + val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MY; + break; + default: + val = HX8357D_MADCTL_MX | HX8357D_MADCTL_MY; + break; + } + + val |= (par->bgr ? HX8357D_MADCTL_RGB : HX8357D_MADCTL_BGR); + + /* Memory Access Control */ + write_reg(par, HX8357_MADCTL, val); + + return 0; +} + +static struct fbtft_display display = { + .regwidth = 8, + .width = WIDTH, + .height = HEIGHT, + .gamma_num = 2, + .gamma_len = 14, + .fbtftops = { + .init_display = init_display, + .set_addr_win = set_addr_win, + .set_var = set_var, + }, +}; +FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8357d", &display); + +MODULE_ALIAS("spi:" DRVNAME); +MODULE_ALIAS("platform:" DRVNAME); +MODULE_ALIAS("spi:hx8357d"); +MODULE_ALIAS("platform:hx8357d"); + +MODULE_DESCRIPTION("FB driver for the HX8357D LCD Controller"); +MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/fbtft/fb_hx8357d.h b/drivers/staging/fbtft/fb_hx8357d.h new file mode 100644 index 000000000000..de05e8cdf04c --- /dev/null +++ b/drivers/staging/fbtft/fb_hx8357d.h @@ -0,0 +1,102 @@ +/*************************************************** + This is our library for the Adafruit ILI9341 Breakout and Shield + ----> http://www.adafruit.com/products/1651 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ + +#ifndef __HX8357_H__ +#define __HX8357_H__ + +#define HX8357D 0xD +#define HX8357B 0xB + +#define HX8357_TFTWIDTH 320 +#define HX8357_TFTHEIGHT 480 + +#define HX8357B_NOP 0x00 +#define HX8357B_SWRESET 0x01 +#define HX8357B_RDDID 0x04 +#define HX8357B_RDDST 0x09 + +#define HX8357B_RDPOWMODE 0x0A +#define HX8357B_RDMADCTL 0x0B +#define HX8357B_RDCOLMOD 0x0C +#define HX8357B_RDDIM 0x0D +#define HX8357B_RDDSDR 0x0F + +#define HX8357_SLPIN 0x10 +#define HX8357_SLPOUT 0x11 +#define HX8357B_PTLON 0x12 +#define HX8357B_NORON 0x13 + +#define HX8357_INVOFF 0x20 +#define HX8357_INVON 0x21 +#define HX8357_DISPOFF 0x28 +#define HX8357_DISPON 0x29 + +#define HX8357_CASET 0x2A +#define HX8357_PASET 0x2B +#define HX8357_RAMWR 0x2C +#define HX8357_RAMRD 0x2E + +#define HX8357B_PTLAR 0x30 +#define HX8357_TEON 0x35 +#define HX8357_TEARLINE 0x44 +#define HX8357_MADCTL 0x36 +#define HX8357_COLMOD 0x3A + +#define HX8357_SETOSC 0xB0 +#define HX8357_SETPWR1 0xB1 +#define HX8357B_SETDISPLAY 0xB2 +#define HX8357_SETRGB 0xB3 +#define HX8357D_SETCOM 0xB6 + +#define HX8357B_SETDISPMODE 0xB4 +#define HX8357D_SETCYC 0xB4 +#define HX8357B_SETOTP 0xB7 +#define HX8357D_SETC 0xB9 + +#define HX8357B_SET_PANEL_DRIVING 0xC0 +#define HX8357D_SETSTBA 0xC0 +#define HX8357B_SETDGC 0xC1 +#define HX8357B_SETID 0xC3 +#define HX8357B_SETDDB 0xC4 +#define HX8357B_SETDISPLAYFRAME 0xC5 +#define HX8357B_GAMMASET 0xC8 +#define HX8357B_SETCABC 0xC9 +#define HX8357_SETPANEL 0xCC + +#define HX8357B_SETPOWER 0xD0 +#define HX8357B_SETVCOM 0xD1 +#define HX8357B_SETPWRNORMAL 0xD2 + +#define HX8357B_RDID1 0xDA +#define HX8357B_RDID2 0xDB +#define HX8357B_RDID3 0xDC +#define HX8357B_RDID4 0xDD + +#define HX8357D_SETGAMMA 0xE0 + +#define HX8357B_SETGAMMA 0xC8 +#define HX8357B_SETPANELRELATED 0xE9 + +/* Color definitions */ +#define HX8357_BLACK 0x0000 +#define HX8357_BLUE 0x001F +#define HX8357_RED 0xF800 +#define HX8357_GREEN 0x07E0 +#define HX8357_CYAN 0x07FF +#define HX8357_MAGENTA 0xF81F +#define HX8357_YELLOW 0xFFE0 +#define HX8357_WHITE 0xFFFF + +#endif /* __HX8357_H__ */ diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index ce645213a539..9cc81412be69 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -486,7 +486,7 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist) index = page->index << PAGE_SHIFT; y_low = index / info->fix.line_length; y_high = (index + PAGE_SIZE - 1) / info->fix.line_length; - fbtft_dev_dbg(DEBUG_DEFERRED_IO, par, info->device, + dev_dbg(info->device, "page->index=%lu y_low=%d y_high=%d\n", page->index, y_low, y_high); if (y_high > info->var.yres - 1) @@ -507,7 +507,7 @@ static void fbtft_fb_fillrect(struct fb_info *info, { struct fbtft_par *par = info->par; - fbtft_dev_dbg(DEBUG_FB_FILLRECT, par, info->dev, + dev_dbg(info->dev, "%s: dx=%d, dy=%d, width=%d, height=%d\n", __func__, rect->dx, rect->dy, rect->width, rect->height); sys_fillrect(info, rect); @@ -520,7 +520,7 @@ static void fbtft_fb_copyarea(struct fb_info *info, { struct fbtft_par *par = info->par; - fbtft_dev_dbg(DEBUG_FB_COPYAREA, par, info->dev, + dev_dbg(info->dev, "%s: dx=%d, dy=%d, width=%d, height=%d\n", __func__, area->dx, area->dy, area->width, area->height); sys_copyarea(info, area); @@ -533,7 +533,7 @@ static void fbtft_fb_imageblit(struct fb_info *info, { struct fbtft_par *par = info->par; - fbtft_dev_dbg(DEBUG_FB_IMAGEBLIT, par, info->dev, + dev_dbg(info->dev, "%s: dx=%d, dy=%d, width=%d, height=%d\n", __func__, image->dx, image->dy, image->width, image->height); sys_imageblit(info, image); @@ -547,7 +547,7 @@ static ssize_t fbtft_fb_write(struct fb_info *info, const char __user *buf, struct fbtft_par *par = info->par; ssize_t res; - fbtft_dev_dbg(DEBUG_FB_WRITE, par, info->dev, + dev_dbg(info->dev, "%s: count=%zd, ppos=%llu\n", __func__, count, *ppos); res = fb_sys_write(info, buf, count, ppos); @@ -570,11 +570,10 @@ static int fbtft_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct fbtft_par *par = info->par; unsigned val; int ret = 1; - fbtft_dev_dbg(DEBUG_FB_SETCOLREG, par, info->dev, + dev_dbg(info->dev, "%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n", __func__, regno, red, green, blue, transp); @@ -601,7 +600,7 @@ static int fbtft_fb_blank(int blank, struct fb_info *info) struct fbtft_par *par = info->par; int ret = -EINVAL; - fbtft_dev_dbg(DEBUG_FB_BLANK, par, info->dev, "%s(blank=%d)\n", + dev_dbg(info->dev, "%s(blank=%d)\n", __func__, blank); if (!par->fbtftops.blank) @@ -1067,8 +1066,6 @@ static int fbtft_init_display_dt(struct fbtft_par *par) const __be32 *p; u32 val; int buf[64], i, j; - char msg[128]; - char str[16]; fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); @@ -1094,13 +1091,11 @@ static int fbtft_init_display_dt(struct fbtft_par *par) p = of_prop_next_u32(prop, p, &val); } /* make debug message */ - msg[0] = '\0'; - for (j = 0; j < i; j++) { - snprintf(str, 128, " %02X", buf[j]); - strcat(msg, str); - } fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, - "init: write_register:%s\n", msg); + "init: write_register:\n"); + for (j = 0; j < i; j++) + fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, + "buf[%d] = %02X\n", j, buf[j]); par->fbtftops.write_register(par, i, buf[0], buf[1], buf[2], buf[3], diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 9fd98cb53418..7d817eb26eab 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -430,11 +430,6 @@ do { \ dev_info(par->info->device, format, ##arg); \ } while (0) -#define fbtft_dev_dbg(level, par, dev, format, arg...) \ -do { \ - if (unlikely(par->debug & level)) \ - dev_info(dev, format, ##arg); \ -} while (0) #define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \ do { \ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 2d758fb26eac..2593413412a3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -588,8 +588,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* Check message qtype type which is the lower byte within qos_class */ qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; /* pr_debug("qtype = %d\n", qtype); */ - if (qtype) { - } else { + if (!qtype) { /* Put message into Slow Queue */ /* Only put a message into the DPRAM if msg doorbell is available */ status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index fdb2418c5f88..b3ea4bb54e2c 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -2815,13 +2815,14 @@ static int __init fwserial_init(void) /* num_ttys/num_ports must not be set above the static alloc avail */ if (num_ttys + num_loops > MAX_CARD_PORTS) num_ttys = MAX_CARD_PORTS - num_loops; + num_ports = num_ttys + num_loops; fwtty_driver = tty_alloc_driver(MAX_TOTAL_PORTS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); if (IS_ERR(fwtty_driver)) { err = PTR_ERR(fwtty_driver); - return err; + goto remove_debugfs; } fwtty_driver->driver_name = KBUILD_MODNAME; @@ -2923,7 +2924,9 @@ unregister_driver: tty_unregister_driver(fwtty_driver); put_tty: put_tty_driver(fwtty_driver); +remove_debugfs: debugfs_remove_recursive(fwserial_debugfs); + return err; } diff --git a/drivers/staging/gdm724x/gdm_endian.c b/drivers/staging/gdm724x/gdm_endian.c index f6cc90ae9ba6..d7144e7afa32 100644 --- a/drivers/staging/gdm724x/gdm_endian.c +++ b/drivers/staging/gdm724x/gdm_endian.c @@ -11,57 +11,45 @@ * GNU General Public License for more details. */ -#include <linux/slab.h> +#include <linux/kernel.h> #include "gdm_endian.h" void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian) { - u8 a[2] = {0x12, 0x34}; - u8 b[2] = {0, }; - u16 c = 0x1234; - if (dev_endian == ENDIANNESS_BIG) ed->dev_ed = ENDIANNESS_BIG; else ed->dev_ed = ENDIANNESS_LITTLE; - - memcpy(b, &c, 2); - - if (a[0] != b[0]) - ed->host_ed = ENDIANNESS_LITTLE; - else - ed->host_ed = ENDIANNESS_BIG; - } u16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x) { - if (ed->dev_ed == ed->host_ed) - return x; - - return Endian16_Swap(x); + if (ed->dev_ed == ENDIANNESS_LITTLE) + return cpu_to_le16(x); + else + return cpu_to_be16(x); } u16 gdm_dev16_to_cpu(struct gdm_endian *ed, u16 x) { - if (ed->dev_ed == ed->host_ed) - return x; - - return Endian16_Swap(x); + if (ed->dev_ed == ENDIANNESS_LITTLE) + return le16_to_cpu(x); + else + return be16_to_cpu(x); } u32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x) { - if (ed->dev_ed == ed->host_ed) - return x; - - return Endian32_Swap(x); + if (ed->dev_ed == ENDIANNESS_LITTLE) + return cpu_to_le32(x); + else + return cpu_to_be32(x); } u32 gdm_dev32_to_cpu(struct gdm_endian *ed, u32 x) { - if (ed->dev_ed == ed->host_ed) - return x; - - return Endian32_Swap(x); + if (ed->dev_ed == ENDIANNESS_LITTLE) + return le32_to_cpu(x); + else + return be32_to_cpu(x); } diff --git a/drivers/staging/gdm724x/gdm_endian.h b/drivers/staging/gdm724x/gdm_endian.h index 9b2531ff908e..6177870830e5 100644 --- a/drivers/staging/gdm724x/gdm_endian.h +++ b/drivers/staging/gdm724x/gdm_endian.h @@ -16,16 +16,6 @@ #include <linux/types.h> -#define Endian16_Swap(value) \ - ((((u16)((value) & 0x00FF)) << 8) | \ - (((u16)((value) & 0xFF00)) >> 8)) - -#define Endian32_Swap(value) \ - ((((u32)((value) & 0x000000FF)) << 24) | \ - (((u32)((value) & 0x0000FF00)) << 8) | \ - (((u32)((value) & 0x00FF0000)) >> 8) | \ - (((u32)((value) & 0xFF000000)) >> 24)) - enum { ENDIANNESS_MIN = 0, ENDIANNESS_UNKNOWN, @@ -37,7 +27,6 @@ enum { struct gdm_endian { u8 dev_ed; - u8 host_ed; }; void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian); diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 8199b0a697bb..1cf24e4edf25 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c @@ -158,7 +158,7 @@ static int up_to_host(struct mux_rx *r) unsigned int start_flag; unsigned int payload_size; unsigned short packet_type; - int dummy_cnt; + int total_len; u32 packet_size_sum = r->offset; int index; int ret = TO_HOST_INVALID_PACKET; @@ -176,10 +176,10 @@ static int up_to_host(struct mux_rx *r) break; } - dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4); + total_len = ALIGN(MUX_HEADER_SIZE + payload_size, 4); if (len - packet_size_sum < - MUX_HEADER_SIZE + payload_size + dummy_cnt) { + total_len) { pr_err("invalid payload : %d %d %04x\n", payload_size, len, packet_type); break; @@ -202,7 +202,7 @@ static int up_to_host(struct mux_rx *r) break; } - packet_size_sum += MUX_HEADER_SIZE + payload_size + dummy_cnt; + packet_size_sum += total_len; if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) { ret = r->callback(NULL, 0, @@ -361,7 +361,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, struct mux_pkt_header *mux_header; struct mux_tx *t = NULL; static u32 seq_num = 1; - int dummy_cnt; int total_len; int ret; unsigned long flags; @@ -374,9 +373,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, spin_lock_irqsave(&mux_dev->write_lock, flags); - dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4); - - total_len = len + MUX_HEADER_SIZE + dummy_cnt; + total_len = ALIGN(MUX_HEADER_SIZE + len, 4); t = alloc_mux_tx(total_len); if (!t) { @@ -392,7 +389,8 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, mux_header->packet_type = __cpu_to_le16(packet_type[tty_index]); memcpy(t->buf+MUX_HEADER_SIZE, data, len); - memset(t->buf+MUX_HEADER_SIZE+len, 0, dummy_cnt); + memset(t->buf+MUX_HEADER_SIZE+len, 0, total_len - MUX_HEADER_SIZE - + len); t->len = total_len; t->callback = cb; diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index 61d168e82011..08290d901b0c 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -584,7 +584,7 @@ static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf, if (T == TLV_T(T_MAC_ADDRESS)) { if (L != dev->addr_len) { netdev_err(dev, - "%s Invalid inofrmation result T/L [%x/%d]\n", + "%s Invalid information result T/L [%x/%d]\n", __func__, T, L); return -1; } diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 9d78bfcdb2c3..f3cdaa6c468c 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -121,7 +121,7 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) int ret = 0; if (group > ND_MAX_GROUP) { - pr_err("Group %d is invalied.\n", group); + pr_err("Group %d is invalid.\n", group); pr_err("Valid group is 0 ~ %d.\n", ND_MAX_GROUP); return -EINVAL; } diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index 702ae04df912..b0927e49d0a8 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -63,7 +63,7 @@ struct goldfish_audio { #define AUDIO_READ(data, addr) (readl(data->reg_base + addr)) #define AUDIO_WRITE(data, addr, x) (writel(x, data->reg_base + addr)) #define AUDIO_WRITE64(data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_dma_addr((x), data->reg_base + addr, data->reg_base+addr2)) /* * temporary variable used between goldfish_audio_probe() and diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c index 213877a2c430..66ae48fcc2b2 100644 --- a/drivers/staging/goldfish/goldfish_nand.c +++ b/drivers/staging/goldfish/goldfish_nand.c @@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, writel((u32)(addr >> 32), base + NAND_ADDR_HIGH); writel((u32)addr, base + NAND_ADDR_LOW); writel(len, base + NAND_TRANSFER_SIZE); - gf_write64((u64)ptr, base + NAND_DATA, base + NAND_DATA_HIGH); + gf_write_ptr(ptr, base + NAND_DATA, base + NAND_DATA_HIGH); writel(cmd, base + NAND_COMMAND); rv = readl(base + NAND_RESULT); } diff --git a/drivers/staging/i2o/Kconfig b/drivers/staging/i2o/Kconfig deleted file mode 100644 index 286c53f4b13d..000000000000 --- a/drivers/staging/i2o/Kconfig +++ /dev/null @@ -1,120 +0,0 @@ -menuconfig I2O - tristate "I2O device support" - depends on PCI - ---help--- - The Intelligent Input/Output (I2O) architecture allows hardware - drivers to be split into two parts: an operating system specific - module called the OSM and an hardware specific module called the - HDM. The OSM can talk to a whole range of HDM's, and ideally the - HDM's are not OS dependent. This allows for the same HDM driver to - be used under different operating systems if the relevant OSM is in - place. In order for this to work, you need to have an I2O interface - adapter card in your computer. This card contains a special I/O - processor (IOP), thus allowing high speeds since the CPU does not - have to deal with I/O. - - If you say Y here, you will get a choice of interface adapter - drivers and OSM's with the following questions. - - To compile this support as a module, choose M here: the - modules will be called i2o_core. - - If unsure, say N. - -if I2O - -config I2O_LCT_NOTIFY_ON_CHANGES - bool "Enable LCT notification" - default y - ---help--- - Only say N here if you have a I2O controller from SUN. The SUN - firmware doesn't support LCT notification on changes. If this option - is enabled on such a controller the driver will hang up in a endless - loop. On all other controllers say Y. - - If unsure, say Y. - -config I2O_EXT_ADAPTEC - bool "Enable Adaptec extensions" - default y - ---help--- - Say Y for support of raidutils for Adaptec I2O controllers. You also - have to say Y to "I2O Configuration support", "I2O SCSI OSM" below - and to "SCSI generic support" under "SCSI device configuration". - -config I2O_EXT_ADAPTEC_DMA64 - bool "Enable 64-bit DMA" - depends on I2O_EXT_ADAPTEC && ( 64BIT || HIGHMEM64G ) - default y - ---help--- - Say Y for support of 64-bit DMA transfer mode on Adaptec I2O - controllers. - Note: You need at least firmware version 3709. - -config I2O_CONFIG - tristate "I2O Configuration support" - depends on VIRT_TO_BUS - ---help--- - Say Y for support of the configuration interface for the I2O adapters. - If you have a RAID controller from Adaptec and you want to use the - raidutils to manage your RAID array, you have to say Y here. - - To compile this support as a module, choose M here: the - module will be called i2o_config. - - Note: If you want to use the new API you have to download the - i2o_config patch from http://i2o.shadowconnect.com/ - -config I2O_CONFIG_OLD_IOCTL - bool "Enable ioctls (OBSOLETE)" - depends on I2O_CONFIG - default y - ---help--- - Enables old ioctls. - -config I2O_BUS - tristate "I2O Bus Adapter OSM" - ---help--- - Include support for the I2O Bus Adapter OSM. The Bus Adapter OSM - provides access to the busses on the I2O controller. The main purpose - is to rescan the bus to find new devices. - - To compile this support as a module, choose M here: the - module will be called i2o_bus. - -config I2O_BLOCK - tristate "I2O Block OSM" - depends on BLOCK - ---help--- - Include support for the I2O Block OSM. The Block OSM presents disk - and other structured block devices to the operating system. If you - are using an RAID controller, you could access the array only by - the Block OSM driver. But it is possible to access the single disks - by the SCSI OSM driver, for example to monitor the disks. - - To compile this support as a module, choose M here: the - module will be called i2o_block. - -config I2O_SCSI - tristate "I2O SCSI OSM" - depends on SCSI - ---help--- - Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel - I2O controller. You can use both the SCSI and Block OSM together if - you wish. To access a RAID array, you must use the Block OSM driver. - But you could use the SCSI OSM driver to monitor the single disks. - - To compile this support as a module, choose M here: the - module will be called i2o_scsi. - -config I2O_PROC - tristate "I2O /proc support" - ---help--- - If you say Y here and to "/proc file system support", you will be - able to read I2O related information from the virtual directory - /proc/i2o. - - To compile this support as a module, choose M here: the - module will be called i2o_proc. - -endif # I2O diff --git a/drivers/staging/i2o/Makefile b/drivers/staging/i2o/Makefile deleted file mode 100644 index b0982dacfd0a..000000000000 --- a/drivers/staging/i2o/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# Makefile for the kernel I2O OSM. -# -# Note : at this point, these files are compiled on all systems. -# In the future, some of these should be built conditionally. -# - -i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o -i2o_bus-y += bus-osm.o -i2o_config-y += config-osm.o -obj-$(CONFIG_I2O) += i2o_core.o -obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o -obj-$(CONFIG_I2O_BUS) += i2o_bus.o -obj-$(CONFIG_I2O_BLOCK) += i2o_block.o -obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o -obj-$(CONFIG_I2O_PROC) += i2o_proc.o diff --git a/drivers/staging/i2o/README b/drivers/staging/i2o/README deleted file mode 100644 index f072a8eb3041..000000000000 --- a/drivers/staging/i2o/README +++ /dev/null @@ -1,98 +0,0 @@ - - Linux I2O Support (c) Copyright 1999 Red Hat Software - and others. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version - 2 of the License, or (at your option) any later version. - -AUTHORS (so far) - -Alan Cox, Building Number Three Ltd. - Core code, SCSI and Block OSMs - -Steve Ralston, LSI Logic Corp. - Debugging SCSI and Block OSM - -Deepak Saxena, Intel Corp. - Various core/block extensions - /proc interface, bug fixes - Ioctl interfaces for control - Debugging LAN OSM - -Philip Rumpf - Fixed assorted dumb SMP locking bugs - -Juha Sievanen, University of Helsinki Finland - LAN OSM code - /proc interface to LAN class - Bug fixes - Core code extensions - -Auvo Häkkinen, University of Helsinki Finland - LAN OSM code - /Proc interface to LAN class - Bug fixes - Core code extensions - -Taneli Vähäkangas, University of Helsinki Finland - Fixes to i2o_config - -CREDITS - - This work was made possible by - -Red Hat Software - Funding for the Building #3 part of the project - -Symbios Logic (Now LSI) - Host adapters, hints, known to work platforms when I hit - compatibility problems - -BoxHill Corporation - Loan of initial FibreChannel disk array used for development work. - -European Commission - Funding the work done by the University of Helsinki - -SysKonnect - Loan of FDDI and Gigabit Ethernet cards - -ASUSTeK - Loan of I2O motherboard - -STATUS: - -o The core setup works within limits. -o The scsi layer seems to almost work. - I'm still chasing down the hang bug. -o The block OSM is mostly functional -o LAN OSM works with FDDI and Ethernet cards. - -TO DO: - -General: -o Provide hidden address space if asked -o Long term message flow control -o PCI IOP's without interrupts are not supported yet -o Push FAIL handling into the core -o DDM control interfaces for module load etc -o Add I2O 2.0 support (Deffered to 2.5 kernel) - -Block: -o Multiple major numbers -o Read ahead and cache handling stuff. Talk to Ingo and people -o Power management -o Finish Media changers - -SCSI: -o Find the right way to associate drives/luns/busses - -Lan: -o Performance tuning -o Test Fibre Channel code - -Tape: -o Anyone seen anything implementing this ? - (D.S: Will attempt to do so if spare cycles permit) diff --git a/drivers/staging/i2o/README.ioctl b/drivers/staging/i2o/README.ioctl deleted file mode 100644 index 4a7d2ebdfc97..000000000000 --- a/drivers/staging/i2o/README.ioctl +++ /dev/null @@ -1,394 +0,0 @@ - -Linux I2O User Space Interface -rev 0.3 - 04/20/99 - -============================================================================= -Originally written by Deepak Saxena(deepak@plexity.net) -Currently maintained by Deepak Saxena(deepak@plexity.net) -============================================================================= - -I. Introduction - -The Linux I2O subsystem provides a set of ioctl() commands that can be -utilized by user space applications to communicate with IOPs and devices -on individual IOPs. This document defines the specific ioctl() commands -that are available to the user and provides examples of their uses. - -This document assumes the reader is familiar with or has access to the -I2O specification as no I2O message parameters are outlined. For information -on the specification, see http://www.i2osig.org - -This document and the I2O user space interface are currently maintained -by Deepak Saxena. Please send all comments, errata, and bug fixes to -deepak@csociety.purdue.edu - -II. IOP Access - -Access to the I2O subsystem is provided through the device file named -/dev/i2o/ctl. This file is a character file with major number 10 and minor -number 166. It can be created through the following command: - - mknod /dev/i2o/ctl c 10 166 - -III. Determining the IOP Count - - SYNOPSIS - - ioctl(fd, I2OGETIOPS, int *count); - - u8 count[MAX_I2O_CONTROLLERS]; - - DESCRIPTION - - This function returns the system's active IOP table. count should - point to a buffer containing MAX_I2O_CONTROLLERS entries. Upon - returning, each entry will contain a non-zero value if the given - IOP unit is active, and NULL if it is inactive or non-existent. - - RETURN VALUE. - - Returns 0 if no errors occur, and -1 otherwise. If an error occurs, - errno is set appropriately: - - EFAULT Invalid user space pointer was passed - -IV. Getting Hardware Resource Table - - SYNOPSIS - - ioctl(fd, I2OHRTGET, struct i2o_cmd_hrt *hrt); - - struct i2o_cmd_hrtlct - { - u32 iop; /* IOP unit number */ - void *resbuf; /* Buffer for result */ - u32 *reslen; /* Buffer length in bytes */ - }; - - DESCRIPTION - - This function returns the Hardware Resource Table of the IOP specified - by hrt->iop in the buffer pointed to by hrt->resbuf. The actual size of - the data is written into *(hrt->reslen). - - RETURNS - - This function returns 0 if no errors occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ENOBUFS Buffer not large enough. If this occurs, the required - buffer length is written into *(hrt->reslen) - -V. Getting Logical Configuration Table - - SYNOPSIS - - ioctl(fd, I2OLCTGET, struct i2o_cmd_lct *lct); - - struct i2o_cmd_hrtlct - { - u32 iop; /* IOP unit number */ - void *resbuf; /* Buffer for result */ - u32 *reslen; /* Buffer length in bytes */ - }; - - DESCRIPTION - - This function returns the Logical Configuration Table of the IOP specified - by lct->iop in the buffer pointed to by lct->resbuf. The actual size of - the data is written into *(lct->reslen). - - RETURNS - - This function returns 0 if no errors occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ENOBUFS Buffer not large enough. If this occurs, the required - buffer length is written into *(lct->reslen) - -VI. Setting Parameters - - SYNOPSIS - - ioctl(fd, I2OPARMSET, struct i2o_parm_setget *ops); - - struct i2o_cmd_psetget - { - u32 iop; /* IOP unit number */ - u32 tid; /* Target device TID */ - void *opbuf; /* Operation List buffer */ - u32 oplen; /* Operation List buffer length in bytes */ - void *resbuf; /* Result List buffer */ - u32 *reslen; /* Result List buffer length in bytes */ - }; - - DESCRIPTION - - This function posts a UtilParamsSet message to the device identified - by ops->iop and ops->tid. The operation list for the message is - sent through the ops->opbuf buffer, and the result list is written - into the buffer pointed to by ops->resbuf. The number of bytes - written is placed into *(ops->reslen). - - RETURNS - - The return value is the size in bytes of the data written into - ops->resbuf if no errors occur. If an error occurs, -1 is returned - and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ENOBUFS Buffer not large enough. If this occurs, the required - buffer length is written into *(ops->reslen) - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - - A return value of 0 does not mean that the value was actually - changed properly on the IOP. The user should check the result - list to determine the specific status of the transaction. - -VII. Getting Parameters - - SYNOPSIS - - ioctl(fd, I2OPARMGET, struct i2o_parm_setget *ops); - - struct i2o_parm_setget - { - u32 iop; /* IOP unit number */ - u32 tid; /* Target device TID */ - void *opbuf; /* Operation List buffer */ - u32 oplen; /* Operation List buffer length in bytes */ - void *resbuf; /* Result List buffer */ - u32 *reslen; /* Result List buffer length in bytes */ - }; - - DESCRIPTION - - This function posts a UtilParamsGet message to the device identified - by ops->iop and ops->tid. The operation list for the message is - sent through the ops->opbuf buffer, and the result list is written - into the buffer pointed to by ops->resbuf. The actual size of data - written is placed into *(ops->reslen). - - RETURNS - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ENOBUFS Buffer not large enough. If this occurs, the required - buffer length is written into *(ops->reslen) - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - - A return value of 0 does not mean that the value was actually - properly retrieved. The user should check the result list - to determine the specific status of the transaction. - -VIII. Downloading Software - - SYNOPSIS - - ioctl(fd, I2OSWDL, struct i2o_sw_xfer *sw); - - struct i2o_sw_xfer - { - u32 iop; /* IOP unit number */ - u8 flags; /* DownloadFlags field */ - u8 sw_type; /* Software type */ - u32 sw_id; /* Software ID */ - void *buf; /* Pointer to software buffer */ - u32 *swlen; /* Length of software buffer */ - u32 *maxfrag; /* Number of fragments */ - u32 *curfrag; /* Current fragment number */ - }; - - DESCRIPTION - - This function downloads a software fragment pointed by sw->buf - to the iop identified by sw->iop. The DownloadFlags, SwID, SwType - and SwSize fields of the ExecSwDownload message are filled in with - the values of sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen). - - The fragments _must_ be sent in order and be 8K in size. The last - fragment _may_ be shorter, however. The kernel will compute its - size based on information in the sw->swlen field. - - Please note that SW transfers can take a long time. - - RETURNS - - This function returns 0 no errors occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - -IX. Uploading Software - - SYNOPSIS - - ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw); - - struct i2o_sw_xfer - { - u32 iop; /* IOP unit number */ - u8 flags; /* UploadFlags */ - u8 sw_type; /* Software type */ - u32 sw_id; /* Software ID */ - void *buf; /* Pointer to software buffer */ - u32 *swlen; /* Length of software buffer */ - u32 *maxfrag; /* Number of fragments */ - u32 *curfrag; /* Current fragment number */ - }; - - DESCRIPTION - - This function uploads a software fragment from the IOP identified - by sw->iop, sw->sw_type, sw->sw_id and optionally sw->swlen fields. - The UploadFlags, SwID, SwType and SwSize fields of the ExecSwUpload - message are filled in with the values of sw->flags, sw->sw_id, - sw->sw_type and *(sw->swlen). - - The fragments _must_ be requested in order and be 8K in size. The - user is responsible for allocating memory pointed by sw->buf. The - last fragment _may_ be shorter. - - Please note that SW transfers can take a long time. - - RETURNS - - This function returns 0 if no errors occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - -X. Removing Software - - SYNOPSIS - - ioctl(fd, I2OSWDEL, struct i2o_sw_xfer *sw); - - struct i2o_sw_xfer - { - u32 iop; /* IOP unit number */ - u8 flags; /* RemoveFlags */ - u8 sw_type; /* Software type */ - u32 sw_id; /* Software ID */ - void *buf; /* Unused */ - u32 *swlen; /* Length of the software data */ - u32 *maxfrag; /* Unused */ - u32 *curfrag; /* Unused */ - }; - - DESCRIPTION - - This function removes software from the IOP identified by sw->iop. - The RemoveFlags, SwID, SwType and SwSize fields of the ExecSwRemove message - are filled in with the values of sw->flags, sw->sw_id, sw->sw_type and - *(sw->swlen). Give zero in *(sw->len) if the value is unknown. IOP uses - *(sw->swlen) value to verify correct identication of the module to remove. - The actual size of the module is written into *(sw->swlen). - - RETURNS - - This function returns 0 if no errors occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - -X. Validating Configuration - - SYNOPSIS - - ioctl(fd, I2OVALIDATE, int *iop); - u32 iop; - - DESCRIPTION - - This function posts an ExecConfigValidate message to the controller - identified by iop. This message indicates that the current - configuration is accepted. The iop changes the status of suspect drivers - to valid and may delete old drivers from its store. - - RETURNS - - This function returns 0 if no erro occur. If an error occurs, -1 is - returned and errno is set appropriately: - - ETIMEDOUT Timeout waiting for reply message - ENXIO Invalid IOP number - -XI. Configuration Dialog - - SYNOPSIS - - ioctl(fd, I2OHTML, struct i2o_html *htquery); - struct i2o_html - { - u32 iop; /* IOP unit number */ - u32 tid; /* Target device ID */ - u32 page; /* HTML page */ - void *resbuf; /* Buffer for reply HTML page */ - u32 *reslen; /* Length in bytes of reply buffer */ - void *qbuf; /* Pointer to HTTP query string */ - u32 qlen; /* Length in bytes of query string buffer */ - }; - - DESCRIPTION - - This function posts an UtilConfigDialog message to the device identified - by htquery->iop and htquery->tid. The requested HTML page number is - provided by the htquery->page field, and the resultant data is stored - in the buffer pointed to by htquery->resbuf. If there is an HTTP query - string that is to be sent to the device, it should be sent in the buffer - pointed to by htquery->qbuf. If there is no query string, this field - should be set to NULL. The actual size of the reply received is written - into *(htquery->reslen). - - RETURNS - - This function returns 0 if no error occur. If an error occurs, -1 - is returned and errno is set appropriately: - - EFAULT Invalid user space pointer was passed - ENXIO Invalid IOP number - ENOBUFS Buffer not large enough. If this occurs, the required - buffer length is written into *(ops->reslen) - ETIMEDOUT Timeout waiting for reply message - ENOMEM Kernel memory allocation error - -XII. Events - - In the process of determining this. Current idea is to have use - the select() interface to allow user apps to periodically poll - the /dev/i2o/ctl device for events. When select() notifies the user - that an event is available, the user would call read() to retrieve - a list of all the events that are pending for the specific device. - -============================================================================= -Revision History -============================================================================= - -Rev 0.1 - 04/01/99 -- Initial revision - -Rev 0.2 - 04/06/99 -- Changed return values to match UNIX ioctl() standard. Only return values - are 0 and -1. All errors are reported through errno. -- Added summary of proposed possible event interfaces - -Rev 0.3 - 04/20/99 -- Changed all ioctls() to use pointers to user data instead of actual data -- Updated error values to match the code diff --git a/drivers/staging/i2o/bus-osm.c b/drivers/staging/i2o/bus-osm.c deleted file mode 100644 index 43e357eeeb67..000000000000 --- a/drivers/staging/i2o/bus-osm.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Bus Adapter OSM - * - * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Fixes/additions: - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * initial version. - */ - -#include <linux/module.h> -#include "i2o.h" - -#define OSM_NAME "bus-osm" -#define OSM_VERSION "1.317" -#define OSM_DESCRIPTION "I2O Bus Adapter OSM" - -static struct i2o_driver i2o_bus_driver; - -/* Bus OSM class handling definition */ -static struct i2o_class_id i2o_bus_class_id[] = { - {I2O_CLASS_BUS_ADAPTER}, - {I2O_CLASS_END} -}; - -/** - * i2o_bus_scan - Scan the bus for new devices - * @dev: I2O device of the bus, which should be scanned - * - * Scans the bus dev for new / removed devices. After the scan a new LCT - * will be fetched automatically. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_bus_scan(struct i2o_device *dev) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return -ETIMEDOUT; - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data. - tid); - - return i2o_msg_post_wait(dev->iop, msg, 60); -}; - -/** - * i2o_bus_store_scan - Scan the I2O Bus Adapter - * @d: device which should be scanned - * @attr: device_attribute - * @buf: output buffer - * @count: buffer size - * - * Returns count. - */ -static ssize_t i2o_bus_store_scan(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2o_device *i2o_dev = to_i2o_device(d); - int rc; - - rc = i2o_bus_scan(i2o_dev); - if (rc) - osm_warn("bus scan failed %d\n", rc); - - return count; -} - -/* Bus Adapter OSM device attributes */ -static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan); - -/** - * i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it - * @dev: device to verify if it is a I2O Bus Adapter device - * - * Because we want all Bus Adapters always return 0. - * Except when we fail. Then we are sad. - * - * Returns 0, except when we fail to excel. - */ -static int i2o_bus_probe(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(get_device(dev)); - int rc; - - rc = device_create_file(dev, &dev_attr_scan); - if (rc) - goto err_out; - - osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid); - - return 0; - -err_out: - put_device(dev); - return rc; -}; - -/** - * i2o_bus_remove - remove the I2O Bus Adapter device from the system again - * @dev: I2O Bus Adapter device which should be removed - * - * Always returns 0. - */ -static int i2o_bus_remove(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - - device_remove_file(dev, &dev_attr_scan); - - put_device(dev); - - osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid); - - return 0; -}; - -/* Bus Adapter OSM driver struct */ -static struct i2o_driver i2o_bus_driver = { - .name = OSM_NAME, - .classes = i2o_bus_class_id, - .driver = { - .probe = i2o_bus_probe, - .remove = i2o_bus_remove, - }, -}; - -/** - * i2o_bus_init - Bus Adapter OSM initialization function - * - * Only register the Bus Adapter OSM in the I2O core. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_bus_init(void) -{ - int rc; - - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - /* Register Bus Adapter OSM into I2O core */ - rc = i2o_driver_register(&i2o_bus_driver); - if (rc) { - osm_err("Could not register Bus Adapter OSM\n"); - return rc; - } - - return 0; -}; - -/** - * i2o_bus_exit - Bus Adapter OSM exit function - * - * Unregisters Bus Adapter OSM from I2O core. - */ -static void __exit i2o_bus_exit(void) -{ - i2o_driver_unregister(&i2o_bus_driver); -}; - -MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -module_init(i2o_bus_init); -module_exit(i2o_bus_exit); diff --git a/drivers/staging/i2o/config-osm.c b/drivers/staging/i2o/config-osm.c deleted file mode 100644 index 45091ac66154..000000000000 --- a/drivers/staging/i2o/config-osm.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Configuration OSM - * - * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Fixes/additions: - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * initial version. - */ - -#include <linux/module.h> -#include "i2o.h" -#include <linux/dcache.h> -#include <linux/namei.h> -#include <linux/fs.h> - -#include <linux/uaccess.h> - -#define OSM_NAME "config-osm" -#define OSM_VERSION "1.323" -#define OSM_DESCRIPTION "I2O Configuration OSM" - -/* access mode user rw */ -#define S_IWRSR (S_IRUSR | S_IWUSR) - -static struct i2o_driver i2o_config_driver; - -/* Config OSM driver struct */ -static struct i2o_driver i2o_config_driver = { - .name = OSM_NAME, -}; - -#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL -#include "i2o_config.c" -#endif - -/** - * i2o_config_init - Configuration OSM initialization function - * - * Registers Configuration OSM in the I2O core and if old ioctl's are - * compiled in initialize them. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_config_init(void) -{ - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - if (i2o_driver_register(&i2o_config_driver)) { - osm_err("handler register failed.\n"); - return -EBUSY; - } -#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL - if (i2o_config_old_init()) { - osm_err("old config handler initialization failed\n"); - i2o_driver_unregister(&i2o_config_driver); - return -EBUSY; - } -#endif - - return 0; -} - -/** - * i2o_config_exit - Configuration OSM exit function - * - * If old ioctl's are compiled in exit remove them and unregisters - * Configuration OSM from I2O core. - */ -static void i2o_config_exit(void) -{ -#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL - i2o_config_old_exit(); -#endif - - i2o_driver_unregister(&i2o_config_driver); -} - -MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -module_init(i2o_config_init); -module_exit(i2o_config_exit); diff --git a/drivers/staging/i2o/core.h b/drivers/staging/i2o/core.h deleted file mode 100644 index 91614f11f89a..000000000000 --- a/drivers/staging/i2o/core.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * I2O core internal declarations - * - * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Fixes/additions: - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * initial version. - */ - -/* Exec-OSM */ -extern struct i2o_driver i2o_exec_driver; -extern int i2o_exec_lct_get(struct i2o_controller *); - -extern int __init i2o_exec_init(void); -extern void i2o_exec_exit(void); - -/* driver */ -extern struct bus_type i2o_bus_type; - -extern int i2o_driver_dispatch(struct i2o_controller *, u32); - -extern int __init i2o_driver_init(void); -extern void i2o_driver_exit(void); - -/* PCI */ -extern int __init i2o_pci_init(void); -extern void __exit i2o_pci_exit(void); - -/* device */ -extern const struct attribute_group *i2o_device_groups[]; - -extern void i2o_device_remove(struct i2o_device *); -extern int i2o_device_parse_lct(struct i2o_controller *); - -int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, - int oplen, void *reslist, int reslen); - -/* IOP */ -extern struct i2o_controller *i2o_iop_alloc(void); - -/** - * i2o_iop_free - Free the i2o_controller struct - * @c: I2O controller to free - */ -static inline void i2o_iop_free(struct i2o_controller *c) -{ - i2o_pool_free(&c->in_msg); - kfree(c); -} - -extern int i2o_iop_add(struct i2o_controller *); -extern void i2o_iop_remove(struct i2o_controller *); - -/* control registers relative to c->base */ -#define I2O_IRQ_STATUS 0x30 -#define I2O_IRQ_MASK 0x34 -#define I2O_IN_PORT 0x40 -#define I2O_OUT_PORT 0x44 - -/* Motorola/Freescale specific register offset */ -#define I2O_MOTOROLA_PORT_OFFSET 0x10400 - -#define I2O_IRQ_OUTBOUND_POST 0x00000008 diff --git a/drivers/staging/i2o/debug.c b/drivers/staging/i2o/debug.c deleted file mode 100644 index 12b783b2a86c..000000000000 --- a/drivers/staging/i2o/debug.c +++ /dev/null @@ -1,473 +0,0 @@ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include "i2o.h" - -static void i2o_report_util_cmd(u8 cmd); -static void i2o_report_exec_cmd(u8 cmd); -static void i2o_report_fail_status(u8 req_status, u32 *msg); -static void i2o_report_common_status(u8 req_status); -static void i2o_report_common_dsc(u16 detailed_status); - -/* - * Used for error reporting/debugging purposes. - * Report Cmd name, Request status, Detailed Status. - */ -void i2o_report_status(const char *severity, const char *str, - struct i2o_message *m) -{ - u32 *msg = (u32 *) m; - u8 cmd = (msg[1] >> 24) & 0xFF; - u8 req_status = (msg[4] >> 24) & 0xFF; - u16 detailed_status = msg[4] & 0xFFFF; - - if (cmd == I2O_CMD_UTIL_EVT_REGISTER) - return; /* No status in this reply */ - - printk("%s%s: ", severity, str); - - if (cmd < 0x1F) // Utility cmd - i2o_report_util_cmd(cmd); - - else if (cmd >= 0xA0 && cmd <= 0xEF) // Executive cmd - i2o_report_exec_cmd(cmd); - else - printk("Cmd = %0#2x, ", cmd); // Other cmds - - if (msg[0] & MSG_FAIL) { - i2o_report_fail_status(req_status, msg); - return; - } - - i2o_report_common_status(req_status); - - if (cmd < 0x1F || (cmd >= 0xA0 && cmd <= 0xEF)) - i2o_report_common_dsc(detailed_status); - else - printk(" / DetailedStatus = %0#4x.\n", - detailed_status); -} - -/* Used to dump a message to syslog during debugging */ -void i2o_dump_message(struct i2o_message *m) -{ -#ifdef DEBUG - u32 *msg = (u32 *) m; - int i; - - printk(KERN_INFO "Dumping I2O message size %d @ %p\n", - msg[0] >> 16 & 0xffff, msg); - for (i = 0; i < ((msg[0] >> 16) & 0xffff); i++) - printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]); -#endif -} - -/* - * Used for error reporting/debugging purposes. - * Following fail status are common to all classes. - * The preserved message must be handled in the reply handler. - */ -static void i2o_report_fail_status(u8 req_status, u32 *msg) -{ - static char *FAIL_STATUS[] = { - "0x80", /* not used */ - "SERVICE_SUSPENDED", /* 0x81 */ - "SERVICE_TERMINATED", /* 0x82 */ - "CONGESTION", - "FAILURE", - "STATE_ERROR", - "TIME_OUT", - "ROUTING_FAILURE", - "INVALID_VERSION", - "INVALID_OFFSET", - "INVALID_MSG_FLAGS", - "FRAME_TOO_SMALL", - "FRAME_TOO_LARGE", - "INVALID_TARGET_ID", - "INVALID_INITIATOR_ID", - "INVALID_INITIATOR_CONTEX", /* 0x8F */ - "UNKNOWN_FAILURE" /* 0xFF */ - }; - - if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE) - printk("TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n", - req_status); - else - printk("TRANSPORT_%s.\n", - FAIL_STATUS[req_status & 0x0F]); - - /* Dump some details */ - - printk(KERN_ERR " InitiatorId = %d, TargetId = %d\n", - (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF); - printk(KERN_ERR " LowestVersion = 0x%02X, HighestVersion = 0x%02X\n", - (msg[4] >> 8) & 0xFF, msg[4] & 0xFF); - printk(KERN_ERR " FailingHostUnit = 0x%04X, FailingIOP = 0x%03X\n", - msg[5] >> 16, msg[5] & 0xFFF); - - printk(KERN_ERR " Severity: 0x%02X\n", (msg[4] >> 16) & 0xFF); - if (msg[4] & (1 << 16)) - printk(KERN_DEBUG "(FormatError), " - "this msg can never be delivered/processed.\n"); - if (msg[4] & (1 << 17)) - printk(KERN_DEBUG "(PathError), " - "this msg can no longer be delivered/processed.\n"); - if (msg[4] & (1 << 18)) - printk(KERN_DEBUG "(PathState), " - "the system state does not allow delivery.\n"); - if (msg[4] & (1 << 19)) - printk(KERN_DEBUG - "(Congestion), resources temporarily not available;" - "do not retry immediately.\n"); -} - -/* - * Used for error reporting/debugging purposes. - * Following reply status are common to all classes. - */ -static void i2o_report_common_status(u8 req_status) -{ - static char *REPLY_STATUS[] = { - "SUCCESS", - "ABORT_DIRTY", - "ABORT_NO_DATA_TRANSFER", - "ABORT_PARTIAL_TRANSFER", - "ERROR_DIRTY", - "ERROR_NO_DATA_TRANSFER", - "ERROR_PARTIAL_TRANSFER", - "PROCESS_ABORT_DIRTY", - "PROCESS_ABORT_NO_DATA_TRANSFER", - "PROCESS_ABORT_PARTIAL_TRANSFER", - "TRANSACTION_ERROR", - "PROGRESS_REPORT" - }; - - if (req_status >= ARRAY_SIZE(REPLY_STATUS)) - printk("RequestStatus = %0#2x", req_status); - else - printk("%s", REPLY_STATUS[req_status]); -} - -/* - * Used for error reporting/debugging purposes. - * Following detailed status are valid for executive class, - * utility class, DDM class and for transaction error replies. - */ -static void i2o_report_common_dsc(u16 detailed_status) -{ - static char *COMMON_DSC[] = { - "SUCCESS", - "0x01", // not used - "BAD_KEY", - "TCL_ERROR", - "REPLY_BUFFER_FULL", - "NO_SUCH_PAGE", - "INSUFFICIENT_RESOURCE_SOFT", - "INSUFFICIENT_RESOURCE_HARD", - "0x08", // not used - "CHAIN_BUFFER_TOO_LARGE", - "UNSUPPORTED_FUNCTION", - "DEVICE_LOCKED", - "DEVICE_RESET", - "INAPPROPRIATE_FUNCTION", - "INVALID_INITIATOR_ADDRESS", - "INVALID_MESSAGE_FLAGS", - "INVALID_OFFSET", - "INVALID_PARAMETER", - "INVALID_REQUEST", - "INVALID_TARGET_ADDRESS", - "MESSAGE_TOO_LARGE", - "MESSAGE_TOO_SMALL", - "MISSING_PARAMETER", - "TIMEOUT", - "UNKNOWN_ERROR", - "UNKNOWN_FUNCTION", - "UNSUPPORTED_VERSION", - "DEVICE_BUSY", - "DEVICE_NOT_AVAILABLE" - }; - - if (detailed_status > I2O_DSC_DEVICE_NOT_AVAILABLE) - printk(" / DetailedStatus = %0#4x.\n", - detailed_status); - else - printk(" / %s.\n", COMMON_DSC[detailed_status]); -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_util_cmd(u8 cmd) -{ - switch (cmd) { - case I2O_CMD_UTIL_NOP: - printk("UTIL_NOP, "); - break; - case I2O_CMD_UTIL_ABORT: - printk("UTIL_ABORT, "); - break; - case I2O_CMD_UTIL_CLAIM: - printk("UTIL_CLAIM, "); - break; - case I2O_CMD_UTIL_RELEASE: - printk("UTIL_CLAIM_RELEASE, "); - break; - case I2O_CMD_UTIL_CONFIG_DIALOG: - printk("UTIL_CONFIG_DIALOG, "); - break; - case I2O_CMD_UTIL_DEVICE_RESERVE: - printk("UTIL_DEVICE_RESERVE, "); - break; - case I2O_CMD_UTIL_DEVICE_RELEASE: - printk("UTIL_DEVICE_RELEASE, "); - break; - case I2O_CMD_UTIL_EVT_ACK: - printk("UTIL_EVENT_ACKNOWLEDGE, "); - break; - case I2O_CMD_UTIL_EVT_REGISTER: - printk("UTIL_EVENT_REGISTER, "); - break; - case I2O_CMD_UTIL_LOCK: - printk("UTIL_LOCK, "); - break; - case I2O_CMD_UTIL_LOCK_RELEASE: - printk("UTIL_LOCK_RELEASE, "); - break; - case I2O_CMD_UTIL_PARAMS_GET: - printk("UTIL_PARAMS_GET, "); - break; - case I2O_CMD_UTIL_PARAMS_SET: - printk("UTIL_PARAMS_SET, "); - break; - case I2O_CMD_UTIL_REPLY_FAULT_NOTIFY: - printk("UTIL_REPLY_FAULT_NOTIFY, "); - break; - default: - printk("Cmd = %0#2x, ", cmd); - } -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_exec_cmd(u8 cmd) -{ - switch (cmd) { - case I2O_CMD_ADAPTER_ASSIGN: - printk("EXEC_ADAPTER_ASSIGN, "); - break; - case I2O_CMD_ADAPTER_READ: - printk("EXEC_ADAPTER_READ, "); - break; - case I2O_CMD_ADAPTER_RELEASE: - printk("EXEC_ADAPTER_RELEASE, "); - break; - case I2O_CMD_BIOS_INFO_SET: - printk("EXEC_BIOS_INFO_SET, "); - break; - case I2O_CMD_BOOT_DEVICE_SET: - printk("EXEC_BOOT_DEVICE_SET, "); - break; - case I2O_CMD_CONFIG_VALIDATE: - printk("EXEC_CONFIG_VALIDATE, "); - break; - case I2O_CMD_CONN_SETUP: - printk("EXEC_CONN_SETUP, "); - break; - case I2O_CMD_DDM_DESTROY: - printk("EXEC_DDM_DESTROY, "); - break; - case I2O_CMD_DDM_ENABLE: - printk("EXEC_DDM_ENABLE, "); - break; - case I2O_CMD_DDM_QUIESCE: - printk("EXEC_DDM_QUIESCE, "); - break; - case I2O_CMD_DDM_RESET: - printk("EXEC_DDM_RESET, "); - break; - case I2O_CMD_DDM_SUSPEND: - printk("EXEC_DDM_SUSPEND, "); - break; - case I2O_CMD_DEVICE_ASSIGN: - printk("EXEC_DEVICE_ASSIGN, "); - break; - case I2O_CMD_DEVICE_RELEASE: - printk("EXEC_DEVICE_RELEASE, "); - break; - case I2O_CMD_HRT_GET: - printk("EXEC_HRT_GET, "); - break; - case I2O_CMD_ADAPTER_CLEAR: - printk("EXEC_IOP_CLEAR, "); - break; - case I2O_CMD_ADAPTER_CONNECT: - printk("EXEC_IOP_CONNECT, "); - break; - case I2O_CMD_ADAPTER_RESET: - printk("EXEC_IOP_RESET, "); - break; - case I2O_CMD_LCT_NOTIFY: - printk("EXEC_LCT_NOTIFY, "); - break; - case I2O_CMD_OUTBOUND_INIT: - printk("EXEC_OUTBOUND_INIT, "); - break; - case I2O_CMD_PATH_ENABLE: - printk("EXEC_PATH_ENABLE, "); - break; - case I2O_CMD_PATH_QUIESCE: - printk("EXEC_PATH_QUIESCE, "); - break; - case I2O_CMD_PATH_RESET: - printk("EXEC_PATH_RESET, "); - break; - case I2O_CMD_STATIC_MF_CREATE: - printk("EXEC_STATIC_MF_CREATE, "); - break; - case I2O_CMD_STATIC_MF_RELEASE: - printk("EXEC_STATIC_MF_RELEASE, "); - break; - case I2O_CMD_STATUS_GET: - printk("EXEC_STATUS_GET, "); - break; - case I2O_CMD_SW_DOWNLOAD: - printk("EXEC_SW_DOWNLOAD, "); - break; - case I2O_CMD_SW_UPLOAD: - printk("EXEC_SW_UPLOAD, "); - break; - case I2O_CMD_SW_REMOVE: - printk("EXEC_SW_REMOVE, "); - break; - case I2O_CMD_SYS_ENABLE: - printk("EXEC_SYS_ENABLE, "); - break; - case I2O_CMD_SYS_MODIFY: - printk("EXEC_SYS_MODIFY, "); - break; - case I2O_CMD_SYS_QUIESCE: - printk("EXEC_SYS_QUIESCE, "); - break; - case I2O_CMD_SYS_TAB_SET: - printk("EXEC_SYS_TAB_SET, "); - break; - default: - printk("Cmd = %#02x, ", cmd); - } -} - -void i2o_debug_state(struct i2o_controller *c) -{ - printk(KERN_INFO "%s: State = ", c->name); - switch (((i2o_status_block *) c->status_block.virt)->iop_state) { - case 0x01: - printk("INIT\n"); - break; - case 0x02: - printk("RESET\n"); - break; - case 0x04: - printk("HOLD\n"); - break; - case 0x05: - printk("READY\n"); - break; - case 0x08: - printk("OPERATIONAL\n"); - break; - case 0x10: - printk("FAILED\n"); - break; - case 0x11: - printk("FAULTED\n"); - break; - default: - printk("%x (unknown !!)\n", - ((i2o_status_block *) c->status_block.virt)->iop_state); - } -}; - -void i2o_dump_hrt(struct i2o_controller *c) -{ - u32 *rows = (u32 *) c->hrt.virt; - u8 *p = (u8 *) c->hrt.virt; - u8 *d; - int count; - int length; - int i; - int state; - - if (p[3] != 0) { - printk(KERN_ERR - "%s: HRT table for controller is too new a version.\n", - c->name); - return; - } - - count = p[0] | (p[1] << 8); - length = p[2]; - - printk(KERN_INFO "%s: HRT has %d entries of %d bytes each.\n", - c->name, count, length << 2); - - rows += 2; - - for (i = 0; i < count; i++) { - printk(KERN_INFO "Adapter %08X: ", rows[0]); - p = (u8 *) (rows + 1); - d = (u8 *) (rows + 2); - state = p[1] << 8 | p[0]; - - printk("TID %04X:[", state & 0xFFF); - state >>= 12; - if (state & (1 << 0)) - printk("H"); /* Hidden */ - if (state & (1 << 2)) { - printk("P"); /* Present */ - if (state & (1 << 1)) - printk("C"); /* Controlled */ - } - if (state > 9) - printk("*"); /* Hard */ - - printk("]:"); - - switch (p[3] & 0xFFFF) { - case 0: - /* Adapter private bus - easy */ - printk("Local bus %d: I/O at 0x%04X Mem 0x%08X", p[2], - d[1] << 8 | d[0], *(u32 *) (d + 4)); - break; - case 1: - /* ISA bus */ - printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X", p[2], - d[2], d[1] << 8 | d[0], *(u32 *) (d + 4)); - break; - - case 2: /* EISA bus */ - printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X", - p[2], d[3], d[1] << 8 | d[0], *(u32 *) (d + 4)); - break; - - case 3: /* MCA bus */ - printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X", p[2], - d[3], d[1] << 8 | d[0], *(u32 *) (d + 4)); - break; - - case 4: /* PCI bus */ - printk("PCI %d: Bus %d Device %d Function %d", p[2], - d[2], d[1], d[0]); - break; - - case 0x80: /* Other */ - default: - printk("Unsupported bus type."); - break; - } - printk("\n"); - rows += length; - } -} - -EXPORT_SYMBOL(i2o_dump_message); diff --git a/drivers/staging/i2o/device.c b/drivers/staging/i2o/device.c deleted file mode 100644 index e47496cb0ac2..000000000000 --- a/drivers/staging/i2o/device.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Functions to handle I2O devices - * - * Copyright (C) 2004 Markus Lidel <Markus.Lidel@shadowconnect.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Fixes/additions: - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * initial version. - */ - -#include <linux/module.h> -#include "i2o.h" -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "core.h" - -/** - * i2o_device_issue_claim - claim or release a device - * @dev: I2O device to claim or release - * @cmd: claim or release command - * @type: type of claim - * - * Issue I2O UTIL_CLAIM or UTIL_RELEASE messages. The message to be sent - * is set by cmd. dev is the I2O device which should be claim or - * released and the type is the claim type (see the I2O spec). - * - * Returs 0 on success or negative error code on failure. - */ -static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd, - u32 type) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid); - msg->body[0] = cpu_to_le32(type); - - return i2o_msg_post_wait(dev->iop, msg, 60); -} - -/** - * i2o_device_claim - claim a device for use by an OSM - * @dev: I2O device to claim - * - * Do the leg work to assign a device to a given OSM. If the claim succeeds, - * the owner is the primary. If the attempt fails a negative errno code - * is returned. On success zero is returned. - */ -int i2o_device_claim(struct i2o_device *dev) -{ - int rc = 0; - - mutex_lock(&dev->lock); - - rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY); - if (!rc) - pr_debug("i2o: claim of device %d succeeded\n", - dev->lct_data.tid); - else - pr_debug("i2o: claim of device %d failed %d\n", - dev->lct_data.tid, rc); - - mutex_unlock(&dev->lock); - - return rc; -} - -/** - * i2o_device_claim_release - release a device that the OSM is using - * @dev: device to release - * - * Drop a claim by an OSM on a given I2O device. - * - * AC - some devices seem to want to refuse an unclaim until they have - * finished internal processing. It makes sense since you don't want a - * new device to go reconfiguring the entire system until you are done. - * Thus we are prepared to wait briefly. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_device_claim_release(struct i2o_device *dev) -{ - int tries; - int rc = 0; - - mutex_lock(&dev->lock); - - /* - * If the controller takes a nonblocking approach to - * releases we have to sleep/poll for a few times. - */ - for (tries = 0; tries < 10; tries++) { - rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_RELEASE, - I2O_CLAIM_PRIMARY); - if (!rc) - break; - - ssleep(1); - } - - if (!rc) - pr_debug("i2o: claim release of device %d succeeded\n", - dev->lct_data.tid); - else - pr_debug("i2o: claim release of device %d failed %d\n", - dev->lct_data.tid, rc); - - mutex_unlock(&dev->lock); - - return rc; -} - -/** - * i2o_device_release - release the memory for a I2O device - * @dev: I2O device which should be released - * - * Release the allocated memory. This function is called if refcount of - * device reaches 0 automatically. - */ -static void i2o_device_release(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - - pr_debug("i2o: device %s released\n", dev_name(dev)); - - kfree(i2o_dev); -} - -/** - * class_id_show - Displays class id of I2O device - * @dev: device of which the class id should be displayed - * @attr: pointer to device attribute - * @buf: buffer into which the class id should be printed - * - * Returns the number of bytes which are printed into the buffer. - */ -static ssize_t class_id_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - - sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id); - return strlen(buf) + 1; -} -static DEVICE_ATTR_RO(class_id); - -/** - * tid_show - Displays TID of I2O device - * @dev: device of which the TID should be displayed - * @attr: pointer to device attribute - * @buf: buffer into which the TID should be printed - * - * Returns the number of bytes which are printed into the buffer. - */ -static ssize_t tid_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - - sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid); - return strlen(buf) + 1; -} -static DEVICE_ATTR_RO(tid); - -/* I2O device attributes */ -static struct attribute *i2o_device_attrs[] = { - &dev_attr_class_id.attr, - &dev_attr_tid.attr, - NULL, -}; - -static const struct attribute_group i2o_device_group = { - .attrs = i2o_device_attrs, -}; - -const struct attribute_group *i2o_device_groups[] = { - &i2o_device_group, - NULL, -}; - -/** - * i2o_device_alloc - Allocate a I2O device and initialize it - * - * Allocate the memory for a I2O device and initialize locks and lists - * - * Returns the allocated I2O device or a negative error code if the device - * could not be allocated. - */ -static struct i2o_device *i2o_device_alloc(void) -{ - struct i2o_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&dev->list); - mutex_init(&dev->lock); - - dev->device.bus = &i2o_bus_type; - dev->device.release = &i2o_device_release; - - return dev; -} - -/** - * i2o_device_add - allocate a new I2O device and add it to the IOP - * @c: I2O controller that the device is on - * @entry: LCT entry of the I2O device - * - * Allocate a new I2O device and initialize it with the LCT entry. The - * device is appended to the device list of the controller. - * - * Returns zero on success, or a -ve errno. - */ -static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) -{ - struct i2o_device *i2o_dev, *tmp; - int rc; - - i2o_dev = i2o_device_alloc(); - if (IS_ERR(i2o_dev)) { - printk(KERN_ERR "i2o: unable to allocate i2o device\n"); - return PTR_ERR(i2o_dev); - } - - i2o_dev->lct_data = *entry; - - dev_set_name(&i2o_dev->device, "%d:%03x", c->unit, - i2o_dev->lct_data.tid); - - i2o_dev->iop = c; - i2o_dev->device.parent = &c->device; - - rc = device_register(&i2o_dev->device); - if (rc) - goto err; - - list_add_tail(&i2o_dev->list, &c->devices); - - /* create user entries for this device */ - tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); - if (tmp && (tmp != i2o_dev)) { - rc = sysfs_create_link(&i2o_dev->device.kobj, - &tmp->device.kobj, "user"); - if (rc) - goto unreg_dev; - } - - /* create user entries referring to this device */ - list_for_each_entry(tmp, &c->devices, list) - if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) { - rc = sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "user"); - if (rc) - goto rmlink1; - } - - /* create parent entries for this device */ - tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); - if (tmp && (tmp != i2o_dev)) { - rc = sysfs_create_link(&i2o_dev->device.kobj, - &tmp->device.kobj, "parent"); - if (rc) - goto rmlink1; - } - - /* create parent entries referring to this device */ - list_for_each_entry(tmp, &c->devices, list) - if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) { - rc = sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "parent"); - if (rc) - goto rmlink2; - } - - i2o_driver_notify_device_add_all(i2o_dev); - - pr_debug("i2o: device %s added\n", dev_name(&i2o_dev->device)); - - return 0; - -rmlink2: - /* If link creating failed halfway, we loop whole list to cleanup. - * And we don't care wrong removing of link, because sysfs_remove_link - * will take care of it. - */ - list_for_each_entry(tmp, &c->devices, list) { - if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "parent"); - } - sysfs_remove_link(&i2o_dev->device.kobj, "parent"); -rmlink1: - list_for_each_entry(tmp, &c->devices, list) - if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "user"); - sysfs_remove_link(&i2o_dev->device.kobj, "user"); -unreg_dev: - list_del(&i2o_dev->list); - device_unregister(&i2o_dev->device); -err: - kfree(i2o_dev); - return rc; -} - -/** - * i2o_device_remove - remove an I2O device from the I2O core - * @i2o_dev: I2O device which should be released - * - * Is used on I2O controller removal or LCT modification, when the device - * is removed from the system. Note that the device could still hang - * around until the refcount reaches 0. - */ -void i2o_device_remove(struct i2o_device *i2o_dev) -{ - struct i2o_device *tmp; - struct i2o_controller *c = i2o_dev->iop; - - i2o_driver_notify_device_remove_all(i2o_dev); - - sysfs_remove_link(&i2o_dev->device.kobj, "parent"); - sysfs_remove_link(&i2o_dev->device.kobj, "user"); - - list_for_each_entry(tmp, &c->devices, list) { - if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "parent"); - if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - sysfs_remove_link(&tmp->device.kobj, "user"); - } - list_del(&i2o_dev->list); - - device_unregister(&i2o_dev->device); -} - -/** - * i2o_device_parse_lct - Parse a previously fetched LCT and create devices - * @c: I2O controller from which the LCT should be parsed. - * - * The Logical Configuration Table tells us what we can talk to on the - * board. For every entry we create an I2O device, which is registered in - * the I2O core. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_device_parse_lct(struct i2o_controller *c) -{ - struct i2o_device *dev, *tmp; - i2o_lct *lct; - u32 *dlct = c->dlct.virt; - int max = 0, i = 0; - u16 table_size; - u32 buf; - - mutex_lock(&c->lct_lock); - - kfree(c->lct); - - buf = le32_to_cpu(*dlct++); - table_size = buf & 0xffff; - - lct = c->lct = kmalloc(table_size * 4, GFP_KERNEL); - if (!lct) { - mutex_unlock(&c->lct_lock); - return -ENOMEM; - } - - lct->lct_ver = buf >> 28; - lct->boot_tid = buf >> 16 & 0xfff; - lct->table_size = table_size; - lct->change_ind = le32_to_cpu(*dlct++); - lct->iop_flags = le32_to_cpu(*dlct++); - - table_size -= 3; - - pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max, - lct->table_size); - - while (table_size > 0) { - i2o_lct_entry *entry = &lct->lct_entry[max]; - int found = 0; - - buf = le32_to_cpu(*dlct++); - entry->entry_size = buf & 0xffff; - entry->tid = buf >> 16 & 0xfff; - - entry->change_ind = le32_to_cpu(*dlct++); - entry->device_flags = le32_to_cpu(*dlct++); - - buf = le32_to_cpu(*dlct++); - entry->class_id = buf & 0xfff; - entry->version = buf >> 12 & 0xf; - entry->vendor_id = buf >> 16; - - entry->sub_class = le32_to_cpu(*dlct++); - - buf = le32_to_cpu(*dlct++); - entry->user_tid = buf & 0xfff; - entry->parent_tid = buf >> 12 & 0xfff; - entry->bios_info = buf >> 24; - - memcpy(&entry->identity_tag, dlct, 8); - dlct += 2; - - entry->event_capabilities = le32_to_cpu(*dlct++); - - /* add new devices, which are new in the LCT */ - list_for_each_entry_safe(dev, tmp, &c->devices, list) { - if (entry->tid == dev->lct_data.tid) { - found = 1; - break; - } - } - - if (!found) - i2o_device_add(c, entry); - - table_size -= 9; - max++; - } - - /* remove devices, which are not in the LCT anymore */ - list_for_each_entry_safe(dev, tmp, &c->devices, list) { - int found = 0; - - for (i = 0; i < max; i++) { - if (lct->lct_entry[i].tid == dev->lct_data.tid) { - found = 1; - break; - } - } - - if (!found) - i2o_device_remove(dev); - } - - mutex_unlock(&c->lct_lock); - - return 0; -} - -/* - * Run time support routines - */ - -/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET - * - * This function can be used for all UtilParamsGet/Set operations. - * The OperationList is given in oplist-buffer, - * and results are returned in reslist-buffer. - * Note that the minimum sized reslist is 8 bytes and contains - * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. - */ -int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, - int oplen, void *reslist, int reslen) -{ - struct i2o_message *msg; - int i = 0; - int rc; - struct i2o_dma res; - struct i2o_controller *c = i2o_dev->iop; - struct device *dev = &c->pdev->dev; - - res.virt = NULL; - - if (i2o_dma_alloc(dev, &res, reslen)) - return -ENOMEM; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) { - i2o_dma_free(dev, &res); - return PTR_ERR(msg); - } - - i = 0; - msg->u.head[1] = - cpu_to_le32(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid); - msg->body[i++] = cpu_to_le32(0x00000000); - msg->body[i++] = cpu_to_le32(0x4C000000 | oplen); /* OperationList */ - memcpy(&msg->body[i], oplist, oplen); - i += (oplen / 4 + (oplen % 4 ? 1 : 0)); - msg->body[i++] = cpu_to_le32(0xD0000000 | res.len); /* ResultList */ - msg->body[i++] = cpu_to_le32(res.phys); - - msg->u.head[0] = - cpu_to_le32(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) | - SGL_OFFSET_5); - - rc = i2o_msg_post_wait_mem(c, msg, 10, &res); - - /* This only looks like a memory leak - don't "fix" it. */ - if (rc == -ETIMEDOUT) - return rc; - - memcpy(reslist, res.virt, res.len); - i2o_dma_free(dev, &res); - - return rc; -} - -/* - * Query one field group value or a whole scalar group. - */ -int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field, - void *buf, int buflen) -{ - u32 opblk[] = { cpu_to_le32(0x00000001), - cpu_to_le32((u16) group << 16 | I2O_PARAMS_FIELD_GET), - cpu_to_le32((s16) field << 16 | 0x00000001) - }; - u8 *resblk; /* 8 bytes for header */ - int rc; - - resblk = kmalloc(buflen + 8, GFP_KERNEL); - if (!resblk) - return -ENOMEM; - - rc = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk, - sizeof(opblk), resblk, buflen + 8); - - memcpy(buf, resblk + 8, buflen); /* cut off header */ - - kfree(resblk); - - return rc; -} - -/* - * if oper == I2O_PARAMS_TABLE_GET, get from all rows - * if fieldcount == -1 return all fields - * ibuf and ibuflen are unused (use NULL, 0) - * else return specific fields - * ibuf contains fieldindexes - * - * if oper == I2O_PARAMS_LIST_GET, get from specific rows - * if fieldcount == -1 return all fields - * ibuf contains rowcount, keyvalues - * else return specific fields - * fieldcount is # of fieldindexes - * ibuf contains fieldindexes, rowcount, keyvalues - * - * You could also use directly function i2o_issue_params(). - */ -int i2o_parm_table_get(struct i2o_device *dev, int oper, int group, - int fieldcount, void *ibuf, int ibuflen, void *resblk, - int reslen) -{ - u16 *opblk; - int size; - - size = 10 + ibuflen; - if (size % 4) - size += 4 - size % 4; - - opblk = kmalloc(size, GFP_KERNEL); - if (opblk == NULL) - return -ENOMEM; - - opblk[0] = 1; /* operation count */ - opblk[1] = 0; /* pad */ - opblk[2] = oper; - opblk[3] = group; - opblk[4] = fieldcount; - memcpy(opblk + 5, ibuf, ibuflen); /* other params */ - - size = i2o_parm_issue(dev, I2O_CMD_UTIL_PARAMS_GET, opblk, - size, resblk, reslen); - - kfree(opblk); - if (size > reslen) - return reslen; - - return size; -} - -EXPORT_SYMBOL(i2o_device_claim); -EXPORT_SYMBOL(i2o_device_claim_release); -EXPORT_SYMBOL(i2o_parm_field_get); -EXPORT_SYMBOL(i2o_parm_table_get); -EXPORT_SYMBOL(i2o_parm_issue); diff --git a/drivers/staging/i2o/driver.c b/drivers/staging/i2o/driver.c deleted file mode 100644 index 06119bb3eb5f..000000000000 --- a/drivers/staging/i2o/driver.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Functions to handle I2O drivers (OSMs) and I2O bus type for sysfs - * - * Copyright (C) 2004 Markus Lidel <Markus.Lidel@shadowconnect.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Fixes/additions: - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * initial version. - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/rwsem.h> -#include "i2o.h" -#include <linux/workqueue.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "core.h" - -#define OSM_NAME "i2o" - -/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ -static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; -module_param_named(max_drivers, i2o_max_drivers, uint, 0); -MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support"); - -/* I2O drivers lock and array */ -static spinlock_t i2o_drivers_lock; -static struct i2o_driver **i2o_drivers; - -/** - * i2o_bus_match - Tell if I2O device class id matches the class ids of the I2O driver (OSM) - * @dev: device which should be verified - * @drv: the driver to match against - * - * Used by the bus to check if the driver wants to handle the device. - * - * Returns 1 if the class ids of the driver match the class id of the - * device, otherwise 0. - */ -static int i2o_bus_match(struct device *dev, struct device_driver *drv) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_driver *i2o_drv = to_i2o_driver(drv); - struct i2o_class_id *ids = i2o_drv->classes; - - if (ids) - while (ids->class_id != I2O_CLASS_END) { - if (ids->class_id == i2o_dev->lct_data.class_id) - return 1; - ids++; - } - return 0; -}; - -/* I2O bus type */ -struct bus_type i2o_bus_type = { - .name = "i2o", - .match = i2o_bus_match, - .dev_groups = i2o_device_groups, -}; - -/** - * i2o_driver_register - Register a I2O driver (OSM) in the I2O core - * @drv: I2O driver which should be registered - * - * Registers the OSM drv in the I2O core and creates an event queues if - * necessary. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_driver_register(struct i2o_driver *drv) -{ - struct i2o_controller *c; - int i; - int rc = 0; - unsigned long flags; - - osm_debug("Register driver %s\n", drv->name); - - if (drv->event) { - drv->event_queue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, - drv->name); - if (!drv->event_queue) { - osm_err("Could not initialize event queue for driver " - "%s\n", drv->name); - return -EFAULT; - } - osm_debug("Event queue initialized for driver %s\n", drv->name); - } else - drv->event_queue = NULL; - - drv->driver.name = drv->name; - drv->driver.bus = &i2o_bus_type; - - spin_lock_irqsave(&i2o_drivers_lock, flags); - - for (i = 0; i2o_drivers[i]; i++) - if (i >= i2o_max_drivers) { - osm_err("too many drivers registered, increase max_drivers\n"); - spin_unlock_irqrestore(&i2o_drivers_lock, flags); - rc = -EFAULT; - goto out; - } - - drv->context = i; - i2o_drivers[i] = drv; - - spin_unlock_irqrestore(&i2o_drivers_lock, flags); - - osm_debug("driver %s gets context id %d\n", drv->name, drv->context); - - list_for_each_entry(c, &i2o_controllers, list) { - struct i2o_device *i2o_dev; - - i2o_driver_notify_controller_add(drv, c); - list_for_each_entry(i2o_dev, &c->devices, list) - i2o_driver_notify_device_add(drv, i2o_dev); - } - - rc = driver_register(&drv->driver); - if (rc) - goto out; - - return 0; -out: - if (drv->event_queue) { - destroy_workqueue(drv->event_queue); - drv->event_queue = NULL; - } - - return rc; -}; - -/** - * i2o_driver_unregister - Unregister a I2O driver (OSM) from the I2O core - * @drv: I2O driver which should be unregistered - * - * Unregisters the OSM drv from the I2O core and cleanup event queues if - * necessary. - */ -void i2o_driver_unregister(struct i2o_driver *drv) -{ - struct i2o_controller *c; - unsigned long flags; - - osm_debug("unregister driver %s\n", drv->name); - - driver_unregister(&drv->driver); - - list_for_each_entry(c, &i2o_controllers, list) { - struct i2o_device *i2o_dev; - - list_for_each_entry(i2o_dev, &c->devices, list) - i2o_driver_notify_device_remove(drv, i2o_dev); - - i2o_driver_notify_controller_remove(drv, c); - } - - spin_lock_irqsave(&i2o_drivers_lock, flags); - i2o_drivers[drv->context] = NULL; - spin_unlock_irqrestore(&i2o_drivers_lock, flags); - - if (drv->event_queue) { - destroy_workqueue(drv->event_queue); - drv->event_queue = NULL; - osm_debug("event queue removed for %s\n", drv->name); - } -}; - -/** - * i2o_driver_dispatch - dispatch an I2O reply message - * @c: I2O controller of the message - * @m: I2O message number - * - * The reply is delivered to the driver from which the original message - * was. This function is only called from interrupt context. - * - * Returns 0 on success and the message should not be flushed. Returns > 0 - * on success and if the message should be flushed afterwords. Returns - * negative error code on failure (the message will be flushed too). - */ -int i2o_driver_dispatch(struct i2o_controller *c, u32 m) -{ - struct i2o_driver *drv; - struct i2o_message *msg = i2o_msg_out_to_virt(c, m); - u32 context = le32_to_cpu(msg->u.s.icntxt); - unsigned long flags; - - if (unlikely(context >= i2o_max_drivers)) { - osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, - context); - return -EIO; - } - - spin_lock_irqsave(&i2o_drivers_lock, flags); - drv = i2o_drivers[context]; - spin_unlock_irqrestore(&i2o_drivers_lock, flags); - - if (unlikely(!drv)) { - osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, - context); - return -EIO; - } - - if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { - struct i2o_device *dev, *tmp; - struct i2o_event *evt; - u16 size; - u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff; - - osm_debug("event received from device %d\n", tid); - - if (!drv->event) - return -EIO; - - /* cut of header from message size (in 32-bit words) */ - size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5; - - evt = kzalloc(size * 4 + sizeof(*evt), GFP_ATOMIC); - if (!evt) - return -ENOMEM; - - evt->size = size; - evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt); - evt->event_indicator = le32_to_cpu(msg->body[0]); - memcpy(&evt->data, &msg->body[1], size * 4); - - list_for_each_entry_safe(dev, tmp, &c->devices, list) - if (dev->lct_data.tid == tid) { - evt->i2o_dev = dev; - break; - } - - INIT_WORK(&evt->work, drv->event); - queue_work(drv->event_queue, &evt->work); - return 1; - } - - if (unlikely(!drv->reply)) { - osm_debug("%s: Reply to driver %s, but no reply function defined!\n", - c->name, drv->name); - return -EIO; - } - - return drv->reply(c, m, msg); -} - -/** - * i2o_driver_notify_controller_add_all - Send notify of added controller - * @c: newly added controller - * - * Send notifications to all registered drivers that a new controller was - * added. - */ -void i2o_driver_notify_controller_add_all(struct i2o_controller *c) -{ - int i; - struct i2o_driver *drv; - - for (i = 0; i < i2o_max_drivers; i++) { - drv = i2o_drivers[i]; - - if (drv) - i2o_driver_notify_controller_add(drv, c); - } -} - -/** - * i2o_driver_notify_controller_remove_all - Send notify of removed controller - * @c: controller that is being removed - * - * Send notifications to all registered drivers that a controller was - * removed. - */ -void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) -{ - int i; - struct i2o_driver *drv; - - for (i = 0; i < i2o_max_drivers; i++) { - drv = i2o_drivers[i]; - - if (drv) - i2o_driver_notify_controller_remove(drv, c); - } -} - -/** - * i2o_driver_notify_device_add_all - Send notify of added device - * @i2o_dev: newly added I2O device - * - * Send notifications to all registered drivers that a device was added. - */ -void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) -{ - int i; - struct i2o_driver *drv; - - for (i = 0; i < i2o_max_drivers; i++) { - drv = i2o_drivers[i]; - - if (drv) - i2o_driver_notify_device_add(drv, i2o_dev); - } -} - -/** - * i2o_driver_notify_device_remove_all - Send notify of removed device - * @i2o_dev: device that is being removed - * - * Send notifications to all registered drivers that a device was removed. - */ -void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev) -{ - int i; - struct i2o_driver *drv; - - for (i = 0; i < i2o_max_drivers; i++) { - drv = i2o_drivers[i]; - - if (drv) - i2o_driver_notify_device_remove(drv, i2o_dev); - } -} - -/** - * i2o_driver_init - initialize I2O drivers (OSMs) - * - * Registers the I2O bus and allocate memory for the array of OSMs. - * - * Returns 0 on success or negative error code on failure. - */ -int __init i2o_driver_init(void) -{ - int rc = 0; - - spin_lock_init(&i2o_drivers_lock); - - if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) { - osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n", - i2o_max_drivers); - i2o_max_drivers = I2O_MAX_DRIVERS; - } - osm_info("max drivers = %d\n", i2o_max_drivers); - - i2o_drivers = - kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL); - if (!i2o_drivers) - return -ENOMEM; - - rc = bus_register(&i2o_bus_type); - - if (rc < 0) - kfree(i2o_drivers); - - return rc; -}; - -/** - * i2o_driver_exit - clean up I2O drivers (OSMs) - * - * Unregisters the I2O bus and frees driver array. - */ -void i2o_driver_exit(void) -{ - bus_unregister(&i2o_bus_type); - kfree(i2o_drivers); -}; - -EXPORT_SYMBOL(i2o_driver_register); -EXPORT_SYMBOL(i2o_driver_unregister); -EXPORT_SYMBOL(i2o_driver_notify_controller_add_all); -EXPORT_SYMBOL(i2o_driver_notify_controller_remove_all); -EXPORT_SYMBOL(i2o_driver_notify_device_add_all); -EXPORT_SYMBOL(i2o_driver_notify_device_remove_all); diff --git a/drivers/staging/i2o/exec-osm.c b/drivers/staging/i2o/exec-osm.c deleted file mode 100644 index dce16e425a6e..000000000000 --- a/drivers/staging/i2o/exec-osm.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Executive OSM - * - * Copyright (C) 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * A lot of the I2O message side code from this is taken from the Red - * Creek RCPCI45 adapter driver by Red Creek Communications - * - * Fixes/additions: - * Philipp Rumpf - * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> - * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> - * Deepak Saxena <deepak@plexity.net> - * Boji T Kannanthanam <boji.t.kannanthanam@intel.com> - * Alan Cox <alan@lxorguk.ukuu.org.uk>: - * Ported to Linux 2.5. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor fixes for 2.6. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Support for sysfs included. - */ - -#include <linux/module.h> -#include "i2o.h" -#include <linux/delay.h> -#include <linux/workqueue.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */ -#include <asm/param.h> /* HZ */ -#include "core.h" - -#define OSM_NAME "exec-osm" - -struct i2o_driver i2o_exec_driver; - -/* global wait list for POST WAIT */ -static LIST_HEAD(i2o_exec_wait_list); - -/* Wait struct needed for POST WAIT */ -struct i2o_exec_wait { - wait_queue_head_t *wq; /* Pointer to Wait queue */ - struct i2o_dma dma; /* DMA buffers to free on failure */ - u32 tcntxt; /* transaction context from reply */ - int complete; /* 1 if reply received otherwise 0 */ - u32 m; /* message id */ - struct i2o_message *msg; /* pointer to the reply message */ - struct list_head list; /* node in global wait list */ - spinlock_t lock; /* lock before modifying */ -}; - -/* Work struct needed to handle LCT NOTIFY replies */ -struct i2o_exec_lct_notify_work { - struct work_struct work; /* work struct */ - struct i2o_controller *c; /* controller on which the LCT NOTIFY - was received */ -}; - -/* Exec OSM class handling definition */ -static struct i2o_class_id i2o_exec_class_id[] = { - {I2O_CLASS_EXECUTIVE}, - {I2O_CLASS_END} -}; - -/** - * i2o_exec_wait_alloc - Allocate a i2o_exec_wait struct an initialize it - * - * Allocate the i2o_exec_wait struct and initialize the wait. - * - * Returns i2o_exec_wait pointer on success or negative error code on - * failure. - */ -static struct i2o_exec_wait *i2o_exec_wait_alloc(void) -{ - struct i2o_exec_wait *wait; - - wait = kzalloc(sizeof(*wait), GFP_KERNEL); - if (!wait) - return NULL; - - INIT_LIST_HEAD(&wait->list); - spin_lock_init(&wait->lock); - - return wait; -}; - -/** - * i2o_exec_wait_free - Free an i2o_exec_wait struct - * @wait: I2O wait data which should be cleaned up - */ -static void i2o_exec_wait_free(struct i2o_exec_wait *wait) -{ - kfree(wait); -}; - -/** - * i2o_msg_post_wait_mem - Post and wait a message with DMA buffers - * @c: controller - * @msg: message to post - * @timeout: time in seconds to wait - * @dma: i2o_dma struct of the DMA buffer to free on failure - * - * This API allows an OSM to post a message and then be told whether or - * not the system received a successful reply. If the message times out - * then the value '-ETIMEDOUT' is returned. This is a special case. In - * this situation the message may (should) complete at an indefinite time - * in the future. When it completes it will use the memory buffer - * attached to the request. If -ETIMEDOUT is returned then the memory - * buffer must not be freed. Instead the event completion will free them - * for you. In all other cases the buffer are your problem. - * - * Returns 0 on success, negative error code on timeout or positive error - * code from reply. - */ -int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, - unsigned long timeout, struct i2o_dma *dma) -{ - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); - struct i2o_exec_wait *wait; - static u32 tcntxt = 0x80000000; - unsigned long flags; - int rc = 0; - - wait = i2o_exec_wait_alloc(); - if (!wait) { - i2o_msg_nop(c, msg); - return -ENOMEM; - } - - if (tcntxt == 0xffffffff) - tcntxt = 0x80000000; - - if (dma) - wait->dma = *dma; - - /* - * Fill in the message initiator context and transaction context. - * We will only use transaction contexts >= 0x80000000 for POST WAIT, - * so we could find a POST WAIT reply easier in the reply handler. - */ - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - wait->tcntxt = tcntxt++; - msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); - - wait->wq = &wq; - /* - * we add elements to the head, because if a entry in the list will - * never be removed, we have to iterate over it every time - */ - list_add(&wait->list, &i2o_exec_wait_list); - - /* - * Post the message to the controller. At some point later it will - * return. If we time out before it returns then complete will be zero. - */ - i2o_msg_post(c, msg); - - wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ); - - spin_lock_irqsave(&wait->lock, flags); - - wait->wq = NULL; - - if (wait->complete) - rc = le32_to_cpu(wait->msg->body[0]) >> 24; - else { - /* - * We cannot remove it now. This is important. When it does - * terminate (which it must do if the controller has not - * died...) then it will otherwise scribble on stuff. - * - * FIXME: try abort message - */ - if (dma) - dma->virt = NULL; - - rc = -ETIMEDOUT; - } - - spin_unlock_irqrestore(&wait->lock, flags); - - if (rc != -ETIMEDOUT) { - i2o_flush_reply(c, wait->m); - i2o_exec_wait_free(wait); - } - - return rc; -}; - -/** - * i2o_msg_post_wait_complete - Reply to a i2o_msg_post request from IOP - * @c: I2O controller which answers - * @m: message id - * @msg: pointer to the I2O reply message - * @context: transaction context of request - * - * This function is called in interrupt context only. If the reply reached - * before the timeout, the i2o_exec_wait struct is filled with the message - * and the task will be waked up. The task is now responsible for returning - * the message m back to the controller! If the message reaches us after - * the timeout clean up the i2o_exec_wait struct (including allocated - * DMA buffer). - * - * Return 0 on success and if the message m should not be given back to the - * I2O controller, or >0 on success and if the message should be given back - * afterwords. Returns negative error code on failure. In this case the - * message must also be given back to the controller. - */ -static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, - struct i2o_message *msg, u32 context) -{ - struct i2o_exec_wait *wait, *tmp; - unsigned long flags; - int rc = 1; - - /* - * We need to search through the i2o_exec_wait_list to see if the given - * message is still outstanding. If not, it means that the IOP took - * longer to respond to the message than we had allowed and timer has - * already expired. Not much we can do about that except log it for - * debug purposes, increase timeout, and recompile. - */ - list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { - if (wait->tcntxt == context) { - spin_lock_irqsave(&wait->lock, flags); - - list_del(&wait->list); - - wait->m = m; - wait->msg = msg; - wait->complete = 1; - - if (wait->wq) - rc = 0; - else - rc = -1; - - spin_unlock_irqrestore(&wait->lock, flags); - - if (rc) { - struct device *dev; - - dev = &c->pdev->dev; - - pr_debug("%s: timedout reply received!\n", - c->name); - i2o_dma_free(dev, &wait->dma); - i2o_exec_wait_free(wait); - } else - wake_up_interruptible(wait->wq); - - return rc; - } - } - - osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, - context); - - return -1; -}; - -/** - * i2o_exec_show_vendor_id - Displays Vendor ID of controller - * @d: device of which the Vendor ID should be displayed - * @attr: device_attribute to display - * @buf: buffer into which the Vendor ID should be printed - * - * Returns number of bytes printed into buffer. - */ -static ssize_t i2o_exec_show_vendor_id(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct i2o_device *dev = to_i2o_device(d); - u16 id; - - if (!i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) { - sprintf(buf, "0x%04x", le16_to_cpu(id)); - return strlen(buf) + 1; - } - - return 0; -}; - -/** - * i2o_exec_show_product_id - Displays Product ID of controller - * @d: device of which the Product ID should be displayed - * @attr: device_attribute to display - * @buf: buffer into which the Product ID should be printed - * - * Returns number of bytes printed into buffer. - */ -static ssize_t i2o_exec_show_product_id(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct i2o_device *dev = to_i2o_device(d); - u16 id; - - if (!i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) { - sprintf(buf, "0x%04x", le16_to_cpu(id)); - return strlen(buf) + 1; - } - - return 0; -}; - -/* Exec-OSM device attributes */ -static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL); -static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); - -/** - * i2o_exec_probe - Called if a new I2O device (executive class) appears - * @dev: I2O device which should be probed - * - * Registers event notification for every event from Executive device. The - * return is always 0, because we want all devices of class Executive. - * - * Returns 0 on success. - */ -static int i2o_exec_probe(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - int rc; - - rc = i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); - if (rc) goto err_out; - - rc = device_create_file(dev, &dev_attr_vendor_id); - if (rc) goto err_evtreg; - rc = device_create_file(dev, &dev_attr_product_id); - if (rc) goto err_vid; - - i2o_dev->iop->exec = i2o_dev; - - return 0; - -err_vid: - device_remove_file(dev, &dev_attr_vendor_id); -err_evtreg: - i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); -err_out: - return rc; -}; - -/** - * i2o_exec_remove - Called on I2O device removal - * @dev: I2O device which was removed - * - * Unregisters event notification from Executive I2O device. - * - * Returns 0 on success. - */ -static int i2o_exec_remove(struct device *dev) -{ - device_remove_file(dev, &dev_attr_product_id); - device_remove_file(dev, &dev_attr_vendor_id); - - i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); - - return 0; -}; - -#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES -/** - * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request - * @c: I2O controller to which the request should be send - * @change_ind: change indicator - * - * This function sends a LCT NOTIFY request to the I2O controller with - * the change indicator change_ind. If the change_ind == 0 the controller - * replies immediately after the request. If change_ind > 0 the reply is - * send after change indicator of the LCT is > change_ind. - */ -static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) -{ - i2o_status_block *sb = c->status_block.virt; - struct device *dev; - struct i2o_message *msg; - - mutex_lock(&c->lct_lock); - - dev = &c->pdev->dev; - - if (i2o_dma_realloc(dev, &c->dlct, - le32_to_cpu(sb->expected_lct_size))) { - mutex_unlock(&c->lct_lock); - return -ENOMEM; - } - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) { - mutex_unlock(&c->lct_lock); - return PTR_ERR(msg); - } - - msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); - msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - msg->u.s.tcntxt = cpu_to_le32(0x00000000); - msg->body[0] = cpu_to_le32(0xffffffff); - msg->body[1] = cpu_to_le32(change_ind); - msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); - msg->body[3] = cpu_to_le32(c->dlct.phys); - - i2o_msg_post(c, msg); - - mutex_unlock(&c->lct_lock); - - return 0; -} -#endif - -/** - * i2o_exec_lct_modified - Called on LCT NOTIFY reply - * @_work: work struct for a specific controller - * - * This function handles asynchronus LCT NOTIFY replies. It parses the - * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY - * again, otherwise send LCT NOTIFY to get informed on next LCT change. - */ -static void i2o_exec_lct_modified(struct work_struct *_work) -{ - struct i2o_exec_lct_notify_work *work = - container_of(_work, struct i2o_exec_lct_notify_work, work); - u32 change_ind = 0; - struct i2o_controller *c = work->c; - - kfree(work); - - if (i2o_device_parse_lct(c) != -EAGAIN) - change_ind = c->lct->change_ind + 1; - -#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES - i2o_exec_lct_notify(c, change_ind); -#endif -}; - -/** - * i2o_exec_reply - I2O Executive reply handler - * @c: I2O controller from which the reply comes - * @m: message id - * @msg: pointer to the I2O reply message - * - * This function is always called from interrupt context. If a POST WAIT - * reply was received, pass it to the complete function. If a LCT NOTIFY - * reply was received, a new event is created to handle the update. - * - * Returns 0 on success and if the reply should not be flushed or > 0 - * on success and if the reply should be flushed. Returns negative error - * code on failure and if the reply should be flushed. - */ -static int i2o_exec_reply(struct i2o_controller *c, u32 m, - struct i2o_message *msg) -{ - u32 context; - - if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { - struct i2o_message __iomem *pmsg; - u32 pm; - - /* - * If Fail bit is set we must take the transaction context of - * the preserved message to find the right request again. - */ - - pm = le32_to_cpu(msg->body[3]); - pmsg = i2o_msg_in_to_virt(c, pm); - context = readl(&pmsg->u.s.tcntxt); - - i2o_report_status(KERN_INFO, "i2o_core", msg); - - /* Release the preserved msg */ - i2o_msg_nop_mfa(c, pm); - } else - context = le32_to_cpu(msg->u.s.tcntxt); - - if (context & 0x80000000) - return i2o_msg_post_wait_complete(c, m, msg, context); - - if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { - struct i2o_exec_lct_notify_work *work; - - pr_debug("%s: LCT notify received\n", c->name); - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return -ENOMEM; - - work->c = c; - - INIT_WORK(&work->work, i2o_exec_lct_modified); - queue_work(i2o_exec_driver.event_queue, &work->work); - return 1; - } - - /* - * If this happens, we want to dump the message to the syslog so - * it can be sent back to the card manufacturer by the end user - * to aid in debugging. - * - */ - printk(KERN_WARNING "%s: Unsolicited message reply sent to core! Message dumped to syslog\n", - c->name); - i2o_dump_message(msg); - - return -EFAULT; -} - -/** - * i2o_exec_event - Event handling function - * @work: Work item in occurring event - * - * Handles events send by the Executive device. At the moment does not do - * anything useful. - */ -static void i2o_exec_event(struct work_struct *work) -{ - struct i2o_event *evt = container_of(work, struct i2o_event, work); - - if (likely(evt->i2o_dev)) - osm_debug("Event received from device: %d\n", - evt->i2o_dev->lct_data.tid); - kfree(evt); -}; - -/** - * i2o_exec_lct_get - Get the IOP's Logical Configuration Table - * @c: I2O controller from which the LCT should be fetched - * - * Send a LCT NOTIFY request to the controller, and wait - * I2O_TIMEOUT_LCT_GET seconds until arrival of response. If the LCT is - * to large, retry it. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_exec_lct_get(struct i2o_controller *c) -{ - struct i2o_message *msg; - int i = 0; - int rc = -EAGAIN; - - for (i = 1; i <= I2O_LCT_GET_TRIES; i++) { - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = - cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->body[0] = cpu_to_le32(0xffffffff); - msg->body[1] = cpu_to_le32(0x00000000); - msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); - msg->body[3] = cpu_to_le32(c->dlct.phys); - - rc = i2o_msg_post_wait(c, msg, I2O_TIMEOUT_LCT_GET); - if (rc < 0) - break; - - rc = i2o_device_parse_lct(c); - if (rc != -EAGAIN) - break; - } - - return rc; -} - -/* Exec OSM driver struct */ -struct i2o_driver i2o_exec_driver = { - .name = OSM_NAME, - .reply = i2o_exec_reply, - .event = i2o_exec_event, - .classes = i2o_exec_class_id, - .driver = { - .probe = i2o_exec_probe, - .remove = i2o_exec_remove, - }, -}; - -/** - * i2o_exec_init - Registers the Exec OSM - * - * Registers the Exec OSM in the I2O core. - * - * Returns 0 on success or negative error code on failure. - */ -int __init i2o_exec_init(void) -{ - return i2o_driver_register(&i2o_exec_driver); -}; - -/** - * i2o_exec_exit - Removes the Exec OSM - * - * Unregisters the Exec OSM from the I2O core. - */ -void i2o_exec_exit(void) -{ - i2o_driver_unregister(&i2o_exec_driver); -}; - -EXPORT_SYMBOL(i2o_msg_post_wait_mem); -EXPORT_SYMBOL(i2o_exec_lct_get); diff --git a/drivers/staging/i2o/i2o.h b/drivers/staging/i2o/i2o.h deleted file mode 100644 index d23c3c20b201..000000000000 --- a/drivers/staging/i2o/i2o.h +++ /dev/null @@ -1,988 +0,0 @@ -/* - * I2O kernel space accessible structures/APIs - * - * (c) Copyright 1999, 2000 Red Hat Software - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - ************************************************************************* - * - * This header file defined the I2O APIs/structures for use by - * the I2O kernel modules. - * - */ - -#ifndef _I2O_H -#define _I2O_H - -#include <linux/i2o-dev.h> - -/* How many different OSM's are we allowing */ -#define I2O_MAX_DRIVERS 8 - -#include <linux/pci.h> -#include <linux/bug.h> -#include <linux/dma-mapping.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/workqueue.h> /* work_struct */ -#include <linux/mempool.h> -#include <linux/mutex.h> -#include <linux/scatterlist.h> -#include <linux/semaphore.h> /* Needed for MUTEX init macros */ - -#include <asm/io.h> - -/* message queue empty */ -#define I2O_QUEUE_EMPTY 0xffffffff - -/* - * Cache strategies - */ - -/* The NULL strategy leaves everything up to the controller. This tends to be a - * pessimal but functional choice. - */ -#define CACHE_NULL 0 -/* Prefetch data when reading. We continually attempt to load the next 32 sectors - * into the controller cache. - */ -#define CACHE_PREFETCH 1 -/* Prefetch data when reading. We sometimes attempt to load the next 32 sectors - * into the controller cache. When an I/O is less <= 8K we assume its probably - * not sequential and don't prefetch (default) - */ -#define CACHE_SMARTFETCH 2 -/* Data is written to the cache and then out on to the disk. The I/O must be - * physically on the medium before the write is acknowledged (default without - * NVRAM) - */ -#define CACHE_WRITETHROUGH 17 -/* Data is written to the cache and then out on to the disk. The controller - * is permitted to write back the cache any way it wants. (default if battery - * backed NVRAM is present). It can be useful to set this for swap regardless of - * battery state. - */ -#define CACHE_WRITEBACK 18 -/* Optimise for under powered controllers, especially on RAID1 and RAID0. We - * write large I/O's directly to disk bypassing the cache to avoid the extra - * memory copy hits. Small writes are writeback cached - */ -#define CACHE_SMARTBACK 19 -/* Optimise for under powered controllers, especially on RAID1 and RAID0. We - * write large I/O's directly to disk bypassing the cache to avoid the extra - * memory copy hits. Small writes are writethrough cached. Suitable for devices - * lacking battery backup - */ -#define CACHE_SMARTTHROUGH 20 - -/* - * Ioctl structures - */ - -#define BLKI2OGRSTRAT _IOR('2', 1, int) -#define BLKI2OGWSTRAT _IOR('2', 2, int) -#define BLKI2OSRSTRAT _IOW('2', 3, int) -#define BLKI2OSWSTRAT _IOW('2', 4, int) - -/* - * I2O Function codes - */ - -/* - * Executive Class - */ -#define I2O_CMD_ADAPTER_ASSIGN 0xB3 -#define I2O_CMD_ADAPTER_READ 0xB2 -#define I2O_CMD_ADAPTER_RELEASE 0xB5 -#define I2O_CMD_BIOS_INFO_SET 0xA5 -#define I2O_CMD_BOOT_DEVICE_SET 0xA7 -#define I2O_CMD_CONFIG_VALIDATE 0xBB -#define I2O_CMD_CONN_SETUP 0xCA -#define I2O_CMD_DDM_DESTROY 0xB1 -#define I2O_CMD_DDM_ENABLE 0xD5 -#define I2O_CMD_DDM_QUIESCE 0xC7 -#define I2O_CMD_DDM_RESET 0xD9 -#define I2O_CMD_DDM_SUSPEND 0xAF -#define I2O_CMD_DEVICE_ASSIGN 0xB7 -#define I2O_CMD_DEVICE_RELEASE 0xB9 -#define I2O_CMD_HRT_GET 0xA8 -#define I2O_CMD_ADAPTER_CLEAR 0xBE -#define I2O_CMD_ADAPTER_CONNECT 0xC9 -#define I2O_CMD_ADAPTER_RESET 0xBD -#define I2O_CMD_LCT_NOTIFY 0xA2 -#define I2O_CMD_OUTBOUND_INIT 0xA1 -#define I2O_CMD_PATH_ENABLE 0xD3 -#define I2O_CMD_PATH_QUIESCE 0xC5 -#define I2O_CMD_PATH_RESET 0xD7 -#define I2O_CMD_STATIC_MF_CREATE 0xDD -#define I2O_CMD_STATIC_MF_RELEASE 0xDF -#define I2O_CMD_STATUS_GET 0xA0 -#define I2O_CMD_SW_DOWNLOAD 0xA9 -#define I2O_CMD_SW_UPLOAD 0xAB -#define I2O_CMD_SW_REMOVE 0xAD -#define I2O_CMD_SYS_ENABLE 0xD1 -#define I2O_CMD_SYS_MODIFY 0xC1 -#define I2O_CMD_SYS_QUIESCE 0xC3 -#define I2O_CMD_SYS_TAB_SET 0xA3 - -/* - * Utility Class - */ -#define I2O_CMD_UTIL_NOP 0x00 -#define I2O_CMD_UTIL_ABORT 0x01 -#define I2O_CMD_UTIL_CLAIM 0x09 -#define I2O_CMD_UTIL_RELEASE 0x0B -#define I2O_CMD_UTIL_PARAMS_GET 0x06 -#define I2O_CMD_UTIL_PARAMS_SET 0x05 -#define I2O_CMD_UTIL_EVT_REGISTER 0x13 -#define I2O_CMD_UTIL_EVT_ACK 0x14 -#define I2O_CMD_UTIL_CONFIG_DIALOG 0x10 -#define I2O_CMD_UTIL_DEVICE_RESERVE 0x0D -#define I2O_CMD_UTIL_DEVICE_RELEASE 0x0F -#define I2O_CMD_UTIL_LOCK 0x17 -#define I2O_CMD_UTIL_LOCK_RELEASE 0x19 -#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY 0x15 - -/* - * SCSI Host Bus Adapter Class - */ -#define I2O_CMD_SCSI_EXEC 0x81 -#define I2O_CMD_SCSI_ABORT 0x83 -#define I2O_CMD_SCSI_BUSRESET 0x27 - -/* - * Bus Adapter Class - */ -#define I2O_CMD_BUS_ADAPTER_RESET 0x85 -#define I2O_CMD_BUS_RESET 0x87 -#define I2O_CMD_BUS_SCAN 0x89 -#define I2O_CMD_BUS_QUIESCE 0x8b - -/* - * Random Block Storage Class - */ -#define I2O_CMD_BLOCK_READ 0x30 -#define I2O_CMD_BLOCK_WRITE 0x31 -#define I2O_CMD_BLOCK_CFLUSH 0x37 -#define I2O_CMD_BLOCK_MLOCK 0x49 -#define I2O_CMD_BLOCK_MUNLOCK 0x4B -#define I2O_CMD_BLOCK_MMOUNT 0x41 -#define I2O_CMD_BLOCK_MEJECT 0x43 -#define I2O_CMD_BLOCK_POWER 0x70 - -#define I2O_CMD_PRIVATE 0xFF - -/* Command status values */ - -#define I2O_CMD_IN_PROGRESS 0x01 -#define I2O_CMD_REJECTED 0x02 -#define I2O_CMD_FAILED 0x03 -#define I2O_CMD_COMPLETED 0x04 - -/* I2O API function return values */ - -#define I2O_RTN_NO_ERROR 0 -#define I2O_RTN_NOT_INIT 1 -#define I2O_RTN_FREE_Q_EMPTY 2 -#define I2O_RTN_TCB_ERROR 3 -#define I2O_RTN_TRANSACTION_ERROR 4 -#define I2O_RTN_ADAPTER_ALREADY_INIT 5 -#define I2O_RTN_MALLOC_ERROR 6 -#define I2O_RTN_ADPTR_NOT_REGISTERED 7 -#define I2O_RTN_MSG_REPLY_TIMEOUT 8 -#define I2O_RTN_NO_STATUS 9 -#define I2O_RTN_NO_FIRM_VER 10 -#define I2O_RTN_NO_LINK_SPEED 11 - -/* Reply message status defines for all messages */ - -#define I2O_REPLY_STATUS_SUCCESS 0x00 -#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 -#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 -#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03 -#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04 -#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05 -#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06 -#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08 -#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09 -#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A -#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B -#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80 - -/* Status codes and Error Information for Parameter functions */ - -#define I2O_PARAMS_STATUS_SUCCESS 0x00 -#define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01 -#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 -#define I2O_PARAMS_STATUS_BUFFER_FULL 0x03 -#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04 -#define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05 -#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE 0x06 -#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS 0x07 -#define I2O_PARAMS_STATUS_INVALID_GROUP_ID 0x08 -#define I2O_PARAMS_STATUS_INVALID_OPERATION 0x09 -#define I2O_PARAMS_STATUS_NO_KEY_FIELD 0x0A -#define I2O_PARAMS_STATUS_NO_SUCH_FIELD 0x0B -#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP 0x0C -#define I2O_PARAMS_STATUS_OPERATION_ERROR 0x0D -#define I2O_PARAMS_STATUS_SCALAR_ERROR 0x0E -#define I2O_PARAMS_STATUS_TABLE_ERROR 0x0F -#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE 0x10 - -/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error - * messages: Table 3-2 Detailed Status Codes.*/ - -#define I2O_DSC_SUCCESS 0x0000 -#define I2O_DSC_BAD_KEY 0x0002 -#define I2O_DSC_TCL_ERROR 0x0003 -#define I2O_DSC_REPLY_BUFFER_FULL 0x0004 -#define I2O_DSC_NO_SUCH_PAGE 0x0005 -#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT 0x0006 -#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD 0x0007 -#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE 0x0009 -#define I2O_DSC_UNSUPPORTED_FUNCTION 0x000A -#define I2O_DSC_DEVICE_LOCKED 0x000B -#define I2O_DSC_DEVICE_RESET 0x000C -#define I2O_DSC_INAPPROPRIATE_FUNCTION 0x000D -#define I2O_DSC_INVALID_INITIATOR_ADDRESS 0x000E -#define I2O_DSC_INVALID_MESSAGE_FLAGS 0x000F -#define I2O_DSC_INVALID_OFFSET 0x0010 -#define I2O_DSC_INVALID_PARAMETER 0x0011 -#define I2O_DSC_INVALID_REQUEST 0x0012 -#define I2O_DSC_INVALID_TARGET_ADDRESS 0x0013 -#define I2O_DSC_MESSAGE_TOO_LARGE 0x0014 -#define I2O_DSC_MESSAGE_TOO_SMALL 0x0015 -#define I2O_DSC_MISSING_PARAMETER 0x0016 -#define I2O_DSC_TIMEOUT 0x0017 -#define I2O_DSC_UNKNOWN_ERROR 0x0018 -#define I2O_DSC_UNKNOWN_FUNCTION 0x0019 -#define I2O_DSC_UNSUPPORTED_VERSION 0x001A -#define I2O_DSC_DEVICE_BUSY 0x001B -#define I2O_DSC_DEVICE_NOT_AVAILABLE 0x001C - -/* DetailedStatusCode defines for Block Storage Operation: Table 6-7 Detailed - Status Codes.*/ - -#define I2O_BSA_DSC_SUCCESS 0x0000 -#define I2O_BSA_DSC_MEDIA_ERROR 0x0001 -#define I2O_BSA_DSC_ACCESS_ERROR 0x0002 -#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003 -#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004 -#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005 -#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006 -#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007 -#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008 -#define I2O_BSA_DSC_BUS_FAILURE 0x0009 -#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A -#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B -#define I2O_BSA_DSC_DEVICE_RESET 0x000C -#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D -#define I2O_BSA_DSC_TIMEOUT 0x000E - -/* FailureStatusCodes, Table 3-3 Message Failure Codes */ - -#define I2O_FSC_TRANSPORT_SERVICE_SUSPENDED 0x81 -#define I2O_FSC_TRANSPORT_SERVICE_TERMINATED 0x82 -#define I2O_FSC_TRANSPORT_CONGESTION 0x83 -#define I2O_FSC_TRANSPORT_FAILURE 0x84 -#define I2O_FSC_TRANSPORT_STATE_ERROR 0x85 -#define I2O_FSC_TRANSPORT_TIME_OUT 0x86 -#define I2O_FSC_TRANSPORT_ROUTING_FAILURE 0x87 -#define I2O_FSC_TRANSPORT_INVALID_VERSION 0x88 -#define I2O_FSC_TRANSPORT_INVALID_OFFSET 0x89 -#define I2O_FSC_TRANSPORT_INVALID_MSG_FLAGS 0x8A -#define I2O_FSC_TRANSPORT_FRAME_TOO_SMALL 0x8B -#define I2O_FSC_TRANSPORT_FRAME_TOO_LARGE 0x8C -#define I2O_FSC_TRANSPORT_INVALID_TARGET_ID 0x8D -#define I2O_FSC_TRANSPORT_INVALID_INITIATOR_ID 0x8E -#define I2O_FSC_TRANSPORT_INVALID_INITIATOR_CONTEXT 0x8F -#define I2O_FSC_TRANSPORT_UNKNOWN_FAILURE 0xFF - -/* Device Claim Types */ -#define I2O_CLAIM_PRIMARY 0x01000000 -#define I2O_CLAIM_MANAGEMENT 0x02000000 -#define I2O_CLAIM_AUTHORIZED 0x03000000 -#define I2O_CLAIM_SECONDARY 0x04000000 - -/* Message header defines for VersionOffset */ -#define I2OVER15 0x0001 -#define I2OVER20 0x0002 - -/* Default is 1.5 */ -#define I2OVERSION I2OVER15 - -#define SGL_OFFSET_0 I2OVERSION -#define SGL_OFFSET_4 (0x0040 | I2OVERSION) -#define SGL_OFFSET_5 (0x0050 | I2OVERSION) -#define SGL_OFFSET_6 (0x0060 | I2OVERSION) -#define SGL_OFFSET_7 (0x0070 | I2OVERSION) -#define SGL_OFFSET_8 (0x0080 | I2OVERSION) -#define SGL_OFFSET_9 (0x0090 | I2OVERSION) -#define SGL_OFFSET_10 (0x00A0 | I2OVERSION) -#define SGL_OFFSET_11 (0x00B0 | I2OVERSION) -#define SGL_OFFSET_12 (0x00C0 | I2OVERSION) -#define SGL_OFFSET(x) (((x)<<4) | I2OVERSION) - -/* Transaction Reply Lists (TRL) Control Word structure */ -#define TRL_SINGLE_FIXED_LENGTH 0x00 -#define TRL_SINGLE_VARIABLE_LENGTH 0x40 -#define TRL_MULTIPLE_FIXED_LENGTH 0x80 - - /* msg header defines for MsgFlags */ -#define MSG_STATIC 0x0100 -#define MSG_64BIT_CNTXT 0x0200 -#define MSG_MULTI_TRANS 0x1000 -#define MSG_FAIL 0x2000 -#define MSG_FINAL 0x4000 -#define MSG_REPLY 0x8000 - - /* minimum size msg */ -#define THREE_WORD_MSG_SIZE 0x00030000 -#define FOUR_WORD_MSG_SIZE 0x00040000 -#define FIVE_WORD_MSG_SIZE 0x00050000 -#define SIX_WORD_MSG_SIZE 0x00060000 -#define SEVEN_WORD_MSG_SIZE 0x00070000 -#define EIGHT_WORD_MSG_SIZE 0x00080000 -#define NINE_WORD_MSG_SIZE 0x00090000 -#define TEN_WORD_MSG_SIZE 0x000A0000 -#define ELEVEN_WORD_MSG_SIZE 0x000B0000 -#define I2O_MESSAGE_SIZE(x) ((x)<<16) - -/* special TID assignments */ -#define ADAPTER_TID 0 -#define HOST_TID 1 - -/* outbound queue defines */ -#define I2O_MAX_OUTBOUND_MSG_FRAMES 128 -#define I2O_OUTBOUND_MSG_FRAME_SIZE 128 /* in 32-bit words */ - -/* inbound queue definitions */ -#define I2O_MSG_INPOOL_MIN 32 -#define I2O_INBOUND_MSG_FRAME_SIZE 128 /* in 32-bit words */ - -#define I2O_POST_WAIT_OK 0 -#define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT - -#define I2O_CONTEXT_LIST_MIN_LENGTH 15 -#define I2O_CONTEXT_LIST_USED 0x01 -#define I2O_CONTEXT_LIST_DELETED 0x02 - -/* timeouts */ -#define I2O_TIMEOUT_INIT_OUTBOUND_QUEUE 15 -#define I2O_TIMEOUT_MESSAGE_GET 5 -#define I2O_TIMEOUT_RESET 30 -#define I2O_TIMEOUT_STATUS_GET 5 -#define I2O_TIMEOUT_LCT_GET 360 -#define I2O_TIMEOUT_SCSI_SCB_ABORT 240 - -/* retries */ -#define I2O_HRT_GET_TRIES 3 -#define I2O_LCT_GET_TRIES 3 - -/* defines for max_sectors and max_phys_segments */ -#define I2O_MAX_SECTORS 1024 -#define I2O_MAX_SECTORS_LIMITED 128 -#define I2O_MAX_PHYS_SEGMENTS BLK_MAX_SEGMENTS - -/* - * Message structures - */ -struct i2o_message { - union { - struct { - u8 version_offset; - u8 flags; - u16 size; - u32 target_tid:12; - u32 init_tid:12; - u32 function:8; - u32 icntxt; /* initiator context */ - u32 tcntxt; /* transaction context */ - } s; - u32 head[4]; - } u; - /* List follows */ - u32 body[0]; -}; - -/* MFA and I2O message used by mempool */ -struct i2o_msg_mfa { - u32 mfa; /* MFA returned by the controller */ - struct i2o_message msg; /* I2O message */ -}; - -/* - * Each I2O device entity has one of these. There is one per device. - */ -struct i2o_device { - i2o_lct_entry lct_data; /* Device LCT information */ - - struct i2o_controller *iop; /* Controlling IOP */ - struct list_head list; /* node in IOP devices list */ - - struct device device; - - struct mutex lock; /* device lock */ -}; - -/* - * Event structure provided to the event handling function - */ -struct i2o_event { - struct work_struct work; - struct i2o_device *i2o_dev; /* I2O device pointer from which the - event reply was initiated */ - u16 size; /* Size of data in 32-bit words */ - u32 tcntxt; /* Transaction context used at - registration */ - u32 event_indicator; /* Event indicator from reply */ - u32 data[0]; /* Event data from reply */ -}; - -/* - * I2O classes which could be handled by the OSM - */ -struct i2o_class_id { - u16 class_id:12; -}; - -/* - * I2O driver structure for OSMs - */ -struct i2o_driver { - char *name; /* OSM name */ - int context; /* Low 8 bits of the transaction info */ - struct i2o_class_id *classes; /* I2O classes that this OSM handles */ - - /* Message reply handler */ - int (*reply) (struct i2o_controller *, u32, struct i2o_message *); - - /* Event handler */ - work_func_t event; - - struct workqueue_struct *event_queue; /* Event queue */ - - struct device_driver driver; - - /* notification of changes */ - void (*notify_controller_add) (struct i2o_controller *); - void (*notify_controller_remove) (struct i2o_controller *); - void (*notify_device_add) (struct i2o_device *); - void (*notify_device_remove) (struct i2o_device *); - - struct semaphore lock; -}; - -/* - * Contains DMA mapped address information - */ -struct i2o_dma { - void *virt; - dma_addr_t phys; - size_t len; -}; - -/* - * Contains slab cache and mempool information - */ -struct i2o_pool { - char *name; - struct kmem_cache *slab; - mempool_t *mempool; -}; - -/* - * Contains IO mapped address information - */ -struct i2o_io { - void __iomem *virt; - unsigned long phys; - unsigned long len; -}; - -/* - * Context queue entry, used for 32-bit context on 64-bit systems - */ -struct i2o_context_list_element { - struct list_head list; - u32 context; - void *ptr; - unsigned long timestamp; -}; - -/* - * Each I2O controller has one of these objects - */ -struct i2o_controller { - char name[16]; - int unit; - int type; - - struct pci_dev *pdev; /* PCI device */ - - unsigned int promise:1; /* Promise controller */ - unsigned int adaptec:1; /* DPT / Adaptec controller */ - unsigned int raptor:1; /* split bar */ - unsigned int no_quiesce:1; /* dont quiesce before reset */ - unsigned int short_req:1; /* use small block sizes */ - unsigned int limit_sectors:1; /* limit number of sectors / request */ - unsigned int pae_support:1; /* controller has 64-bit SGL support */ - - struct list_head devices; /* list of I2O devices */ - struct list_head list; /* Controller list */ - - void __iomem *in_port; /* Inbout port address */ - void __iomem *out_port; /* Outbound port address */ - void __iomem *irq_status; /* Interrupt status register address */ - void __iomem *irq_mask; /* Interrupt mask register address */ - - struct i2o_dma status; /* IOP status block */ - - struct i2o_dma hrt; /* HW Resource Table */ - i2o_lct *lct; /* Logical Config Table */ - struct i2o_dma dlct; /* Temp LCT */ - struct mutex lct_lock; /* Lock for LCT updates */ - struct i2o_dma status_block; /* IOP status block */ - - struct i2o_io base; /* controller messaging unit */ - struct i2o_io in_queue; /* inbound message queue Host->IOP */ - struct i2o_dma out_queue; /* outbound message queue IOP->Host */ - - struct i2o_pool in_msg; /* mempool for inbound messages */ - - unsigned int battery:1; /* Has a battery backup */ - unsigned int io_alloc:1; /* An I/O resource was allocated */ - unsigned int mem_alloc:1; /* A memory resource was allocated */ - - struct resource io_resource; /* I/O resource allocated to the IOP */ - struct resource mem_resource; /* Mem resource allocated to the IOP */ - - struct device device; - struct i2o_device *exec; /* Executive */ -#if BITS_PER_LONG == 64 - spinlock_t context_list_lock; /* lock for context_list */ - atomic_t context_list_counter; /* needed for unique contexts */ - struct list_head context_list; /* list of context id's - and pointers */ -#endif - spinlock_t lock; /* lock for controller - configuration */ - void *driver_data[I2O_MAX_DRIVERS]; /* storage for drivers */ -}; - -/* - * I2O System table entry - * - * The system table contains information about all the IOPs in the - * system. It is sent to all IOPs so that they can create peer2peer - * connections between them. - */ -struct i2o_sys_tbl_entry { - u16 org_id; - u16 reserved1; - u32 iop_id:12; - u32 reserved2:20; - u16 seg_num:12; - u16 i2o_version:4; - u8 iop_state; - u8 msg_type; - u16 frame_size; - u16 reserved3; - u32 last_changed; - u32 iop_capabilities; - u32 inbound_low; - u32 inbound_high; -}; - -struct i2o_sys_tbl { - u8 num_entries; - u8 version; - u16 reserved1; - u32 change_ind; - u32 reserved2; - u32 reserved3; - struct i2o_sys_tbl_entry iops[0]; -}; - -extern struct list_head i2o_controllers; - -/* Message functions */ -extern struct i2o_message *i2o_msg_get_wait(struct i2o_controller *, int); -extern int i2o_msg_post_wait_mem(struct i2o_controller *, struct i2o_message *, - unsigned long, struct i2o_dma *); - -/* IOP functions */ -extern int i2o_status_get(struct i2o_controller *); - -extern int i2o_event_register(struct i2o_device *, struct i2o_driver *, int, - u32); -extern struct i2o_device *i2o_iop_find_device(struct i2o_controller *, u16); -extern struct i2o_controller *i2o_find_iop(int); - -/* Functions needed for handling 64-bit pointers in 32-bit context */ -#if BITS_PER_LONG == 64 -extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *); -extern void *i2o_cntxt_list_get(struct i2o_controller *, u32); -extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *); -extern u32 i2o_cntxt_list_get_ptr(struct i2o_controller *, void *); - -static inline u32 i2o_ptr_low(void *ptr) -{ - return (u32) (u64) ptr; -}; - -static inline u32 i2o_ptr_high(void *ptr) -{ - return (u32) ((u64) ptr >> 32); -}; - -static inline u32 i2o_dma_low(dma_addr_t dma_addr) -{ - return (u32) (u64) dma_addr; -}; - -static inline u32 i2o_dma_high(dma_addr_t dma_addr) -{ - return (u32) ((u64) dma_addr >> 32); -}; -#else -static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr) -{ - return (u32) ptr; -}; - -static inline void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context) -{ - return (void *)context; -}; - -static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr) -{ - return (u32) ptr; -}; - -static inline u32 i2o_cntxt_list_get_ptr(struct i2o_controller *c, void *ptr) -{ - return (u32) ptr; -}; - -static inline u32 i2o_ptr_low(void *ptr) -{ - return (u32) ptr; -}; - -static inline u32 i2o_ptr_high(void *ptr) -{ - return 0; -}; - -static inline u32 i2o_dma_low(dma_addr_t dma_addr) -{ - return (u32) dma_addr; -}; - -static inline u32 i2o_dma_high(dma_addr_t dma_addr) -{ - return 0; -}; -#endif - -extern u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size); -extern dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, - size_t size, - enum dma_data_direction direction, - u32 ** sg_ptr); -extern int i2o_dma_map_sg(struct i2o_controller *c, - struct scatterlist *sg, int sg_count, - enum dma_data_direction direction, - u32 ** sg_ptr); -extern int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len); -extern void i2o_dma_free(struct device *dev, struct i2o_dma *addr); -extern int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, - size_t len); -extern int i2o_pool_alloc(struct i2o_pool *pool, const char *name, - size_t size, int min_nr); -extern void i2o_pool_free(struct i2o_pool *pool); -/* I2O driver (OSM) functions */ -extern int i2o_driver_register(struct i2o_driver *); -extern void i2o_driver_unregister(struct i2o_driver *); - -/** - * i2o_driver_notify_controller_add - Send notification of added controller - * @drv: I2O driver - * @c: I2O controller - * - * Send notification of added controller to a single registered driver. - */ -static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv, - struct i2o_controller *c) -{ - if (drv->notify_controller_add) - drv->notify_controller_add(c); -}; - -/** - * i2o_driver_notify_controller_remove - Send notification of removed controller - * @drv: I2O driver - * @c: I2O controller - * - * Send notification of removed controller to a single registered driver. - */ -static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv, - struct i2o_controller *c) -{ - if (drv->notify_controller_remove) - drv->notify_controller_remove(c); -}; - -/** - * i2o_driver_notify_device_add - Send notification of added device - * @drv: I2O driver - * @i2o_dev: the added i2o_device - * - * Send notification of added device to a single registered driver. - */ -static inline void i2o_driver_notify_device_add(struct i2o_driver *drv, - struct i2o_device *i2o_dev) -{ - if (drv->notify_device_add) - drv->notify_device_add(i2o_dev); -}; - -/** - * i2o_driver_notify_device_remove - Send notification of removed device - * @drv: I2O driver - * @i2o_dev: the added i2o_device - * - * Send notification of removed device to a single registered driver. - */ -static inline void i2o_driver_notify_device_remove(struct i2o_driver *drv, - struct i2o_device *i2o_dev) -{ - if (drv->notify_device_remove) - drv->notify_device_remove(i2o_dev); -}; - -extern void i2o_driver_notify_controller_add_all(struct i2o_controller *); -extern void i2o_driver_notify_controller_remove_all(struct i2o_controller *); -extern void i2o_driver_notify_device_add_all(struct i2o_device *); -extern void i2o_driver_notify_device_remove_all(struct i2o_device *); - -/* I2O device functions */ -extern int i2o_device_claim(struct i2o_device *); -extern int i2o_device_claim_release(struct i2o_device *); - -/* Exec OSM functions */ -extern int i2o_exec_lct_get(struct i2o_controller *); - -/* device / driver / kobject conversion functions */ -#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) -#define to_i2o_device(dev) container_of(dev, struct i2o_device, device) -#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device) - -/** - * i2o_out_to_virt - Turn an I2O message to a virtual address - * @c: controller - * @m: message engine value - * - * Turn a receive message from an I2O controller bus address into - * a Linux virtual address. The shared page frame is a linear block - * so we simply have to shift the offset. This function does not - * work for sender side messages as they are ioremap objects - * provided by the I2O controller. - */ -static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c, - u32 m) -{ - BUG_ON(m < c->out_queue.phys - || m >= c->out_queue.phys + c->out_queue.len); - - return c->out_queue.virt + (m - c->out_queue.phys); -}; - -/** - * i2o_msg_in_to_virt - Turn an I2O message to a virtual address - * @c: controller - * @m: message engine value - * - * Turn a send message from an I2O controller bus address into - * a Linux virtual address. The shared page frame is a linear block - * so we simply have to shift the offset. This function does not - * work for receive side messages as they are kmalloc objects - * in a different pool. - */ -static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct - i2o_controller *c, - u32 m) -{ - return c->in_queue.virt + m; -}; - -/** - * i2o_msg_get - obtain an I2O message from the IOP - * @c: I2O controller - * - * This function tries to get a message frame. If no message frame is - * available do not wait until one is available (see also i2o_msg_get_wait). - * The returned pointer to the message frame is not in I/O memory, it is - * allocated from a mempool. But because a MFA is allocated from the - * controller too it is guaranteed that i2o_msg_post() will never fail. - * - * On a success a pointer to the message frame is returned. If the message - * queue is empty -EBUSY is returned and if no memory is available -ENOMEM - * is returned. - */ -static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c) -{ - struct i2o_msg_mfa *mmsg = mempool_alloc(c->in_msg.mempool, GFP_ATOMIC); - if (!mmsg) - return ERR_PTR(-ENOMEM); - - mmsg->mfa = readl(c->in_port); - if (unlikely(mmsg->mfa >= c->in_queue.len)) { - u32 mfa = mmsg->mfa; - - mempool_free(mmsg, c->in_msg.mempool); - - if (mfa == I2O_QUEUE_EMPTY) - return ERR_PTR(-EBUSY); - return ERR_PTR(-EFAULT); - } - - return &mmsg->msg; -}; - -/** - * i2o_msg_post - Post I2O message to I2O controller - * @c: I2O controller to which the message should be send - * @msg: message returned by i2o_msg_get() - * - * Post the message to the I2O controller and return immediately. - */ -static inline void i2o_msg_post(struct i2o_controller *c, - struct i2o_message *msg) -{ - struct i2o_msg_mfa *mmsg; - - mmsg = container_of(msg, struct i2o_msg_mfa, msg); - memcpy_toio(i2o_msg_in_to_virt(c, mmsg->mfa), msg, - (le32_to_cpu(msg->u.head[0]) >> 16) << 2); - writel(mmsg->mfa, c->in_port); - mempool_free(mmsg, c->in_msg.mempool); -}; - -/** - * i2o_msg_post_wait - Post and wait a message and wait until return - * @c: controller - * @msg: message to post - * @timeout: time in seconds to wait - * - * This API allows an OSM to post a message and then be told whether or - * not the system received a successful reply. If the message times out - * then the value '-ETIMEDOUT' is returned. - * - * Returns 0 on success or negative error code on failure. - */ -static inline int i2o_msg_post_wait(struct i2o_controller *c, - struct i2o_message *msg, - unsigned long timeout) -{ - return i2o_msg_post_wait_mem(c, msg, timeout, NULL); -}; - -/** - * i2o_msg_nop_mfa - Returns a fetched MFA back to the controller - * @c: I2O controller from which the MFA was fetched - * @mfa: MFA which should be returned - * - * This function must be used for preserved messages, because i2o_msg_nop() - * also returns the allocated memory back to the msg_pool mempool. - */ -static inline void i2o_msg_nop_mfa(struct i2o_controller *c, u32 mfa) -{ - struct i2o_message __iomem *msg; - u32 nop[3] = { - THREE_WORD_MSG_SIZE | SGL_OFFSET_0, - I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID, - 0x00000000 - }; - - msg = i2o_msg_in_to_virt(c, mfa); - memcpy_toio(msg, nop, sizeof(nop)); - writel(mfa, c->in_port); -}; - -/** - * i2o_msg_nop - Returns a message which is not used - * @c: I2O controller from which the message was created - * @msg: message which should be returned - * - * If you fetch a message via i2o_msg_get, and can't use it, you must - * return the message with this function. Otherwise the MFA is lost as well - * as the allocated memory from the mempool. - */ -static inline void i2o_msg_nop(struct i2o_controller *c, - struct i2o_message *msg) -{ - struct i2o_msg_mfa *mmsg; - mmsg = container_of(msg, struct i2o_msg_mfa, msg); - - i2o_msg_nop_mfa(c, mmsg->mfa); - mempool_free(mmsg, c->in_msg.mempool); -}; - -/** - * i2o_flush_reply - Flush reply from I2O controller - * @c: I2O controller - * @m: the message identifier - * - * The I2O controller must be informed that the reply message is not needed - * anymore. If you forget to flush the reply, the message frame can't be - * used by the controller anymore and is therefore lost. - */ -static inline void i2o_flush_reply(struct i2o_controller *c, u32 m) -{ - writel(m, c->out_port); -}; - -/* - * Endian handling wrapped into the macro - keeps the core code - * cleaner. - */ - -#define i2o_raw_writel(val, mem) __raw_writel(cpu_to_le32(val), mem) - -extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int); -extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int, - void *, int); - -/* debugging and troubleshooting/diagnostic helpers. */ -#define osm_printk(level, format, arg...) \ - printk(level "%s: " format, OSM_NAME , ## arg) - -#ifdef DEBUG -#define osm_debug(format, arg...) \ - osm_printk(KERN_DEBUG, format , ## arg) -#else -#define osm_debug(format, arg...) \ - do { } while (0) -#endif - -#define osm_err(format, arg...) \ - osm_printk(KERN_ERR, format , ## arg) -#define osm_info(format, arg...) \ - osm_printk(KERN_INFO, format , ## arg) -#define osm_warn(format, arg...) \ - osm_printk(KERN_WARNING, format , ## arg) - -/* debugging functions */ -extern void i2o_report_status(const char *, const char *, struct i2o_message *); -extern void i2o_dump_message(struct i2o_message *); -extern void i2o_dump_hrt(struct i2o_controller *c); -extern void i2o_debug_state(struct i2o_controller *c); - -#endif /* _I2O_H */ diff --git a/drivers/staging/i2o/i2o_block.c b/drivers/staging/i2o/i2o_block.c deleted file mode 100644 index 406758f755ee..000000000000 --- a/drivers/staging/i2o/i2o_block.c +++ /dev/null @@ -1,1228 +0,0 @@ -/* - * Block OSM - * - * Copyright (C) 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * For the purpose of avoiding doubt the preferred form of the work - * for making modifications shall be a standards compliant form such - * gzipped tar and not one requiring a proprietary or patent encumbered - * tool to unpack. - * - * Fixes/additions: - * Steve Ralston: - * Multiple device handling error fixes, - * Added a queue depth. - * Alan Cox: - * FC920 has an rmw bug. Dont or in the end marker. - * Removed queue walk, fixed for 64bitness. - * Rewrote much of the code over time - * Added indirect block lists - * Handle 64K limits on many controllers - * Don't use indirects on the Promise (breaks) - * Heavily chop down the queue depths - * Deepak Saxena: - * Independent queues per IOP - * Support for dynamic device creation/deletion - * Code cleanup - * Support for larger I/Os through merge* functions - * (taken from DAC960 driver) - * Boji T Kannanthanam: - * Set the I2O Block devices to be detected in increasing - * order of TIDs during boot. - * Search and set the I2O block device that we boot off - * from as the first device to be claimed (as /dev/i2o/hda) - * Properly attach/detach I2O gendisk structure from the - * system gendisk list. The I2O block devices now appear in - * /proc/partitions. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor bugfixes for 2.6. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include "i2o.h" -#include <linux/mutex.h> - -#include <linux/mempool.h> - -#include <linux/genhd.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> - -#include <scsi/scsi.h> - -#include "i2o_block.h" - -#define OSM_NAME "block-osm" -#define OSM_VERSION "1.325" -#define OSM_DESCRIPTION "I2O Block Device OSM" - -static DEFINE_MUTEX(i2o_block_mutex); -static struct i2o_driver i2o_block_driver; - -/* global Block OSM request mempool */ -static struct i2o_block_mempool i2o_blk_req_pool; - -/* Block OSM class handling definition */ -static struct i2o_class_id i2o_block_class_id[] = { - {I2O_CLASS_RANDOM_BLOCK_STORAGE}, - {I2O_CLASS_END} -}; - -/** - * i2o_block_device_free - free the memory of the I2O Block device - * @dev: I2O Block device, which should be cleaned up - * - * Frees the request queue, gendisk and the i2o_block_device structure. - */ -static void i2o_block_device_free(struct i2o_block_device *dev) -{ - blk_cleanup_queue(dev->gd->queue); - - put_disk(dev->gd); - - kfree(dev); -}; - -/** - * i2o_block_remove - remove the I2O Block device from the system again - * @dev: I2O Block device which should be removed - * - * Remove gendisk from system and free all allocated memory. - * - * Always returns 0. - */ -static int i2o_block_remove(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev); - - osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid, - i2o_blk_dev->gd->disk_name); - - i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0); - - del_gendisk(i2o_blk_dev->gd); - - dev_set_drvdata(dev, NULL); - - i2o_device_claim_release(i2o_dev); - - i2o_block_device_free(i2o_blk_dev); - - return 0; -}; - -/** - * i2o_block_device flush - Flush all dirty data of I2O device dev - * @dev: I2O device which should be flushed - * - * Flushes all dirty data on device dev. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_device_flush(struct i2o_device *dev) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev-> - lct_data.tid); - msg->body[0] = cpu_to_le32(60 << 16); - osm_debug("Flushing...\n"); - - return i2o_msg_post_wait(dev->iop, msg, 60); -}; - -/** - * i2o_block_device_mount - Mount (load) the media of device dev - * @dev: I2O device which should receive the mount request - * @media_id: Media Identifier - * - * Load a media into drive. Identifier should be set to -1, because the - * spec does not support any other value. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev-> - lct_data.tid); - msg->body[0] = cpu_to_le32(-1); - msg->body[1] = cpu_to_le32(0x00000000); - osm_debug("Mounting...\n"); - - return i2o_msg_post_wait(dev->iop, msg, 2); -}; - -/** - * i2o_block_device_lock - Locks the media of device dev - * @dev: I2O device which should receive the lock request - * @media_id: Media Identifier - * - * Lock media of device dev to prevent removal. The media identifier - * should be set to -1, because the spec does not support any other value. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev-> - lct_data.tid); - msg->body[0] = cpu_to_le32(-1); - osm_debug("Locking...\n"); - - return i2o_msg_post_wait(dev->iop, msg, 2); -}; - -/** - * i2o_block_device_unlock - Unlocks the media of device dev - * @dev: I2O device which should receive the unlocked request - * @media_id: Media Identifier - * - * Unlocks the media in device dev. The media identifier should be set to - * -1, because the spec does not support any other value. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id) -{ - struct i2o_message *msg; - - msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev-> - lct_data.tid); - msg->body[0] = cpu_to_le32(media_id); - osm_debug("Unlocking...\n"); - - return i2o_msg_post_wait(dev->iop, msg, 2); -}; - -/** - * i2o_block_device_power - Power management for device dev - * @dev: I2O device which should receive the power management request - * @op: Operation to send - * - * Send a power management request to the device dev. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_device_power(struct i2o_block_device *dev, u8 op) -{ - struct i2o_device *i2o_dev = dev->i2o_dev; - struct i2o_controller *c = i2o_dev->iop; - struct i2o_message *msg; - int rc; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev-> - lct_data.tid); - msg->body[0] = cpu_to_le32(op << 24); - osm_debug("Power...\n"); - - rc = i2o_msg_post_wait(c, msg, 60); - if (!rc) - dev->power = op; - - return rc; -}; - -/** - * i2o_block_request_alloc - Allocate an I2O block request struct - * - * Allocates an I2O block request struct and initialize the list. - * - * Returns a i2o_block_request pointer on success or negative error code - * on failure. - */ -static inline struct i2o_block_request *i2o_block_request_alloc(void) -{ - struct i2o_block_request *ireq; - - ireq = mempool_alloc(i2o_blk_req_pool.pool, GFP_ATOMIC); - if (!ireq) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&ireq->queue); - sg_init_table(ireq->sg_table, I2O_MAX_PHYS_SEGMENTS); - - return ireq; -}; - -/** - * i2o_block_request_free - Frees a I2O block request - * @ireq: I2O block request which should be freed - * - * Frees the allocated memory (give it back to the request mempool). - */ -static inline void i2o_block_request_free(struct i2o_block_request *ireq) -{ - mempool_free(ireq, i2o_blk_req_pool.pool); -}; - -/** - * i2o_block_sglist_alloc - Allocate the SG list and map it - * @c: I2O controller to which the request belongs - * @ireq: I2O block request - * @mptr: message body pointer - * - * Builds the SG list and map it to be accessible by the controller. - * - * Returns 0 on failure or 1 on success. - */ -static inline int i2o_block_sglist_alloc(struct i2o_controller *c, - struct i2o_block_request *ireq, - u32 ** mptr) -{ - int nents; - enum dma_data_direction direction; - - ireq->dev = &c->pdev->dev; - nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table); - - if (rq_data_dir(ireq->req) == READ) - direction = PCI_DMA_FROMDEVICE; - else - direction = PCI_DMA_TODEVICE; - - ireq->sg_nents = nents; - - return i2o_dma_map_sg(c, ireq->sg_table, nents, direction, mptr); -}; - -/** - * i2o_block_sglist_free - Frees the SG list - * @ireq: I2O block request from which the SG should be freed - * - * Frees the SG list from the I2O block request. - */ -static inline void i2o_block_sglist_free(struct i2o_block_request *ireq) -{ - enum dma_data_direction direction; - - if (rq_data_dir(ireq->req) == READ) - direction = PCI_DMA_FROMDEVICE; - else - direction = PCI_DMA_TODEVICE; - - dma_unmap_sg(ireq->dev, ireq->sg_table, ireq->sg_nents, direction); -}; - -/** - * i2o_block_prep_req_fn - Allocates I2O block device specific struct - * @q: request queue for the request - * @req: the request to prepare - * - * Allocate the necessary i2o_block_request struct and connect it to - * the request. This is needed that we not lose the SG list later on. - * - * Returns BLKPREP_OK on success or BLKPREP_DEFER on failure. - */ -static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) -{ - struct i2o_block_device *i2o_blk_dev = q->queuedata; - struct i2o_block_request *ireq; - - if (unlikely(!i2o_blk_dev)) { - osm_err("block device already removed\n"); - return BLKPREP_KILL; - } - - /* connect the i2o_block_request to the request */ - if (!req->special) { - ireq = i2o_block_request_alloc(); - if (IS_ERR(ireq)) { - osm_debug("unable to allocate i2o_block_request!\n"); - return BLKPREP_DEFER; - } - - ireq->i2o_blk_dev = i2o_blk_dev; - req->special = ireq; - ireq->req = req; - } - /* do not come back here */ - req->cmd_flags |= REQ_DONTPREP; - - return BLKPREP_OK; -}; - -/** - * i2o_block_delayed_request_fn - delayed request queue function - * @work: the delayed request with the queue to start - * - * If the request queue is stopped for a disk, and there is no open - * request, a new event is created, which calls this function to start - * the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never - * be started again. - */ -static void i2o_block_delayed_request_fn(struct work_struct *work) -{ - struct i2o_block_delayed_request *dreq = - container_of(work, struct i2o_block_delayed_request, - work.work); - struct request_queue *q = dreq->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - blk_start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); - kfree(dreq); -}; - -/** - * i2o_block_end_request - Post-processing of completed commands - * @req: request which should be completed - * @error: 0 for success, < 0 for error - * @nr_bytes: number of bytes to complete - * - * Mark the request as complete. The lock must not be held when entering. - * - */ -static void i2o_block_end_request(struct request *req, int error, - int nr_bytes) -{ - struct i2o_block_request *ireq = req->special; - struct i2o_block_device *dev = ireq->i2o_blk_dev; - struct request_queue *q = req->q; - unsigned long flags; - - if (blk_end_request(req, error, nr_bytes)) - if (error) - blk_end_request_all(req, -EIO); - - spin_lock_irqsave(q->queue_lock, flags); - - if (likely(dev)) { - dev->open_queue_depth--; - list_del(&ireq->queue); - } - - blk_start_queue(q); - - spin_unlock_irqrestore(q->queue_lock, flags); - - i2o_block_sglist_free(ireq); - i2o_block_request_free(ireq); -}; - -/** - * i2o_block_reply - Block OSM reply handler. - * @c: I2O controller from which the message arrives - * @m: message id of reply - * @msg: the actual I2O message reply - * - * This function gets all the message replies. - * - */ -static int i2o_block_reply(struct i2o_controller *c, u32 m, - struct i2o_message *msg) -{ - struct request *req; - int error = 0; - - req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); - if (unlikely(!req)) { - osm_err("NULL reply received!\n"); - return -1; - } - - /* - * Lets see what is cooking. We stuffed the - * request in the context. - */ - - if ((le32_to_cpu(msg->body[0]) >> 24) != 0) { - u32 status = le32_to_cpu(msg->body[0]); - /* - * Device not ready means two things. One is that the - * the thing went offline (but not a removal media) - * - * The second is that you have a SuperTrak 100 and the - * firmware got constipated. Unlike standard i2o card - * setups the supertrak returns an error rather than - * blocking for the timeout in these cases. - * - * Don't stick a supertrak100 into cache aggressive modes - */ - - osm_err("TID %03x error status: 0x%02x, detailed status: " - "0x%04x\n", (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff), - status >> 24, status & 0xffff); - - req->errors++; - - error = -EIO; - } - - i2o_block_end_request(req, error, le32_to_cpu(msg->body[1])); - - return 1; -}; - -static void i2o_block_event(struct work_struct *work) -{ - struct i2o_event *evt = container_of(work, struct i2o_event, work); - osm_debug("event received\n"); - kfree(evt); -}; - -/* - * SCSI-CAM for ioctl geometry mapping - * Duplicated with SCSI - this should be moved into somewhere common - * perhaps genhd ? - * - * LBA -> CHS mapping table taken from: - * - * "Incorporating the I2O Architecture into BIOS for Intel Architecture - * Platforms" - * - * This is an I2O document that is only available to I2O members, - * not developers. - * - * From my understanding, this is how all the I2O cards do this - * - * Disk Size | Sectors | Heads | Cylinders - * ---------------+---------+-------+------------------- - * 1 < X <= 528M | 63 | 16 | X/(63 * 16 * 512) - * 528M < X <= 1G | 63 | 32 | X/(63 * 32 * 512) - * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512) - * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512) - * - */ -#define BLOCK_SIZE_528M 1081344 -#define BLOCK_SIZE_1G 2097152 -#define BLOCK_SIZE_21G 4403200 -#define BLOCK_SIZE_42G 8806400 -#define BLOCK_SIZE_84G 17612800 - -static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls, - unsigned char *hds, unsigned char *secs) -{ - unsigned long heads, sectors, cylinders; - - sectors = 63L; /* Maximize sectors per track */ - if (capacity <= BLOCK_SIZE_528M) - heads = 16; - else if (capacity <= BLOCK_SIZE_1G) - heads = 32; - else if (capacity <= BLOCK_SIZE_21G) - heads = 64; - else if (capacity <= BLOCK_SIZE_42G) - heads = 128; - else - heads = 255; - - cylinders = (unsigned long)capacity / (heads * sectors); - - *cyls = (unsigned short)cylinders; /* Stuff return values */ - *secs = (unsigned char)sectors; - *hds = (unsigned char)heads; -} - -/** - * i2o_block_open - Open the block device - * @bdev: block device being opened - * @mode: file open mode - * - * Power up the device, mount and lock the media. This function is called, - * if the block device is opened for access. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_open(struct block_device *bdev, fmode_t mode) -{ - struct i2o_block_device *dev = bdev->bd_disk->private_data; - - if (!dev->i2o_dev) - return -ENODEV; - - mutex_lock(&i2o_block_mutex); - if (dev->power > 0x1f) - i2o_block_device_power(dev, 0x02); - - i2o_block_device_mount(dev->i2o_dev, -1); - - i2o_block_device_lock(dev->i2o_dev, -1); - - osm_debug("Ready.\n"); - mutex_unlock(&i2o_block_mutex); - - return 0; -}; - -/** - * i2o_block_release - Release the I2O block device - * @disk: gendisk device being released - * @mode: file open mode - * - * Unlock and unmount the media, and power down the device. Gets called if - * the block device is closed. - */ -static void i2o_block_release(struct gendisk *disk, fmode_t mode) -{ - struct i2o_block_device *dev = disk->private_data; - u8 operation; - - /* - * This is to deal with the case of an application - * opening a device and then the device disappears while - * it's in use, and then the application tries to release - * it. ex: Unmounting a deleted RAID volume at reboot. - * If we send messages, it will just cause FAILs since - * the TID no longer exists. - */ - if (!dev->i2o_dev) - return; - - mutex_lock(&i2o_block_mutex); - i2o_block_device_flush(dev->i2o_dev); - - i2o_block_device_unlock(dev->i2o_dev, -1); - - if (dev->flags & (1 << 3 | 1 << 4)) /* Removable */ - operation = 0x21; - else - operation = 0x24; - - i2o_block_device_power(dev, operation); - mutex_unlock(&i2o_block_mutex); -} - -static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - i2o_block_biosparam(get_capacity(bdev->bd_disk), - &geo->cylinders, &geo->heads, &geo->sectors); - return 0; -} - -/** - * i2o_block_ioctl - Issue device specific ioctl calls. - * @bdev: block device being opened - * @mode: file open mode - * @cmd: ioctl command - * @arg: arg - * - * Handles ioctl request for the block device. - * - * Return 0 on success or negative error on failure. - */ -static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - struct gendisk *disk = bdev->bd_disk; - struct i2o_block_device *dev = disk->private_data; - int ret = -ENOTTY; - - /* Anyone capable of this syscall can do *real bad* things */ - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - mutex_lock(&i2o_block_mutex); - switch (cmd) { - case BLKI2OGRSTRAT: - ret = put_user(dev->rcache, (int __user *)arg); - break; - case BLKI2OGWSTRAT: - ret = put_user(dev->wcache, (int __user *)arg); - break; - case BLKI2OSRSTRAT: - ret = -EINVAL; - if (arg < 0 || arg > CACHE_SMARTFETCH) - break; - dev->rcache = arg; - ret = 0; - break; - case BLKI2OSWSTRAT: - ret = -EINVAL; - if (arg != 0 - && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) - break; - dev->wcache = arg; - ret = 0; - break; - } - mutex_unlock(&i2o_block_mutex); - - return ret; -}; - -/** - * i2o_block_check_events - Have we seen a media change? - * @disk: gendisk which should be verified - * @clearing: events being cleared - * - * Verifies if the media has changed. - * - * Returns 1 if the media was changed or 0 otherwise. - */ -static unsigned int i2o_block_check_events(struct gendisk *disk, - unsigned int clearing) -{ - struct i2o_block_device *p = disk->private_data; - - if (p->media_change_flag) { - p->media_change_flag = 0; - return DISK_EVENT_MEDIA_CHANGE; - } - return 0; -} - -/** - * i2o_block_transfer - Transfer a request to/from the I2O controller - * @req: the request which should be transferred - * - * This function converts the request into a I2O message. The necessary - * DMA buffers are allocated and after everything is setup post the message - * to the I2O controller. No cleanup is done by this function. It is done - * on the interrupt side when the reply arrives. - * - * Return 0 on success or negative error code on failure. - */ -static int i2o_block_transfer(struct request *req) -{ - struct i2o_block_device *dev = req->rq_disk->private_data; - struct i2o_controller *c; - u32 tid; - struct i2o_message *msg; - u32 *mptr; - struct i2o_block_request *ireq = req->special; - u32 tcntxt; - u32 sgl_offset = SGL_OFFSET_8; - u32 ctl_flags = 0x00000000; - int rc; - u32 cmd; - - if (unlikely(!dev->i2o_dev)) { - osm_err("transfer to removed drive\n"); - rc = -ENODEV; - goto exit; - } - - tid = dev->i2o_dev->lct_data.tid; - c = dev->i2o_dev->iop; - - msg = i2o_msg_get(c); - if (IS_ERR(msg)) { - rc = PTR_ERR(msg); - goto exit; - } - - tcntxt = i2o_cntxt_list_add(c, req); - if (!tcntxt) { - rc = -ENOMEM; - goto nop_msg; - } - - msg->u.s.icntxt = cpu_to_le32(i2o_block_driver.context); - msg->u.s.tcntxt = cpu_to_le32(tcntxt); - - mptr = &msg->body[0]; - - if (rq_data_dir(req) == READ) { - cmd = I2O_CMD_BLOCK_READ << 24; - - switch (dev->rcache) { - case CACHE_PREFETCH: - ctl_flags = 0x201F0008; - break; - - case CACHE_SMARTFETCH: - if (blk_rq_sectors(req) > 16) - ctl_flags = 0x201F0008; - else - ctl_flags = 0x001F0000; - break; - - default: - break; - } - } else { - cmd = I2O_CMD_BLOCK_WRITE << 24; - - switch (dev->wcache) { - case CACHE_WRITETHROUGH: - ctl_flags = 0x001F0008; - break; - case CACHE_WRITEBACK: - ctl_flags = 0x001F0010; - break; - case CACHE_SMARTBACK: - if (blk_rq_sectors(req) > 16) - ctl_flags = 0x001F0004; - else - ctl_flags = 0x001F0010; - break; - case CACHE_SMARTTHROUGH: - if (blk_rq_sectors(req) > 16) - ctl_flags = 0x001F0004; - else - ctl_flags = 0x001F0010; - default: - break; - } - } - -#ifdef CONFIG_I2O_EXT_ADAPTEC - if (c->adaptec) { - u8 cmd[10]; - u32 scsi_flags; - u16 hwsec; - - hwsec = queue_logical_block_size(req->q) >> KERNEL_SECTOR_SHIFT; - memset(cmd, 0, 10); - - sgl_offset = SGL_OFFSET_12; - - msg->u.head[1] = - cpu_to_le32(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid); - - *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC); - *mptr++ = cpu_to_le32(tid); - - /* - * ENABLE_DISCONNECT - * SIMPLE_TAG - * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME - */ - if (rq_data_dir(req) == READ) { - cmd[0] = READ_10; - scsi_flags = 0x60a0000a; - } else { - cmd[0] = WRITE_10; - scsi_flags = 0xa0a0000a; - } - - *mptr++ = cpu_to_le32(scsi_flags); - - *((u32 *) & cmd[2]) = cpu_to_be32(blk_rq_pos(req) * hwsec); - *((u16 *) & cmd[7]) = cpu_to_be16(blk_rq_sectors(req) * hwsec); - - memcpy(mptr, cmd, 10); - mptr += 4; - *mptr++ = cpu_to_le32(blk_rq_bytes(req)); - } else -#endif - { - msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid); - *mptr++ = cpu_to_le32(ctl_flags); - *mptr++ = cpu_to_le32(blk_rq_bytes(req)); - *mptr++ = - cpu_to_le32((u32) (blk_rq_pos(req) << KERNEL_SECTOR_SHIFT)); - *mptr++ = - cpu_to_le32(blk_rq_pos(req) >> (32 - KERNEL_SECTOR_SHIFT)); - } - - if (!i2o_block_sglist_alloc(c, ireq, &mptr)) { - rc = -ENOMEM; - goto context_remove; - } - - msg->u.head[0] = - cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset); - - list_add_tail(&ireq->queue, &dev->open_queue); - dev->open_queue_depth++; - - i2o_msg_post(c, msg); - - return 0; - -context_remove: - i2o_cntxt_list_remove(c, req); - -nop_msg: - i2o_msg_nop(c, msg); - -exit: - return rc; -}; - -/** - * i2o_block_request_fn - request queue handling function - * @q: request queue from which the request could be fetched - * - * Takes the next request from the queue, transfers it and if no error - * occurs dequeue it from the queue. On arrival of the reply the message - * will be processed further. If an error occurs requeue the request. - */ -static void i2o_block_request_fn(struct request_queue *q) -{ - struct request *req; - - while ((req = blk_peek_request(q)) != NULL) { - if (req->cmd_type == REQ_TYPE_FS) { - struct i2o_block_delayed_request *dreq; - struct i2o_block_request *ireq = req->special; - unsigned int queue_depth; - - queue_depth = ireq->i2o_blk_dev->open_queue_depth; - - if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) { - if (!i2o_block_transfer(req)) { - blk_start_request(req); - continue; - } else - osm_info("transfer error\n"); - } - - if (queue_depth) - break; - - /* stop the queue and retry later */ - dreq = kmalloc(sizeof(*dreq), GFP_ATOMIC); - if (!dreq) - continue; - - dreq->queue = q; - INIT_DELAYED_WORK(&dreq->work, - i2o_block_delayed_request_fn); - - if (!queue_delayed_work(i2o_block_driver.event_queue, - &dreq->work, - I2O_BLOCK_RETRY_TIME)) - kfree(dreq); - else { - blk_stop_queue(q); - break; - } - } else { - blk_start_request(req); - __blk_end_request_all(req, -EIO); - } - } -}; - -/* I2O Block device operations definition */ -static const struct block_device_operations i2o_block_fops = { - .owner = THIS_MODULE, - .open = i2o_block_open, - .release = i2o_block_release, - .ioctl = i2o_block_ioctl, - .compat_ioctl = i2o_block_ioctl, - .getgeo = i2o_block_getgeo, - .check_events = i2o_block_check_events, -}; - -/** - * i2o_block_device_alloc - Allocate memory for a I2O Block device - * - * Allocate memory for the i2o_block_device struct, gendisk and request - * queue and initialize them as far as no additional information is needed. - * - * Returns a pointer to the allocated I2O Block device on success or a - * negative error code on failure. - */ -static struct i2o_block_device *i2o_block_device_alloc(void) -{ - struct i2o_block_device *dev; - struct gendisk *gd; - struct request_queue *queue; - int rc; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - osm_err("Insufficient memory to allocate I2O Block disk.\n"); - rc = -ENOMEM; - goto exit; - } - - INIT_LIST_HEAD(&dev->open_queue); - spin_lock_init(&dev->lock); - dev->rcache = CACHE_PREFETCH; - dev->wcache = CACHE_WRITEBACK; - - /* allocate a gendisk with 16 partitions */ - gd = alloc_disk(16); - if (!gd) { - osm_err("Insufficient memory to allocate gendisk.\n"); - rc = -ENOMEM; - goto cleanup_dev; - } - - /* initialize the request queue */ - queue = blk_init_queue(i2o_block_request_fn, &dev->lock); - if (!queue) { - osm_err("Insufficient memory to allocate request queue.\n"); - rc = -ENOMEM; - goto cleanup_queue; - } - - blk_queue_prep_rq(queue, i2o_block_prep_req_fn); - - gd->major = I2O_MAJOR; - gd->queue = queue; - gd->fops = &i2o_block_fops; - gd->private_data = dev; - - dev->gd = gd; - - return dev; - -cleanup_queue: - put_disk(gd); - -cleanup_dev: - kfree(dev); - -exit: - return ERR_PTR(rc); -}; - -/** - * i2o_block_probe - verify if dev is a I2O Block device and install it - * @dev: device to verify if it is a I2O Block device - * - * We only verify if the user_tid of the device is 0xfff and then install - * the device. Otherwise it is used by some other device (e. g. RAID). - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_block_probe(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_controller *c = i2o_dev->iop; - struct i2o_block_device *i2o_blk_dev; - struct gendisk *gd; - struct request_queue *queue; - static int unit; - int rc; - u64 size; - u32 blocksize; - u16 body_size = 4; - u16 power; - unsigned short max_sectors; - -#ifdef CONFIG_I2O_EXT_ADAPTEC - if (c->adaptec) - body_size = 8; -#endif - - if (c->limit_sectors) - max_sectors = I2O_MAX_SECTORS_LIMITED; - else - max_sectors = I2O_MAX_SECTORS; - - /* skip devices which are used by IOP */ - if (i2o_dev->lct_data.user_tid != 0xfff) { - osm_debug("skipping used device %03x\n", i2o_dev->lct_data.tid); - return -ENODEV; - } - - if (i2o_device_claim(i2o_dev)) { - osm_warn("Unable to claim device. Installation aborted\n"); - rc = -EFAULT; - goto exit; - } - - i2o_blk_dev = i2o_block_device_alloc(); - if (IS_ERR(i2o_blk_dev)) { - osm_err("could not alloc a new I2O block device"); - rc = PTR_ERR(i2o_blk_dev); - goto claim_release; - } - - i2o_blk_dev->i2o_dev = i2o_dev; - dev_set_drvdata(dev, i2o_blk_dev); - - /* setup gendisk */ - gd = i2o_blk_dev->gd; - gd->first_minor = unit << 4; - sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit); - gd->driverfs_dev = &i2o_dev->device; - - /* setup request queue */ - queue = gd->queue; - queue->queuedata = i2o_blk_dev; - - blk_queue_max_hw_sectors(queue, max_sectors); - blk_queue_max_segments(queue, i2o_sg_tablesize(c, body_size)); - - osm_debug("max sectors = %d\n", queue->max_sectors); - osm_debug("phys segments = %d\n", queue->max_phys_segments); - osm_debug("max hw segments = %d\n", queue->max_hw_segments); - - /* - * Ask for the current media data. If that isn't supported - * then we ask for the device capacity data - */ - if (!i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) || - !i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) { - blk_queue_logical_block_size(queue, le32_to_cpu(blocksize)); - } else - osm_warn("unable to get blocksize of %s\n", gd->disk_name); - - if (!i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) || - !i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) { - set_capacity(gd, le64_to_cpu(size) >> KERNEL_SECTOR_SHIFT); - } else - osm_warn("could not get size of %s\n", gd->disk_name); - - if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2)) - i2o_blk_dev->power = power; - - i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff); - - add_disk(gd); - - unit++; - - osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid, - i2o_blk_dev->gd->disk_name); - - return 0; - -claim_release: - i2o_device_claim_release(i2o_dev); - -exit: - return rc; -}; - -/* Block OSM driver struct */ -static struct i2o_driver i2o_block_driver = { - .name = OSM_NAME, - .event = i2o_block_event, - .reply = i2o_block_reply, - .classes = i2o_block_class_id, - .driver = { - .probe = i2o_block_probe, - .remove = i2o_block_remove, - }, -}; - -/** - * i2o_block_init - Block OSM initialization function - * - * Allocate the slab and mempool for request structs, registers i2o_block - * block device and finally register the Block OSM in the I2O core. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_block_init(void) -{ - int rc; - int size; - - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - /* Allocate request mempool and slab */ - size = sizeof(struct i2o_block_request); - i2o_blk_req_pool.slab = kmem_cache_create("i2o_block_req", size, 0, - SLAB_HWCACHE_ALIGN, NULL); - if (!i2o_blk_req_pool.slab) { - osm_err("can't init request slab\n"); - rc = -ENOMEM; - goto exit; - } - - i2o_blk_req_pool.pool = - mempool_create_slab_pool(I2O_BLOCK_REQ_MEMPOOL_SIZE, - i2o_blk_req_pool.slab); - if (!i2o_blk_req_pool.pool) { - osm_err("can't init request mempool\n"); - rc = -ENOMEM; - goto free_slab; - } - - /* Register the block device interfaces */ - rc = register_blkdev(I2O_MAJOR, "i2o_block"); - if (rc) { - osm_err("unable to register block device\n"); - goto free_mempool; - } -#ifdef MODULE - osm_info("registered device at major %d\n", I2O_MAJOR); -#endif - - /* Register Block OSM into I2O core */ - rc = i2o_driver_register(&i2o_block_driver); - if (rc) { - osm_err("Could not register Block driver\n"); - goto unregister_blkdev; - } - - return 0; - -unregister_blkdev: - unregister_blkdev(I2O_MAJOR, "i2o_block"); - -free_mempool: - mempool_destroy(i2o_blk_req_pool.pool); - -free_slab: - kmem_cache_destroy(i2o_blk_req_pool.slab); - -exit: - return rc; -}; - -/** - * i2o_block_exit - Block OSM exit function - * - * Unregisters Block OSM from I2O core, unregisters i2o_block block device - * and frees the mempool and slab. - */ -static void __exit i2o_block_exit(void) -{ - /* Unregister I2O Block OSM from I2O core */ - i2o_driver_unregister(&i2o_block_driver); - - /* Unregister block device */ - unregister_blkdev(I2O_MAJOR, "i2o_block"); - - /* Free request mempool and slab */ - mempool_destroy(i2o_blk_req_pool.pool); - kmem_cache_destroy(i2o_blk_req_pool.slab); -}; - -MODULE_AUTHOR("Red Hat"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -module_init(i2o_block_init); -module_exit(i2o_block_exit); diff --git a/drivers/staging/i2o/i2o_block.h b/drivers/staging/i2o/i2o_block.h deleted file mode 100644 index cf8873cbca3f..000000000000 --- a/drivers/staging/i2o/i2o_block.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Block OSM structures/API - * - * Copyright (C) 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * For the purpose of avoiding doubt the preferred form of the work - * for making modifications shall be a standards compliant form such - * gzipped tar and not one requiring a proprietary or patent encumbered - * tool to unpack. - * - * Fixes/additions: - * Steve Ralston: - * Multiple device handling error fixes, - * Added a queue depth. - * Alan Cox: - * FC920 has an rmw bug. Dont or in the end marker. - * Removed queue walk, fixed for 64bitness. - * Rewrote much of the code over time - * Added indirect block lists - * Handle 64K limits on many controllers - * Don't use indirects on the Promise (breaks) - * Heavily chop down the queue depths - * Deepak Saxena: - * Independent queues per IOP - * Support for dynamic device creation/deletion - * Code cleanup - * Support for larger I/Os through merge* functions - * (taken from DAC960 driver) - * Boji T Kannanthanam: - * Set the I2O Block devices to be detected in increasing - * order of TIDs during boot. - * Search and set the I2O block device that we boot off - * from as the first device to be claimed (as /dev/i2o/hda) - * Properly attach/detach I2O gendisk structure from the - * system gendisk list. The I2O block devices now appear in - * /proc/partitions. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor bugfixes for 2.6. - */ - -#ifndef I2O_BLOCK_OSM_H -#define I2O_BLOCK_OSM_H - -#define I2O_BLOCK_RETRY_TIME HZ/4 -#define I2O_BLOCK_MAX_OPEN_REQUESTS 50 - -/* request queue sizes */ -#define I2O_BLOCK_REQ_MEMPOOL_SIZE 32 - -#define KERNEL_SECTOR_SHIFT 9 -#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT) - -/* I2O Block OSM mempool struct */ -struct i2o_block_mempool { - struct kmem_cache *slab; - mempool_t *pool; -}; - -/* I2O Block device descriptor */ -struct i2o_block_device { - struct i2o_device *i2o_dev; /* pointer to I2O device */ - struct gendisk *gd; - spinlock_t lock; /* queue lock */ - struct list_head open_queue; /* list of transferred, but unfinished - requests */ - unsigned int open_queue_depth; /* number of requests in the queue */ - - int rcache; /* read cache flags */ - int wcache; /* write cache flags */ - int flags; - u16 power; /* power state */ - int media_change_flag; /* media changed flag */ -}; - -/* I2O Block device request */ -struct i2o_block_request { - struct list_head queue; - struct request *req; /* corresponding request */ - struct i2o_block_device *i2o_blk_dev; /* I2O block device */ - struct device *dev; /* device used for DMA */ - int sg_nents; /* number of SG elements */ - struct scatterlist sg_table[I2O_MAX_PHYS_SEGMENTS]; /* SG table */ -}; - -/* I2O Block device delayed request */ -struct i2o_block_delayed_request { - struct delayed_work work; - struct request_queue *queue; -}; - -#endif diff --git a/drivers/staging/i2o/i2o_config.c b/drivers/staging/i2o/i2o_config.c deleted file mode 100644 index cd7ca5eb18ff..000000000000 --- a/drivers/staging/i2o/i2o_config.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* - * I2O Configuration Interface Driver - * - * (C) Copyright 1999-2002 Red Hat - * - * Written by Alan Cox, Building Number Three Ltd - * - * Fixes/additions: - * Deepak Saxena (04/20/1999): - * Added basic ioctl() support - * Deepak Saxena (06/07/1999): - * Added software download ioctl (still testing) - * Auvo Häkkinen (09/10/1999): - * Changes to i2o_cfg_reply(), ioctl_parms() - * Added ioct_validate() - * Taneli Vähäkangas (09/30/1999): - * Fixed ioctl_swdl() - * Taneli Vähäkangas (10/04/1999): - * Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel() - * Deepak Saxena (11/18/1999): - * Added event managmenet support - * Alan Cox <alan@lxorguk.ukuu.org.uk>: - * 2.4 rewrite ported to 2.5 - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Added pass-thru support for Adaptec's raidutils - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <linux/miscdevice.h> -#include <linux/mutex.h> -#include <linux/compat.h> -#include <linux/slab.h> -#include <linux/uaccess.h> - -#include "core.h" - -#define SG_TABLESIZE 30 - -static DEFINE_MUTEX(i2o_cfg_mutex); -static long i2o_cfg_ioctl(struct file *, unsigned int, unsigned long); - -static spinlock_t i2o_config_lock; - -#define MODINC(x,y) ((x) = ((x) + 1) % (y)) - -struct sg_simple_element { - u32 flag_count; - u32 addr_bus; -}; - -struct i2o_cfg_info { - struct file *fp; - struct fasync_struct *fasync; - struct i2o_evt_info event_q[I2O_EVT_Q_LEN]; - u16 q_in; // Queue head index - u16 q_out; // Queue tail index - u16 q_len; // Queue length - u16 q_lost; // Number of lost events - ulong q_id; // Event queue ID...used as tx_context - struct i2o_cfg_info *next; -}; -static struct i2o_cfg_info *open_files = NULL; -static ulong i2o_cfg_info_id; - -static int i2o_cfg_getiops(unsigned long arg) -{ - struct i2o_controller *c; - u8 __user *user_iop_table = (void __user *)arg; - u8 tmp[MAX_I2O_CONTROLLERS]; - int ret = 0; - - memset(tmp, 0, MAX_I2O_CONTROLLERS); - - list_for_each_entry(c, &i2o_controllers, list) - tmp[c->unit] = 1; - - if (copy_to_user(user_iop_table, tmp, MAX_I2O_CONTROLLERS)) - ret = -EFAULT; - - return ret; -}; - -static int i2o_cfg_gethrt(unsigned long arg) -{ - struct i2o_controller *c; - struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg; - struct i2o_cmd_hrtlct kcmd; - i2o_hrt *hrt; - int len; - u32 reslen; - int ret = 0; - - if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct))) - return -EFAULT; - - if (get_user(reslen, kcmd.reslen) < 0) - return -EFAULT; - - if (kcmd.resbuf == NULL) - return -EFAULT; - - c = i2o_find_iop(kcmd.iop); - if (!c) - return -ENXIO; - - hrt = (i2o_hrt *) c->hrt.virt; - - len = 8 + ((hrt->entry_len * hrt->num_entries) << 2); - - if (put_user(len, kcmd.reslen)) - ret = -EFAULT; - else if (len > reslen) - ret = -ENOBUFS; - else if (copy_to_user(kcmd.resbuf, (void *)hrt, len)) - ret = -EFAULT; - - return ret; -}; - -static int i2o_cfg_getlct(unsigned long arg) -{ - struct i2o_controller *c; - struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg; - struct i2o_cmd_hrtlct kcmd; - i2o_lct *lct; - int len; - int ret = 0; - u32 reslen; - - if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct))) - return -EFAULT; - - if (get_user(reslen, kcmd.reslen) < 0) - return -EFAULT; - - if (kcmd.resbuf == NULL) - return -EFAULT; - - c = i2o_find_iop(kcmd.iop); - if (!c) - return -ENXIO; - - lct = (i2o_lct *) c->lct; - - len = (unsigned int)lct->table_size << 2; - if (put_user(len, kcmd.reslen)) - ret = -EFAULT; - else if (len > reslen) - ret = -ENOBUFS; - else if (copy_to_user(kcmd.resbuf, lct, len)) - ret = -EFAULT; - - return ret; -}; - -static int i2o_cfg_parms(unsigned long arg, unsigned int type) -{ - int ret = 0; - struct i2o_controller *c; - struct i2o_device *dev; - struct i2o_cmd_psetget __user *cmd = - (struct i2o_cmd_psetget __user *)arg; - struct i2o_cmd_psetget kcmd; - u32 reslen; - u8 *ops; - u8 *res; - int len = 0; - - u32 i2o_cmd = (type == I2OPARMGET ? - I2O_CMD_UTIL_PARAMS_GET : I2O_CMD_UTIL_PARAMS_SET); - - if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_psetget))) - return -EFAULT; - - if (get_user(reslen, kcmd.reslen)) - return -EFAULT; - - c = i2o_find_iop(kcmd.iop); - if (!c) - return -ENXIO; - - dev = i2o_iop_find_device(c, kcmd.tid); - if (!dev) - return -ENXIO; - - /* - * Stop users being able to try and allocate arbitrary amounts - * of DMA space. 64K is way more than sufficient for this. - */ - if (kcmd.oplen > 65536) - return -EMSGSIZE; - - ops = memdup_user(kcmd.opbuf, kcmd.oplen); - if (IS_ERR(ops)) - return PTR_ERR(ops); - - /* - * It's possible to have a _very_ large table - * and that the user asks for all of it at once... - */ - res = kmalloc(65536, GFP_KERNEL); - if (!res) { - kfree(ops); - return -ENOMEM; - } - - len = i2o_parm_issue(dev, i2o_cmd, ops, kcmd.oplen, res, 65536); - kfree(ops); - - if (len < 0) { - kfree(res); - return -EAGAIN; - } - - if (put_user(len, kcmd.reslen)) - ret = -EFAULT; - else if (len > reslen) - ret = -ENOBUFS; - else if (copy_to_user(kcmd.resbuf, res, len)) - ret = -EFAULT; - - kfree(res); - - return ret; -}; - -static int i2o_cfg_swdl(unsigned long arg) -{ - struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; - unsigned char maxfrag = 0, curfrag = 1; - struct i2o_dma buffer; - struct i2o_message *msg; - unsigned int status = 0, swlen = 0, fragsize = 8192; - struct i2o_controller *c; - - if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) - return -EFAULT; - - if (get_user(swlen, kxfer.swlen) < 0) - return -EFAULT; - - if (get_user(maxfrag, kxfer.maxfrag) < 0) - return -EFAULT; - - if (get_user(curfrag, kxfer.curfrag) < 0) - return -EFAULT; - - if (curfrag == maxfrag) - fragsize = swlen - (maxfrag - 1) * 8192; - - if (!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize)) - return -EFAULT; - - c = i2o_find_iop(kxfer.iop); - if (!c) - return -ENXIO; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) { - i2o_msg_nop(c, msg); - return -ENOMEM; - } - - if (__copy_from_user(buffer.virt, kxfer.buf, fragsize)) { - i2o_msg_nop(c, msg); - i2o_dma_free(&c->pdev->dev, &buffer); - return -EFAULT; - } - - msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); - msg->u.head[3] = cpu_to_le32(0); - msg->body[0] = - cpu_to_le32((((u32) kxfer.flags) << 24) | (((u32) kxfer. - sw_type) << 16) | - (((u32) maxfrag) << 8) | (((u32) curfrag))); - msg->body[1] = cpu_to_le32(swlen); - msg->body[2] = cpu_to_le32(kxfer.sw_id); - msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); - msg->body[4] = cpu_to_le32(buffer.phys); - - osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); - status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); - - if (status != -ETIMEDOUT) - i2o_dma_free(&c->pdev->dev, &buffer); - - if (status != I2O_POST_WAIT_OK) { - // it fails if you try and send frags out of order - // and for some yet unknown reasons too - osm_info("swdl failed, DetailedStatus = %d\n", status); - return status; - } - - return 0; -}; - -static int i2o_cfg_swul(unsigned long arg) -{ - struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; - unsigned char maxfrag = 0, curfrag = 1; - struct i2o_dma buffer; - struct i2o_message *msg; - unsigned int status = 0, swlen = 0, fragsize = 8192; - struct i2o_controller *c; - int ret = 0; - - if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) - return -EFAULT; - - if (get_user(swlen, kxfer.swlen) < 0) - return -EFAULT; - - if (get_user(maxfrag, kxfer.maxfrag) < 0) - return -EFAULT; - - if (get_user(curfrag, kxfer.curfrag) < 0) - return -EFAULT; - - if (curfrag == maxfrag) - fragsize = swlen - (maxfrag - 1) * 8192; - - if (!kxfer.buf) - return -EFAULT; - - c = i2o_find_iop(kxfer.iop); - if (!c) - return -ENXIO; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) { - i2o_msg_nop(c, msg); - return -ENOMEM; - } - - msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID); - msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); - msg->u.head[3] = cpu_to_le32(0); - msg->body[0] = - cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer. - sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag); - msg->body[1] = cpu_to_le32(swlen); - msg->body[2] = cpu_to_le32(kxfer.sw_id); - msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); - msg->body[4] = cpu_to_le32(buffer.phys); - - osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); - status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); - - if (status != I2O_POST_WAIT_OK) { - if (status != -ETIMEDOUT) - i2o_dma_free(&c->pdev->dev, &buffer); - - osm_info("swul failed, DetailedStatus = %d\n", status); - return status; - } - - if (copy_to_user(kxfer.buf, buffer.virt, fragsize)) - ret = -EFAULT; - - i2o_dma_free(&c->pdev->dev, &buffer); - - return ret; -} - -static int i2o_cfg_swdel(unsigned long arg) -{ - struct i2o_controller *c; - struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; - struct i2o_message *msg; - unsigned int swlen; - int token; - - if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) - return -EFAULT; - - if (get_user(swlen, kxfer.swlen) < 0) - return -EFAULT; - - c = i2o_find_iop(kxfer.iop); - if (!c) - return -ENXIO; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID); - msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); - msg->u.head[3] = cpu_to_le32(0); - msg->body[0] = - cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16); - msg->body[1] = cpu_to_le32(swlen); - msg->body[2] = cpu_to_le32(kxfer.sw_id); - - token = i2o_msg_post_wait(c, msg, 10); - - if (token != I2O_POST_WAIT_OK) { - osm_info("swdel failed, DetailedStatus = %d\n", token); - return -ETIMEDOUT; - } - - return 0; -}; - -static int i2o_cfg_validate(unsigned long arg) -{ - int token; - int iop = (int)arg; - struct i2o_message *msg; - struct i2o_controller *c; - - c = i2o_find_iop(iop); - if (!c) - return -ENXIO; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop); - msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); - msg->u.head[3] = cpu_to_le32(0); - - token = i2o_msg_post_wait(c, msg, 10); - - if (token != I2O_POST_WAIT_OK) { - osm_info("Can't validate configuration, ErrorStatus = %d\n", - token); - return -ETIMEDOUT; - } - - return 0; -}; - -static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) -{ - struct i2o_message *msg; - struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg; - struct i2o_evt_id kdesc; - struct i2o_controller *c; - struct i2o_device *d; - - if (copy_from_user(&kdesc, pdesc, sizeof(struct i2o_evt_id))) - return -EFAULT; - - /* IOP exists? */ - c = i2o_find_iop(kdesc.iop); - if (!c) - return -ENXIO; - - /* Device exists? */ - d = i2o_iop_find_device(c, kdesc.tid); - if (!d) - return -ENODEV; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | - kdesc.tid); - msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); - msg->u.head[3] = cpu_to_le32(i2o_cntxt_list_add(c, fp->private_data)); - msg->body[0] = cpu_to_le32(kdesc.evt_mask); - - i2o_msg_post(c, msg); - - return 0; -} - -static int i2o_cfg_evt_get(unsigned long arg, struct file *fp) -{ - struct i2o_cfg_info *p = NULL; - struct i2o_evt_get __user *uget = (struct i2o_evt_get __user *)arg; - struct i2o_evt_get kget; - unsigned long flags; - - for (p = open_files; p; p = p->next) - if (p->q_id == (ulong) fp->private_data) - break; - - if (!p->q_len) - return -ENOENT; - - memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info)); - MODINC(p->q_out, I2O_EVT_Q_LEN); - spin_lock_irqsave(&i2o_config_lock, flags); - p->q_len--; - kget.pending = p->q_len; - kget.lost = p->q_lost; - spin_unlock_irqrestore(&i2o_config_lock, flags); - - if (copy_to_user(uget, &kget, sizeof(struct i2o_evt_get))) - return -EFAULT; - return 0; -} - -#ifdef CONFIG_COMPAT -static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, - unsigned long arg) -{ - struct i2o_cmd_passthru32 __user *cmd; - struct i2o_controller *c; - u32 __user *user_msg; - u32 *reply = NULL; - u32 __user *user_reply = NULL; - u32 size = 0; - u32 reply_size = 0; - u32 rcode = 0; - struct i2o_dma sg_list[SG_TABLESIZE]; - u32 sg_offset = 0; - u32 sg_count = 0; - u32 i = 0; - u32 sg_index = 0; - i2o_status_block *sb; - struct i2o_message *msg; - unsigned int iop; - - cmd = (struct i2o_cmd_passthru32 __user *)arg; - - if (get_user(iop, &cmd->iop) || get_user(i, &cmd->msg)) - return -EFAULT; - - user_msg = compat_ptr(i); - - c = i2o_find_iop(iop); - if (!c) { - osm_debug("controller %d not found\n", iop); - return -ENXIO; - } - - sb = c->status_block.virt; - - if (get_user(size, &user_msg[0])) { - osm_warn("unable to get size!\n"); - return -EFAULT; - } - size = size >> 16; - - if (size > sb->inbound_frame_size) { - osm_warn("size of message > inbound_frame_size"); - return -EFAULT; - } - - user_reply = &user_msg[size]; - - size <<= 2; // Convert to bytes - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - rcode = -EFAULT; - /* Copy in the user's I2O command */ - if (copy_from_user(msg, user_msg, size)) { - osm_warn("unable to copy user message\n"); - goto out; - } - i2o_dump_message(msg); - - if (get_user(reply_size, &user_reply[0]) < 0) - goto out; - - reply_size >>= 16; - reply_size <<= 2; - - rcode = -ENOMEM; - reply = kzalloc(reply_size, GFP_KERNEL); - if (!reply) { - printk(KERN_WARNING "%s: Could not allocate reply buffer\n", - c->name); - goto out; - } - - sg_offset = (msg->u.head[0] >> 4) & 0x0f; - - memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); - if (sg_offset) { - struct sg_simple_element *sg; - - if (sg_offset * 4 >= size) { - rcode = -EFAULT; - goto cleanup; - } - // TODO 64bit fix - sg = (struct sg_simple_element *)((&msg->u.head[0]) + - sg_offset); - sg_count = - (size - sg_offset * 4) / sizeof(struct sg_simple_element); - if (sg_count > SG_TABLESIZE) { - printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n", - c->name, sg_count); - rcode = -EINVAL; - goto cleanup; - } - - for (i = 0; i < sg_count; i++) { - int sg_size; - struct i2o_dma *p; - - if (!(sg[i].flag_count & 0x10000000 - /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) { - printk(KERN_DEBUG - "%s:Bad SG element %d - not simple (%x)\n", - c->name, i, sg[i].flag_count); - rcode = -EINVAL; - goto cleanup; - } - sg_size = sg[i].flag_count & 0xffffff; - p = &(sg_list[sg_index]); - /* Allocate memory for the transfer */ - if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) { - printk(KERN_DEBUG - "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - c->name, sg_size, i, sg_count); - rcode = -ENOMEM; - goto sg_list_cleanup; - } - sg_index++; - /* Copy in the user's SG buffer if necessary */ - if (sg[i]. - flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { - // TODO 64bit fix - if (copy_from_user - (p->virt, - (void __user *)(unsigned long)sg[i]. - addr_bus, sg_size)) { - printk(KERN_DEBUG - "%s: Could not copy SG buf %d FROM user\n", - c->name, i); - rcode = -EFAULT; - goto sg_list_cleanup; - } - } - //TODO 64bit fix - sg[i].addr_bus = (u32) p->phys; - } - } - - rcode = i2o_msg_post_wait(c, msg, 60); - msg = NULL; - if (rcode) { - reply[4] = ((u32) rcode) << 24; - goto sg_list_cleanup; - } - - if (sg_offset) { - u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE]; - /* Copy back the Scatter Gather buffers back to user space */ - u32 j; - // TODO 64bit fix - struct sg_simple_element *sg; - int sg_size; - - // re-acquire the original message to handle correctly the sg copy operation - memset(&rmsg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4); - // get user msg size in u32s - if (get_user(size, &user_msg[0])) { - rcode = -EFAULT; - goto sg_list_cleanup; - } - size = size >> 16; - size *= 4; - if (size > sizeof(rmsg)) { - rcode = -EINVAL; - goto sg_list_cleanup; - } - - /* Copy in the user's I2O command */ - if (copy_from_user(rmsg, user_msg, size)) { - rcode = -EFAULT; - goto sg_list_cleanup; - } - sg_count = - (size - sg_offset * 4) / sizeof(struct sg_simple_element); - - // TODO 64bit fix - sg = (struct sg_simple_element *)(rmsg + sg_offset); - for (j = 0; j < sg_count; j++) { - /* Copy out the SG list to user's buffer if necessary */ - if (! - (sg[j]. - flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) { - sg_size = sg[j].flag_count & 0xffffff; - // TODO 64bit fix - if (copy_to_user - ((void __user *)(u64) sg[j].addr_bus, - sg_list[j].virt, sg_size)) { - printk(KERN_WARNING - "%s: Could not copy %p TO user %x\n", - c->name, sg_list[j].virt, - sg[j].addr_bus); - rcode = -EFAULT; - goto sg_list_cleanup; - } - } - } - } - -sg_list_cleanup: - /* Copy back the reply to user space */ - if (reply_size) { - // we wrote our own values for context - now restore the user supplied ones - if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) { - printk(KERN_WARNING - "%s: Could not copy message context FROM user\n", - c->name); - rcode = -EFAULT; - } - if (copy_to_user(user_reply, reply, reply_size)) { - printk(KERN_WARNING - "%s: Could not copy reply TO user\n", c->name); - rcode = -EFAULT; - } - } - for (i = 0; i < sg_index; i++) - i2o_dma_free(&c->pdev->dev, &sg_list[i]); - -cleanup: - kfree(reply); -out: - if (msg) - i2o_msg_nop(c, msg); - return rcode; -} - -static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, - unsigned long arg) -{ - int ret; - switch (cmd) { - case I2OGETIOPS: - ret = i2o_cfg_ioctl(file, cmd, arg); - break; - case I2OPASSTHRU32: - mutex_lock(&i2o_cfg_mutex); - ret = i2o_cfg_passthru32(file, cmd, arg); - mutex_unlock(&i2o_cfg_mutex); - break; - default: - ret = -ENOIOCTLCMD; - break; - } - return ret; -} - -#endif - -#ifdef CONFIG_I2O_EXT_ADAPTEC -static int i2o_cfg_passthru(unsigned long arg) -{ - struct i2o_cmd_passthru __user *cmd = - (struct i2o_cmd_passthru __user *)arg; - struct i2o_controller *c; - u32 __user *user_msg; - u32 *reply = NULL; - u32 __user *user_reply = NULL; - u32 size = 0; - u32 reply_size = 0; - u32 rcode = 0; - struct i2o_dma sg_list[SG_TABLESIZE]; - u32 sg_offset = 0; - u32 sg_count = 0; - int sg_index = 0; - u32 i = 0; - i2o_status_block *sb; - struct i2o_message *msg; - unsigned int iop; - - if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) - return -EFAULT; - - c = i2o_find_iop(iop); - if (!c) { - osm_warn("controller %d not found\n", iop); - return -ENXIO; - } - - sb = c->status_block.virt; - - if (get_user(size, &user_msg[0])) - return -EFAULT; - size = size >> 16; - - if (size > sb->inbound_frame_size) { - osm_warn("size of message > inbound_frame_size"); - return -EFAULT; - } - - user_reply = &user_msg[size]; - - size <<= 2; // Convert to bytes - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - rcode = -EFAULT; - /* Copy in the user's I2O command */ - if (copy_from_user(msg, user_msg, size)) - goto out; - - if (get_user(reply_size, &user_reply[0]) < 0) - goto out; - - reply_size >>= 16; - reply_size <<= 2; - - reply = kzalloc(reply_size, GFP_KERNEL); - if (!reply) { - printk(KERN_WARNING "%s: Could not allocate reply buffer\n", - c->name); - rcode = -ENOMEM; - goto out; - } - - sg_offset = (msg->u.head[0] >> 4) & 0x0f; - - memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); - if (sg_offset) { - struct sg_simple_element *sg; - struct i2o_dma *p; - - if (sg_offset * 4 >= size) { - rcode = -EFAULT; - goto cleanup; - } - // TODO 64bit fix - sg = (struct sg_simple_element *)((&msg->u.head[0]) + - sg_offset); - sg_count = - (size - sg_offset * 4) / sizeof(struct sg_simple_element); - if (sg_count > SG_TABLESIZE) { - printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n", - c->name, sg_count); - rcode = -EINVAL; - goto cleanup; - } - - for (i = 0; i < sg_count; i++) { - int sg_size; - - if (!(sg[i].flag_count & 0x10000000 - /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) { - printk(KERN_DEBUG - "%s:Bad SG element %d - not simple (%x)\n", - c->name, i, sg[i].flag_count); - rcode = -EINVAL; - goto sg_list_cleanup; - } - sg_size = sg[i].flag_count & 0xffffff; - p = &(sg_list[sg_index]); - if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) { - /* Allocate memory for the transfer */ - printk(KERN_DEBUG - "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - c->name, sg_size, i, sg_count); - rcode = -ENOMEM; - goto sg_list_cleanup; - } - sg_index++; - /* Copy in the user's SG buffer if necessary */ - if (sg[i]. - flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { - // TODO 64bit fix - if (copy_from_user - (p->virt, (void __user *)sg[i].addr_bus, - sg_size)) { - printk(KERN_DEBUG - "%s: Could not copy SG buf %d FROM user\n", - c->name, i); - rcode = -EFAULT; - goto sg_list_cleanup; - } - } - sg[i].addr_bus = p->phys; - } - } - - rcode = i2o_msg_post_wait(c, msg, 60); - msg = NULL; - if (rcode) { - reply[4] = ((u32) rcode) << 24; - goto sg_list_cleanup; - } - - if (sg_offset) { - u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE]; - /* Copy back the Scatter Gather buffers back to user space */ - u32 j; - // TODO 64bit fix - struct sg_simple_element *sg; - int sg_size; - - // re-acquire the original message to handle correctly the sg copy operation - memset(&rmsg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4); - // get user msg size in u32s - if (get_user(size, &user_msg[0])) { - rcode = -EFAULT; - goto sg_list_cleanup; - } - size = size >> 16; - size *= 4; - if (size > sizeof(rmsg)) { - rcode = -EFAULT; - goto sg_list_cleanup; - } - - /* Copy in the user's I2O command */ - if (copy_from_user(rmsg, user_msg, size)) { - rcode = -EFAULT; - goto sg_list_cleanup; - } - sg_count = - (size - sg_offset * 4) / sizeof(struct sg_simple_element); - - // TODO 64bit fix - sg = (struct sg_simple_element *)(rmsg + sg_offset); - for (j = 0; j < sg_count; j++) { - /* Copy out the SG list to user's buffer if necessary */ - if (! - (sg[j]. - flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) { - sg_size = sg[j].flag_count & 0xffffff; - // TODO 64bit fix - if (copy_to_user - ((void __user *)sg[j].addr_bus, sg_list[j].virt, - sg_size)) { - printk(KERN_WARNING - "%s: Could not copy %p TO user %x\n", - c->name, sg_list[j].virt, - sg[j].addr_bus); - rcode = -EFAULT; - goto sg_list_cleanup; - } - } - } - } - -sg_list_cleanup: - /* Copy back the reply to user space */ - if (reply_size) { - // we wrote our own values for context - now restore the user supplied ones - if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) { - printk(KERN_WARNING - "%s: Could not copy message context FROM user\n", - c->name); - rcode = -EFAULT; - } - if (copy_to_user(user_reply, reply, reply_size)) { - printk(KERN_WARNING - "%s: Could not copy reply TO user\n", c->name); - rcode = -EFAULT; - } - } - - for (i = 0; i < sg_index; i++) - i2o_dma_free(&c->pdev->dev, &sg_list[i]); - -cleanup: - kfree(reply); -out: - if (msg) - i2o_msg_nop(c, msg); - return rcode; -} -#endif - -/* - * IOCTL Handler - */ -static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) -{ - int ret; - - mutex_lock(&i2o_cfg_mutex); - switch (cmd) { - case I2OGETIOPS: - ret = i2o_cfg_getiops(arg); - break; - - case I2OHRTGET: - ret = i2o_cfg_gethrt(arg); - break; - - case I2OLCTGET: - ret = i2o_cfg_getlct(arg); - break; - - case I2OPARMSET: - ret = i2o_cfg_parms(arg, I2OPARMSET); - break; - - case I2OPARMGET: - ret = i2o_cfg_parms(arg, I2OPARMGET); - break; - - case I2OSWDL: - ret = i2o_cfg_swdl(arg); - break; - - case I2OSWUL: - ret = i2o_cfg_swul(arg); - break; - - case I2OSWDEL: - ret = i2o_cfg_swdel(arg); - break; - - case I2OVALIDATE: - ret = i2o_cfg_validate(arg); - break; - - case I2OEVTREG: - ret = i2o_cfg_evt_reg(arg, fp); - break; - - case I2OEVTGET: - ret = i2o_cfg_evt_get(arg, fp); - break; - -#ifdef CONFIG_I2O_EXT_ADAPTEC - case I2OPASSTHRU: - ret = i2o_cfg_passthru(arg); - break; -#endif - - default: - osm_debug("unknown ioctl called!\n"); - ret = -EINVAL; - } - mutex_unlock(&i2o_cfg_mutex); - return ret; -} - -static int cfg_open(struct inode *inode, struct file *file) -{ - struct i2o_cfg_info *tmp = kmalloc(sizeof(struct i2o_cfg_info), - GFP_KERNEL); - unsigned long flags; - - if (!tmp) - return -ENOMEM; - - mutex_lock(&i2o_cfg_mutex); - file->private_data = (void *)(i2o_cfg_info_id++); - tmp->fp = file; - tmp->fasync = NULL; - tmp->q_id = (ulong) file->private_data; - tmp->q_len = 0; - tmp->q_in = 0; - tmp->q_out = 0; - tmp->q_lost = 0; - tmp->next = open_files; - - spin_lock_irqsave(&i2o_config_lock, flags); - open_files = tmp; - spin_unlock_irqrestore(&i2o_config_lock, flags); - mutex_unlock(&i2o_cfg_mutex); - - return 0; -} - -static int cfg_fasync(int fd, struct file *fp, int on) -{ - ulong id = (ulong) fp->private_data; - struct i2o_cfg_info *p; - int ret = -EBADF; - - mutex_lock(&i2o_cfg_mutex); - for (p = open_files; p; p = p->next) - if (p->q_id == id) - break; - - if (p) - ret = fasync_helper(fd, fp, on, &p->fasync); - mutex_unlock(&i2o_cfg_mutex); - return ret; -} - -static int cfg_release(struct inode *inode, struct file *file) -{ - ulong id = (ulong) file->private_data; - struct i2o_cfg_info *p, **q; - unsigned long flags; - - mutex_lock(&i2o_cfg_mutex); - spin_lock_irqsave(&i2o_config_lock, flags); - for (q = &open_files; (p = *q) != NULL; q = &p->next) { - if (p->q_id == id) { - *q = p->next; - kfree(p); - break; - } - } - spin_unlock_irqrestore(&i2o_config_lock, flags); - mutex_unlock(&i2o_cfg_mutex); - - return 0; -} - -static const struct file_operations config_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .unlocked_ioctl = i2o_cfg_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = i2o_cfg_compat_ioctl, -#endif - .open = cfg_open, - .release = cfg_release, - .fasync = cfg_fasync, -}; - -static struct miscdevice i2o_miscdev = { - I2O_MINOR, - "i2octl", - &config_fops -}; - -static int __init i2o_config_old_init(void) -{ - spin_lock_init(&i2o_config_lock); - - if (misc_register(&i2o_miscdev) < 0) { - osm_err("can't register device.\n"); - return -EBUSY; - } - - return 0; -} - -static void i2o_config_old_exit(void) -{ - misc_deregister(&i2o_miscdev); -} - -MODULE_AUTHOR("Red Hat Software"); diff --git a/drivers/staging/i2o/i2o_proc.c b/drivers/staging/i2o/i2o_proc.c deleted file mode 100644 index 780fee3224ea..000000000000 --- a/drivers/staging/i2o/i2o_proc.c +++ /dev/null @@ -1,2049 +0,0 @@ -/* - * procfs handler for Linux I2O subsystem - * - * (c) Copyright 1999 Deepak Saxena - * - * Originally written by Deepak Saxena(deepak@plexity.net) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This is an initial test release. The code is based on the design of the - * ide procfs system (drivers/block/ide-proc.c). Some code taken from - * i2o-core module by Alan Cox. - * - * DISCLAIMER: This code is still under development/test and may cause - * your system to behave unpredictably. Use at your own discretion. - * - * - * Fixes/additions: - * Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI), - * Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI) - * University of Helsinki, Department of Computer Science - * LAN entries - * Markus Lidel <Markus.Lidel@shadowconnect.com> - * Changes for new I2O API - */ - -#define OSM_NAME "proc-osm" -#define OSM_VERSION "1.316" -#define OSM_DESCRIPTION "I2O ProcFS OSM" - -#define I2O_MAX_MODULES 4 -// FIXME! -#define FMT_U64_HEX "0x%08x%08x" -#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64)) - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include "i2o.h" -#include <linux/slab.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/spinlock.h> -#include <linux/workqueue.h> -#include <linux/uaccess.h> - -#include <asm/io.h> -#include <asm/byteorder.h> - -/* Structure used to define /proc entries */ -typedef struct _i2o_proc_entry_t { - char *name; /* entry name */ - umode_t mode; /* mode */ - const struct file_operations *fops; /* open function */ -} i2o_proc_entry; - -/* global I2O /proc/i2o entry */ -static struct proc_dir_entry *i2o_proc_dir_root; - -/* proc OSM driver struct */ -static struct i2o_driver i2o_proc_driver = { - .name = OSM_NAME, -}; - -static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len) -{ - int i; - - /* 19990419 -sralston - * The I2O v1.5 (and v2.0 so far) "official specification" - * got serial numbers WRONG! - * Apparently, and despite what Section 3.4.4 says and - * Figure 3-35 shows (pg 3-39 in the pdf doc), - * the convention / consensus seems to be: - * + First byte is SNFormat - * + Second byte is SNLen (but only if SNFormat==7 (?)) - * + (v2.0) SCSI+BS may use IEEE Registered (64 or 128 bit) format - */ - switch (serialno[0]) { - case I2O_SNFORMAT_BINARY: /* Binary */ - seq_printf(seq, "0x"); - for (i = 0; i < serialno[1]; i++) - seq_printf(seq, "%02X", serialno[2 + i]); - break; - - case I2O_SNFORMAT_ASCII: /* ASCII */ - if (serialno[1] < ' ') { /* printable or SNLen? */ - /* sanity */ - max_len = - (max_len < serialno[1]) ? max_len : serialno[1]; - serialno[1 + max_len] = '\0'; - - /* just print it */ - seq_printf(seq, "%s", &serialno[2]); - } else { - /* print chars for specified length */ - for (i = 0; i < serialno[1]; i++) - seq_printf(seq, "%c", serialno[2 + i]); - } - break; - - case I2O_SNFORMAT_UNICODE: /* UNICODE */ - seq_printf(seq, "UNICODE Format. Can't Display\n"); - break; - - case I2O_SNFORMAT_LAN48_MAC: /* LAN-48 MAC Address */ - seq_printf(seq, "LAN-48 MAC address @ %pM", &serialno[2]); - break; - - case I2O_SNFORMAT_WAN: /* WAN MAC Address */ - /* FIXME: Figure out what a WAN access address looks like?? */ - seq_printf(seq, "WAN Access Address"); - break; - -/* plus new in v2.0 */ - case I2O_SNFORMAT_LAN64_MAC: /* LAN-64 MAC Address */ - /* FIXME: Figure out what a LAN-64 address really looks like?? */ - seq_printf(seq, - "LAN-64 MAC address @ [?:%02X:%02X:?] %pM", - serialno[8], serialno[9], &serialno[2]); - break; - - case I2O_SNFORMAT_DDM: /* I2O DDM */ - seq_printf(seq, - "DDM: Tid=%03Xh, Rsvd=%04Xh, OrgId=%04Xh", - *(u16 *) & serialno[2], - *(u16 *) & serialno[4], *(u16 *) & serialno[6]); - break; - - case I2O_SNFORMAT_IEEE_REG64: /* IEEE Registered (64-bit) */ - case I2O_SNFORMAT_IEEE_REG128: /* IEEE Registered (128-bit) */ - /* FIXME: Figure if this is even close?? */ - seq_printf(seq, - "IEEE NodeName(hi,lo)=(%08Xh:%08Xh), PortName(hi,lo)=(%08Xh:%08Xh)\n", - *(u32 *) & serialno[2], - *(u32 *) & serialno[6], - *(u32 *) & serialno[10], *(u32 *) & serialno[14]); - break; - - case I2O_SNFORMAT_UNKNOWN: /* Unknown 0 */ - case I2O_SNFORMAT_UNKNOWN2: /* Unknown 0xff */ - default: - seq_printf(seq, "Unknown data format (0x%02x)", serialno[0]); - break; - } - - return 0; -} - -/** - * i2o_get_class_name - do i2o class name lookup - * @class: class number - * - * Return a descriptive string for an i2o class. - */ -static const char *i2o_get_class_name(int class) -{ - int idx = 16; - static char *i2o_class_name[] = { - "Executive", - "Device Driver Module", - "Block Device", - "Tape Device", - "LAN Interface", - "WAN Interface", - "Fibre Channel Port", - "Fibre Channel Device", - "SCSI Device", - "ATE Port", - "ATE Device", - "Floppy Controller", - "Floppy Device", - "Secondary Bus Port", - "Peer Transport Agent", - "Peer Transport", - "Unknown" - }; - - switch (class & 0xfff) { - case I2O_CLASS_EXECUTIVE: - idx = 0; - break; - case I2O_CLASS_DDM: - idx = 1; - break; - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - idx = 2; - break; - case I2O_CLASS_SEQUENTIAL_STORAGE: - idx = 3; - break; - case I2O_CLASS_LAN: - idx = 4; - break; - case I2O_CLASS_WAN: - idx = 5; - break; - case I2O_CLASS_FIBRE_CHANNEL_PORT: - idx = 6; - break; - case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL: - idx = 7; - break; - case I2O_CLASS_SCSI_PERIPHERAL: - idx = 8; - break; - case I2O_CLASS_ATE_PORT: - idx = 9; - break; - case I2O_CLASS_ATE_PERIPHERAL: - idx = 10; - break; - case I2O_CLASS_FLOPPY_CONTROLLER: - idx = 11; - break; - case I2O_CLASS_FLOPPY_DEVICE: - idx = 12; - break; - case I2O_CLASS_BUS_ADAPTER: - idx = 13; - break; - case I2O_CLASS_PEER_TRANSPORT_AGENT: - idx = 14; - break; - case I2O_CLASS_PEER_TRANSPORT: - idx = 15; - break; - } - - return i2o_class_name[idx]; -} - -#define SCSI_TABLE_SIZE 13 -static char *scsi_devices[] = { - "Direct-Access Read/Write", - "Sequential-Access Storage", - "Printer", - "Processor", - "WORM Device", - "CD-ROM Device", - "Scanner Device", - "Optical Memory Device", - "Medium Changer Device", - "Communications Device", - "Graphics Art Pre-Press Device", - "Graphics Art Pre-Press Device", - "Array Controller Device" -}; - -static char *chtostr(char *tmp, u8 *chars, int n) -{ - tmp[0] = 0; - return strncat(tmp, (char *)chars, n); -} - -static int i2o_report_query_status(struct seq_file *seq, int block_status, - char *group) -{ - switch (block_status) { - case -ETIMEDOUT: - seq_printf(seq, "Timeout reading group %s.\n", group); - break; - case -ENOMEM: - seq_puts(seq, "No free memory to read the table.\n"); - break; - case -I2O_PARAMS_STATUS_INVALID_GROUP_ID: - seq_printf(seq, "Group %s not supported.\n", group); - break; - default: - seq_printf(seq, - "Error reading group %s. BlockStatus 0x%02X\n", - group, -block_status); - break; - } - - return 0; -} - -static char *bus_strings[] = { - "Local Bus", - "ISA", - "EISA", - "PCI", - "PCMCIA", - "NUBUS", - "CARDBUS" -}; - -static int i2o_seq_show_hrt(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - i2o_hrt *hrt = (i2o_hrt *) c->hrt.virt; - u32 bus; - int i; - - if (hrt->hrt_version) { - seq_printf(seq, - "HRT table for controller is too new a version.\n"); - return 0; - } - - seq_printf(seq, "HRT has %d entries of %d bytes each.\n", - hrt->num_entries, hrt->entry_len << 2); - - for (i = 0; i < hrt->num_entries; i++) { - seq_printf(seq, "Entry %d:\n", i); - seq_printf(seq, " Adapter ID: %0#10x\n", - hrt->hrt_entry[i].adapter_id); - seq_printf(seq, " Controlling tid: %0#6x\n", - hrt->hrt_entry[i].parent_tid); - - if (hrt->hrt_entry[i].bus_type != 0x80) { - bus = hrt->hrt_entry[i].bus_type; - seq_printf(seq, " %s Information\n", - bus_strings[bus]); - - switch (bus) { - case I2O_BUS_LOCAL: - seq_printf(seq, " IOBase: %0#6x,", - hrt->hrt_entry[i].bus.local_bus. - LbBaseIOPort); - seq_printf(seq, " MemoryBase: %0#10x\n", - hrt->hrt_entry[i].bus.local_bus. - LbBaseMemoryAddress); - break; - - case I2O_BUS_ISA: - seq_printf(seq, " IOBase: %0#6x,", - hrt->hrt_entry[i].bus.isa_bus. - IsaBaseIOPort); - seq_printf(seq, " MemoryBase: %0#10x,", - hrt->hrt_entry[i].bus.isa_bus. - IsaBaseMemoryAddress); - seq_printf(seq, " CSN: %0#4x,", - hrt->hrt_entry[i].bus.isa_bus.CSN); - break; - - case I2O_BUS_EISA: - seq_printf(seq, " IOBase: %0#6x,", - hrt->hrt_entry[i].bus.eisa_bus. - EisaBaseIOPort); - seq_printf(seq, " MemoryBase: %0#10x,", - hrt->hrt_entry[i].bus.eisa_bus. - EisaBaseMemoryAddress); - seq_printf(seq, " Slot: %0#4x,", - hrt->hrt_entry[i].bus.eisa_bus. - EisaSlotNumber); - break; - - case I2O_BUS_PCI: - seq_printf(seq, " Bus: %0#4x", - hrt->hrt_entry[i].bus.pci_bus. - PciBusNumber); - seq_printf(seq, " Dev: %0#4x", - hrt->hrt_entry[i].bus.pci_bus. - PciDeviceNumber); - seq_printf(seq, " Func: %0#4x", - hrt->hrt_entry[i].bus.pci_bus. - PciFunctionNumber); - seq_printf(seq, " Vendor: %0#6x", - hrt->hrt_entry[i].bus.pci_bus. - PciVendorID); - seq_printf(seq, " Device: %0#6x\n", - hrt->hrt_entry[i].bus.pci_bus. - PciDeviceID); - break; - - default: - seq_printf(seq, " Unsupported Bus Type\n"); - } - } else - seq_printf(seq, " Unknown Bus Type\n"); - } - - return 0; -} - -static int i2o_seq_show_lct(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - i2o_lct *lct = (i2o_lct *) c->lct; - int entries; - int i; - -#define BUS_TABLE_SIZE 3 - static char *bus_ports[] = { - "Generic Bus", - "SCSI Bus", - "Fibre Channel Bus" - }; - - entries = (lct->table_size - 3) / 9; - - seq_printf(seq, "LCT contains %d %s\n", entries, - entries == 1 ? "entry" : "entries"); - if (lct->boot_tid) - seq_printf(seq, "Boot Device @ ID %d\n", lct->boot_tid); - - seq_printf(seq, "Current Change Indicator: %#10x\n", lct->change_ind); - - for (i = 0; i < entries; i++) { - seq_printf(seq, "Entry %d\n", i); - seq_printf(seq, " Class, SubClass : %s", - i2o_get_class_name(lct->lct_entry[i].class_id)); - - /* - * Classes which we'll print subclass info for - */ - switch (lct->lct_entry[i].class_id & 0xFFF) { - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - switch (lct->lct_entry[i].sub_class) { - case 0x00: - seq_printf(seq, ", Direct-Access Read/Write"); - break; - - case 0x04: - seq_printf(seq, ", WORM Drive"); - break; - - case 0x05: - seq_printf(seq, ", CD-ROM Drive"); - break; - - case 0x07: - seq_printf(seq, ", Optical Memory Device"); - break; - - default: - seq_printf(seq, ", Unknown (0x%02x)", - lct->lct_entry[i].sub_class); - break; - } - break; - - case I2O_CLASS_LAN: - switch (lct->lct_entry[i].sub_class & 0xFF) { - case 0x30: - seq_printf(seq, ", Ethernet"); - break; - - case 0x40: - seq_printf(seq, ", 100base VG"); - break; - - case 0x50: - seq_printf(seq, ", IEEE 802.5/Token-Ring"); - break; - - case 0x60: - seq_printf(seq, ", ANSI X3T9.5 FDDI"); - break; - - case 0x70: - seq_printf(seq, ", Fibre Channel"); - break; - - default: - seq_printf(seq, ", Unknown Sub-Class (0x%02x)", - lct->lct_entry[i].sub_class & 0xFF); - break; - } - break; - - case I2O_CLASS_SCSI_PERIPHERAL: - if (lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE) - seq_printf(seq, ", %s", - scsi_devices[lct->lct_entry[i]. - sub_class]); - else - seq_printf(seq, ", Unknown Device Type"); - break; - - case I2O_CLASS_BUS_ADAPTER: - if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE) - seq_printf(seq, ", %s", - bus_ports[lct->lct_entry[i]. - sub_class]); - else - seq_printf(seq, ", Unknown Bus Type"); - break; - } - seq_printf(seq, "\n"); - - seq_printf(seq, " Local TID : 0x%03x\n", - lct->lct_entry[i].tid); - seq_printf(seq, " User TID : 0x%03x\n", - lct->lct_entry[i].user_tid); - seq_printf(seq, " Parent TID : 0x%03x\n", - lct->lct_entry[i].parent_tid); - seq_printf(seq, " Identity Tag : 0x%x%x%x%x%x%x%x%x\n", - lct->lct_entry[i].identity_tag[0], - lct->lct_entry[i].identity_tag[1], - lct->lct_entry[i].identity_tag[2], - lct->lct_entry[i].identity_tag[3], - lct->lct_entry[i].identity_tag[4], - lct->lct_entry[i].identity_tag[5], - lct->lct_entry[i].identity_tag[6], - lct->lct_entry[i].identity_tag[7]); - seq_printf(seq, " Change Indicator : %0#10x\n", - lct->lct_entry[i].change_ind); - seq_printf(seq, " Event Capab Mask : %0#10x\n", - lct->lct_entry[i].device_flags); - } - - return 0; -} - -static int i2o_seq_show_status(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - char prodstr[25]; - int version; - i2o_status_block *sb = c->status_block.virt; - - i2o_status_get(c); // reread the status block - - seq_printf(seq, "Organization ID : %0#6x\n", sb->org_id); - - version = sb->i2o_version; - -/* FIXME for Spec 2.0 - if (version == 0x02) { - seq_printf(seq, "Lowest I2O version supported: "); - switch(workspace[2]) { - case 0x00: - seq_printf(seq, "1.0\n"); - break; - case 0x01: - seq_printf(seq, "1.5\n"); - break; - case 0x02: - seq_printf(seq, "2.0\n"); - break; - } - - seq_printf(seq, "Highest I2O version supported: "); - switch(workspace[3]) { - case 0x00: - seq_printf(seq, "1.0\n"); - break; - case 0x01: - seq_printf(seq, "1.5\n"); - break; - case 0x02: - seq_printf(seq, "2.0\n"); - break; - } - } -*/ - seq_printf(seq, "IOP ID : %0#5x\n", sb->iop_id); - seq_printf(seq, "Host Unit ID : %0#6x\n", sb->host_unit_id); - seq_printf(seq, "Segment Number : %0#5x\n", sb->segment_number); - - seq_printf(seq, "I2O version : "); - switch (version) { - case 0x00: - seq_printf(seq, "1.0\n"); - break; - case 0x01: - seq_printf(seq, "1.5\n"); - break; - case 0x02: - seq_printf(seq, "2.0\n"); - break; - default: - seq_printf(seq, "Unknown version\n"); - } - - seq_printf(seq, "IOP State : "); - switch (sb->iop_state) { - case 0x01: - seq_printf(seq, "INIT\n"); - break; - - case 0x02: - seq_printf(seq, "RESET\n"); - break; - - case 0x04: - seq_printf(seq, "HOLD\n"); - break; - - case 0x05: - seq_printf(seq, "READY\n"); - break; - - case 0x08: - seq_printf(seq, "OPERATIONAL\n"); - break; - - case 0x10: - seq_printf(seq, "FAILED\n"); - break; - - case 0x11: - seq_printf(seq, "FAULTED\n"); - break; - - default: - seq_printf(seq, "Unknown\n"); - break; - } - - seq_printf(seq, "Messenger Type : "); - switch (sb->msg_type) { - case 0x00: - seq_printf(seq, "Memory mapped\n"); - break; - case 0x01: - seq_printf(seq, "Memory mapped only\n"); - break; - case 0x02: - seq_printf(seq, "Remote only\n"); - break; - case 0x03: - seq_printf(seq, "Memory mapped and remote\n"); - break; - default: - seq_printf(seq, "Unknown\n"); - } - - seq_printf(seq, "Inbound Frame Size : %d bytes\n", - sb->inbound_frame_size << 2); - seq_printf(seq, "Max Inbound Frames : %d\n", - sb->max_inbound_frames); - seq_printf(seq, "Current Inbound Frames : %d\n", - sb->cur_inbound_frames); - seq_printf(seq, "Max Outbound Frames : %d\n", - sb->max_outbound_frames); - - /* Spec doesn't say if NULL terminated or not... */ - memcpy(prodstr, sb->product_id, 24); - prodstr[24] = '\0'; - seq_printf(seq, "Product ID : %s\n", prodstr); - seq_printf(seq, "Expected LCT Size : %d bytes\n", - sb->expected_lct_size); - - seq_printf(seq, "IOP Capabilities\n"); - seq_printf(seq, " Context Field Size Support : "); - switch (sb->iop_capabilities & 0x0000003) { - case 0: - seq_printf(seq, "Supports only 32-bit context fields\n"); - break; - case 1: - seq_printf(seq, "Supports only 64-bit context fields\n"); - break; - case 2: - seq_printf(seq, "Supports 32-bit and 64-bit context fields, " - "but not concurrently\n"); - break; - case 3: - seq_printf(seq, "Supports 32-bit and 64-bit context fields " - "concurrently\n"); - break; - default: - seq_printf(seq, "0x%08x\n", sb->iop_capabilities); - } - seq_printf(seq, " Current Context Field Size : "); - switch (sb->iop_capabilities & 0x0000000C) { - case 0: - seq_printf(seq, "not configured\n"); - break; - case 4: - seq_printf(seq, "Supports only 32-bit context fields\n"); - break; - case 8: - seq_printf(seq, "Supports only 64-bit context fields\n"); - break; - case 12: - seq_printf(seq, "Supports both 32-bit or 64-bit context fields " - "concurrently\n"); - break; - default: - seq_printf(seq, "\n"); - } - seq_printf(seq, " Inbound Peer Support : %s\n", - (sb-> - iop_capabilities & 0x00000010) ? "Supported" : - "Not supported"); - seq_printf(seq, " Outbound Peer Support : %s\n", - (sb-> - iop_capabilities & 0x00000020) ? "Supported" : - "Not supported"); - seq_printf(seq, " Peer to Peer Support : %s\n", - (sb-> - iop_capabilities & 0x00000040) ? "Supported" : - "Not supported"); - - seq_printf(seq, "Desired private memory size : %d kB\n", - sb->desired_mem_size >> 10); - seq_printf(seq, "Allocated private memory size : %d kB\n", - sb->current_mem_size >> 10); - seq_printf(seq, "Private memory base address : %0#10x\n", - sb->current_mem_base); - seq_printf(seq, "Desired private I/O size : %d kB\n", - sb->desired_io_size >> 10); - seq_printf(seq, "Allocated private I/O size : %d kB\n", - sb->current_io_size >> 10); - seq_printf(seq, "Private I/O base address : %0#10x\n", - sb->current_io_base); - - return 0; -} - -static int i2o_seq_show_hw(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - static u32 work32[5]; - static u8 *work8 = (u8 *) work32; - static u16 *work16 = (u16 *) work32; - int token; - u32 hwcap; - - static char *cpu_table[] = { - "Intel 80960 series", - "AMD2900 series", - "Motorola 68000 series", - "ARM series", - "MIPS series", - "Sparc series", - "PowerPC series", - "Intel x86 series" - }; - - token = - i2o_parm_field_get(c->exec, 0x0000, -1, &work32, sizeof(work32)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0x0000 IOP Hardware"); - return 0; - } - - seq_printf(seq, "I2O Vendor ID : %0#6x\n", work16[0]); - seq_printf(seq, "Product ID : %0#6x\n", work16[1]); - seq_printf(seq, "CPU : "); - if (work8[16] > 8) - seq_printf(seq, "Unknown\n"); - else - seq_printf(seq, "%s\n", cpu_table[work8[16]]); - /* Anyone using ProcessorVersion? */ - - seq_printf(seq, "RAM : %dkB\n", work32[1] >> 10); - seq_printf(seq, "Non-Volatile Mem : %dkB\n", work32[2] >> 10); - - hwcap = work32[3]; - seq_printf(seq, "Capabilities : 0x%08x\n", hwcap); - seq_printf(seq, " [%s] Self booting\n", - (hwcap & 0x00000001) ? "+" : "-"); - seq_printf(seq, " [%s] Upgradable IRTOS\n", - (hwcap & 0x00000002) ? "+" : "-"); - seq_printf(seq, " [%s] Supports downloading DDMs\n", - (hwcap & 0x00000004) ? "+" : "-"); - seq_printf(seq, " [%s] Supports installing DDMs\n", - (hwcap & 0x00000008) ? "+" : "-"); - seq_printf(seq, " [%s] Battery-backed RAM\n", - (hwcap & 0x00000010) ? "+" : "-"); - - return 0; -} - -/* Executive group 0003h - Executing DDM List (table) */ -static int i2o_seq_show_ddm_table(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - int token; - int i; - - typedef struct _i2o_exec_execute_ddm_table { - u16 ddm_tid; - u8 module_type; - u8 reserved; - u16 i2o_vendor_id; - u16 module_id; - u8 module_name_version[28]; - u32 data_size; - u32 code_size; - } i2o_exec_execute_ddm_table; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - i2o_exec_execute_ddm_table ddm_table[I2O_MAX_MODULES]; - } *result; - - i2o_exec_execute_ddm_table ddm_table; - char tmp[28 + 1]; - - result = kmalloc(sizeof(*result), GFP_KERNEL); - if (!result) - return -ENOMEM; - - token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0003, -1, - NULL, 0, result, sizeof(*result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0x0003 Executing DDM List"); - goto out; - } - - seq_printf(seq, - "Tid Module_type Vendor Mod_id Module_name Vrs Data_size Code_size\n"); - ddm_table = result->ddm_table[0]; - - for (i = 0; i < result->row_count; ddm_table = result->ddm_table[++i]) { - seq_printf(seq, "0x%03x ", ddm_table.ddm_tid & 0xFFF); - - switch (ddm_table.module_type) { - case 0x01: - seq_printf(seq, "Downloaded DDM "); - break; - case 0x22: - seq_printf(seq, "Embedded DDM "); - break; - default: - seq_printf(seq, " "); - } - - seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id); - seq_printf(seq, "%-#8x", ddm_table.module_id); - seq_printf(seq, "%-29s", - chtostr(tmp, ddm_table.module_name_version, 28)); - seq_printf(seq, "%9d ", ddm_table.data_size); - seq_printf(seq, "%8d", ddm_table.code_size); - - seq_printf(seq, "\n"); - } - out: - kfree(result); - return 0; -} - -/* Executive group 0004h - Driver Store (scalar) */ -static int i2o_seq_show_driver_store(struct seq_file *seq, void *v) -{ - struct i2o_controller *c = (struct i2o_controller *)seq->private; - u32 work32[8]; - int token; - - token = - i2o_parm_field_get(c->exec, 0x0004, -1, &work32, sizeof(work32)); - if (token < 0) { - i2o_report_query_status(seq, token, "0x0004 Driver Store"); - return 0; - } - - seq_printf(seq, "Module limit : %d\n" - "Module count : %d\n" - "Current space : %d kB\n" - "Free space : %d kB\n", - work32[0], work32[1], work32[2] >> 10, work32[3] >> 10); - - return 0; -} - -/* Executive group 0005h - Driver Store Table (table) */ -static int i2o_seq_show_drivers_stored(struct seq_file *seq, void *v) -{ - typedef struct _i2o_driver_store { - u16 stored_ddm_index; - u8 module_type; - u8 reserved; - u16 i2o_vendor_id; - u16 module_id; - u8 module_name_version[28]; - u8 date[8]; - u32 module_size; - u32 mpb_size; - u32 module_flags; - } i2o_driver_store_table; - - struct i2o_controller *c = (struct i2o_controller *)seq->private; - int token; - int i; - - typedef struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - i2o_driver_store_table dst[I2O_MAX_MODULES]; - } i2o_driver_result_table; - - i2o_driver_result_table *result; - i2o_driver_store_table *dst; - char tmp[28 + 1]; - - result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL); - if (result == NULL) - return -ENOMEM; - - token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0005, -1, - NULL, 0, result, sizeof(*result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0x0005 DRIVER STORE TABLE"); - kfree(result); - return 0; - } - - seq_printf(seq, - "# Module_type Vendor Mod_id Module_name Vrs" - "Date Mod_size Par_size Flags\n"); - for (i = 0, dst = &result->dst[0]; i < result->row_count; - dst = &result->dst[++i]) { - seq_printf(seq, "%-3d", dst->stored_ddm_index); - switch (dst->module_type) { - case 0x01: - seq_printf(seq, "Downloaded DDM "); - break; - case 0x22: - seq_printf(seq, "Embedded DDM "); - break; - default: - seq_printf(seq, " "); - } - - seq_printf(seq, "%-#7x", dst->i2o_vendor_id); - seq_printf(seq, "%-#8x", dst->module_id); - seq_printf(seq, "%-29s", - chtostr(tmp, dst->module_name_version, 28)); - seq_printf(seq, "%-9s", chtostr(tmp, dst->date, 8)); - seq_printf(seq, "%8d ", dst->module_size); - seq_printf(seq, "%8d ", dst->mpb_size); - seq_printf(seq, "0x%04x", dst->module_flags); - seq_printf(seq, "\n"); - } - - kfree(result); - return 0; -} - -/* Generic group F000h - Params Descriptor (table) */ -static int i2o_seq_show_groups(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - u8 properties; - - typedef struct _i2o_group_info { - u16 group_number; - u16 field_count; - u16 row_count; - u8 properties; - u8 reserved; - } i2o_group_info; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - i2o_group_info group[256]; - } *result; - - result = kmalloc(sizeof(*result), GFP_KERNEL); - if (!result) - return -ENOMEM; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0, - result, sizeof(*result)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF000 Params Descriptor"); - goto out; - } - - seq_printf(seq, - "# Group FieldCount RowCount Type Add Del Clear\n"); - - for (i = 0; i < result->row_count; i++) { - seq_printf(seq, "%-3d", i); - seq_printf(seq, "0x%04X ", result->group[i].group_number); - seq_printf(seq, "%10d ", result->group[i].field_count); - seq_printf(seq, "%8d ", result->group[i].row_count); - - properties = result->group[i].properties; - if (properties & 0x1) - seq_printf(seq, "Table "); - else - seq_printf(seq, "Scalar "); - if (properties & 0x2) - seq_printf(seq, " + "); - else - seq_printf(seq, " - "); - if (properties & 0x4) - seq_printf(seq, " + "); - else - seq_printf(seq, " - "); - if (properties & 0x8) - seq_printf(seq, " + "); - else - seq_printf(seq, " - "); - - seq_printf(seq, "\n"); - } - - if (result->more_flag) - seq_printf(seq, "There is more...\n"); - out: - kfree(result); - return 0; -} - -/* Generic group F001h - Physical Device Table (table) */ -static int i2o_seq_show_phys_device(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - u32 adapter_id[64]; - } result; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF001, -1, NULL, 0, - &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0xF001 Physical Device Table"); - return 0; - } - - if (result.row_count) - seq_printf(seq, "# AdapterId\n"); - - for (i = 0; i < result.row_count; i++) { - seq_printf(seq, "%-2d", i); - seq_printf(seq, "%#7x\n", result.adapter_id[i]); - } - - if (result.more_flag) - seq_printf(seq, "There is more...\n"); - - return 0; -} - -/* Generic group F002h - Claimed Table (table) */ -static int i2o_seq_show_claimed(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - u16 claimed_tid[64]; - } result; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF002, -1, NULL, 0, - &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF002 Claimed Table"); - return 0; - } - - if (result.row_count) - seq_printf(seq, "# ClaimedTid\n"); - - for (i = 0; i < result.row_count; i++) { - seq_printf(seq, "%-2d", i); - seq_printf(seq, "%#7x\n", result.claimed_tid[i]); - } - - if (result.more_flag) - seq_printf(seq, "There is more...\n"); - - return 0; -} - -/* Generic group F003h - User Table (table) */ -static int i2o_seq_show_users(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - - typedef struct _i2o_user_table { - u16 instance; - u16 user_tid; - u8 claim_type; - u8 reserved1; - u16 reserved2; - } i2o_user_table; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - i2o_user_table user[64]; - } *result; - - result = kmalloc(sizeof(*result), GFP_KERNEL); - if (!result) - return -ENOMEM; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF003, -1, NULL, 0, - result, sizeof(*result)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF003 User Table"); - goto out; - } - - seq_printf(seq, "# Instance UserTid ClaimType\n"); - - for (i = 0; i < result->row_count; i++) { - seq_printf(seq, "%-3d", i); - seq_printf(seq, "%#8x ", result->user[i].instance); - seq_printf(seq, "%#7x ", result->user[i].user_tid); - seq_printf(seq, "%#9x\n", result->user[i].claim_type); - } - - if (result->more_flag) - seq_printf(seq, "There is more...\n"); - out: - kfree(result); - return 0; -} - -/* Generic group F005h - Private message extensions (table) (optional) */ -static int i2o_seq_show_priv_msgs(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - - typedef struct _i2o_private { - u16 ext_instance; - u16 organization_id; - u16 x_function_code; - } i2o_private; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - i2o_private extension[64]; - } result; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0, - &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0xF005 Private Message Extensions (optional)"); - return 0; - } - - seq_printf(seq, "Instance# OrgId FunctionCode\n"); - - for (i = 0; i < result.row_count; i++) { - seq_printf(seq, "%0#9x ", result.extension[i].ext_instance); - seq_printf(seq, "%0#6x ", result.extension[i].organization_id); - seq_printf(seq, "%0#6x", result.extension[i].x_function_code); - - seq_printf(seq, "\n"); - } - - if (result.more_flag) - seq_printf(seq, "There is more...\n"); - - return 0; -} - -/* Generic group F006h - Authorized User Table (table) */ -static int i2o_seq_show_authorized_users(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - int i; - - struct { - u16 result_count; - u16 pad; - u16 block_size; - u8 block_status; - u8 error_info_size; - u16 row_count; - u16 more_flag; - u32 alternate_tid[64]; - } result; - - token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF006, -1, NULL, 0, - &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0xF006 Autohorized User Table"); - return 0; - } - - if (result.row_count) - seq_printf(seq, "# AlternateTid\n"); - - for (i = 0; i < result.row_count; i++) { - seq_printf(seq, "%-2d", i); - seq_printf(seq, "%#7x ", result.alternate_tid[i]); - } - - if (result.more_flag) - seq_printf(seq, "There is more...\n"); - - return 0; -} - -/* Generic group F100h - Device Identity (scalar) */ -static int i2o_seq_show_dev_identity(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number - // == (allow) 512d bytes (max) - static u16 *work16 = (u16 *) work32; - int token; - char tmp[16 + 1]; - - token = i2o_parm_field_get(d, 0xF100, -1, &work32, sizeof(work32)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF100 Device Identity"); - return 0; - } - - seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0])); - seq_printf(seq, "Owner TID : %0#5x\n", work16[2]); - seq_printf(seq, "Parent TID : %0#5x\n", work16[3]); - seq_printf(seq, "Vendor info : %s\n", - chtostr(tmp, (u8 *) (work32 + 2), 16)); - seq_printf(seq, "Product info : %s\n", - chtostr(tmp, (u8 *) (work32 + 6), 16)); - seq_printf(seq, "Description : %s\n", - chtostr(tmp, (u8 *) (work32 + 10), 16)); - seq_printf(seq, "Product rev. : %s\n", - chtostr(tmp, (u8 *) (work32 + 14), 8)); - - seq_printf(seq, "Serial number : "); - print_serial_number(seq, (u8 *) (work32 + 16), - /* allow for SNLen plus - * possible trailing '\0' - */ - sizeof(work32) - (16 * sizeof(u32)) - 2); - seq_printf(seq, "\n"); - - return 0; -} - -static int i2o_seq_show_dev_name(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - - seq_printf(seq, "%s\n", dev_name(&d->device)); - - return 0; -} - -/* Generic group F101h - DDM Identity (scalar) */ -static int i2o_seq_show_ddm_identity(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - - struct { - u16 ddm_tid; - u8 module_name[24]; - u8 module_rev[8]; - u8 sn_format; - u8 serial_number[12]; - u8 pad[256]; // allow up to 256 byte (max) serial number - } result; - - char tmp[24 + 1]; - - token = i2o_parm_field_get(d, 0xF101, -1, &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF101 DDM Identity"); - return 0; - } - - seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid); - seq_printf(seq, "Module name : %s\n", - chtostr(tmp, result.module_name, 24)); - seq_printf(seq, "Module revision : %s\n", - chtostr(tmp, result.module_rev, 8)); - - seq_printf(seq, "Serial number : "); - print_serial_number(seq, result.serial_number, sizeof(result) - 36); - /* allow for SNLen plus possible trailing '\0' */ - - seq_printf(seq, "\n"); - - return 0; -} - -/* Generic group F102h - User Information (scalar) */ -static int i2o_seq_show_uinfo(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - - struct { - u8 device_name[64]; - u8 service_name[64]; - u8 physical_location[64]; - u8 instance_number[4]; - } result; - - char tmp[64 + 1]; - - token = i2o_parm_field_get(d, 0xF102, -1, &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, "0xF102 User Information"); - return 0; - } - - seq_printf(seq, "Device name : %s\n", - chtostr(tmp, result.device_name, 64)); - seq_printf(seq, "Service name : %s\n", - chtostr(tmp, result.service_name, 64)); - seq_printf(seq, "Physical name : %s\n", - chtostr(tmp, result.physical_location, 64)); - seq_printf(seq, "Instance number : %s\n", - chtostr(tmp, result.instance_number, 4)); - - return 0; -} - -/* Generic group F103h - SGL Operating Limits (scalar) */ -static int i2o_seq_show_sgl_limits(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - static u32 work32[12]; - static u16 *work16 = (u16 *) work32; - static u8 *work8 = (u8 *) work32; - int token; - - token = i2o_parm_field_get(d, 0xF103, -1, &work32, sizeof(work32)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0xF103 SGL Operating Limits"); - return 0; - } - - seq_printf(seq, "SGL chain size : %d\n", work32[0]); - seq_printf(seq, "Max SGL chain size : %d\n", work32[1]); - seq_printf(seq, "SGL chain size target : %d\n", work32[2]); - seq_printf(seq, "SGL frag count : %d\n", work16[6]); - seq_printf(seq, "Max SGL frag count : %d\n", work16[7]); - seq_printf(seq, "SGL frag count target : %d\n", work16[8]); - -/* FIXME - if (d->i2oversion == 0x02) - { -*/ - seq_printf(seq, "SGL data alignment : %d\n", work16[8]); - seq_printf(seq, "SGL addr limit : %d\n", work8[20]); - seq_printf(seq, "SGL addr sizes supported : "); - if (work8[21] & 0x01) - seq_printf(seq, "32 bit "); - if (work8[21] & 0x02) - seq_printf(seq, "64 bit "); - if (work8[21] & 0x04) - seq_printf(seq, "96 bit "); - if (work8[21] & 0x08) - seq_printf(seq, "128 bit "); - seq_printf(seq, "\n"); -/* - } -*/ - - return 0; -} - -/* Generic group F200h - Sensors (scalar) */ -static int i2o_seq_show_sensors(struct seq_file *seq, void *v) -{ - struct i2o_device *d = (struct i2o_device *)seq->private; - int token; - - struct { - u16 sensor_instance; - u8 component; - u16 component_instance; - u8 sensor_class; - u8 sensor_type; - u8 scaling_exponent; - u32 actual_reading; - u32 minimum_reading; - u32 low2lowcat_treshold; - u32 lowcat2low_treshold; - u32 lowwarn2low_treshold; - u32 low2lowwarn_treshold; - u32 norm2lowwarn_treshold; - u32 lowwarn2norm_treshold; - u32 nominal_reading; - u32 hiwarn2norm_treshold; - u32 norm2hiwarn_treshold; - u32 high2hiwarn_treshold; - u32 hiwarn2high_treshold; - u32 hicat2high_treshold; - u32 hi2hicat_treshold; - u32 maximum_reading; - u8 sensor_state; - u16 event_enable; - } result; - - token = i2o_parm_field_get(d, 0xF200, -1, &result, sizeof(result)); - - if (token < 0) { - i2o_report_query_status(seq, token, - "0xF200 Sensors (optional)"); - return 0; - } - - seq_printf(seq, "Sensor instance : %d\n", result.sensor_instance); - - seq_printf(seq, "Component : %d = ", result.component); - switch (result.component) { - case 0: - seq_printf(seq, "Other"); - break; - case 1: - seq_printf(seq, "Planar logic Board"); - break; - case 2: - seq_printf(seq, "CPU"); - break; - case 3: - seq_printf(seq, "Chassis"); - break; - case 4: - seq_printf(seq, "Power Supply"); - break; - case 5: - seq_printf(seq, "Storage"); - break; - case 6: - seq_printf(seq, "External"); - break; - } - seq_printf(seq, "\n"); - - seq_printf(seq, "Component instance : %d\n", - result.component_instance); - seq_printf(seq, "Sensor class : %s\n", - result.sensor_class ? "Analog" : "Digital"); - - seq_printf(seq, "Sensor type : %d = ", result.sensor_type); - switch (result.sensor_type) { - case 0: - seq_printf(seq, "Other\n"); - break; - case 1: - seq_printf(seq, "Thermal\n"); - break; - case 2: - seq_printf(seq, "DC voltage (DC volts)\n"); - break; - case 3: - seq_printf(seq, "AC voltage (AC volts)\n"); - break; - case 4: - seq_printf(seq, "DC current (DC amps)\n"); - break; - case 5: - seq_printf(seq, "AC current (AC volts)\n"); - break; - case 6: - seq_printf(seq, "Door open\n"); - break; - case 7: - seq_printf(seq, "Fan operational\n"); - break; - } - - seq_printf(seq, "Scaling exponent : %d\n", - result.scaling_exponent); - seq_printf(seq, "Actual reading : %d\n", result.actual_reading); - seq_printf(seq, "Minimum reading : %d\n", result.minimum_reading); - seq_printf(seq, "Low2LowCat treshold : %d\n", - result.low2lowcat_treshold); - seq_printf(seq, "LowCat2Low treshold : %d\n", - result.lowcat2low_treshold); - seq_printf(seq, "LowWarn2Low treshold : %d\n", - result.lowwarn2low_treshold); - seq_printf(seq, "Low2LowWarn treshold : %d\n", - result.low2lowwarn_treshold); - seq_printf(seq, "Norm2LowWarn treshold : %d\n", - result.norm2lowwarn_treshold); - seq_printf(seq, "LowWarn2Norm treshold : %d\n", - result.lowwarn2norm_treshold); - seq_printf(seq, "Nominal reading : %d\n", result.nominal_reading); - seq_printf(seq, "HiWarn2Norm treshold : %d\n", - result.hiwarn2norm_treshold); - seq_printf(seq, "Norm2HiWarn treshold : %d\n", - result.norm2hiwarn_treshold); - seq_printf(seq, "High2HiWarn treshold : %d\n", - result.high2hiwarn_treshold); - seq_printf(seq, "HiWarn2High treshold : %d\n", - result.hiwarn2high_treshold); - seq_printf(seq, "HiCat2High treshold : %d\n", - result.hicat2high_treshold); - seq_printf(seq, "High2HiCat treshold : %d\n", - result.hi2hicat_treshold); - seq_printf(seq, "Maximum reading : %d\n", result.maximum_reading); - - seq_printf(seq, "Sensor state : %d = ", result.sensor_state); - switch (result.sensor_state) { - case 0: - seq_printf(seq, "Normal\n"); - break; - case 1: - seq_printf(seq, "Abnormal\n"); - break; - case 2: - seq_printf(seq, "Unknown\n"); - break; - case 3: - seq_printf(seq, "Low Catastrophic (LoCat)\n"); - break; - case 4: - seq_printf(seq, "Low (Low)\n"); - break; - case 5: - seq_printf(seq, "Low Warning (LoWarn)\n"); - break; - case 6: - seq_printf(seq, "High Warning (HiWarn)\n"); - break; - case 7: - seq_printf(seq, "High (High)\n"); - break; - case 8: - seq_printf(seq, "High Catastrophic (HiCat)\n"); - break; - } - - seq_printf(seq, "Event_enable : 0x%02X\n", result.event_enable); - seq_printf(seq, " [%s] Operational state change. \n", - (result.event_enable & 0x01) ? "+" : "-"); - seq_printf(seq, " [%s] Low catastrophic. \n", - (result.event_enable & 0x02) ? "+" : "-"); - seq_printf(seq, " [%s] Low reading. \n", - (result.event_enable & 0x04) ? "+" : "-"); - seq_printf(seq, " [%s] Low warning. \n", - (result.event_enable & 0x08) ? "+" : "-"); - seq_printf(seq, - " [%s] Change back to normal from out of range state. \n", - (result.event_enable & 0x10) ? "+" : "-"); - seq_printf(seq, " [%s] High warning. \n", - (result.event_enable & 0x20) ? "+" : "-"); - seq_printf(seq, " [%s] High reading. \n", - (result.event_enable & 0x40) ? "+" : "-"); - seq_printf(seq, " [%s] High catastrophic. \n", - (result.event_enable & 0x80) ? "+" : "-"); - - return 0; -} - -static int i2o_seq_open_hrt(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_hrt, PDE_DATA(inode)); -}; - -static int i2o_seq_open_lct(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_lct, PDE_DATA(inode)); -}; - -static int i2o_seq_open_status(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_status, PDE_DATA(inode)); -}; - -static int i2o_seq_open_hw(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_hw, PDE_DATA(inode)); -}; - -static int i2o_seq_open_ddm_table(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_ddm_table, PDE_DATA(inode)); -}; - -static int i2o_seq_open_driver_store(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_driver_store, PDE_DATA(inode)); -}; - -static int i2o_seq_open_drivers_stored(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_drivers_stored, PDE_DATA(inode)); -}; - -static int i2o_seq_open_groups(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_groups, PDE_DATA(inode)); -}; - -static int i2o_seq_open_phys_device(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_phys_device, PDE_DATA(inode)); -}; - -static int i2o_seq_open_claimed(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_claimed, PDE_DATA(inode)); -}; - -static int i2o_seq_open_users(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_users, PDE_DATA(inode)); -}; - -static int i2o_seq_open_priv_msgs(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_priv_msgs, PDE_DATA(inode)); -}; - -static int i2o_seq_open_authorized_users(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_authorized_users, - PDE_DATA(inode)); -}; - -static int i2o_seq_open_dev_identity(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_dev_identity, PDE_DATA(inode)); -}; - -static int i2o_seq_open_ddm_identity(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_ddm_identity, PDE_DATA(inode)); -}; - -static int i2o_seq_open_uinfo(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_uinfo, PDE_DATA(inode)); -}; - -static int i2o_seq_open_sgl_limits(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_sgl_limits, PDE_DATA(inode)); -}; - -static int i2o_seq_open_sensors(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_sensors, PDE_DATA(inode)); -}; - -static int i2o_seq_open_dev_name(struct inode *inode, struct file *file) -{ - return single_open(file, i2o_seq_show_dev_name, PDE_DATA(inode)); -}; - -static const struct file_operations i2o_seq_fops_lct = { - .open = i2o_seq_open_lct, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_hrt = { - .open = i2o_seq_open_hrt, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_status = { - .open = i2o_seq_open_status, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_hw = { - .open = i2o_seq_open_hw, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_ddm_table = { - .open = i2o_seq_open_ddm_table, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_driver_store = { - .open = i2o_seq_open_driver_store, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_drivers_stored = { - .open = i2o_seq_open_drivers_stored, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_groups = { - .open = i2o_seq_open_groups, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_phys_device = { - .open = i2o_seq_open_phys_device, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_claimed = { - .open = i2o_seq_open_claimed, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_users = { - .open = i2o_seq_open_users, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_priv_msgs = { - .open = i2o_seq_open_priv_msgs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_authorized_users = { - .open = i2o_seq_open_authorized_users, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_dev_name = { - .open = i2o_seq_open_dev_name, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_dev_identity = { - .open = i2o_seq_open_dev_identity, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_ddm_identity = { - .open = i2o_seq_open_ddm_identity, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_uinfo = { - .open = i2o_seq_open_uinfo, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_sgl_limits = { - .open = i2o_seq_open_sgl_limits, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations i2o_seq_fops_sensors = { - .open = i2o_seq_open_sensors, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * IOP specific entries...write field just in case someone - * ever wants one. - */ -static i2o_proc_entry i2o_proc_generic_iop_entries[] = { - {"hrt", S_IFREG | S_IRUGO, &i2o_seq_fops_hrt}, - {"lct", S_IFREG | S_IRUGO, &i2o_seq_fops_lct}, - {"status", S_IFREG | S_IRUGO, &i2o_seq_fops_status}, - {"hw", S_IFREG | S_IRUGO, &i2o_seq_fops_hw}, - {"ddm_table", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_table}, - {"driver_store", S_IFREG | S_IRUGO, &i2o_seq_fops_driver_store}, - {"drivers_stored", S_IFREG | S_IRUGO, &i2o_seq_fops_drivers_stored}, - {NULL, 0, NULL} -}; - -/* - * Device specific entries - */ -static i2o_proc_entry generic_dev_entries[] = { - {"groups", S_IFREG | S_IRUGO, &i2o_seq_fops_groups}, - {"phys_dev", S_IFREG | S_IRUGO, &i2o_seq_fops_phys_device}, - {"claimed", S_IFREG | S_IRUGO, &i2o_seq_fops_claimed}, - {"users", S_IFREG | S_IRUGO, &i2o_seq_fops_users}, - {"priv_msgs", S_IFREG | S_IRUGO, &i2o_seq_fops_priv_msgs}, - {"authorized_users", S_IFREG | S_IRUGO, &i2o_seq_fops_authorized_users}, - {"dev_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_identity}, - {"ddm_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_identity}, - {"user_info", S_IFREG | S_IRUGO, &i2o_seq_fops_uinfo}, - {"sgl_limits", S_IFREG | S_IRUGO, &i2o_seq_fops_sgl_limits}, - {"sensors", S_IFREG | S_IRUGO, &i2o_seq_fops_sensors}, - {NULL, 0, NULL} -}; - -/* - * Storage unit specific entries (SCSI Periph, BS) with device names - */ -static i2o_proc_entry rbs_dev_entries[] = { - {"dev_name", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_name}, - {NULL, 0, NULL} -}; - -/** - * i2o_proc_create_entries - Creates proc dir entries - * @dir: proc dir entry under which the entries should be placed - * @i2o_pe: pointer to the entries which should be added - * @data: pointer to I2O controller or device - * - * Create proc dir entries for a I2O controller or I2O device. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_proc_create_entries(struct proc_dir_entry *dir, - i2o_proc_entry * i2o_pe, void *data) -{ - struct proc_dir_entry *tmp; - - while (i2o_pe->name) { - tmp = proc_create_data(i2o_pe->name, i2o_pe->mode, dir, - i2o_pe->fops, data); - if (!tmp) - return -1; - - i2o_pe++; - } - - return 0; -} - -/** - * i2o_proc_device_add - Add an I2O device to the proc dir - * @dir: proc dir entry to which the device should be added - * @dev: I2O device which should be added - * - * Add an I2O device to the proc dir entry dir and create the entries for - * the device depending on the class of the I2O device. - */ -static void i2o_proc_device_add(struct proc_dir_entry *dir, - struct i2o_device *dev) -{ - char buff[10]; - struct proc_dir_entry *devdir; - i2o_proc_entry *i2o_pe = NULL; - - sprintf(buff, "%03x", dev->lct_data.tid); - - osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff); - - devdir = proc_mkdir_data(buff, 0, dir, dev); - if (!devdir) { - osm_warn("Could not allocate procdir!\n"); - return; - } - - i2o_proc_create_entries(devdir, generic_dev_entries, dev); - - /* Inform core that we want updates about this device's status */ - switch (dev->lct_data.class_id) { - case I2O_CLASS_SCSI_PERIPHERAL: - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - i2o_pe = rbs_dev_entries; - break; - default: - break; - } - if (i2o_pe) - i2o_proc_create_entries(devdir, i2o_pe, dev); -} - -/** - * i2o_proc_iop_add - Add an I2O controller to the i2o proc tree - * @dir: parent proc dir entry - * @c: I2O controller which should be added - * - * Add the entries to the parent proc dir entry. Also each device is added - * to the controllers proc dir entry. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_proc_iop_add(struct proc_dir_entry *dir, - struct i2o_controller *c) -{ - struct proc_dir_entry *iopdir; - struct i2o_device *dev; - - osm_debug("adding IOP /proc/i2o/%s\n", c->name); - - iopdir = proc_mkdir_data(c->name, 0, dir, c); - if (!iopdir) - return -1; - - i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c); - - list_for_each_entry(dev, &c->devices, list) - i2o_proc_device_add(iopdir, dev); - - return 0; -} - -/** - * i2o_proc_fs_create - Create the i2o proc fs. - * - * Iterate over each I2O controller and create the entries for it. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_proc_fs_create(void) -{ - struct i2o_controller *c; - - i2o_proc_dir_root = proc_mkdir("i2o", NULL); - if (!i2o_proc_dir_root) - return -1; - - list_for_each_entry(c, &i2o_controllers, list) - i2o_proc_iop_add(i2o_proc_dir_root, c); - - return 0; -}; - -/** - * i2o_proc_fs_destroy - Cleanup the all i2o proc entries - * - * Iterate over each I2O controller and remove the entries for it. - * - * Returns 0 on success or negative error code on failure. - */ -static int __exit i2o_proc_fs_destroy(void) -{ - remove_proc_subtree("i2o", NULL); - - return 0; -}; - -/** - * i2o_proc_init - Init function for procfs - * - * Registers Proc OSM and creates procfs entries. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_proc_init(void) -{ - int rc; - - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - rc = i2o_driver_register(&i2o_proc_driver); - if (rc) - return rc; - - rc = i2o_proc_fs_create(); - if (rc) { - i2o_driver_unregister(&i2o_proc_driver); - return rc; - } - - return 0; -}; - -/** - * i2o_proc_exit - Exit function for procfs - * - * Unregisters Proc OSM and removes procfs entries. - */ -static void __exit i2o_proc_exit(void) -{ - i2o_driver_unregister(&i2o_proc_driver); - i2o_proc_fs_destroy(); -}; - -MODULE_AUTHOR("Deepak Saxena"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -module_init(i2o_proc_init); -module_exit(i2o_proc_exit); diff --git a/drivers/staging/i2o/i2o_scsi.c b/drivers/staging/i2o/i2o_scsi.c deleted file mode 100644 index 1b11dcb3faea..000000000000 --- a/drivers/staging/i2o/i2o_scsi.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * For the avoidance of doubt the "preferred form" of this code is one which - * is in an open non patent encumbered format. Where cryptographic key signing - * forms part of the process of creating an executable the information - * including keys needed to generate an equivalently functional executable - * are deemed to be part of the source code. - * - * Complications for I2O scsi - * - * o Each (bus,lun) is a logical device in I2O. We keep a map - * table. We spoof failed selection for unmapped units - * o Request sense buffers can come back for free. - * o Scatter gather is a bit dynamic. We have to investigate at - * setup time. - * o Some of our resources are dynamically shared. The i2o core - * needs a message reservation protocol to avoid swap v net - * deadlocking. We need to back off queue requests. - * - * In general the firmware wants to help. Where its help isn't performance - * useful we just ignore the aid. Its not worth the code in truth. - * - * Fixes/additions: - * Steve Ralston: - * Scatter gather now works - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor fixes for 2.6. - * - * To Do: - * 64bit cleanups - * Fix the resource management problems. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/ioport.h> -#include <linux/jiffies.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/delay.h> -#include <linux/proc_fs.h> -#include <linux/prefetch.h> -#include <linux/pci.h> -#include <linux/blkdev.h> -#include "i2o.h" -#include <linux/scatterlist.h> - -#include <asm/dma.h> -#include <asm/io.h> -#include <linux/atomic.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_host.h> -#include <scsi/scsi_device.h> -#include <scsi/scsi_cmnd.h> -#include <scsi/sg.h> - -#define OSM_NAME "scsi-osm" -#define OSM_VERSION "1.316" -#define OSM_DESCRIPTION "I2O SCSI Peripheral OSM" - -static struct i2o_driver i2o_scsi_driver; - -static unsigned int i2o_scsi_max_id = 16; -static unsigned int i2o_scsi_max_lun = 255; - -struct i2o_scsi_host { - struct Scsi_Host *scsi_host; /* pointer to the SCSI host */ - struct i2o_controller *iop; /* pointer to the I2O controller */ - u64 lun; /* lun's used for block devices */ - struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */ -}; - -static struct scsi_host_template i2o_scsi_host_template; - -#define I2O_SCSI_CAN_QUEUE 4 - -/* SCSI OSM class handling definition */ -static struct i2o_class_id i2o_scsi_class_id[] = { - {I2O_CLASS_SCSI_PERIPHERAL}, - {I2O_CLASS_END} -}; - -static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c) -{ - struct i2o_scsi_host *i2o_shost; - struct i2o_device *i2o_dev; - struct Scsi_Host *scsi_host; - int max_channel = 0; - u8 type; - int i; - size_t size; - u16 body_size = 6; - -#ifdef CONFIG_I2O_EXT_ADAPTEC - if (c->adaptec) - body_size = 8; -#endif - - list_for_each_entry(i2o_dev, &c->devices, list) - if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) { - if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) - && (type == 0x01)) /* SCSI bus */ - max_channel++; - } - - if (!max_channel) { - osm_warn("no channels found on %s\n", c->name); - return ERR_PTR(-EFAULT); - } - - size = max_channel * sizeof(struct i2o_device *) - + sizeof(struct i2o_scsi_host); - - scsi_host = scsi_host_alloc(&i2o_scsi_host_template, size); - if (!scsi_host) { - osm_warn("Could not allocate SCSI host\n"); - return ERR_PTR(-ENOMEM); - } - - scsi_host->max_channel = max_channel - 1; - scsi_host->max_id = i2o_scsi_max_id; - scsi_host->max_lun = i2o_scsi_max_lun; - scsi_host->this_id = c->unit; - scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size); - - i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata; - i2o_shost->scsi_host = scsi_host; - i2o_shost->iop = c; - i2o_shost->lun = 1; - - i = 0; - list_for_each_entry(i2o_dev, &c->devices, list) - if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) { - if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) - && (type == 0x01)) /* only SCSI bus */ - i2o_shost->channel[i++] = i2o_dev; - - if (i >= max_channel) - break; - } - - return i2o_shost; -}; - -/** - * i2o_scsi_get_host - Get an I2O SCSI host - * @c: I2O controller to for which to get the SCSI host - * - * If the I2O controller already exists as SCSI host, the SCSI host - * is returned, otherwise the I2O controller is added to the SCSI - * core. - * - * Returns pointer to the I2O SCSI host on success or NULL on failure. - */ -static struct i2o_scsi_host *i2o_scsi_get_host(struct i2o_controller *c) -{ - return c->driver_data[i2o_scsi_driver.context]; -}; - -/** - * i2o_scsi_remove - Remove I2O device from SCSI core - * @dev: device which should be removed - * - * Removes the I2O device from the SCSI core again. - * - * Returns 0 on success. - */ -static int i2o_scsi_remove(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_controller *c = i2o_dev->iop; - struct i2o_scsi_host *i2o_shost; - struct scsi_device *scsi_dev; - - osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid); - - i2o_shost = i2o_scsi_get_host(c); - - shost_for_each_device(scsi_dev, i2o_shost->scsi_host) - if (scsi_dev->hostdata == i2o_dev) { - sysfs_remove_link(&i2o_dev->device.kobj, "scsi"); - scsi_remove_device(scsi_dev); - scsi_device_put(scsi_dev); - break; - } - - return 0; -}; - -/** - * i2o_scsi_probe - verify if dev is a I2O SCSI device and install it - * @dev: device to verify if it is a I2O SCSI device - * - * Retrieve channel, id and lun for I2O device. If everything goes well - * register the I2O device as SCSI device on the I2O SCSI controller. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_scsi_probe(struct device *dev) -{ - struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_controller *c = i2o_dev->iop; - struct i2o_scsi_host *i2o_shost; - struct Scsi_Host *scsi_host; - struct i2o_device *parent; - struct scsi_device *scsi_dev; - u32 id = -1; - u64 lun = -1; - int channel = -1; - int i, rc; - - i2o_shost = i2o_scsi_get_host(c); - if (!i2o_shost) - return -EFAULT; - - scsi_host = i2o_shost->scsi_host; - - switch (i2o_dev->lct_data.class_id) { - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - case I2O_CLASS_EXECUTIVE: -#ifdef CONFIG_I2O_EXT_ADAPTEC - if (c->adaptec) { - u8 type; - struct i2o_device *d = i2o_shost->channel[0]; - - if (!i2o_parm_field_get(d, 0x0000, 0, &type, 1) - && (type == 0x01)) /* SCSI bus */ - if (!i2o_parm_field_get(d, 0x0200, 4, &id, 4)) { - channel = 0; - if (i2o_dev->lct_data.class_id == - I2O_CLASS_RANDOM_BLOCK_STORAGE) - lun = - cpu_to_le64(i2o_shost-> - lun++); - else - lun = 0; - } - } -#endif - break; - - case I2O_CLASS_SCSI_PERIPHERAL: - if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4)) - return -EFAULT; - - if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8)) - return -EFAULT; - - parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid); - if (!parent) { - osm_warn("can not find parent of device %03x\n", - i2o_dev->lct_data.tid); - return -EFAULT; - } - - for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++) - if (i2o_shost->channel[i] == parent) - channel = i; - break; - - default: - return -EFAULT; - } - - if (channel == -1) { - osm_warn("can not find channel of device %03x\n", - i2o_dev->lct_data.tid); - return -EFAULT; - } - - if (le32_to_cpu(id) >= scsi_host->max_id) { - osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", - le32_to_cpu(id), scsi_host->max_id); - return -EFAULT; - } - - if (le64_to_cpu(lun) >= scsi_host->max_lun) { - osm_warn("SCSI device lun (%llu) >= max_lun of I2O host (%llu)", - le64_to_cpu(lun), scsi_host->max_lun); - return -EFAULT; - } - - scsi_dev = - __scsi_add_device(i2o_shost->scsi_host, channel, le32_to_cpu(id), - le64_to_cpu(lun), i2o_dev); - - if (IS_ERR(scsi_dev)) { - osm_warn("can not add SCSI device %03x\n", - i2o_dev->lct_data.tid); - return PTR_ERR(scsi_dev); - } - - rc = sysfs_create_link(&i2o_dev->device.kobj, - &scsi_dev->sdev_gendev.kobj, "scsi"); - if (rc) - goto err; - - osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %llu\n", - i2o_dev->lct_data.tid, channel, le32_to_cpu(id), - le64_to_cpu(lun)); - - return 0; - -err: - scsi_remove_device(scsi_dev); - return rc; -}; - -static const char *i2o_scsi_info(struct Scsi_Host *SChost) -{ - struct i2o_scsi_host *hostdata; - hostdata = (struct i2o_scsi_host *)SChost->hostdata; - return hostdata->iop->name; -} - -/** - * i2o_scsi_reply - SCSI OSM message reply handler - * @c: controller issuing the reply - * @m: message id for flushing - * @msg: the message from the controller - * - * Process reply messages (interrupts in normal scsi controller think). - * We can get a variety of messages to process. The normal path is - * scsi command completions. We must also deal with IOP failures, - * the reply to a bus reset and the reply to a LUN query. - * - * Returns 0 on success and if the reply should not be flushed or > 0 - * on success and if the reply should be flushed. Returns negative error - * code on failure and if the reply should be flushed. - */ -static int i2o_scsi_reply(struct i2o_controller *c, u32 m, - struct i2o_message *msg) -{ - struct scsi_cmnd *cmd; - u32 error; - struct device *dev; - - cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); - if (unlikely(!cmd)) { - osm_err("NULL reply received!\n"); - return -1; - } - - /* - * Low byte is device status, next is adapter status, - * (then one byte reserved), then request status. - */ - error = le32_to_cpu(msg->body[0]); - - osm_debug("Completed %0x%p\n", cmd); - - cmd->result = error & 0xff; - /* - * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let - * the SCSI layer handle the error - */ - if (cmd->result) - memcpy(cmd->sense_buffer, &msg->body[3], - min(SCSI_SENSE_BUFFERSIZE, 40)); - - /* only output error code if AdapterStatus is not HBA_SUCCESS */ - if ((error >> 8) & 0xff) - osm_err("SCSI error %08x\n", error); - - dev = &c->pdev->dev; - - scsi_dma_unmap(cmd); - - cmd->scsi_done(cmd); - - return 1; -}; - -/** - * i2o_scsi_notify_device_add - Retrieve notifications of added devices - * @i2o_dev: the I2O device which was added - * - * If a I2O device is added we catch the notification, because I2O classes - * other than SCSI peripheral will not be received through - * i2o_scsi_probe(). - */ -static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev) -{ - switch (i2o_dev->lct_data.class_id) { - case I2O_CLASS_EXECUTIVE: - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - i2o_scsi_probe(&i2o_dev->device); - break; - - default: - break; - } -}; - -/** - * i2o_scsi_notify_device_remove - Retrieve notifications of removed devices - * @i2o_dev: the I2O device which was removed - * - * If a I2O device is removed, we catch the notification to remove the - * corresponding SCSI device. - */ -static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev) -{ - switch (i2o_dev->lct_data.class_id) { - case I2O_CLASS_EXECUTIVE: - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - i2o_scsi_remove(&i2o_dev->device); - break; - - default: - break; - } -}; - -/** - * i2o_scsi_notify_controller_add - Retrieve notifications of added controllers - * @c: the controller which was added - * - * If a I2O controller is added, we catch the notification to add a - * corresponding Scsi_Host. - */ -static void i2o_scsi_notify_controller_add(struct i2o_controller *c) -{ - struct i2o_scsi_host *i2o_shost; - int rc; - - i2o_shost = i2o_scsi_host_alloc(c); - if (IS_ERR(i2o_shost)) { - osm_err("Could not initialize SCSI host\n"); - return; - } - - rc = scsi_add_host(i2o_shost->scsi_host, &c->device); - if (rc) { - osm_err("Could not add SCSI host\n"); - scsi_host_put(i2o_shost->scsi_host); - return; - } - - c->driver_data[i2o_scsi_driver.context] = i2o_shost; - - osm_debug("new I2O SCSI host added\n"); -}; - -/** - * i2o_scsi_notify_controller_remove - Retrieve notifications of removed controllers - * @c: the controller which was removed - * - * If a I2O controller is removed, we catch the notification to remove the - * corresponding Scsi_Host. - */ -static void i2o_scsi_notify_controller_remove(struct i2o_controller *c) -{ - struct i2o_scsi_host *i2o_shost; - i2o_shost = i2o_scsi_get_host(c); - if (!i2o_shost) - return; - - c->driver_data[i2o_scsi_driver.context] = NULL; - - scsi_remove_host(i2o_shost->scsi_host); - scsi_host_put(i2o_shost->scsi_host); - osm_debug("I2O SCSI host removed\n"); -}; - -/* SCSI OSM driver struct */ -static struct i2o_driver i2o_scsi_driver = { - .name = OSM_NAME, - .reply = i2o_scsi_reply, - .classes = i2o_scsi_class_id, - .notify_device_add = i2o_scsi_notify_device_add, - .notify_device_remove = i2o_scsi_notify_device_remove, - .notify_controller_add = i2o_scsi_notify_controller_add, - .notify_controller_remove = i2o_scsi_notify_controller_remove, - .driver = { - .probe = i2o_scsi_probe, - .remove = i2o_scsi_remove, - }, -}; - -/** - * i2o_scsi_queuecommand - queue a SCSI command - * @SCpnt: scsi command pointer - * @done: callback for completion - * - * Issue a scsi command asynchronously. Return 0 on success or 1 if - * we hit an error (normally message queue congestion). The only - * minor complication here is that I2O deals with the device addressing - * so we have to map the bus/dev/lun back to an I2O handle as well - * as faking absent devices ourself. - * - * Locks: takes the controller lock on error path only - */ - -static int i2o_scsi_queuecommand_lck(struct scsi_cmnd *SCpnt, - void (*done) (struct scsi_cmnd *)) -{ - struct i2o_controller *c; - struct i2o_device *i2o_dev; - int tid; - struct i2o_message *msg; - /* - * ENABLE_DISCONNECT - * SIMPLE_TAG - * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME - */ - u32 scsi_flags = 0x20a00000; - u32 sgl_offset; - u32 *mptr; - u32 cmd = I2O_CMD_SCSI_EXEC << 24; - int rc = 0; - - /* - * Do the incoming paperwork - */ - i2o_dev = SCpnt->device->hostdata; - - SCpnt->scsi_done = done; - - if (unlikely(!i2o_dev)) { - osm_warn("no I2O device in request\n"); - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - goto exit; - } - c = i2o_dev->iop; - tid = i2o_dev->lct_data.tid; - - osm_debug("qcmd: Tid = %03x\n", tid); - osm_debug("Real scsi messages.\n"); - - /* - * Put together a scsi execscb message - */ - switch (SCpnt->sc_data_direction) { - case PCI_DMA_NONE: - /* DATA NO XFER */ - sgl_offset = SGL_OFFSET_0; - break; - - case PCI_DMA_TODEVICE: - /* DATA OUT (iop-->dev) */ - scsi_flags |= 0x80000000; - sgl_offset = SGL_OFFSET_10; - break; - - case PCI_DMA_FROMDEVICE: - /* DATA IN (iop<--dev) */ - scsi_flags |= 0x40000000; - sgl_offset = SGL_OFFSET_10; - break; - - default: - /* Unknown - kill the command */ - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - goto exit; - } - - /* - * Obtain an I2O message. If there are none free then - * throw it back to the scsi layer - */ - - msg = i2o_msg_get(c); - if (IS_ERR(msg)) { - rc = SCSI_MLQUEUE_HOST_BUSY; - goto exit; - } - - mptr = &msg->body[0]; - -#if 0 /* this code can't work */ -#ifdef CONFIG_I2O_EXT_ADAPTEC - if (c->adaptec) { - u32 adpt_flags = 0; - - if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) { - i2o_sg_io_hdr_t __user *usr_ptr = - ((Sg_request *) (SCpnt->sc_request-> - upper_private_data))->header. - usr_ptr; - - if (usr_ptr) - get_user(adpt_flags, &usr_ptr->flags); - } - - switch (i2o_dev->lct_data.class_id) { - case I2O_CLASS_EXECUTIVE: - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - /* interpret flag has to be set for executive */ - adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET; - break; - - default: - break; - } - - /* - * for Adaptec controllers we use the PRIVATE command, because - * the normal SCSI EXEC doesn't support all SCSI commands on - * all controllers (for example READ CAPACITY). - */ - if (sgl_offset == SGL_OFFSET_10) - sgl_offset = SGL_OFFSET_12; - cmd = I2O_CMD_PRIVATE << 24; - *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC); - *mptr++ = cpu_to_le32(adpt_flags | tid); - } -#endif -#endif - - msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid); - msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context); - - /* We want the SCSI control block back */ - msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, SCpnt)); - - /* LSI_920_PCI_QUIRK - * - * Intermittant observations of msg frame word data corruption - * observed on msg[4] after: - * WRITE, READ-MODIFY-WRITE - * operations. 19990606 -sralston - * - * (Hence we build this word via tag. Its good practice anyway - * we don't want fetches over PCI needlessly) - */ - - /* Attach tags to the devices */ - /* FIXME: implement - if(SCpnt->device->tagged_supported) { - if(SCpnt->tag == HEAD_OF_QUEUE_TAG) - scsi_flags |= 0x01000000; - else if(SCpnt->tag == ORDERED_QUEUE_TAG) - scsi_flags |= 0x01800000; - } - */ - - *mptr++ = cpu_to_le32(scsi_flags | SCpnt->cmd_len); - - /* Write SCSI command into the message - always 16 byte block */ - memcpy(mptr, SCpnt->cmnd, 16); - mptr += 4; - - if (sgl_offset != SGL_OFFSET_0) { - /* write size of data addressed by SGL */ - *mptr++ = cpu_to_le32(scsi_bufflen(SCpnt)); - - /* Now fill in the SGList and command */ - - if (scsi_sg_count(SCpnt)) { - if (!i2o_dma_map_sg(c, scsi_sglist(SCpnt), - scsi_sg_count(SCpnt), - SCpnt->sc_data_direction, &mptr)) - goto nomem; - } - } - - /* Stick the headers on */ - msg->u.head[0] = - cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset); - - /* Queue the message */ - i2o_msg_post(c, msg); - - osm_debug("Issued %0x%p\n", SCpnt); - - return 0; - - nomem: - rc = -ENOMEM; - i2o_msg_nop(c, msg); - - exit: - return rc; -} - -static DEF_SCSI_QCMD(i2o_scsi_queuecommand) - -/** - * i2o_scsi_abort - abort a running command - * @SCpnt: command to abort - * - * Ask the I2O controller to abort a command. This is an asynchrnous - * process and our callback handler will see the command complete with an - * aborted message if it succeeds. - * - * Returns 0 if the command is successfully aborted or negative error code - * on failure. - */ -static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) -{ - struct i2o_device *i2o_dev; - struct i2o_controller *c; - struct i2o_message *msg; - int tid; - int status = FAILED; - - osm_warn("Aborting command block.\n"); - - i2o_dev = SCpnt->device->hostdata; - c = i2o_dev->iop; - tid = i2o_dev->lct_data.tid; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return SCSI_MLQUEUE_HOST_BUSY; - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); - msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); - - if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) - status = SUCCESS; - - return status; -} - -/** - * i2o_scsi_bios_param - Invent disk geometry - * @sdev: scsi device - * @dev: block layer device - * @capacity: size in sectors - * @ip: geometry array - * - * This is anyone's guess quite frankly. We use the same rules everyone - * else appears to and hope. It seems to work. - */ - -static int i2o_scsi_bios_param(struct scsi_device *sdev, - struct block_device *dev, sector_t capacity, - int *ip) -{ - int size; - - size = capacity; - ip[0] = 64; /* heads */ - ip[1] = 32; /* sectors */ - if ((ip[2] = size >> 11) > 1024) { /* cylinders, test for big disk */ - ip[0] = 255; /* heads */ - ip[1] = 63; /* sectors */ - ip[2] = size / (255 * 63); /* cylinders */ - } - return 0; -} - -static struct scsi_host_template i2o_scsi_host_template = { - .proc_name = OSM_NAME, - .name = OSM_DESCRIPTION, - .info = i2o_scsi_info, - .queuecommand = i2o_scsi_queuecommand, - .eh_abort_handler = i2o_scsi_abort, - .bios_param = i2o_scsi_bios_param, - .can_queue = I2O_SCSI_CAN_QUEUE, - .sg_tablesize = 8, - .cmd_per_lun = 6, - .use_clustering = ENABLE_CLUSTERING, -}; - -/** - * i2o_scsi_init - SCSI OSM initialization function - * - * Register SCSI OSM into I2O core. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_scsi_init(void) -{ - int rc; - - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - /* Register SCSI OSM into I2O core */ - rc = i2o_driver_register(&i2o_scsi_driver); - if (rc) { - osm_err("Could not register SCSI driver\n"); - return rc; - } - - return 0; -}; - -/** - * i2o_scsi_exit - SCSI OSM exit function - * - * Unregisters SCSI OSM from I2O core. - */ -static void __exit i2o_scsi_exit(void) -{ - /* Unregister I2O SCSI OSM from I2O core */ - i2o_driver_unregister(&i2o_scsi_driver); -}; - -MODULE_AUTHOR("Red Hat Software"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -module_init(i2o_scsi_init); -module_exit(i2o_scsi_exit); diff --git a/drivers/staging/i2o/iop.c b/drivers/staging/i2o/iop.c deleted file mode 100644 index 3c2379097586..000000000000 --- a/drivers/staging/i2o/iop.c +++ /dev/null @@ -1,1254 +0,0 @@ -/* - * Functions to handle I2O controllers and I2O message handling - * - * Copyright (C) 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * A lot of the I2O message side code from this is taken from the - * Red Creek RCPCI45 adapter driver by Red Creek Communications - * - * Fixes/additions: - * Philipp Rumpf - * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> - * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> - * Deepak Saxena <deepak@plexity.net> - * Boji T Kannanthanam <boji.t.kannanthanam@intel.com> - * Alan Cox <alan@lxorguk.ukuu.org.uk>: - * Ported to Linux 2.5. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor fixes for 2.6. - */ - -#include <linux/module.h> -#include "i2o.h" -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include "core.h" - -#define OSM_NAME "i2o" -#define OSM_VERSION "1.325" -#define OSM_DESCRIPTION "I2O subsystem" - -/* global I2O controller list */ -LIST_HEAD(i2o_controllers); - -/* - * global I2O System Table. Contains information about all the IOPs in the - * system. Used to inform IOPs about each others existence. - */ -static struct i2o_dma i2o_systab; - -static int i2o_hrt_get(struct i2o_controller *c); - -/** - * i2o_msg_get_wait - obtain an I2O message from the IOP - * @c: I2O controller - * @wait: how long to wait until timeout - * - * This function waits up to wait seconds for a message slot to be - * available. - * - * On a success the message is returned and the pointer to the message is - * set in msg. The returned message is the physical page frame offset - * address from the read port (see the i2o spec). If no message is - * available returns I2O_QUEUE_EMPTY and msg is leaved untouched. - */ -struct i2o_message *i2o_msg_get_wait(struct i2o_controller *c, int wait) -{ - unsigned long timeout = jiffies + wait * HZ; - struct i2o_message *msg; - - while (IS_ERR(msg = i2o_msg_get(c))) { - if (time_after(jiffies, timeout)) { - osm_debug("%s: Timeout waiting for message frame.\n", - c->name); - return ERR_PTR(-ETIMEDOUT); - } - schedule_timeout_uninterruptible(1); - } - - return msg; -} - -#if BITS_PER_LONG == 64 -/** - * i2o_cntxt_list_add - Append a pointer to context list and return a id - * @c: controller to which the context list belong - * @ptr: pointer to add to the context list - * - * Because the context field in I2O is only 32-bit large, on 64-bit the - * pointer is to large to fit in the context field. The i2o_cntxt_list - * functions therefore map pointers to context fields. - * - * Returns context id > 0 on success or 0 on failure. - */ -u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr) -{ - struct i2o_context_list_element *entry; - unsigned long flags; - - if (!ptr) - osm_err("%s: couldn't add NULL pointer to context list!\n", - c->name); - - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) { - osm_err("%s: Could not allocate memory for context list element" - "\n", c->name); - return 0; - } - - entry->ptr = ptr; - entry->timestamp = jiffies; - INIT_LIST_HEAD(&entry->list); - - spin_lock_irqsave(&c->context_list_lock, flags); - - if (unlikely(atomic_inc_and_test(&c->context_list_counter))) - atomic_inc(&c->context_list_counter); - - entry->context = atomic_read(&c->context_list_counter); - - list_add(&entry->list, &c->context_list); - - spin_unlock_irqrestore(&c->context_list_lock, flags); - - osm_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context); - - return entry->context; -} - -/** - * i2o_cntxt_list_remove - Remove a pointer from the context list - * @c: controller to which the context list belong - * @ptr: pointer which should be removed from the context list - * - * Removes a previously added pointer from the context list and returns - * the matching context id. - * - * Returns context id on success or 0 on failure. - */ -u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr) -{ - struct i2o_context_list_element *entry; - u32 context = 0; - unsigned long flags; - - spin_lock_irqsave(&c->context_list_lock, flags); - list_for_each_entry(entry, &c->context_list, list) - if (entry->ptr == ptr) { - list_del(&entry->list); - context = entry->context; - kfree(entry); - break; - } - spin_unlock_irqrestore(&c->context_list_lock, flags); - - if (!context) - osm_warn("%s: Could not remove nonexistent ptr %p\n", c->name, - ptr); - - osm_debug("%s: remove ptr from context list %d -> %p\n", c->name, - context, ptr); - - return context; -} - -/** - * i2o_cntxt_list_get - Get a pointer from the context list and remove it - * @c: controller to which the context list belong - * @context: context id to which the pointer belong - * - * Returns pointer to the matching context id on success or NULL on - * failure. - */ -void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context) -{ - struct i2o_context_list_element *entry; - unsigned long flags; - void *ptr = NULL; - - spin_lock_irqsave(&c->context_list_lock, flags); - list_for_each_entry(entry, &c->context_list, list) - if (entry->context == context) { - list_del(&entry->list); - ptr = entry->ptr; - kfree(entry); - break; - } - spin_unlock_irqrestore(&c->context_list_lock, flags); - - if (!ptr) - osm_warn("%s: context id %d not found\n", c->name, context); - - osm_debug("%s: get ptr from context list %d -> %p\n", c->name, context, - ptr); - - return ptr; -} - -/** - * i2o_cntxt_list_get_ptr - Get a context id from the context list - * @c: controller to which the context list belong - * @ptr: pointer to which the context id should be fetched - * - * Returns context id which matches to the pointer on success or 0 on - * failure. - */ -u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr) -{ - struct i2o_context_list_element *entry; - u32 context = 0; - unsigned long flags; - - spin_lock_irqsave(&c->context_list_lock, flags); - list_for_each_entry(entry, &c->context_list, list) - if (entry->ptr == ptr) { - context = entry->context; - break; - } - spin_unlock_irqrestore(&c->context_list_lock, flags); - - if (!context) - osm_warn("%s: Could not find nonexistent ptr %p\n", c->name, - ptr); - - osm_debug("%s: get context id from context list %p -> %d\n", c->name, - ptr, context); - - return context; -} -#endif - -/** - * i2o_iop_find - Find an I2O controller by id - * @unit: unit number of the I2O controller to search for - * - * Lookup the I2O controller on the controller list. - * - * Returns pointer to the I2O controller on success or NULL if not found. - */ -struct i2o_controller *i2o_find_iop(int unit) -{ - struct i2o_controller *c; - - list_for_each_entry(c, &i2o_controllers, list) { - if (c->unit == unit) - return c; - } - - return NULL; -} - -/** - * i2o_iop_find_device - Find a I2O device on an I2O controller - * @c: I2O controller where the I2O device hangs on - * @tid: TID of the I2O device to search for - * - * Searches the devices of the I2O controller for a device with TID tid and - * returns it. - * - * Returns a pointer to the I2O device if found, otherwise NULL. - */ -struct i2o_device *i2o_iop_find_device(struct i2o_controller *c, u16 tid) -{ - struct i2o_device *dev; - - list_for_each_entry(dev, &c->devices, list) - if (dev->lct_data.tid == tid) - return dev; - - return NULL; -} - -/** - * i2o_quiesce_controller - quiesce controller - * @c: controller - * - * Quiesce an IOP. Causes IOP to make external operation quiescent - * (i2o 'READY' state). Internal operation of the IOP continues normally. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_quiesce(struct i2o_controller *c) -{ - struct i2o_message *msg; - i2o_status_block *sb = c->status_block.virt; - int rc; - - i2o_status_get(c); - - /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */ - if ((sb->iop_state != ADAPTER_STATE_READY) && - (sb->iop_state != ADAPTER_STATE_OPERATIONAL)) - return 0; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SYS_QUIESCE << 24 | HOST_TID << 12 | - ADAPTER_TID); - - /* Long timeout needed for quiesce if lots of devices */ - rc = i2o_msg_post_wait(c, msg, 240); - if (rc) - osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc); - else - osm_debug("%s: Quiesced.\n", c->name); - - i2o_status_get(c); // Entered READY state - - return rc; -} - -/** - * i2o_iop_enable - move controller from ready to OPERATIONAL - * @c: I2O controller - * - * Enable IOP. This allows the IOP to resume external operations and - * reverses the effect of a quiesce. Returns zero or an error code if - * an error occurs. - */ -static int i2o_iop_enable(struct i2o_controller *c) -{ - struct i2o_message *msg; - i2o_status_block *sb = c->status_block.virt; - int rc; - - i2o_status_get(c); - - /* Enable only allowed on READY state */ - if (sb->iop_state != ADAPTER_STATE_READY) - return -EINVAL; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SYS_ENABLE << 24 | HOST_TID << 12 | - ADAPTER_TID); - - /* How long of a timeout do we need? */ - rc = i2o_msg_post_wait(c, msg, 240); - if (rc) - osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc); - else - osm_debug("%s: Enabled.\n", c->name); - - i2o_status_get(c); // entered OPERATIONAL state - - return rc; -} - -/** - * i2o_iop_quiesce_all - Quiesce all I2O controllers on the system - * - * Quiesce all I2O controllers which are connected to the system. - */ -static inline void i2o_iop_quiesce_all(void) -{ - struct i2o_controller *c, *tmp; - - list_for_each_entry_safe(c, tmp, &i2o_controllers, list) { - if (!c->no_quiesce) - i2o_iop_quiesce(c); - } -} - -/** - * i2o_iop_enable_all - Enables all controllers on the system - * - * Enables all I2O controllers which are connected to the system. - */ -static inline void i2o_iop_enable_all(void) -{ - struct i2o_controller *c, *tmp; - - list_for_each_entry_safe(c, tmp, &i2o_controllers, list) - i2o_iop_enable(c); -} - -/** - * i2o_clear_controller - Bring I2O controller into HOLD state - * @c: controller - * - * Clear an IOP to HOLD state, ie. terminate external operations, clear all - * input queues and prepare for a system restart. IOP's internal operation - * continues normally and the outbound queue is alive. The IOP is not - * expected to rebuild its LCT. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_clear(struct i2o_controller *c) -{ - struct i2o_message *msg; - int rc; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - /* Quiesce all IOPs first */ - i2o_iop_quiesce_all(); - - msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_ADAPTER_CLEAR << 24 | HOST_TID << 12 | - ADAPTER_TID); - - rc = i2o_msg_post_wait(c, msg, 30); - if (rc) - osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc); - else - osm_debug("%s: Cleared.\n", c->name); - - /* Enable all IOPs */ - i2o_iop_enable_all(); - - return rc; -} - -/** - * i2o_iop_init_outbound_queue - setup the outbound message queue - * @c: I2O controller - * - * Clear and (re)initialize IOP's outbound queue and post the message - * frames to the IOP. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_init_outbound_queue(struct i2o_controller *c) -{ - u32 m; - volatile u8 *status = c->status.virt; - struct i2o_message *msg; - ulong timeout; - int i; - - osm_debug("%s: Initializing Outbound Queue...\n", c->name); - - memset(c->status.virt, 0, 4); - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - msg->u.s.tcntxt = cpu_to_le32(0x00000000); - msg->body[0] = cpu_to_le32(PAGE_SIZE); - /* Outbound msg frame size in words and Initcode */ - msg->body[1] = cpu_to_le32(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80); - msg->body[2] = cpu_to_le32(0xd0000004); - msg->body[3] = cpu_to_le32(i2o_dma_low(c->status.phys)); - msg->body[4] = cpu_to_le32(i2o_dma_high(c->status.phys)); - - i2o_msg_post(c, msg); - - timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ; - while (*status <= I2O_CMD_IN_PROGRESS) { - if (time_after(jiffies, timeout)) { - osm_warn("%s: Timeout Initializing\n", c->name); - return -ETIMEDOUT; - } - schedule_timeout_uninterruptible(1); - } - - m = c->out_queue.phys; - - /* Post frames */ - for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) { - i2o_flush_reply(c, m); - udelay(1); /* Promise */ - m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32); - } - - return 0; -} - -/** - * i2o_iop_reset - reset an I2O controller - * @c: controller to reset - * - * Reset the IOP into INIT state and wait until IOP gets into RESET state. - * Terminate all external operations, clear IOP's inbound and outbound - * queues, terminate all DDMs, and reload the IOP's operating environment - * and all local DDMs. The IOP rebuilds its LCT. - */ -static int i2o_iop_reset(struct i2o_controller *c) -{ - volatile u8 *status = c->status.virt; - struct i2o_message *msg; - unsigned long timeout; - i2o_status_block *sb = c->status_block.virt; - int rc = 0; - - osm_debug("%s: Resetting controller\n", c->name); - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - memset(c->status_block.virt, 0, 8); - - /* Quiesce all IOPs first */ - i2o_iop_quiesce_all(); - - msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_ADAPTER_RESET << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - msg->u.s.tcntxt = cpu_to_le32(0x00000000); - msg->body[0] = cpu_to_le32(0x00000000); - msg->body[1] = cpu_to_le32(0x00000000); - msg->body[2] = cpu_to_le32(i2o_dma_low(c->status.phys)); - msg->body[3] = cpu_to_le32(i2o_dma_high(c->status.phys)); - - i2o_msg_post(c, msg); - - /* Wait for a reply */ - timeout = jiffies + I2O_TIMEOUT_RESET * HZ; - while (!*status) { - if (time_after(jiffies, timeout)) - break; - - schedule_timeout_uninterruptible(1); - } - - switch (*status) { - case I2O_CMD_REJECTED: - osm_warn("%s: IOP reset rejected\n", c->name); - rc = -EPERM; - break; - - case I2O_CMD_IN_PROGRESS: - /* - * Once the reset is sent, the IOP goes into the INIT state - * which is indeterminate. We need to wait until the IOP has - * rebooted before we can let the system talk to it. We read - * the inbound Free_List until a message is available. If we - * can't read one in the given amount of time, we assume the - * IOP could not reboot properly. - */ - osm_debug("%s: Reset in progress, waiting for reboot...\n", - c->name); - - while (IS_ERR(msg = i2o_msg_get_wait(c, I2O_TIMEOUT_RESET))) { - if (time_after(jiffies, timeout)) { - osm_err("%s: IOP reset timeout.\n", c->name); - rc = PTR_ERR(msg); - goto exit; - } - schedule_timeout_uninterruptible(1); - } - i2o_msg_nop(c, msg); - - /* from here all quiesce commands are safe */ - c->no_quiesce = 0; - - /* verify if controller is in state RESET */ - i2o_status_get(c); - - if (!c->promise && (sb->iop_state != ADAPTER_STATE_RESET)) - osm_warn("%s: reset completed, but adapter not in RESET" - " state.\n", c->name); - else - osm_debug("%s: reset completed.\n", c->name); - - break; - - default: - osm_err("%s: IOP reset timeout.\n", c->name); - rc = -ETIMEDOUT; - break; - } - - exit: - /* Enable all IOPs */ - i2o_iop_enable_all(); - - return rc; -} - -/** - * i2o_iop_activate - Bring controller up to HOLD - * @c: controller - * - * This function brings an I2O controller into HOLD state. The adapter - * is reset if necessary and then the queues and resource table are read. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_activate(struct i2o_controller *c) -{ - i2o_status_block *sb = c->status_block.virt; - int rc; - int state; - - /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */ - /* In READY state, Get status */ - - rc = i2o_status_get(c); - if (rc) { - osm_info("%s: Unable to obtain status, attempting a reset.\n", - c->name); - rc = i2o_iop_reset(c); - if (rc) - return rc; - } - - if (sb->i2o_version > I2OVER15) { - osm_err("%s: Not running version 1.5 of the I2O Specification." - "\n", c->name); - return -ENODEV; - } - - switch (sb->iop_state) { - case ADAPTER_STATE_FAULTED: - osm_err("%s: hardware fault\n", c->name); - return -EFAULT; - - case ADAPTER_STATE_READY: - case ADAPTER_STATE_OPERATIONAL: - case ADAPTER_STATE_HOLD: - case ADAPTER_STATE_FAILED: - osm_debug("%s: already running, trying to reset...\n", c->name); - rc = i2o_iop_reset(c); - if (rc) - return rc; - } - - /* preserve state */ - state = sb->iop_state; - - rc = i2o_iop_init_outbound_queue(c); - if (rc) - return rc; - - /* if adapter was not in RESET state clear now */ - if (state != ADAPTER_STATE_RESET) - i2o_iop_clear(c); - - i2o_status_get(c); - - if (sb->iop_state != ADAPTER_STATE_HOLD) { - osm_err("%s: failed to bring IOP into HOLD state\n", c->name); - return -EIO; - } - - return i2o_hrt_get(c); -} - -static void i2o_res_alloc(struct i2o_controller *c, unsigned long flags) -{ - i2o_status_block *sb = c->status_block.virt; - struct resource *res = &c->mem_resource; - resource_size_t size, align; - int err; - - res->name = c->pdev->bus->name; - res->flags = flags; - res->start = 0; - res->end = 0; - osm_info("%s: requires private memory resources.\n", c->name); - - if (flags & IORESOURCE_MEM) { - size = sb->desired_mem_size; - align = 1 << 20; /* unspecified, use 1Mb and play safe */ - } else { - size = sb->desired_io_size; - align = 1 << 12; /* unspecified, use 4Kb and play safe */ - } - - err = pci_bus_alloc_resource(c->pdev->bus, res, size, align, 0, 0, - NULL, NULL); - if (err < 0) - return; - - if (flags & IORESOURCE_MEM) { - c->mem_alloc = 1; - sb->current_mem_size = resource_size(res); - sb->current_mem_base = res->start; - } else if (flags & IORESOURCE_IO) { - c->io_alloc = 1; - sb->current_io_size = resource_size(res); - sb->current_io_base = res->start; - } - osm_info("%s: allocated PCI space %pR\n", c->name, res); -} - -/** - * i2o_iop_systab_set - Set the I2O System Table of the specified IOP - * @c: I2O controller to which the system table should be send - * - * Before the systab could be set i2o_systab_build() must be called. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_systab_set(struct i2o_controller *c) -{ - struct i2o_message *msg; - i2o_status_block *sb = c->status_block.virt; - struct device *dev = &c->pdev->dev; - int rc; - - if (sb->current_mem_size < sb->desired_mem_size) - i2o_res_alloc(c, IORESOURCE_MEM); - - if (sb->current_io_size < sb->desired_io_size) - i2o_res_alloc(c, IORESOURCE_IO); - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - i2o_systab.phys = dma_map_single(dev, i2o_systab.virt, i2o_systab.len, - PCI_DMA_TODEVICE); - if (!i2o_systab.phys) { - i2o_msg_nop(c, msg); - return -ENOMEM; - } - - msg->u.head[0] = cpu_to_le32(I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_SYS_TAB_SET << 24 | HOST_TID << 12 | - ADAPTER_TID); - - /* - * Provide three SGL-elements: - * System table (SysTab), Private memory space declaration and - * Private i/o space declaration - */ - - msg->body[0] = cpu_to_le32(c->unit + 2); - msg->body[1] = cpu_to_le32(0x00000000); - msg->body[2] = cpu_to_le32(0x54000000 | i2o_systab.len); - msg->body[3] = cpu_to_le32(i2o_systab.phys); - msg->body[4] = cpu_to_le32(0x54000000 | sb->current_mem_size); - msg->body[5] = cpu_to_le32(sb->current_mem_base); - msg->body[6] = cpu_to_le32(0xd4000000 | sb->current_io_size); - msg->body[6] = cpu_to_le32(sb->current_io_base); - - rc = i2o_msg_post_wait(c, msg, 120); - - dma_unmap_single(dev, i2o_systab.phys, i2o_systab.len, - PCI_DMA_TODEVICE); - - if (rc < 0) - osm_err("%s: Unable to set SysTab (status=%#x).\n", c->name, - -rc); - else - osm_debug("%s: SysTab set.\n", c->name); - - return rc; -} - -/** - * i2o_iop_online - Bring a controller online into OPERATIONAL state. - * @c: I2O controller - * - * Send the system table and enable the I2O controller. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_iop_online(struct i2o_controller *c) -{ - int rc; - - rc = i2o_iop_systab_set(c); - if (rc) - return rc; - - /* In READY state */ - osm_debug("%s: Attempting to enable...\n", c->name); - return i2o_iop_enable(c); -} - -/** - * i2o_iop_remove - Remove the I2O controller from the I2O core - * @c: I2O controller - * - * Remove the I2O controller from the I2O core. If devices are attached to - * the controller remove these also and finally reset the controller. - */ -void i2o_iop_remove(struct i2o_controller *c) -{ - struct i2o_device *dev, *tmp; - - osm_debug("%s: deleting controller\n", c->name); - - i2o_driver_notify_controller_remove_all(c); - - list_del(&c->list); - - list_for_each_entry_safe(dev, tmp, &c->devices, list) - i2o_device_remove(dev); - - device_del(&c->device); - - /* Ask the IOP to switch to RESET state */ - i2o_iop_reset(c); -} - -/** - * i2o_systab_build - Build system table - * - * The system table contains information about all the IOPs in the system - * (duh) and is used by the Executives on the IOPs to establish peer2peer - * connections. We're not supporting peer2peer at the moment, but this - * will be needed down the road for things like lan2lan forwarding. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_systab_build(void) -{ - struct i2o_controller *c, *tmp; - int num_controllers = 0; - u32 change_ind = 0; - int count = 0; - struct i2o_sys_tbl *systab = i2o_systab.virt; - - list_for_each_entry_safe(c, tmp, &i2o_controllers, list) - num_controllers++; - - if (systab) { - change_ind = systab->change_ind; - kfree(i2o_systab.virt); - } - - /* Header + IOPs */ - i2o_systab.len = sizeof(struct i2o_sys_tbl) + num_controllers * - sizeof(struct i2o_sys_tbl_entry); - - systab = i2o_systab.virt = kzalloc(i2o_systab.len, GFP_KERNEL); - if (!systab) { - osm_err("unable to allocate memory for System Table\n"); - return -ENOMEM; - } - - systab->version = I2OVERSION; - systab->change_ind = change_ind + 1; - - list_for_each_entry_safe(c, tmp, &i2o_controllers, list) { - i2o_status_block *sb; - - if (count >= num_controllers) { - osm_err("controller added while building system table" - "\n"); - break; - } - - sb = c->status_block.virt; - - /* - * Get updated IOP state so we have the latest information - * - * We should delete the controller at this point if it - * doesn't respond since if it's not on the system table - * it is techninically not part of the I2O subsystem... - */ - if (unlikely(i2o_status_get(c))) { - osm_err("%s: Deleting b/c could not get status while " - "attempting to build system table\n", c->name); - i2o_iop_remove(c); - continue; // try the next one - } - - systab->iops[count].org_id = sb->org_id; - systab->iops[count].iop_id = c->unit + 2; - systab->iops[count].seg_num = 0; - systab->iops[count].i2o_version = sb->i2o_version; - systab->iops[count].iop_state = sb->iop_state; - systab->iops[count].msg_type = sb->msg_type; - systab->iops[count].frame_size = sb->inbound_frame_size; - systab->iops[count].last_changed = change_ind; - systab->iops[count].iop_capabilities = sb->iop_capabilities; - systab->iops[count].inbound_low = - i2o_dma_low(c->base.phys + I2O_IN_PORT); - systab->iops[count].inbound_high = - i2o_dma_high(c->base.phys + I2O_IN_PORT); - - count++; - } - - systab->num_entries = count; - - return 0; -} - -/** - * i2o_parse_hrt - Parse the hardware resource table. - * @c: I2O controller - * - * We don't do anything with it except dumping it (in debug mode). - * - * Returns 0. - */ -static int i2o_parse_hrt(struct i2o_controller *c) -{ - i2o_dump_hrt(c); - return 0; -} - -/** - * i2o_status_get - Get the status block from the I2O controller - * @c: I2O controller - * - * Issue a status query on the controller. This updates the attached - * status block. The status block could then be accessed through - * c->status_block. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_status_get(struct i2o_controller *c) -{ - struct i2o_message *msg; - volatile u8 *status_block; - unsigned long timeout; - - status_block = (u8 *) c->status_block.virt; - memset(c->status_block.virt, 0, sizeof(i2o_status_block)); - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_STATUS_GET << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - msg->u.s.tcntxt = cpu_to_le32(0x00000000); - msg->body[0] = cpu_to_le32(0x00000000); - msg->body[1] = cpu_to_le32(0x00000000); - msg->body[2] = cpu_to_le32(i2o_dma_low(c->status_block.phys)); - msg->body[3] = cpu_to_le32(i2o_dma_high(c->status_block.phys)); - msg->body[4] = cpu_to_le32(sizeof(i2o_status_block)); /* always 88 bytes */ - - i2o_msg_post(c, msg); - - /* Wait for a reply */ - timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ; - while (status_block[87] != 0xFF) { - if (time_after(jiffies, timeout)) { - osm_err("%s: Get status timeout.\n", c->name); - return -ETIMEDOUT; - } - - schedule_timeout_uninterruptible(1); - } - -#ifdef DEBUG - i2o_debug_state(c); -#endif - - return 0; -} - -/* - * i2o_hrt_get - Get the Hardware Resource Table from the I2O controller - * @c: I2O controller from which the HRT should be fetched - * - * The HRT contains information about possible hidden devices but is - * mostly useless to us. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_hrt_get(struct i2o_controller *c) -{ - int rc; - int i; - i2o_hrt *hrt = c->hrt.virt; - u32 size = sizeof(i2o_hrt); - struct device *dev = &c->pdev->dev; - - for (i = 0; i < I2O_HRT_GET_TRIES; i++) { - struct i2o_message *msg; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(SIX_WORD_MSG_SIZE | SGL_OFFSET_4); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_HRT_GET << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->body[0] = cpu_to_le32(0xd0000000 | c->hrt.len); - msg->body[1] = cpu_to_le32(c->hrt.phys); - - rc = i2o_msg_post_wait_mem(c, msg, 20, &c->hrt); - - if (rc < 0) { - osm_err("%s: Unable to get HRT (status=%#x)\n", c->name, - -rc); - return rc; - } - - size = hrt->num_entries * hrt->entry_len << 2; - if (size > c->hrt.len) { - if (i2o_dma_realloc(dev, &c->hrt, size)) - return -ENOMEM; - else - hrt = c->hrt.virt; - } else - return i2o_parse_hrt(c); - } - - osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name, - I2O_HRT_GET_TRIES); - - return -EBUSY; -} - -/** - * i2o_iop_release - release the memory for a I2O controller - * @dev: I2O controller which should be released - * - * Release the allocated memory. This function is called if refcount of - * device reaches 0 automatically. - */ -static void i2o_iop_release(struct device *dev) -{ - struct i2o_controller *c = to_i2o_controller(dev); - - i2o_iop_free(c); -} - -/** - * i2o_iop_alloc - Allocate and initialize a i2o_controller struct - * - * Allocate the necessary memory for a i2o_controller struct and - * initialize the lists and message mempool. - * - * Returns a pointer to the I2O controller or a negative error code on - * failure. - */ -struct i2o_controller *i2o_iop_alloc(void) -{ - static int unit; /* 0 and 1 are NULL IOP and Local Host */ - struct i2o_controller *c; - char poolname[32]; - - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) { - osm_err("i2o: Insufficient memory to allocate a I2O controller." - "\n"); - return ERR_PTR(-ENOMEM); - } - - c->unit = unit++; - sprintf(c->name, "iop%d", c->unit); - - snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); - if (i2o_pool_alloc - (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32), - I2O_MSG_INPOOL_MIN)) { - kfree(c); - return ERR_PTR(-ENOMEM); - } - - INIT_LIST_HEAD(&c->devices); - spin_lock_init(&c->lock); - mutex_init(&c->lct_lock); - - device_initialize(&c->device); - - c->device.release = &i2o_iop_release; - - dev_set_name(&c->device, "iop%d", c->unit); - -#if BITS_PER_LONG == 64 - spin_lock_init(&c->context_list_lock); - atomic_set(&c->context_list_counter, 0); - INIT_LIST_HEAD(&c->context_list); -#endif - - return c; -} - -/** - * i2o_iop_add - Initialize the I2O controller and add him to the I2O core - * @c: controller - * - * Initialize the I2O controller and if no error occurs add him to the I2O - * core. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_iop_add(struct i2o_controller *c) -{ - int rc; - - rc = device_add(&c->device); - if (rc) { - osm_err("%s: could not add controller\n", c->name); - goto iop_reset; - } - - osm_info("%s: Activating I2O controller...\n", c->name); - osm_info("%s: This may take a few minutes if there are many devices\n", - c->name); - - rc = i2o_iop_activate(c); - if (rc) { - osm_err("%s: could not activate controller\n", c->name); - goto device_del; - } - - osm_debug("%s: building sys table...\n", c->name); - - rc = i2o_systab_build(); - if (rc) - goto device_del; - - osm_debug("%s: online controller...\n", c->name); - - rc = i2o_iop_online(c); - if (rc) - goto device_del; - - osm_debug("%s: getting LCT...\n", c->name); - - rc = i2o_exec_lct_get(c); - if (rc) - goto device_del; - - list_add(&c->list, &i2o_controllers); - - i2o_driver_notify_controller_add_all(c); - - osm_info("%s: Controller added\n", c->name); - - return 0; - - device_del: - device_del(&c->device); - - iop_reset: - i2o_iop_reset(c); - - return rc; -} - -/** - * i2o_event_register - Turn on/off event notification for a I2O device - * @dev: I2O device which should receive the event registration request - * @drv: driver which want to get notified - * @tcntxt: transaction context to use with this notifier - * @evt_mask: mask of events - * - * Create and posts an event registration message to the task. No reply - * is waited for, or expected. If you do not want further notifications, - * call the i2o_event_register again with a evt_mask of 0. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_event_register(struct i2o_device *dev, struct i2o_driver *drv, - int tcntxt, u32 evt_mask) -{ - struct i2o_controller *c = dev->iop; - struct i2o_message *msg; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); - msg->u.head[1] = - cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | dev-> - lct_data.tid); - msg->u.s.icntxt = cpu_to_le32(drv->context); - msg->u.s.tcntxt = cpu_to_le32(tcntxt); - msg->body[0] = cpu_to_le32(evt_mask); - - i2o_msg_post(c, msg); - - return 0; -} - -/** - * i2o_iop_init - I2O main initialization function - * - * Initialize the I2O drivers (OSM) functions, register the Executive OSM, - * initialize the I2O PCI part and finally initialize I2O device stuff. - * - * Returns 0 on success or negative error code on failure. - */ -static int __init i2o_iop_init(void) -{ - int rc = 0; - - printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); - - rc = i2o_driver_init(); - if (rc) - goto exit; - - rc = i2o_exec_init(); - if (rc) - goto driver_exit; - - rc = i2o_pci_init(); - if (rc) - goto exec_exit; - - return 0; - - exec_exit: - i2o_exec_exit(); - - driver_exit: - i2o_driver_exit(); - - exit: - return rc; -} - -/** - * i2o_iop_exit - I2O main exit function - * - * Removes I2O controllers from PCI subsystem and shut down OSMs. - */ -static void __exit i2o_iop_exit(void) -{ - i2o_pci_exit(); - i2o_exec_exit(); - i2o_driver_exit(); -} - -module_init(i2o_iop_init); -module_exit(i2o_iop_exit); - -MODULE_AUTHOR("Red Hat Software"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(OSM_DESCRIPTION); -MODULE_VERSION(OSM_VERSION); - -#if BITS_PER_LONG == 64 -EXPORT_SYMBOL(i2o_cntxt_list_add); -EXPORT_SYMBOL(i2o_cntxt_list_get); -EXPORT_SYMBOL(i2o_cntxt_list_remove); -EXPORT_SYMBOL(i2o_cntxt_list_get_ptr); -#endif -EXPORT_SYMBOL(i2o_msg_get_wait); -EXPORT_SYMBOL(i2o_find_iop); -EXPORT_SYMBOL(i2o_iop_find_device); -EXPORT_SYMBOL(i2o_event_register); -EXPORT_SYMBOL(i2o_status_get); -EXPORT_SYMBOL(i2o_controllers); diff --git a/drivers/staging/i2o/memory.c b/drivers/staging/i2o/memory.c deleted file mode 100644 index 78b702c18537..000000000000 --- a/drivers/staging/i2o/memory.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Functions to handle I2O memory - * - * Pulled from the inlines in i2o headers and uninlined - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include "i2o.h" -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "core.h" - -/* Protects our 32/64bit mask switching */ -static DEFINE_MUTEX(mem_lock); - -/** - * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL - * @c: I2O controller for which the calculation should be done - * @body_size: maximum body size used for message in 32-bit words. - * - * Return the maximum number of SG elements in a SG list. - */ -u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size) -{ - i2o_status_block *sb = c->status_block.virt; - u16 sg_count = - (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) - - body_size; - - if (c->pae_support) { - /* - * for 64-bit a SG attribute element must be added and each - * SG element needs 12 bytes instead of 8. - */ - sg_count -= 2; - sg_count /= 3; - } else - sg_count /= 2; - - if (c->short_req && (sg_count > 8)) - sg_count = 8; - - return sg_count; -} -EXPORT_SYMBOL_GPL(i2o_sg_tablesize); - - -/** - * i2o_dma_map_single - Map pointer to controller and fill in I2O message. - * @c: I2O controller - * @ptr: pointer to the data which should be mapped - * @size: size of data in bytes - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_single(). The pointer sg_ptr will only be set to the end of the - * SG list if the allocation was successful. - * - * Returns DMA address which must be checked for failures using - * dma_mapping_error(). - */ -dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, - size_t size, - enum dma_data_direction direction, - u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - dma_addr_t dma_addr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0xd4000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0xd0000000; - break; - default: - return 0; - } - - dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - *mptr++ = cpu_to_le32(sg_flags | size); - *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr)); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr)); -#endif - *sg_ptr = mptr; - } - return dma_addr; -} -EXPORT_SYMBOL_GPL(i2o_dma_map_single); - -/** - * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message. - * @c: I2O controller - * @sg: SG list to be mapped - * @sg_count: number of elements in the SG list - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG - * list if the allocation was successful. - * - * Returns 0 on failure or 1 on success. - */ -int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg, - int sg_count, enum dma_data_direction direction, u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0x14000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0x10000000; - break; - default: - return 0; - } - - sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction); - if (!sg_count) - return 0; - -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - while (sg_count-- > 0) { - if (!sg_count) - sg_flags |= 0xC0000000; - *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg)); - *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg))); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg))); -#endif - sg = sg_next(sg); - } - *sg_ptr = mptr; - - return 1; -} -EXPORT_SYMBOL_GPL(i2o_dma_map_sg); - -/** - * i2o_dma_alloc - Allocate DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which should get the DMA buffer - * @len: length of the new DMA memory - * - * Allocate a coherent DMA memory and write the pointers into addr. - * - * Returns 0 on success or -ENOMEM on failure. - */ -int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len) -{ - struct pci_dev *pdev = to_pci_dev(dev); - int dma_64 = 0; - - mutex_lock(&mem_lock); - if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_BIT_MASK(64))) { - dma_64 = 1; - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - mutex_unlock(&mem_lock); - return -ENOMEM; - } - } - - addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL); - - if ((sizeof(dma_addr_t) > 4) && dma_64) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) - printk(KERN_WARNING "i2o: unable to set 64-bit DMA"); - mutex_unlock(&mem_lock); - - if (!addr->virt) - return -ENOMEM; - - memset(addr->virt, 0, len); - addr->len = len; - - return 0; -} -EXPORT_SYMBOL_GPL(i2o_dma_alloc); - - -/** - * i2o_dma_free - Free DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which contains the DMA buffer - * - * Free a coherent DMA memory and set virtual address of addr to NULL. - */ -void i2o_dma_free(struct device *dev, struct i2o_dma *addr) -{ - if (addr->virt) { - if (addr->phys) - dma_free_coherent(dev, addr->len, addr->virt, - addr->phys); - else - kfree(addr->virt); - addr->virt = NULL; - } -} -EXPORT_SYMBOL_GPL(i2o_dma_free); - - -/** - * i2o_dma_realloc - Realloc DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: pointer to a i2o_dma struct DMA buffer - * @len: new length of memory - * - * If there was something allocated in the addr, free it first. If len > 0 - * than try to allocate it and write the addresses back to the addr - * structure. If len == 0 set the virtual address to NULL. - * - * Returns the 0 on success or negative error code on failure. - */ -int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len) -{ - i2o_dma_free(dev, addr); - - if (len) - return i2o_dma_alloc(dev, addr, len); - - return 0; -} -EXPORT_SYMBOL_GPL(i2o_dma_realloc); - -/* - * i2o_pool_alloc - Allocate an slab cache and mempool - * @mempool: pointer to struct i2o_pool to write data into. - * @name: name which is used to identify cache - * @size: size of each object - * @min_nr: minimum number of objects - * - * First allocates a slab cache with name and size. Then allocates a - * mempool which uses the slab cache for allocation and freeing. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_pool_alloc(struct i2o_pool *pool, const char *name, - size_t size, int min_nr) -{ - pool->name = kstrdup(name, GFP_KERNEL); - if (!pool->name) - goto exit; - - pool->slab = - kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL); - if (!pool->slab) - goto free_name; - - pool->mempool = mempool_create_slab_pool(min_nr, pool->slab); - if (!pool->mempool) - goto free_slab; - - return 0; - -free_slab: - kmem_cache_destroy(pool->slab); - -free_name: - kfree(pool->name); - -exit: - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(i2o_pool_alloc); - -/* - * i2o_pool_free - Free slab cache and mempool again - * @mempool: pointer to struct i2o_pool which should be freed - * - * Note that you have to return all objects to the mempool again before - * calling i2o_pool_free(). - */ -void i2o_pool_free(struct i2o_pool *pool) -{ - mempool_destroy(pool->mempool); - kmem_cache_destroy(pool->slab); - kfree(pool->name); -}; -EXPORT_SYMBOL_GPL(i2o_pool_free); diff --git a/drivers/staging/i2o/pci.c b/drivers/staging/i2o/pci.c deleted file mode 100644 index 49804c9cf74f..000000000000 --- a/drivers/staging/i2o/pci.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * PCI handling of I2O controller - * - * Copyright (C) 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * A lot of the I2O message side code from this is taken from the Red - * Creek RCPCI45 adapter driver by Red Creek Communications - * - * Fixes/additions: - * Philipp Rumpf - * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> - * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> - * Deepak Saxena <deepak@plexity.net> - * Boji T Kannanthanam <boji.t.kannanthanam@intel.com> - * Alan Cox <alan@lxorguk.ukuu.org.uk>: - * Ported to Linux 2.5. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Minor fixes for 2.6. - * Markus Lidel <Markus.Lidel@shadowconnect.com>: - * Support for sysfs included. - */ - -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/slab.h> -#include "i2o.h" -#include <linux/module.h> -#include "core.h" - -#define OSM_DESCRIPTION "I2O-subsystem" - -/* PCI device id table for all I2O controllers */ -static struct pci_device_id i2o_pci_ids[] = { - {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, - {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)}, - {.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962, - .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID}, - {0} -}; - -/** - * i2o_pci_free - Frees the DMA memory for the I2O controller - * @c: I2O controller to free - * - * Remove all allocated DMA memory and unmap memory IO regions. If MTRR - * is enabled, also remove it again. - */ -static void i2o_pci_free(struct i2o_controller *c) -{ - struct device *dev; - - dev = &c->pdev->dev; - - i2o_dma_free(dev, &c->out_queue); - i2o_dma_free(dev, &c->status_block); - kfree(c->lct); - i2o_dma_free(dev, &c->dlct); - i2o_dma_free(dev, &c->hrt); - i2o_dma_free(dev, &c->status); - - if (c->raptor && c->in_queue.virt) - iounmap(c->in_queue.virt); - - if (c->base.virt) - iounmap(c->base.virt); - - pci_release_regions(c->pdev); -} - -/** - * i2o_pci_alloc - Allocate DMA memory, map IO memory for I2O controller - * @c: I2O controller - * - * Allocate DMA memory for a PCI (or in theory AGP) I2O controller. All - * IO mappings are also done here. If MTRR is enabled, also do add memory - * regions here. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_pci_alloc(struct i2o_controller *c) -{ - struct pci_dev *pdev = c->pdev; - struct device *dev = &pdev->dev; - int i; - - if (pci_request_regions(pdev, OSM_DESCRIPTION)) { - printk(KERN_ERR "%s: device already claimed\n", c->name); - return -ENODEV; - } - - for (i = 0; i < 6; i++) { - /* Skip I/O spaces */ - if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { - if (!c->base.phys) { - c->base.phys = pci_resource_start(pdev, i); - c->base.len = pci_resource_len(pdev, i); - - /* - * If we know what card it is, set the size - * correctly. Code is taken from dpt_i2o.c - */ - if (pdev->device == 0xa501) { - if (pdev->subsystem_device >= 0xc032 && - pdev->subsystem_device <= 0xc03b) { - if (c->base.len > 0x400000) - c->base.len = 0x400000; - } else { - if (c->base.len > 0x100000) - c->base.len = 0x100000; - } - } - if (!c->raptor) - break; - } else { - c->in_queue.phys = pci_resource_start(pdev, i); - c->in_queue.len = pci_resource_len(pdev, i); - break; - } - } - } - - if (i == 6) { - printk(KERN_ERR "%s: I2O controller has no memory regions" - " defined.\n", c->name); - i2o_pci_free(c); - return -EINVAL; - } - - /* Map the I2O controller */ - if (c->raptor) { - printk(KERN_INFO "%s: PCI I2O controller\n", c->name); - printk(KERN_INFO " BAR0 at 0x%08lX size=%ld\n", - (unsigned long)c->base.phys, (unsigned long)c->base.len); - printk(KERN_INFO " BAR1 at 0x%08lX size=%ld\n", - (unsigned long)c->in_queue.phys, - (unsigned long)c->in_queue.len); - } else - printk(KERN_INFO "%s: PCI I2O controller at %08lX size=%ld\n", - c->name, (unsigned long)c->base.phys, - (unsigned long)c->base.len); - - c->base.virt = ioremap_nocache(c->base.phys, c->base.len); - if (!c->base.virt) { - printk(KERN_ERR "%s: Unable to map controller.\n", c->name); - i2o_pci_free(c); - return -ENOMEM; - } - - if (c->raptor) { - c->in_queue.virt = - ioremap_nocache(c->in_queue.phys, c->in_queue.len); - if (!c->in_queue.virt) { - printk(KERN_ERR "%s: Unable to map controller.\n", - c->name); - i2o_pci_free(c); - return -ENOMEM; - } - } else - c->in_queue = c->base; - - c->irq_status = c->base.virt + I2O_IRQ_STATUS; - c->irq_mask = c->base.virt + I2O_IRQ_MASK; - c->in_port = c->base.virt + I2O_IN_PORT; - c->out_port = c->base.virt + I2O_OUT_PORT; - - /* Motorola/Freescale chip does not follow spec */ - if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) { - /* Check if CPU is enabled */ - if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) { - printk(KERN_INFO "%s: MPC82XX needs CPU running to " - "service I2O.\n", c->name); - i2o_pci_free(c); - return -ENODEV; - } else { - c->irq_status += I2O_MOTOROLA_PORT_OFFSET; - c->irq_mask += I2O_MOTOROLA_PORT_OFFSET; - c->in_port += I2O_MOTOROLA_PORT_OFFSET; - c->out_port += I2O_MOTOROLA_PORT_OFFSET; - printk(KERN_INFO "%s: MPC82XX workarounds activated.\n", - c->name); - } - } - - if (i2o_dma_alloc(dev, &c->status, 8)) { - i2o_pci_free(c); - return -ENOMEM; - } - - if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) { - i2o_pci_free(c); - return -ENOMEM; - } - - if (i2o_dma_alloc(dev, &c->dlct, 8192)) { - i2o_pci_free(c); - return -ENOMEM; - } - - if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) { - i2o_pci_free(c); - return -ENOMEM; - } - - if (i2o_dma_alloc(dev, &c->out_queue, - I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * - sizeof(u32))) { - i2o_pci_free(c); - return -ENOMEM; - } - - pci_set_drvdata(pdev, c); - - return 0; -} - -/** - * i2o_pci_interrupt - Interrupt handler for I2O controller - * @irq: interrupt line - * @dev_id: pointer to the I2O controller - * - * Handle an interrupt from a PCI based I2O controller. This turns out - * to be rather simple. We keep the controller pointer in the cookie. - */ -static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id) -{ - struct i2o_controller *c = dev_id; - u32 m; - irqreturn_t rc = IRQ_NONE; - - while (readl(c->irq_status) & I2O_IRQ_OUTBOUND_POST) { - m = readl(c->out_port); - if (m == I2O_QUEUE_EMPTY) { - /* - * Old 960 steppings had a bug in the I2O unit that - * caused the queue to appear empty when it wasn't. - */ - m = readl(c->out_port); - if (unlikely(m == I2O_QUEUE_EMPTY)) - break; - } - - /* dispatch it */ - if (i2o_driver_dispatch(c, m)) - /* flush it if result != 0 */ - i2o_flush_reply(c, m); - - rc = IRQ_HANDLED; - } - - return rc; -} - -/** - * i2o_pci_irq_enable - Allocate interrupt for I2O controller - * @c: i2o_controller that the request is for - * - * Allocate an interrupt for the I2O controller, and activate interrupts - * on the I2O controller. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_pci_irq_enable(struct i2o_controller *c) -{ - struct pci_dev *pdev = c->pdev; - int rc; - - writel(0xffffffff, c->irq_mask); - - if (pdev->irq) { - rc = request_irq(pdev->irq, i2o_pci_interrupt, IRQF_SHARED, - c->name, c); - if (rc < 0) { - printk(KERN_ERR "%s: unable to allocate interrupt %d." - "\n", c->name, pdev->irq); - return rc; - } - } - - writel(0x00000000, c->irq_mask); - - printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); - - return 0; -} - -/** - * i2o_pci_irq_disable - Free interrupt for I2O controller - * @c: I2O controller - * - * Disable interrupts in I2O controller and then free interrupt. - */ -static void i2o_pci_irq_disable(struct i2o_controller *c) -{ - writel(0xffffffff, c->irq_mask); - - if (c->pdev->irq > 0) - free_irq(c->pdev->irq, c); -} - -/** - * i2o_pci_probe - Probe the PCI device for an I2O controller - * @pdev: PCI device to test - * @id: id which matched with the PCI device id table - * - * Probe the PCI device for any device which is a memory of the - * Intelligent, I2O class or an Adaptec Zero Channel Controller. We - * attempt to set up each such device and register it with the core. - * - * Returns 0 on success or negative error code on failure. - */ -static int i2o_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct i2o_controller *c; - int rc; - struct pci_dev *i960 = NULL; - - printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); - - if ((pdev->class & 0xff) > 1) { - printk(KERN_WARNING "i2o: %s does not support I2O 1.5 " - "(skipping).\n", pci_name(pdev)); - return -ENODEV; - } - - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_WARNING "i2o: couldn't enable device %s\n", - pci_name(pdev)); - return rc; - } - - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", - pci_name(pdev)); - rc = -ENODEV; - goto disable; - } - - pci_set_master(pdev); - - c = i2o_iop_alloc(); - if (IS_ERR(c)) { - printk(KERN_ERR "i2o: couldn't allocate memory for %s\n", - pci_name(pdev)); - rc = PTR_ERR(c); - goto disable; - } else - printk(KERN_INFO "%s: controller found (%s)\n", c->name, - pci_name(pdev)); - - c->pdev = pdev; - c->device.parent = &pdev->dev; - - /* Cards that fall apart if you hit them with large I/O loads... */ - if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { - c->short_req = 1; - printk(KERN_INFO "%s: Symbios FC920 workarounds activated.\n", - c->name); - } - - if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { - /* - * Expose the ship behind i960 for initialization, or it will - * failed - */ - i960 = pci_get_slot(c->pdev->bus, - PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0)); - - if (i960) { - pci_write_config_word(i960, 0x42, 0); - pci_dev_put(i960); - } - - c->promise = 1; - c->limit_sectors = 1; - } - - if (pdev->subsystem_vendor == PCI_VENDOR_ID_DPT) - c->adaptec = 1; - - /* Cards that go bananas if you quiesce them before you reset them. */ - if (pdev->vendor == PCI_VENDOR_ID_DPT) { - c->no_quiesce = 1; - if (pdev->device == 0xa511) - c->raptor = 1; - - if (pdev->subsystem_device == 0xc05a) { - c->limit_sectors = 1; - printk(KERN_INFO - "%s: limit sectors per request to %d\n", c->name, - I2O_MAX_SECTORS_LIMITED); - } -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if (sizeof(dma_addr_t) > 4) { - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) - printk(KERN_INFO "%s: 64-bit DMA unavailable\n", - c->name); - else { - c->pae_support = 1; - printk(KERN_INFO "%s: using 64-bit DMA\n", - c->name); - } - } -#endif - } - - rc = i2o_pci_alloc(c); - if (rc) { - printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " - "failed\n", c->name); - goto free_controller; - } - - if (i2o_pci_irq_enable(c)) { - printk(KERN_ERR "%s: unable to enable interrupts for I2O " - "controller\n", c->name); - goto free_pci; - } - - rc = i2o_iop_add(c); - if (rc) - goto uninstall; - - if (i960) - pci_write_config_word(i960, 0x42, 0x03ff); - - return 0; - - uninstall: - i2o_pci_irq_disable(c); - - free_pci: - i2o_pci_free(c); - - free_controller: - i2o_iop_free(c); - - disable: - pci_disable_device(pdev); - - return rc; -} - -/** - * i2o_pci_remove - Removes a I2O controller from the system - * @pdev: I2O controller which should be removed - * - * Reset the I2O controller, disable interrupts and remove all allocated - * resources. - */ -static void i2o_pci_remove(struct pci_dev *pdev) -{ - struct i2o_controller *c; - c = pci_get_drvdata(pdev); - - i2o_iop_remove(c); - i2o_pci_irq_disable(c); - i2o_pci_free(c); - - pci_disable_device(pdev); - - printk(KERN_INFO "%s: Controller removed.\n", c->name); - - put_device(&c->device); -}; - -/* PCI driver for I2O controller */ -static struct pci_driver i2o_pci_driver = { - .name = "PCI_I2O", - .id_table = i2o_pci_ids, - .probe = i2o_pci_probe, - .remove = i2o_pci_remove, -}; - -/** - * i2o_pci_init - registers I2O PCI driver in PCI subsystem - * - * Returns > 0 on success or negative error code on failure. - */ -int __init i2o_pci_init(void) -{ - return pci_register_driver(&i2o_pci_driver); -}; - -/** - * i2o_pci_exit - unregisters I2O PCI driver from PCI subsystem - */ -void __exit i2o_pci_exit(void) -{ - pci_unregister_driver(&i2o_pci_driver); -}; - -MODULE_DEVICE_TABLE(pci, i2o_pci_ids); diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 4410d7fdc1b4..5dd9cdfae30c 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -37,34 +37,11 @@ #ifndef __LIBCFS_LIBCFS_H__ #define __LIBCFS_LIBCFS_H__ -#if !__GNUC__ -#define __attribute__(x) -#endif - #include "linux/libcfs.h" #include <linux/gfp.h> #include "curproc.h" -#ifndef offsetof -# define offsetof(typ, memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb))) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0]))) -#endif - -#if !defined(swap) -#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -#endif - -#if !defined(container_of) -/* given a pointer @ptr to the field @member embedded into type (usually - * struct) @type, return pointer to the embedding instance of @type. */ -#define container_of(ptr, type, member) \ - ((type *)((char *)(ptr)-(char *)(&((type *)0)->member))) -#endif - static inline int __is_po2(unsigned long long val) { return !(val & (val - 1)); @@ -88,23 +65,6 @@ static inline int __is_po2(unsigned long long val) int libcfs_arch_init(void); void libcfs_arch_cleanup(void); -/* libcfs tcpip */ -int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask); -int libcfs_ipif_enumerate(char ***names); -void libcfs_ipif_free_enumeration(char **names, int n); -int libcfs_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog); -int libcfs_sock_accept(struct socket **newsockp, struct socket *sock); -void libcfs_sock_abort_accept(struct socket *sock); -int libcfs_sock_connect(struct socket **sockp, int *fatal, - __u32 local_ip, int local_port, - __u32 peer_ip, int peer_port); -int libcfs_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize); -int libcfs_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize); -int libcfs_sock_getaddr(struct socket *socket, int remote, __u32 *ip, int *port); -int libcfs_sock_write(struct socket *sock, void *buffer, int nob, int timeout); -int libcfs_sock_read(struct socket *sock, void *buffer, int nob, int timeout); -void libcfs_sock_release(struct socket *sock); - /* need both kernel and user-land acceptor */ #define LNET_ACCEPTOR_MIN_RESERVED_PORT 512 #define LNET_ACCEPTOR_MAX_RESERVED_PORT 1023 @@ -184,4 +144,8 @@ static inline void *__container_of(void *ptr, unsigned long shift) #define _LIBCFS_H +void *libcfs_kvzalloc(size_t size, gfp_t flags); +void *libcfs_kvzalloc_cpt(struct cfs_cpt_table *cptab, int cpt, size_t size, + gfp_t flags); + #endif /* _LIBCFS_H */ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index fef882530455..d8f8543de573 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -496,19 +496,6 @@ static inline size_t cfs_round_strlen(char *fset) return (size_t)cfs_size_round((int)strlen(fset) + 1); } -/* roundup \a val to power2 */ -static inline unsigned int cfs_power2_roundup(unsigned int val) -{ - if (val != LOWEST_BIT_SET(val)) { /* not a power of 2 already */ - do { - val &= ~LOWEST_BIT_SET(val); - } while (val != LOWEST_BIT_SET(val)); - /* ...and round up */ - val <<= 1; - } - return val; -} - #define LOGL(var, len, ptr) \ do { \ if (var) \ diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h index 4fe50841e8e3..3e2502a69bbd 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h @@ -61,7 +61,6 @@ #include <linux/moduleparam.h> #include <linux/mutex.h> #include <linux/notifier.h> -#include <linux/proc_fs.h> #include <linux/random.h> #include <linux/rbtree.h> #include <linux/rwsem.h> diff --git a/drivers/staging/lustre/include/linux/lnet/api.h b/drivers/staging/lustre/include/linux/lnet/api.h index cd865175703f..c4dc1b2f605d 100644 --- a/drivers/staging/lustre/include/linux/lnet/api.h +++ b/drivers/staging/lustre/include/linux/lnet/api.h @@ -209,7 +209,6 @@ int LNetGet(lnet_nid_t self, int LNetSetLazyPortal(int portal); int LNetClearLazyPortal(int portal); int LNetCtl(unsigned int cmd, void *arg); -int LNetSetAsync(lnet_process_id_t id, int nasync); /** @} lnet_misc */ diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 0038d29a37fe..ac3be9486e8f 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -49,24 +49,17 @@ extern lnet_t the_lnet; /* THE network */ -#if defined(LNET_USE_LIB_FREELIST) -/* 1 CPT, simplify implementation... */ -# define LNET_CPT_MAX_BITS 0 - -#else /* KERNEL and no freelist */ - -# if (BITS_PER_LONG == 32) +#if (BITS_PER_LONG == 32) /* 2 CPTs, allowing more CPTs might make us under memory pressure */ -# define LNET_CPT_MAX_BITS 1 +# define LNET_CPT_MAX_BITS 1 -# else /* 64-bit system */ +#else /* 64-bit system */ /* * 256 CPTs for thousands of CPUs, allowing more CPTs might make us * under risk of consuming all lh_cookie. */ -# define LNET_CPT_MAX_BITS 8 -# endif /* BITS_PER_LONG == 32 */ -#endif +# define LNET_CPT_MAX_BITS 8 +#endif /* BITS_PER_LONG == 32 */ /* max allowed CPT number */ #define LNET_CPT_MAX (1 << LNET_CPT_MAX_BITS) @@ -172,196 +165,12 @@ lnet_net_lock_current(void) #define lnet_eq_wait_unlock() spin_unlock(&the_lnet.ln_eq_wait_lock) #define lnet_ni_lock(ni) spin_lock(&(ni)->ni_lock) #define lnet_ni_unlock(ni) spin_unlock(&(ni)->ni_lock) -#define LNET_MUTEX_LOCK(m) mutex_lock(m) -#define LNET_MUTEX_UNLOCK(m) mutex_unlock(m) #define MAX_PORTALS 64 -/* these are only used by code with LNET_USE_LIB_FREELIST, but we still - * exported them to !LNET_USE_LIB_FREELIST for easy implementation */ -#define LNET_FL_MAX_MES 2048 -#define LNET_FL_MAX_MDS 2048 -#define LNET_FL_MAX_EQS 512 -#define LNET_FL_MAX_MSGS 2048 /* Outstanding messages */ - -#ifdef LNET_USE_LIB_FREELIST - -int lnet_freelist_init(lnet_freelist_t *fl, int n, int size); -void lnet_freelist_fini(lnet_freelist_t *fl); - -static inline void * -lnet_freelist_alloc(lnet_freelist_t *fl) -{ - /* ALWAYS called with liblock held */ - lnet_freeobj_t *o; - - if (list_empty(&fl->fl_list)) - return NULL; - - o = list_entry(fl->fl_list.next, lnet_freeobj_t, fo_list); - list_del(&o->fo_list); - return (void *)&o->fo_contents; -} - -static inline void -lnet_freelist_free(lnet_freelist_t *fl, void *obj) -{ - /* ALWAYS called with liblock held */ - lnet_freeobj_t *o = list_entry(obj, lnet_freeobj_t, fo_contents); - - list_add(&o->fo_list, &fl->fl_list); -} - static inline lnet_eq_t * lnet_eq_alloc(void) { - /* NEVER called with resource lock held */ - struct lnet_res_container *rec = &the_lnet.ln_eq_container; - lnet_eq_t *eq; - - LASSERT(LNET_CPT_NUMBER == 1); - - lnet_res_lock(0); - eq = (lnet_eq_t *)lnet_freelist_alloc(&rec->rec_freelist); - lnet_res_unlock(0); - - return eq; -} - -static inline void -lnet_eq_free_locked(lnet_eq_t *eq) -{ - /* ALWAYS called with resource lock held */ - struct lnet_res_container *rec = &the_lnet.ln_eq_container; - - LASSERT(LNET_CPT_NUMBER == 1); - lnet_freelist_free(&rec->rec_freelist, eq); -} - -static inline void -lnet_eq_free(lnet_eq_t *eq) -{ - lnet_res_lock(0); - lnet_eq_free_locked(eq); - lnet_res_unlock(0); -} - -static inline lnet_libmd_t * -lnet_md_alloc(lnet_md_t *umd) -{ - /* NEVER called with resource lock held */ - struct lnet_res_container *rec = the_lnet.ln_md_containers[0]; - lnet_libmd_t *md; - - LASSERT(LNET_CPT_NUMBER == 1); - - lnet_res_lock(0); - md = (lnet_libmd_t *)lnet_freelist_alloc(&rec->rec_freelist); - lnet_res_unlock(0); - - if (md != NULL) - INIT_LIST_HEAD(&md->md_list); - - return md; -} - -static inline void -lnet_md_free_locked(lnet_libmd_t *md) -{ - /* ALWAYS called with resource lock held */ - struct lnet_res_container *rec = the_lnet.ln_md_containers[0]; - - LASSERT(LNET_CPT_NUMBER == 1); - lnet_freelist_free(&rec->rec_freelist, md); -} - -static inline void -lnet_md_free(lnet_libmd_t *md) -{ - lnet_res_lock(0); - lnet_md_free_locked(md); - lnet_res_unlock(0); -} - -static inline lnet_me_t * -lnet_me_alloc(void) -{ - /* NEVER called with resource lock held */ - struct lnet_res_container *rec = the_lnet.ln_me_containers[0]; - lnet_me_t *me; - - LASSERT(LNET_CPT_NUMBER == 1); - - lnet_res_lock(0); - me = (lnet_me_t *)lnet_freelist_alloc(&rec->rec_freelist); - lnet_res_unlock(0); - - return me; -} - -static inline void -lnet_me_free_locked(lnet_me_t *me) -{ - /* ALWAYS called with resource lock held */ - struct lnet_res_container *rec = the_lnet.ln_me_containers[0]; - - LASSERT(LNET_CPT_NUMBER == 1); - lnet_freelist_free(&rec->rec_freelist, me); -} - -static inline void -lnet_me_free(lnet_me_t *me) -{ - lnet_res_lock(0); - lnet_me_free_locked(me); - lnet_res_unlock(0); -} - -static inline lnet_msg_t * -lnet_msg_alloc(void) -{ - /* NEVER called with network lock held */ - struct lnet_msg_container *msc = the_lnet.ln_msg_containers[0]; - lnet_msg_t *msg; - - LASSERT(LNET_CPT_NUMBER == 1); - - lnet_net_lock(0); - msg = (lnet_msg_t *)lnet_freelist_alloc(&msc->msc_freelist); - lnet_net_unlock(0); - - if (msg != NULL) { - /* NULL pointers, clear flags etc */ - memset(msg, 0, sizeof(*msg)); - } - return msg; -} - -static inline void -lnet_msg_free_locked(lnet_msg_t *msg) -{ - /* ALWAYS called with network lock held */ - struct lnet_msg_container *msc = the_lnet.ln_msg_containers[0]; - - LASSERT(LNET_CPT_NUMBER == 1); - LASSERT(!msg->msg_onactivelist); - lnet_freelist_free(&msc->msc_freelist, msg); -} - -static inline void -lnet_msg_free(lnet_msg_t *msg) -{ - lnet_net_lock(0); - lnet_msg_free_locked(msg); - lnet_net_unlock(0); -} - -#else /* !LNET_USE_LIB_FREELIST */ - -static inline lnet_eq_t * -lnet_eq_alloc(void) -{ - /* NEVER called with liblock held */ lnet_eq_t *eq; LIBCFS_ALLOC(eq, sizeof(*eq)); @@ -371,14 +180,12 @@ lnet_eq_alloc(void) static inline void lnet_eq_free(lnet_eq_t *eq) { - /* ALWAYS called with resource lock held */ LIBCFS_FREE(eq, sizeof(*eq)); } static inline lnet_libmd_t * lnet_md_alloc(lnet_md_t *umd) { - /* NEVER called with liblock held */ lnet_libmd_t *md; unsigned int size; unsigned int niov; @@ -407,7 +214,6 @@ lnet_md_alloc(lnet_md_t *umd) static inline void lnet_md_free(lnet_libmd_t *md) { - /* ALWAYS called with resource lock held */ unsigned int size; if ((md->md_options & LNET_MD_KIOV) != 0) @@ -421,7 +227,6 @@ lnet_md_free(lnet_libmd_t *md) static inline lnet_me_t * lnet_me_alloc(void) { - /* NEVER called with liblock held */ lnet_me_t *me; LIBCFS_ALLOC(me, sizeof(*me)); @@ -431,14 +236,12 @@ lnet_me_alloc(void) static inline void lnet_me_free(lnet_me_t *me) { - /* ALWAYS called with resource lock held */ LIBCFS_FREE(me, sizeof(*me)); } static inline lnet_msg_t * lnet_msg_alloc(void) { - /* NEVER called with liblock held */ lnet_msg_t *msg; LIBCFS_ALLOC(msg, sizeof(*msg)); @@ -450,18 +253,10 @@ lnet_msg_alloc(void) static inline void lnet_msg_free(lnet_msg_t *msg) { - /* ALWAYS called with network lock held */ LASSERT(!msg->msg_onactivelist); LIBCFS_FREE(msg, sizeof(*msg)); } -#define lnet_eq_free_locked(eq) lnet_eq_free(eq) -#define lnet_md_free_locked(md) lnet_md_free(md) -#define lnet_me_free_locked(me) lnet_me_free(me) -#define lnet_msg_free_locked(msg) lnet_msg_free(msg) - -#endif /* LNET_USE_LIB_FREELIST */ - lnet_libhandle_t *lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie); void lnet_res_lh_initialize(struct lnet_res_container *rec, @@ -469,7 +264,6 @@ void lnet_res_lh_initialize(struct lnet_res_container *rec, static inline void lnet_res_lh_invalidate(lnet_libhandle_t *lh) { - /* ALWAYS called with resource lock held */ /* NB: cookie is still useful, don't reset it */ list_del(&lh->lh_hash_chain); } @@ -488,7 +282,6 @@ lnet_eq2handle(lnet_handle_eq_t *handle, lnet_eq_t *eq) static inline lnet_eq_t * lnet_handle2eq(lnet_handle_eq_t *handle) { - /* ALWAYS called with resource lock held */ lnet_libhandle_t *lh; lh = lnet_res_lh_lookup(&the_lnet.ln_eq_container, handle->cookie); @@ -846,6 +639,22 @@ int lnet_acceptor_port(void); int lnet_acceptor_start(void); void lnet_acceptor_stop(void); +int lnet_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask); +int lnet_ipif_enumerate(char ***names); +void lnet_ipif_free_enumeration(char **names, int n); +int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize); +int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize); +int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port); +int lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout); +int lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout); + +int lnet_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog); +int lnet_sock_accept(struct socket **newsockp, struct socket *sock); +int lnet_sock_connect(struct socket **sockp, int *fatal, + __u32 local_ip, int local_port, + __u32 peer_ip, int peer_port); +void libcfs_sock_release(struct socket *sock); + void lnet_get_tunables(void); int lnet_peers_start_down(void); int lnet_peer_buffer_credits(lnet_ni_t *ni); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 50537668f59d..41827a0c8f74 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -280,20 +280,6 @@ typedef struct lnet_libmd { #define LNET_MD_FLAG_AUTO_UNLINK (1 << 1) #define LNET_MD_FLAG_ABORTED (1 << 2) -#ifdef LNET_USE_LIB_FREELIST -typedef struct { - void *fl_objs; /* single contiguous array of objects */ - int fl_nobjs; /* the number of them */ - int fl_objsize; /* the size (including overhead) of each of them */ - struct list_head fl_list; /* where they are enqueued */ -} lnet_freelist_t; - -typedef struct { - struct list_head fo_list; /* enqueue on fl_list */ - void *fo_contents; /* aligned contents */ -} lnet_freeobj_t; -#endif - typedef struct { /* info about peers we are trying to fail */ struct list_head tp_list; /* ln_test_peers */ @@ -639,9 +625,6 @@ struct lnet_res_container { __u64 rec_lh_cookie; /* cookie generator */ struct list_head rec_active; /* active resource list */ struct list_head *rec_lh_hash; /* handle hash */ -#ifdef LNET_USE_LIB_FREELIST - lnet_freelist_t rec_freelist; /* freelist for resources */ -#endif }; /* message container */ @@ -654,9 +637,6 @@ struct lnet_msg_container { struct list_head msc_active; /* active message list */ /* threads doing finalization */ void **msc_finalizers; -#ifdef LNET_USE_LIB_FREELIST - lnet_freelist_t msc_freelist; /* freelist for messages */ -#endif }; /* Router Checker states */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 3bad441de8dc..2a72427bdd69 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -42,21 +42,21 @@ #include <asm/div64.h> static lnd_t the_o2iblnd = { - .lnd_type = O2IBLND, - .lnd_startup = kiblnd_startup, - .lnd_shutdown = kiblnd_shutdown, - .lnd_ctl = kiblnd_ctl, - .lnd_query = kiblnd_query, - .lnd_send = kiblnd_send, - .lnd_recv = kiblnd_recv, + .lnd_type = O2IBLND, + .lnd_startup = kiblnd_startup, + .lnd_shutdown = kiblnd_shutdown, + .lnd_ctl = kiblnd_ctl, + .lnd_query = kiblnd_query, + .lnd_send = kiblnd_send, + .lnd_recv = kiblnd_recv, }; -kib_data_t kiblnd_data; +kib_data_t kiblnd_data; static __u32 kiblnd_cksum(void *ptr, int nob) { - char *c = ptr; - __u32 sum = 0; + char *c = ptr; + __u32 sum = 0; while (nob-- > 0) sum = ((sum << 1) | (sum >> 31)) + *c++; @@ -138,10 +138,10 @@ static int kiblnd_msgtype2size(int type) static int kiblnd_unpack_rd(kib_msg_t *msg, int flip) { - kib_rdma_desc_t *rd; - int nob; - int n; - int i; + kib_rdma_desc_t *rd; + int nob; + int n; + int i; LASSERT(msg->ibm_type == IBLND_MSG_GET_REQ || msg->ibm_type == IBLND_MSG_PUT_ACK); @@ -210,10 +210,10 @@ void kiblnd_pack_msg(lnet_ni_t *ni, kib_msg_t *msg, int version, int kiblnd_unpack_msg(kib_msg_t *msg, int nob) { const int hdr_size = offsetof(kib_msg_t, ibm_u); - __u32 msg_cksum; - __u16 version; - int msg_nob; - int flip; + __u32 msg_cksum; + __u16 version; + int msg_nob; + int flip; /* 6 bytes are enough to have received magic + version */ if (nob < 6) { @@ -320,10 +320,10 @@ int kiblnd_unpack_msg(kib_msg_t *msg, int nob) int kiblnd_create_peer(lnet_ni_t *ni, kib_peer_t **peerp, lnet_nid_t nid) { - kib_peer_t *peer; - kib_net_t *net = ni->ni_data; - int cpt = lnet_cpt_of_nid(nid); - unsigned long flags; + kib_peer_t *peer; + kib_net_t *net = ni->ni_data; + int cpt = lnet_cpt_of_nid(nid); + unsigned long flags; LASSERT(net != NULL); LASSERT(nid != LNET_NID_ANY); @@ -385,9 +385,9 @@ kib_peer_t *kiblnd_find_peer_locked(lnet_nid_t nid) { /* the caller is responsible for accounting the additional reference * that this creates */ - struct list_head *peer_list = kiblnd_nid2peerlist(nid); - struct list_head *tmp; - kib_peer_t *peer; + struct list_head *peer_list = kiblnd_nid2peerlist(nid); + struct list_head *tmp; + kib_peer_t *peer; list_for_each(tmp, peer_list) { @@ -422,10 +422,10 @@ void kiblnd_unlink_peer_locked(kib_peer_t *peer) static int kiblnd_get_peer_info(lnet_ni_t *ni, int index, lnet_nid_t *nidp, int *count) { - kib_peer_t *peer; - struct list_head *ptmp; - int i; - unsigned long flags; + kib_peer_t *peer; + struct list_head *ptmp; + int i; + unsigned long flags; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -459,9 +459,9 @@ static int kiblnd_get_peer_info(lnet_ni_t *ni, int index, static void kiblnd_del_peer_locked(kib_peer_t *peer) { - struct list_head *ctmp; - struct list_head *cnxt; - kib_conn_t *conn; + struct list_head *ctmp; + struct list_head *cnxt; + kib_conn_t *conn; if (list_empty(&peer->ibp_conns)) { kiblnd_unlink_peer_locked(peer); @@ -480,14 +480,14 @@ static void kiblnd_del_peer_locked(kib_peer_t *peer) static int kiblnd_del_peer(lnet_ni_t *ni, lnet_nid_t nid) { LIST_HEAD(zombies); - struct list_head *ptmp; - struct list_head *pnxt; - kib_peer_t *peer; - int lo; - int hi; - int i; - unsigned long flags; - int rc = -ENOENT; + struct list_head *ptmp; + struct list_head *pnxt; + kib_peer_t *peer; + int lo; + int hi; + int i; + unsigned long flags; + int rc = -ENOENT; write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -532,12 +532,12 @@ static int kiblnd_del_peer(lnet_ni_t *ni, lnet_nid_t nid) static kib_conn_t *kiblnd_get_conn_by_idx(lnet_ni_t *ni, int index) { - kib_peer_t *peer; - struct list_head *ptmp; - kib_conn_t *conn; - struct list_head *ctmp; - int i; - unsigned long flags; + kib_peer_t *peer; + struct list_head *ptmp; + kib_conn_t *conn; + struct list_head *ctmp; + int i; + unsigned long flags; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -593,7 +593,7 @@ int kiblnd_translate_mtu(int value) static void kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid) { - int mtu; + int mtu; /* XXX There is no path record for iWARP, set by netdev->change_mtu? */ if (cmid->route.path_rec == NULL) @@ -607,11 +607,11 @@ static void kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid) static int kiblnd_get_completion_vector(kib_conn_t *conn, int cpt) { - cpumask_t *mask; - int vectors; - int off; - int i; - lnet_nid_t nid = conn->ibc_peer->ibp_nid; + cpumask_t *mask; + int vectors; + int off; + int i; + lnet_nid_t nid = conn->ibc_peer->ibp_nid; vectors = conn->ibc_cmid->device->num_comp_vectors; if (vectors <= 1) @@ -642,17 +642,17 @@ kib_conn_t *kiblnd_create_conn(kib_peer_t *peer, struct rdma_cm_id *cmid, * she must dispose of 'cmid'. (Actually I'd block forever if I tried * to destroy 'cmid' here since I'm called from the CM which still has * its ref on 'cmid'). */ - rwlock_t *glock = &kiblnd_data.kib_global_lock; - kib_net_t *net = peer->ibp_ni->ni_data; - kib_dev_t *dev; + rwlock_t *glock = &kiblnd_data.kib_global_lock; + kib_net_t *net = peer->ibp_ni->ni_data; + kib_dev_t *dev; struct ib_qp_init_attr *init_qp_attr; - struct kib_sched_info *sched; - kib_conn_t *conn; - struct ib_cq *cq; - unsigned long flags; - int cpt; - int rc; - int i; + struct kib_sched_info *sched; + kib_conn_t *conn; + struct ib_cq *cq; + unsigned long flags; + int cpt; + int rc; + int i; LASSERT(net != NULL); LASSERT(!in_interrupt()); @@ -837,8 +837,8 @@ kib_conn_t *kiblnd_create_conn(kib_peer_t *peer, struct rdma_cm_id *cmid, void kiblnd_destroy_conn(kib_conn_t *conn) { struct rdma_cm_id *cmid = conn->ibc_cmid; - kib_peer_t *peer = conn->ibc_peer; - int rc; + kib_peer_t *peer = conn->ibc_peer; + int rc; LASSERT(!in_interrupt()); LASSERT(atomic_read(&conn->ibc_refcount) == 0); @@ -904,10 +904,10 @@ void kiblnd_destroy_conn(kib_conn_t *conn) int kiblnd_close_peer_conns_locked(kib_peer_t *peer, int why) { - kib_conn_t *conn; - struct list_head *ctmp; - struct list_head *cnxt; - int count = 0; + kib_conn_t *conn; + struct list_head *ctmp; + struct list_head *cnxt; + int count = 0; list_for_each_safe(ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); @@ -926,10 +926,10 @@ int kiblnd_close_peer_conns_locked(kib_peer_t *peer, int why) int kiblnd_close_stale_conns_locked(kib_peer_t *peer, int version, __u64 incarnation) { - kib_conn_t *conn; - struct list_head *ctmp; - struct list_head *cnxt; - int count = 0; + kib_conn_t *conn; + struct list_head *ctmp; + struct list_head *cnxt; + int count = 0; list_for_each_safe(ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); @@ -953,14 +953,14 @@ int kiblnd_close_stale_conns_locked(kib_peer_t *peer, static int kiblnd_close_matching_conns(lnet_ni_t *ni, lnet_nid_t nid) { - kib_peer_t *peer; - struct list_head *ptmp; - struct list_head *pnxt; - int lo; - int hi; - int i; - unsigned long flags; - int count = 0; + kib_peer_t *peer; + struct list_head *ptmp; + struct list_head *pnxt; + int lo; + int hi; + int i; + unsigned long flags; + int count = 0; write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -1001,17 +1001,17 @@ static int kiblnd_close_matching_conns(lnet_ni_t *ni, lnet_nid_t nid) int kiblnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg) { struct libcfs_ioctl_data *data = arg; - int rc = -EINVAL; + int rc = -EINVAL; switch (cmd) { case IOC_LIBCFS_GET_PEER: { - lnet_nid_t nid = 0; - int count = 0; + lnet_nid_t nid = 0; + int count = 0; rc = kiblnd_get_peer_info(ni, data->ioc_count, &nid, &count); - data->ioc_nid = nid; - data->ioc_count = count; + data->ioc_nid = nid; + data->ioc_count = count; break; } @@ -1053,11 +1053,11 @@ int kiblnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg) void kiblnd_query(lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when) { - unsigned long last_alive = 0; - unsigned long now = cfs_time_current(); - rwlock_t *glock = &kiblnd_data.kib_global_lock; - kib_peer_t *peer; - unsigned long flags; + unsigned long last_alive = 0; + unsigned long now = cfs_time_current(); + rwlock_t *glock = &kiblnd_data.kib_global_lock; + kib_peer_t *peer; + unsigned long flags; read_lock_irqsave(glock, flags); @@ -1086,8 +1086,8 @@ void kiblnd_query(lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when) void kiblnd_free_pages(kib_pages_t *p) { - int npages = p->ibp_npages; - int i; + int npages = p->ibp_npages; + int i; for (i = 0; i < npages; i++) { if (p->ibp_pages[i] != NULL) @@ -1099,8 +1099,8 @@ void kiblnd_free_pages(kib_pages_t *p) int kiblnd_alloc_pages(kib_pages_t **pp, int cpt, int npages) { - kib_pages_t *p; - int i; + kib_pages_t *p; + int i; LIBCFS_CPT_ALLOC(p, lnet_cpt_table(), cpt, offsetof(kib_pages_t, ibp_pages[npages])); @@ -1130,7 +1130,7 @@ int kiblnd_alloc_pages(kib_pages_t **pp, int cpt, int npages) void kiblnd_unmap_rx_descs(kib_conn_t *conn) { kib_rx_t *rx; - int i; + int i; LASSERT(conn->ibc_rxs != NULL); LASSERT(conn->ibc_hdev != NULL); @@ -1153,14 +1153,13 @@ void kiblnd_unmap_rx_descs(kib_conn_t *conn) void kiblnd_map_rx_descs(kib_conn_t *conn) { - kib_rx_t *rx; - struct page *pg; - int pg_off; - int ipg; - int i; + kib_rx_t *rx; + struct page *pg; + int pg_off; + int ipg; + int i; - for (pg_off = ipg = i = 0; - i < IBLND_RX_MSGS(conn->ibc_version); i++) { + for (pg_off = ipg = i = 0; i < IBLND_RX_MSGS(conn->ibc_version); i++) { pg = conn->ibc_rx_pages->ibp_pages[ipg]; rx = &conn->ibc_rxs[i]; @@ -1192,9 +1191,9 @@ void kiblnd_map_rx_descs(kib_conn_t *conn) static void kiblnd_unmap_tx_pool(kib_tx_pool_t *tpo) { - kib_hca_dev_t *hdev = tpo->tpo_hdev; - kib_tx_t *tx; - int i; + kib_hca_dev_t *hdev = tpo->tpo_hdev; + kib_tx_t *tx; + int i; LASSERT(tpo->tpo_pool.po_allocated == 0); @@ -1216,8 +1215,8 @@ static void kiblnd_unmap_tx_pool(kib_tx_pool_t *tpo) static kib_hca_dev_t *kiblnd_current_hdev(kib_dev_t *dev) { kib_hca_dev_t *hdev; - unsigned long flags; - int i = 0; + unsigned long flags; + int i = 0; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); while (dev->ibd_failover) { @@ -1240,15 +1239,15 @@ static kib_hca_dev_t *kiblnd_current_hdev(kib_dev_t *dev) static void kiblnd_map_tx_pool(kib_tx_pool_t *tpo) { - kib_pages_t *txpgs = tpo->tpo_tx_pages; - kib_pool_t *pool = &tpo->tpo_pool; - kib_net_t *net = pool->po_owner->ps_net; - kib_dev_t *dev; - struct page *page; - kib_tx_t *tx; - int page_offset; - int ipage; - int i; + kib_pages_t *txpgs = tpo->tpo_tx_pages; + kib_pool_t *pool = &tpo->tpo_pool; + kib_net_t *net = pool->po_owner->ps_net; + kib_dev_t *dev; + struct page *page; + kib_tx_t *tx; + int page_offset; + int ipage; + int i; LASSERT(net != NULL); @@ -1291,7 +1290,7 @@ static void kiblnd_map_tx_pool(kib_tx_pool_t *tpo) struct ib_mr *kiblnd_find_dma_mr(kib_hca_dev_t *hdev, __u64 addr, __u64 size) { - __u64 index; + __u64 index; LASSERT(hdev->ibh_mrs[0] != NULL); @@ -1311,7 +1310,7 @@ struct ib_mr *kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev, kib_rdma_desc_t *rd) { struct ib_mr *prev_mr; struct ib_mr *mr; - int i; + int i; LASSERT(hdev->ibh_mrs[0] != NULL); @@ -1382,18 +1381,18 @@ static int kiblnd_create_fmr_pool(kib_fmr_poolset_t *fps, kib_fmr_pool_t **pp_fpo) { /* FMR pool for RDMA */ - kib_dev_t *dev = fps->fps_net->ibn_dev; - kib_fmr_pool_t *fpo; + kib_dev_t *dev = fps->fps_net->ibn_dev; + kib_fmr_pool_t *fpo; struct ib_fmr_pool_param param = { .max_pages_per_fmr = LNET_MAX_PAYLOAD/PAGE_SIZE, - .page_shift = PAGE_SHIFT, - .access = (IB_ACCESS_LOCAL_WRITE | - IB_ACCESS_REMOTE_WRITE), - .pool_size = fps->fps_pool_size, + .page_shift = PAGE_SHIFT, + .access = (IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_WRITE), + .pool_size = fps->fps_pool_size, .dirty_watermark = fps->fps_flush_trigger, .flush_function = NULL, - .flush_arg = NULL, - .cache = !!*kiblnd_tunables.kib_fmr_cache}; + .flush_arg = NULL, + .cache = !!*kiblnd_tunables.kib_fmr_cache}; int rc; LIBCFS_CPT_ALLOC(fpo, lnet_cpt_table(), fps->fps_cpt, sizeof(*fpo)); @@ -1454,7 +1453,7 @@ static int kiblnd_init_fmr_poolset(kib_fmr_poolset_t *fps, int cpt, int flush_trigger) { kib_fmr_pool_t *fpo; - int rc; + int rc; memset(fps, 0, sizeof(kib_fmr_poolset_t)); @@ -1485,11 +1484,11 @@ static int kiblnd_fmr_pool_is_idle(kib_fmr_pool_t *fpo, unsigned long now) void kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status) { LIST_HEAD(zombies); - kib_fmr_pool_t *fpo = fmr->fmr_pool; + kib_fmr_pool_t *fpo = fmr->fmr_pool; kib_fmr_poolset_t *fps = fpo->fpo_owner; - unsigned long now = cfs_time_current(); - kib_fmr_pool_t *tmp; - int rc; + unsigned long now = cfs_time_current(); + kib_fmr_pool_t *tmp; + int rc; rc = ib_fmr_pool_unmap(fmr->fmr_pfmr); LASSERT(rc == 0); @@ -1525,9 +1524,9 @@ int kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages, int npages, __u64 iov, kib_fmr_t *fmr) { struct ib_pool_fmr *pfmr; - kib_fmr_pool_t *fpo; - __u64 version; - int rc; + kib_fmr_pool_t *fpo; + __u64 version; + int rc; again: spin_lock(&fps->fps_lock); @@ -1658,13 +1657,13 @@ static int kiblnd_init_poolset(kib_poolset_t *ps, int cpt, kib_ps_node_init_t nd_init, kib_ps_node_fini_t nd_fini) { - kib_pool_t *pool; - int rc; + kib_pool_t *pool; + int rc; memset(ps, 0, sizeof(kib_poolset_t)); - ps->ps_cpt = cpt; - ps->ps_net = net; + ps->ps_cpt = cpt; + ps->ps_net = net; ps->ps_pool_create = po_create; ps->ps_pool_destroy = po_destroy; ps->ps_node_init = nd_init; @@ -1698,9 +1697,9 @@ static int kiblnd_pool_is_idle(kib_pool_t *pool, unsigned long now) void kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node) { LIST_HEAD(zombies); - kib_poolset_t *ps = pool->po_owner; - kib_pool_t *tmp; - unsigned long now = cfs_time_current(); + kib_poolset_t *ps = pool->po_owner; + kib_pool_t *tmp; + unsigned long now = cfs_time_current(); spin_lock(&ps->ps_lock); @@ -1727,9 +1726,9 @@ void kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node) struct list_head *kiblnd_pool_alloc_node(kib_poolset_t *ps) { - struct list_head *node; - kib_pool_t *pool; - int rc; + struct list_head *node; + kib_pool_t *pool; + int rc; again: spin_lock(&ps->ps_lock); @@ -1789,8 +1788,8 @@ struct list_head *kiblnd_pool_alloc_node(kib_poolset_t *ps) void kiblnd_pmr_pool_unmap(kib_phys_mr_t *pmr) { - kib_pmr_pool_t *ppo = pmr->pmr_pool; - struct ib_mr *mr = pmr->pmr_mr; + kib_pmr_pool_t *ppo = pmr->pmr_pool; + struct ib_mr *mr = pmr->pmr_mr; pmr->pmr_mr = NULL; kiblnd_pool_free_node(&ppo->ppo_pool, &pmr->pmr_list); @@ -1802,9 +1801,9 @@ int kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev, kib_rdma_desc_t *rd, __u64 *iova, kib_phys_mr_t **pp_pmr) { kib_phys_mr_t *pmr; - struct list_head *node; - int rc; - int i; + struct list_head *node; + int rc; + int i; node = kiblnd_pool_alloc_node(&pps->pps_poolset); if (node == NULL) { @@ -1846,7 +1845,7 @@ int kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev, static void kiblnd_destroy_pmr_pool(kib_pool_t *pool) { kib_pmr_pool_t *ppo = container_of(pool, kib_pmr_pool_t, ppo_pool); - kib_phys_mr_t *pmr; + kib_phys_mr_t *pmr; kib_phys_mr_t *tmp; LASSERT(pool->po_allocated == 0); @@ -1881,10 +1880,10 @@ static inline int kiblnd_pmr_pool_size(int ncpts) static int kiblnd_create_pmr_pool(kib_poolset_t *ps, int size, kib_pool_t **pp_po) { - struct kib_pmr_pool *ppo; - struct kib_pool *pool; - kib_phys_mr_t *pmr; - int i; + struct kib_pmr_pool *ppo; + struct kib_pool *pool; + kib_phys_mr_t *pmr; + int i; LIBCFS_CPT_ALLOC(ppo, lnet_cpt_table(), ps->ps_cpt, sizeof(kib_pmr_pool_t)); @@ -1923,8 +1922,8 @@ static int kiblnd_create_pmr_pool(kib_poolset_t *ps, int size, static void kiblnd_destroy_tx_pool(kib_pool_t *pool) { - kib_tx_pool_t *tpo = container_of(pool, kib_tx_pool_t, tpo_pool); - int i; + kib_tx_pool_t *tpo = container_of(pool, kib_tx_pool_t, tpo_pool); + int i; LASSERT(pool->po_allocated == 0); @@ -1979,9 +1978,9 @@ static int kiblnd_tx_pool_size(int ncpts) static int kiblnd_create_tx_pool(kib_poolset_t *ps, int size, kib_pool_t **pp_po) { - int i; - int npg; - kib_pool_t *pool; + int i; + int npg; + kib_pool_t *pool; kib_tx_pool_t *tpo; LIBCFS_CPT_ALLOC(tpo, lnet_cpt_table(), ps->ps_cpt, sizeof(*tpo)); @@ -2064,19 +2063,19 @@ static void kiblnd_tx_init(kib_pool_t *pool, struct list_head *node) { kib_tx_poolset_t *tps = container_of(pool->po_owner, kib_tx_poolset_t, tps_poolset); - kib_tx_t *tx = list_entry(node, kib_tx_t, tx_list); + kib_tx_t *tx = list_entry(node, kib_tx_t, tx_list); tx->tx_cookie = tps->tps_next_tx_cookie++; } static void kiblnd_net_fini_pools(kib_net_t *net) { - int i; + int i; cfs_cpt_for_each(i, lnet_cpt_table()) { - kib_tx_poolset_t *tps; - kib_fmr_poolset_t *fps; - kib_pmr_poolset_t *pps; + kib_tx_poolset_t *tps; + kib_fmr_poolset_t *fps; + kib_pmr_poolset_t *pps; if (net->ibn_tx_ps != NULL) { tps = net->ibn_tx_ps[i]; @@ -2112,16 +2111,15 @@ static void kiblnd_net_fini_pools(kib_net_t *net) static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) { - unsigned long flags; - int cpt; - int rc; - int i; + unsigned long flags; + int cpt; + int rc; + int i; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); if (*kiblnd_tunables.kib_map_on_demand == 0 && net->ibn_dev->ibd_hdev->ibh_nmrs == 1) { - read_unlock_irqrestore(&kiblnd_data.kib_global_lock, - flags); + read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); goto create_tx_pool; } @@ -2241,7 +2239,7 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) static int kiblnd_hdev_get_attr(kib_hca_dev_t *hdev) { struct ib_device_attr *attr; - int rc; + int rc; /* It's safe to assume a HCA can handle a page size * matching that of the native system */ @@ -2284,7 +2282,7 @@ static int kiblnd_hdev_get_attr(kib_hca_dev_t *hdev) static void kiblnd_hdev_cleanup_mrs(kib_hca_dev_t *hdev) { - int i; + int i; if (hdev->ibh_nmrs == 0 || hdev->ibh_mrs == NULL) return; @@ -2317,12 +2315,11 @@ void kiblnd_hdev_destroy(kib_hca_dev_t *hdev) static int kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev) { struct ib_mr *mr; - int i; - int rc; - __u64 mm_size; - __u64 mr_size; - int acflags = IB_ACCESS_LOCAL_WRITE | - IB_ACCESS_REMOTE_WRITE; + int i; + int rc; + __u64 mm_size; + __u64 mr_size; + int acflags = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE; rc = kiblnd_hdev_get_attr(hdev); if (rc != 0) @@ -2371,11 +2368,11 @@ static int kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev) for (i = 0; i < hdev->ibh_nmrs; i++) { struct ib_phys_buf ipb; - __u64 iova; + __u64 iova; ipb.size = hdev->ibh_mr_size; ipb.addr = i * mr_size; - iova = ipb.addr; + iova = ipb.addr; mr = ib_reg_phys_mr(hdev->ibh_pd, &ipb, 1, acflags, &iova); if (IS_ERR(mr)) { @@ -2406,10 +2403,10 @@ static int kiblnd_dummy_callback(struct rdma_cm_id *cmid, static int kiblnd_dev_need_failover(kib_dev_t *dev) { - struct rdma_cm_id *cmid; - struct sockaddr_in srcaddr; - struct sockaddr_in dstaddr; - int rc; + struct rdma_cm_id *cmid; + struct sockaddr_in srcaddr; + struct sockaddr_in dstaddr; + int rc; if (dev->ibd_hdev == NULL || /* initializing */ dev->ibd_hdev->ibh_cmid == NULL || /* listener is dead */ @@ -2435,7 +2432,7 @@ static int kiblnd_dev_need_failover(kib_dev_t *dev) } memset(&srcaddr, 0, sizeof(srcaddr)); - srcaddr.sin_family = AF_INET; + srcaddr.sin_family = AF_INET; srcaddr.sin_addr.s_addr = (__force u32)htonl(dev->ibd_ifip); memset(&dstaddr, 0, sizeof(dstaddr)); @@ -2464,15 +2461,14 @@ int kiblnd_dev_failover(kib_dev_t *dev) LIST_HEAD(zombie_tpo); LIST_HEAD(zombie_ppo); LIST_HEAD(zombie_fpo); - struct rdma_cm_id *cmid = NULL; - kib_hca_dev_t *hdev = NULL; - kib_hca_dev_t *old; - struct ib_pd *pd; - kib_net_t *net; - struct sockaddr_in addr; - unsigned long flags; - int rc = 0; - int i; + struct rdma_cm_id *cmid = NULL; + kib_hca_dev_t *hdev = NULL; + struct ib_pd *pd; + kib_net_t *net; + struct sockaddr_in addr; + unsigned long flags; + int rc = 0; + int i; LASSERT(*kiblnd_tunables.kib_dev_failover > 1 || dev->ibd_can_failover || @@ -2558,9 +2554,7 @@ int kiblnd_dev_failover(kib_dev_t *dev) write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); - old = dev->ibd_hdev; - dev->ibd_hdev = hdev; /* take over the refcount */ - hdev = old; + swap(dev->ibd_hdev, hdev); /* take over the refcount */ list_for_each_entry(net, &dev->ibd_nets, ibn_list) { cfs_cpt_for_each(i, lnet_cpt_table()) { @@ -2614,13 +2608,13 @@ void kiblnd_destroy_dev(kib_dev_t *dev) static kib_dev_t *kiblnd_create_dev(char *ifname) { struct net_device *netdev; - kib_dev_t *dev; - __u32 netmask; - __u32 ip; - int up; - int rc; + kib_dev_t *dev; + __u32 netmask; + __u32 ip; + int up; + int rc; - rc = libcfs_ipif_query(ifname, &up, &ip, &netmask); + rc = lnet_ipif_query(ifname, &up, &ip, &netmask); if (rc != 0) { CERROR("Can't query IPoIB interface %s: %d\n", ifname, rc); @@ -2665,8 +2659,8 @@ static kib_dev_t *kiblnd_create_dev(char *ifname) static void kiblnd_base_shutdown(void) { - struct kib_sched_info *sched; - int i; + struct kib_sched_info *sched; + int i; LASSERT(list_empty(&kiblnd_data.kib_devs)); @@ -2732,10 +2726,10 @@ static void kiblnd_base_shutdown(void) void kiblnd_shutdown(lnet_ni_t *ni) { - kib_net_t *net = ni->ni_data; - rwlock_t *g_lock = &kiblnd_data.kib_global_lock; - int i; - unsigned long flags; + kib_net_t *net = ni->ni_data; + rwlock_t *g_lock = &kiblnd_data.kib_global_lock; + int i; + unsigned long flags; LASSERT(kiblnd_data.kib_init == IBLND_INIT_ALL); @@ -2804,9 +2798,9 @@ out: static int kiblnd_base_startup(void) { - struct kib_sched_info *sched; - int rc; - int i; + struct kib_sched_info *sched; + int rc; + int i; LASSERT(kiblnd_data.kib_init == IBLND_INIT_NOTHING); @@ -2821,8 +2815,7 @@ static int kiblnd_base_startup(void) kiblnd_data.kib_peer_hash_size = IBLND_PEER_HASH_SIZE; LIBCFS_ALLOC(kiblnd_data.kib_peers, - sizeof(struct list_head) * - kiblnd_data.kib_peer_hash_size); + sizeof(struct list_head) * kiblnd_data.kib_peer_hash_size); if (kiblnd_data.kib_peers == NULL) goto failed; for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) @@ -2840,7 +2833,7 @@ static int kiblnd_base_startup(void) goto failed; cfs_percpt_for_each(sched, i, kiblnd_data.kib_scheds) { - int nthrs; + int nthrs; spin_lock_init(&sched->ibs_lock); INIT_LIST_HEAD(&sched->ibs_conns); @@ -2893,9 +2886,9 @@ static int kiblnd_base_startup(void) static int kiblnd_start_schedulers(struct kib_sched_info *sched) { - int rc = 0; - int nthrs; - int i; + int rc = 0; + int nthrs; + int i; if (sched->ibs_nthreads == 0) { if (*kiblnd_tunables.kib_nscheds > 0) { @@ -2913,8 +2906,8 @@ static int kiblnd_start_schedulers(struct kib_sched_info *sched) } for (i = 0; i < nthrs; i++) { - long id; - char name[20]; + long id; + char name[20]; id = KIB_THREAD_ID(sched->ibs_cpt, sched->ibs_nthreads + i); snprintf(name, sizeof(name), "kiblnd_sd_%02ld_%02ld", @@ -2935,9 +2928,9 @@ static int kiblnd_start_schedulers(struct kib_sched_info *sched) static int kiblnd_dev_start_threads(kib_dev_t *dev, int newdev, __u32 *cpts, int ncpts) { - int cpt; - int rc; - int i; + int cpt; + int rc; + int i; for (i = 0; i < ncpts; i++) { struct kib_sched_info *sched; @@ -2960,10 +2953,10 @@ static int kiblnd_dev_start_threads(kib_dev_t *dev, int newdev, __u32 *cpts, static kib_dev_t *kiblnd_dev_search(char *ifname) { - kib_dev_t *alias = NULL; - kib_dev_t *dev; - char *colon; - char *colon2; + kib_dev_t *alias = NULL; + kib_dev_t *dev; + char *colon; + char *colon2; colon = strchr(ifname, ':'); list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) { @@ -2992,13 +2985,13 @@ static kib_dev_t *kiblnd_dev_search(char *ifname) int kiblnd_startup(lnet_ni_t *ni) { - char *ifname; - kib_dev_t *ibdev = NULL; - kib_net_t *net; - struct timeval tv; - unsigned long flags; - int rc; - int newdev; + char *ifname; + kib_dev_t *ibdev = NULL; + kib_net_t *net; + struct timeval tv; + unsigned long flags; + int rc; + int newdev; LASSERT(ni->ni_lnd == &the_o2iblnd); @@ -3091,7 +3084,7 @@ static void __exit kiblnd_module_fini(void) static int __init kiblnd_module_init(void) { - int rc; + int rc; CLASSERT(sizeof(kib_msg_t) <= IBLND_MSG_SIZE); CLASSERT(offsetof(kib_msg_t, diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index cd664d025f41..7f52c6963427 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -80,42 +80,47 @@ #define IBLND_N_SCHED_HIGH 4 typedef struct { - int *kib_dev_failover; /* HCA failover */ - unsigned int *kib_service; /* IB service number */ - int *kib_min_reconnect_interval; /* first failed connection retry... */ - int *kib_max_reconnect_interval; /* ...exponentially increasing to this */ - int *kib_cksum; /* checksum kib_msg_t? */ - int *kib_timeout; /* comms timeout (seconds) */ - int *kib_keepalive; /* keepalive timeout (seconds) */ - int *kib_ntx; /* # tx descs */ - int *kib_credits; /* # concurrent sends */ - int *kib_peertxcredits; /* # concurrent sends to 1 peer */ - int *kib_peerrtrcredits; /* # per-peer router buffer credits */ - int *kib_peercredits_hiw; /* # when eagerly to return credits */ - int *kib_peertimeout; /* seconds to consider peer dead */ - char **kib_default_ipif; /* default IPoIB interface */ - int *kib_retry_count; - int *kib_rnr_retry_count; - int *kib_concurrent_sends; /* send work queue sizing */ - int *kib_ib_mtu; /* IB MTU */ - int *kib_map_on_demand; /* map-on-demand if RD has more fragments - * than this value, 0 disable map-on-demand */ - int *kib_pmr_pool_size; /* # physical MR in pool */ - int *kib_fmr_pool_size; /* # FMRs in pool */ - int *kib_fmr_flush_trigger; /* When to trigger FMR flush */ - int *kib_fmr_cache; /* enable FMR pool cache? */ - int *kib_require_priv_port;/* accept only privileged ports */ - int *kib_use_priv_port; /* use privileged port for active connect */ - /* # threads on each CPT */ - int *kib_nscheds; + int *kib_dev_failover; /* HCA failover */ + unsigned int *kib_service; /* IB service number */ + int *kib_min_reconnect_interval; /* first failed connection + * retry... */ + int *kib_max_reconnect_interval; /* ...exponentially increasing + * to this */ + int *kib_cksum; /* checksum kib_msg_t? */ + int *kib_timeout; /* comms timeout (seconds) */ + int *kib_keepalive; /* keepalive timeout (seconds) */ + int *kib_ntx; /* # tx descs */ + int *kib_credits; /* # concurrent sends */ + int *kib_peertxcredits; /* # concurrent sends to 1 peer */ + int *kib_peerrtrcredits; /* # per-peer router buffer + * credits */ + int *kib_peercredits_hiw; /* # when eagerly to return + * credits */ + int *kib_peertimeout; /* seconds to consider peer dead */ + char **kib_default_ipif; /* default IPoIB interface */ + int *kib_retry_count; + int *kib_rnr_retry_count; + int *kib_concurrent_sends; /* send work queue sizing */ + int *kib_ib_mtu; /* IB MTU */ + int *kib_map_on_demand; /* map-on-demand if RD has more + * fragments than this value, 0 + * disable map-on-demand */ + int *kib_pmr_pool_size; /* # physical MR in pool */ + int *kib_fmr_pool_size; /* # FMRs in pool */ + int *kib_fmr_flush_trigger; /* When to trigger FMR flush */ + int *kib_fmr_cache; /* enable FMR pool cache? */ + int *kib_require_priv_port; /* accept only privileged ports */ + int *kib_use_priv_port; /* use privileged port for active + * connect */ + int *kib_nscheds; /* # threads on each CPT */ } kib_tunables_t; extern kib_tunables_t kiblnd_tunables; -#define IBLND_MSG_QUEUE_SIZE_V1 8 /* V1 only : # messages/RDMAs in-flight */ -#define IBLND_CREDIT_HIGHWATER_V1 7 /* V1 only : when eagerly to return credits */ +#define IBLND_MSG_QUEUE_SIZE_V1 8 /* V1 only : # messages/RDMAs in-flight */ +#define IBLND_CREDIT_HIGHWATER_V1 7 /* V1 only : when eagerly to return credits */ -#define IBLND_CREDITS_DEFAULT 8 /* default # of peer credits */ +#define IBLND_CREDITS_DEFAULT 8 /* default # of peer credits */ #define IBLND_CREDITS_MAX ((typeof(((kib_msg_t*) 0)->ibm_credits)) - 1) /* Max # of peer credits */ #define IBLND_MSG_QUEUE_SIZE(v) ((v) == IBLND_MSG_VERSION_1 ? \ @@ -186,34 +191,36 @@ struct kib_hca_dev; #endif typedef struct { - struct list_head ibd_list; /* chain on kib_devs */ - struct list_head ibd_fail_list; /* chain on kib_failed_devs */ - __u32 ibd_ifip; /* IPoIB interface IP */ - /** IPoIB interface name */ - char ibd_ifname[KIB_IFNAME_SIZE]; - int ibd_nnets; /* # nets extant */ - - unsigned long ibd_next_failover; - int ibd_failed_failover; /* # failover failures */ - unsigned int ibd_failover; /* failover in progress */ - unsigned int ibd_can_failover; /* IPoIB interface is a bonding master */ - struct list_head ibd_nets; - struct kib_hca_dev *ibd_hdev; + struct list_head ibd_list; /* chain on kib_devs */ + struct list_head ibd_fail_list; /* chain on kib_failed_devs */ + __u32 ibd_ifip; /* IPoIB interface IP */ + + /* IPoIB interface name */ + char ibd_ifname[KIB_IFNAME_SIZE]; + int ibd_nnets; /* # nets extant */ + + unsigned long ibd_next_failover; + int ibd_failed_failover; /* # failover failures */ + unsigned int ibd_failover; /* failover in progress */ + unsigned int ibd_can_failover; /* IPoIB interface is a bonding + * master */ + struct list_head ibd_nets; + struct kib_hca_dev *ibd_hdev; } kib_dev_t; typedef struct kib_hca_dev { - struct rdma_cm_id *ibh_cmid; /* listener cmid */ - struct ib_device *ibh_ibdev; /* IB device */ - int ibh_page_shift; /* page shift of current HCA */ - int ibh_page_size; /* page size of current HCA */ - __u64 ibh_page_mask; /* page mask of current HCA */ - int ibh_mr_shift; /* bits shift of max MR size */ - __u64 ibh_mr_size; /* size of MR */ - int ibh_nmrs; /* # of global MRs */ - struct ib_mr **ibh_mrs; /* global MR */ - struct ib_pd *ibh_pd; /* PD */ - kib_dev_t *ibh_dev; /* owner */ - atomic_t ibh_ref; /* refcount */ + struct rdma_cm_id *ibh_cmid; /* listener cmid */ + struct ib_device *ibh_ibdev; /* IB device */ + int ibh_page_shift; /* page shift of current HCA */ + int ibh_page_size; /* page size of current HCA */ + __u64 ibh_page_mask; /* page mask of current HCA */ + int ibh_mr_shift; /* bits shift of max MR size */ + __u64 ibh_mr_size; /* size of MR */ + int ibh_nmrs; /* # of global MRs */ + struct ib_mr **ibh_mrs; /* global MR */ + struct ib_pd *ibh_pd; /* PD */ + kib_dev_t *ibh_dev; /* owner */ + atomic_t ibh_ref; /* refcount */ } kib_hca_dev_t; /** # of seconds to keep pool alive */ @@ -222,19 +229,19 @@ typedef struct kib_hca_dev { #define IBLND_POOL_RETRY 1 typedef struct { - int ibp_npages; /* # pages */ - struct page *ibp_pages[0]; /* page array */ + int ibp_npages; /* # pages */ + struct page *ibp_pages[0]; /* page array */ } kib_pages_t; struct kib_pmr_pool; typedef struct { - struct list_head pmr_list; /* chain node */ - struct ib_phys_buf *pmr_ipb; /* physical buffer */ - struct ib_mr *pmr_mr; /* IB MR */ - struct kib_pmr_pool *pmr_pool; /* owner of this MR */ - __u64 pmr_iova; /* Virtual I/O address */ - int pmr_refcount; /* reference count */ + struct list_head pmr_list; /* chain node */ + struct ib_phys_buf *pmr_ipb; /* physical buffer */ + struct ib_mr *pmr_mr; /* IB MR */ + struct kib_pmr_pool *pmr_pool; /* owner of this MR */ + __u64 pmr_iova; /* Virtual I/O address */ + int pmr_refcount; /* reference count */ } kib_phys_mr_t; struct kib_pool; @@ -251,97 +258,99 @@ struct kib_net; #define IBLND_POOL_NAME_LEN 32 typedef struct kib_poolset { - spinlock_t ps_lock; /* serialize */ - struct kib_net *ps_net; /* network it belongs to */ - char ps_name[IBLND_POOL_NAME_LEN]; /* pool set name */ - struct list_head ps_pool_list; /* list of pools */ - struct list_head ps_failed_pool_list; /* failed pool list */ - unsigned long ps_next_retry; /* time stamp for retry if failed to allocate */ - int ps_increasing; /* is allocating new pool */ - int ps_pool_size; /* new pool size */ - int ps_cpt; /* CPT id */ - - kib_ps_pool_create_t ps_pool_create; /* create a new pool */ - kib_ps_pool_destroy_t ps_pool_destroy; /* destroy a pool */ - kib_ps_node_init_t ps_node_init; /* initialize new allocated node */ - kib_ps_node_fini_t ps_node_fini; /* finalize node */ + spinlock_t ps_lock; /* serialize */ + struct kib_net *ps_net; /* network it belongs to */ + char ps_name[IBLND_POOL_NAME_LEN]; /* pool set name */ + struct list_head ps_pool_list; /* list of pools */ + struct list_head ps_failed_pool_list;/* failed pool list */ + unsigned long ps_next_retry; /* time stamp for retry if + * failed to allocate */ + int ps_increasing; /* is allocating new pool */ + int ps_pool_size; /* new pool size */ + int ps_cpt; /* CPT id */ + + kib_ps_pool_create_t ps_pool_create; /* create a new pool */ + kib_ps_pool_destroy_t ps_pool_destroy; /* destroy a pool */ + kib_ps_node_init_t ps_node_init; /* initialize new allocated + * node */ + kib_ps_node_fini_t ps_node_fini; /* finalize node */ } kib_poolset_t; typedef struct kib_pool { - struct list_head po_list; /* chain on pool list */ - struct list_head po_free_list; /* pre-allocated node */ - kib_poolset_t *po_owner; /* pool_set of this pool */ - unsigned long po_deadline; /* deadline of this pool */ - int po_allocated; /* # of elements in use */ - int po_failed; /* pool is created on failed HCA */ - int po_size; /* # of pre-allocated elements */ + struct list_head po_list; /* chain on pool list */ + struct list_head po_free_list; /* pre-allocated node */ + kib_poolset_t *po_owner; /* pool_set of this pool */ + unsigned long po_deadline; /* deadline of this pool */ + int po_allocated; /* # of elements in use */ + int po_failed; /* pool is created on failed + * HCA */ + int po_size; /* # of pre-allocated elements */ } kib_pool_t; typedef struct { - kib_poolset_t tps_poolset; /* pool-set */ - __u64 tps_next_tx_cookie; /* cookie of TX */ + kib_poolset_t tps_poolset; /* pool-set */ + __u64 tps_next_tx_cookie; /* cookie of TX */ } kib_tx_poolset_t; typedef struct { - kib_pool_t tpo_pool; /* pool */ - struct kib_hca_dev *tpo_hdev; /* device for this pool */ - struct kib_tx *tpo_tx_descs; /* all the tx descriptors */ - kib_pages_t *tpo_tx_pages; /* premapped tx msg pages */ + kib_pool_t tpo_pool; /* pool */ + struct kib_hca_dev *tpo_hdev; /* device for this pool */ + struct kib_tx *tpo_tx_descs; /* all the tx descriptors */ + kib_pages_t *tpo_tx_pages; /* premapped tx msg pages */ } kib_tx_pool_t; typedef struct { - kib_poolset_t pps_poolset; /* pool-set */ + kib_poolset_t pps_poolset; /* pool-set */ } kib_pmr_poolset_t; typedef struct kib_pmr_pool { - struct kib_hca_dev *ppo_hdev; /* device for this pool */ - kib_pool_t ppo_pool; /* pool */ + struct kib_hca_dev *ppo_hdev; /* device for this pool */ + kib_pool_t ppo_pool; /* pool */ } kib_pmr_pool_t; typedef struct { - spinlock_t fps_lock; /* serialize */ - struct kib_net *fps_net; /* IB network */ - struct list_head fps_pool_list; /* FMR pool list */ - struct list_head fps_failed_pool_list; /* FMR pool list */ - __u64 fps_version; /* validity stamp */ - int fps_cpt; /* CPT id */ - int fps_pool_size; - int fps_flush_trigger; - /* is allocating new pool */ - int fps_increasing; - /* time stamp for retry if failed to allocate */ - unsigned long fps_next_retry; + spinlock_t fps_lock; /* serialize */ + struct kib_net *fps_net; /* IB network */ + struct list_head fps_pool_list; /* FMR pool list */ + struct list_head fps_failed_pool_list;/* FMR pool list */ + __u64 fps_version; /* validity stamp */ + int fps_cpt; /* CPT id */ + int fps_pool_size; + int fps_flush_trigger; + int fps_increasing; /* is allocating new pool */ + unsigned long fps_next_retry; /* time stamp for retry if + * failed to allocate */ } kib_fmr_poolset_t; typedef struct { - struct list_head fpo_list; /* chain on pool list */ - struct kib_hca_dev *fpo_hdev; /* device for this pool */ - kib_fmr_poolset_t *fpo_owner; /* owner of this pool */ - struct ib_fmr_pool *fpo_fmr_pool; /* IB FMR pool */ - unsigned long fpo_deadline; /* deadline of this pool */ - int fpo_failed; /* fmr pool is failed */ - int fpo_map_count; /* # of mapped FMR */ + struct list_head fpo_list; /* chain on pool list */ + struct kib_hca_dev *fpo_hdev; /* device for this pool */ + kib_fmr_poolset_t *fpo_owner; /* owner of this pool */ + struct ib_fmr_pool *fpo_fmr_pool; /* IB FMR pool */ + unsigned long fpo_deadline; /* deadline of this pool */ + int fpo_failed; /* fmr pool is failed */ + int fpo_map_count; /* # of mapped FMR */ } kib_fmr_pool_t; typedef struct { - struct ib_pool_fmr *fmr_pfmr; /* IB pool fmr */ - kib_fmr_pool_t *fmr_pool; /* pool of FMR */ + struct ib_pool_fmr *fmr_pfmr; /* IB pool fmr */ + kib_fmr_pool_t *fmr_pool; /* pool of FMR */ } kib_fmr_t; typedef struct kib_net { - struct list_head ibn_list; /* chain on kib_dev_t::ibd_nets */ - __u64 ibn_incarnation; /* my epoch */ - int ibn_init; /* initialisation state */ - int ibn_shutdown; /* shutting down? */ + struct list_head ibn_list; /* chain on kib_dev_t::ibd_nets */ + __u64 ibn_incarnation;/* my epoch */ + int ibn_init; /* initialisation state */ + int ibn_shutdown; /* shutting down? */ - atomic_t ibn_npeers; /* # peers extant */ - atomic_t ibn_nconns; /* # connections extant */ + atomic_t ibn_npeers; /* # peers extant */ + atomic_t ibn_nconns; /* # connections extant */ - kib_tx_poolset_t **ibn_tx_ps; /* tx pool-set */ - kib_fmr_poolset_t **ibn_fmr_ps; /* fmr pool-set */ - kib_pmr_poolset_t **ibn_pmr_ps; /* pmr pool-set */ + kib_tx_poolset_t **ibn_tx_ps; /* tx pool-set */ + kib_fmr_poolset_t **ibn_fmr_ps; /* fmr pool-set */ + kib_pmr_poolset_t **ibn_pmr_ps; /* pmr pool-set */ - kib_dev_t *ibn_dev; /* underlying IB device */ + kib_dev_t *ibn_dev; /* underlying IB device */ } kib_net_t; #define KIB_THREAD_SHIFT 16 @@ -350,51 +359,45 @@ typedef struct kib_net { #define KIB_THREAD_TID(id) ((id) & ((1UL << KIB_THREAD_SHIFT) - 1)) struct kib_sched_info { - /* serialise */ - spinlock_t ibs_lock; - /* schedulers sleep here */ - wait_queue_head_t ibs_waitq; - /* conns to check for rx completions */ - struct list_head ibs_conns; - /* number of scheduler threads */ - int ibs_nthreads; - /* max allowed scheduler threads */ - int ibs_nthreads_max; - int ibs_cpt; /* CPT id */ + spinlock_t ibs_lock; /* serialise */ + wait_queue_head_t ibs_waitq; /* schedulers sleep here */ + struct list_head ibs_conns; /* conns to check for rx completions */ + int ibs_nthreads; /* number of scheduler threads */ + int ibs_nthreads_max; /* max allowed scheduler threads */ + int ibs_cpt; /* CPT id */ }; typedef struct { - int kib_init; /* initialisation state */ - int kib_shutdown; /* shut down? */ - struct list_head kib_devs; /* IB devices extant */ - /* list head of failed devices */ - struct list_head kib_failed_devs; - /* schedulers sleep here */ - wait_queue_head_t kib_failover_waitq; - atomic_t kib_nthreads; /* # live threads */ - /* stabilize net/dev/peer/conn ops */ - rwlock_t kib_global_lock; - /* hash table of all my known peers */ - struct list_head *kib_peers; - /* size of kib_peers */ - int kib_peer_hash_size; - /* the connd task (serialisation assertions) */ - void *kib_connd; - /* connections to setup/teardown */ - struct list_head kib_connd_conns; - /* connections with zero refcount */ - struct list_head kib_connd_zombies; - /* connection daemon sleeps here */ - wait_queue_head_t kib_connd_waitq; - spinlock_t kib_connd_lock; /* serialise */ - struct ib_qp_attr kib_error_qpa; /* QP->ERROR */ - /* percpt data for schedulers */ - struct kib_sched_info **kib_scheds; + int kib_init; /* initialisation state */ + int kib_shutdown; /* shut down? */ + struct list_head kib_devs; /* IB devices extant */ + struct list_head kib_failed_devs; /* list head of failed + * devices */ + wait_queue_head_t kib_failover_waitq; /* schedulers sleep here */ + atomic_t kib_nthreads; /* # live threads */ + rwlock_t kib_global_lock; /* stabilize net/dev/peer/conn + * ops */ + struct list_head *kib_peers; /* hash table of all my known + * peers */ + int kib_peer_hash_size; /* size of kib_peers */ + void *kib_connd; /* the connd task + * (serialisation assertions) + */ + struct list_head kib_connd_conns; /* connections to + * setup/teardown */ + struct list_head kib_connd_zombies; /* connections with zero + * refcount */ + wait_queue_head_t kib_connd_waitq; /* connection daemon sleeps + * here */ + spinlock_t kib_connd_lock; /* serialise */ + struct ib_qp_attr kib_error_qpa; /* QP->ERROR */ + struct kib_sched_info **kib_scheds; /* percpt data for schedulers + */ } kib_data_t; -#define IBLND_INIT_NOTHING 0 -#define IBLND_INIT_DATA 1 -#define IBLND_INIT_ALL 2 +#define IBLND_INIT_NOTHING 0 +#define IBLND_INIT_DATA 1 +#define IBLND_INIT_ALL 2 /************************************************************************ * IB Wire message format. @@ -402,228 +405,243 @@ typedef struct { */ typedef struct kib_connparams { - __u16 ibcp_queue_depth; - __u16 ibcp_max_frags; - __u32 ibcp_max_msg_size; + __u16 ibcp_queue_depth; + __u16 ibcp_max_frags; + __u32 ibcp_max_msg_size; } WIRE_ATTR kib_connparams_t; typedef struct { - lnet_hdr_t ibim_hdr; /* portals header */ - char ibim_payload[0]; /* piggy-backed payload */ + lnet_hdr_t ibim_hdr; /* portals header */ + char ibim_payload[0]; /* piggy-backed payload */ } WIRE_ATTR kib_immediate_msg_t; typedef struct { - __u32 rf_nob; /* # bytes this frag */ - __u64 rf_addr; /* CAVEAT EMPTOR: misaligned!! */ + __u32 rf_nob; /* # bytes this frag */ + __u64 rf_addr; /* CAVEAT EMPTOR: misaligned!! */ } WIRE_ATTR kib_rdma_frag_t; typedef struct { - __u32 rd_key; /* local/remote key */ - __u32 rd_nfrags; /* # fragments */ - kib_rdma_frag_t rd_frags[0]; /* buffer frags */ + __u32 rd_key; /* local/remote key */ + __u32 rd_nfrags; /* # fragments */ + kib_rdma_frag_t rd_frags[0]; /* buffer frags */ } WIRE_ATTR kib_rdma_desc_t; typedef struct { - lnet_hdr_t ibprm_hdr; /* portals header */ - __u64 ibprm_cookie; /* opaque completion cookie */ + lnet_hdr_t ibprm_hdr; /* portals header */ + __u64 ibprm_cookie; /* opaque completion cookie */ } WIRE_ATTR kib_putreq_msg_t; typedef struct { - __u64 ibpam_src_cookie; /* reflected completion cookie */ - __u64 ibpam_dst_cookie; /* opaque completion cookie */ - kib_rdma_desc_t ibpam_rd; /* sender's sink buffer */ + __u64 ibpam_src_cookie; /* reflected completion cookie */ + __u64 ibpam_dst_cookie; /* opaque completion cookie */ + kib_rdma_desc_t ibpam_rd; /* sender's sink buffer */ } WIRE_ATTR kib_putack_msg_t; typedef struct { - lnet_hdr_t ibgm_hdr; /* portals header */ - __u64 ibgm_cookie; /* opaque completion cookie */ - kib_rdma_desc_t ibgm_rd; /* rdma descriptor */ + lnet_hdr_t ibgm_hdr; /* portals header */ + __u64 ibgm_cookie; /* opaque completion cookie */ + kib_rdma_desc_t ibgm_rd; /* rdma descriptor */ } WIRE_ATTR kib_get_msg_t; typedef struct { - __u64 ibcm_cookie; /* opaque completion cookie */ - __s32 ibcm_status; /* < 0 failure: >= 0 length */ + __u64 ibcm_cookie; /* opaque completion cookie */ + __s32 ibcm_status; /* < 0 failure: >= 0 length */ } WIRE_ATTR kib_completion_msg_t; typedef struct { /* First 2 fields fixed FOR ALL TIME */ - __u32 ibm_magic; /* I'm an ibnal message */ - __u16 ibm_version; /* this is my version number */ - - __u8 ibm_type; /* msg type */ - __u8 ibm_credits; /* returned credits */ - __u32 ibm_nob; /* # bytes in whole message */ - __u32 ibm_cksum; /* checksum (0 == no checksum) */ - __u64 ibm_srcnid; /* sender's NID */ - __u64 ibm_srcstamp; /* sender's incarnation */ - __u64 ibm_dstnid; /* destination's NID */ - __u64 ibm_dststamp; /* destination's incarnation */ + __u32 ibm_magic; /* I'm an ibnal message */ + __u16 ibm_version; /* this is my version number */ + + __u8 ibm_type; /* msg type */ + __u8 ibm_credits; /* returned credits */ + __u32 ibm_nob; /* # bytes in whole message */ + __u32 ibm_cksum; /* checksum (0 == no checksum) */ + __u64 ibm_srcnid; /* sender's NID */ + __u64 ibm_srcstamp; /* sender's incarnation */ + __u64 ibm_dstnid; /* destination's NID */ + __u64 ibm_dststamp; /* destination's incarnation */ union { - kib_connparams_t connparams; - kib_immediate_msg_t immediate; - kib_putreq_msg_t putreq; - kib_putack_msg_t putack; - kib_get_msg_t get; - kib_completion_msg_t completion; + kib_connparams_t connparams; + kib_immediate_msg_t immediate; + kib_putreq_msg_t putreq; + kib_putack_msg_t putack; + kib_get_msg_t get; + kib_completion_msg_t completion; } WIRE_ATTR ibm_u; } WIRE_ATTR kib_msg_t; -#define IBLND_MSG_MAGIC LNET_PROTO_IB_MAGIC /* unique magic */ +#define IBLND_MSG_MAGIC LNET_PROTO_IB_MAGIC /* unique magic */ -#define IBLND_MSG_VERSION_1 0x11 -#define IBLND_MSG_VERSION_2 0x12 -#define IBLND_MSG_VERSION IBLND_MSG_VERSION_2 +#define IBLND_MSG_VERSION_1 0x11 +#define IBLND_MSG_VERSION_2 0x12 +#define IBLND_MSG_VERSION IBLND_MSG_VERSION_2 -#define IBLND_MSG_CONNREQ 0xc0 /* connection request */ -#define IBLND_MSG_CONNACK 0xc1 /* connection acknowledge */ -#define IBLND_MSG_NOOP 0xd0 /* nothing (just credits) */ -#define IBLND_MSG_IMMEDIATE 0xd1 /* immediate */ -#define IBLND_MSG_PUT_REQ 0xd2 /* putreq (src->sink) */ -#define IBLND_MSG_PUT_NAK 0xd3 /* completion (sink->src) */ -#define IBLND_MSG_PUT_ACK 0xd4 /* putack (sink->src) */ -#define IBLND_MSG_PUT_DONE 0xd5 /* completion (src->sink) */ -#define IBLND_MSG_GET_REQ 0xd6 /* getreq (sink->src) */ -#define IBLND_MSG_GET_DONE 0xd7 /* completion (src->sink: all OK) */ +#define IBLND_MSG_CONNREQ 0xc0 /* connection request */ +#define IBLND_MSG_CONNACK 0xc1 /* connection acknowledge */ +#define IBLND_MSG_NOOP 0xd0 /* nothing (just credits) */ +#define IBLND_MSG_IMMEDIATE 0xd1 /* immediate */ +#define IBLND_MSG_PUT_REQ 0xd2 /* putreq (src->sink) */ +#define IBLND_MSG_PUT_NAK 0xd3 /* completion (sink->src) */ +#define IBLND_MSG_PUT_ACK 0xd4 /* putack (sink->src) */ +#define IBLND_MSG_PUT_DONE 0xd5 /* completion (src->sink) */ +#define IBLND_MSG_GET_REQ 0xd6 /* getreq (sink->src) */ +#define IBLND_MSG_GET_DONE 0xd7 /* completion (src->sink: all OK) */ typedef struct { - __u32 ibr_magic; /* sender's magic */ - __u16 ibr_version; /* sender's version */ - __u8 ibr_why; /* reject reason */ - __u8 ibr_padding; /* padding */ - __u64 ibr_incarnation; /* incarnation of peer */ - kib_connparams_t ibr_cp; /* connection parameters */ + __u32 ibr_magic; /* sender's magic */ + __u16 ibr_version; /* sender's version */ + __u8 ibr_why; /* reject reason */ + __u8 ibr_padding; /* padding */ + __u64 ibr_incarnation; /* incarnation of peer */ + kib_connparams_t ibr_cp; /* connection parameters */ } WIRE_ATTR kib_rej_t; /* connection rejection reasons */ -#define IBLND_REJECT_CONN_RACE 1 /* You lost connection race */ -#define IBLND_REJECT_NO_RESOURCES 2 /* Out of memory/conns etc */ -#define IBLND_REJECT_FATAL 3 /* Anything else */ - -#define IBLND_REJECT_CONN_UNCOMPAT 4 /* incompatible version peer */ -#define IBLND_REJECT_CONN_STALE 5 /* stale peer */ - -#define IBLND_REJECT_RDMA_FRAGS 6 /* Fatal: peer's rdma frags can't match mine */ -#define IBLND_REJECT_MSG_QUEUE_SIZE 7 /* Fatal: peer's msg queue size can't match mine */ +#define IBLND_REJECT_CONN_RACE 1 /* You lost connection race */ +#define IBLND_REJECT_NO_RESOURCES 2 /* Out of memory/conns etc */ +#define IBLND_REJECT_FATAL 3 /* Anything else */ +#define IBLND_REJECT_CONN_UNCOMPAT 4 /* incompatible version peer */ +#define IBLND_REJECT_CONN_STALE 5 /* stale peer */ +#define IBLND_REJECT_RDMA_FRAGS 6 /* Fatal: peer's rdma frags can't match + * mine */ +#define IBLND_REJECT_MSG_QUEUE_SIZE 7 /* Fatal: peer's msg queue size can't + * match mine */ /***********************************************************************/ -typedef struct kib_rx /* receive message */ +typedef struct kib_rx /* receive message */ { - struct list_head rx_list; /* queue for attention */ - struct kib_conn *rx_conn; /* owning conn */ - int rx_nob; /* # bytes received (-1 while posted) */ - enum ib_wc_status rx_status; /* completion status */ - kib_msg_t *rx_msg; /* message buffer (host vaddr) */ - __u64 rx_msgaddr; /* message buffer (I/O addr) */ - DECLARE_PCI_UNMAP_ADDR (rx_msgunmap); /* for dma_unmap_single() */ - struct ib_recv_wr rx_wrq; /* receive work item... */ - struct ib_sge rx_sge; /* ...and its memory */ + struct list_head rx_list; /* queue for attention */ + struct kib_conn *rx_conn; /* owning conn */ + int rx_nob; /* # bytes received (-1 while + * posted) */ + enum ib_wc_status rx_status; /* completion status */ + kib_msg_t *rx_msg; /* message buffer (host vaddr) */ + __u64 rx_msgaddr; /* message buffer (I/O addr) */ + DECLARE_PCI_UNMAP_ADDR (rx_msgunmap); /* for dma_unmap_single() */ + struct ib_recv_wr rx_wrq; /* receive work item... */ + struct ib_sge rx_sge; /* ...and its memory */ } kib_rx_t; -#define IBLND_POSTRX_DONT_POST 0 /* don't post */ -#define IBLND_POSTRX_NO_CREDIT 1 /* post: no credits */ -#define IBLND_POSTRX_PEER_CREDIT 2 /* post: give peer back 1 credit */ -#define IBLND_POSTRX_RSRVD_CREDIT 3 /* post: give myself back 1 reserved credit */ +#define IBLND_POSTRX_DONT_POST 0 /* don't post */ +#define IBLND_POSTRX_NO_CREDIT 1 /* post: no credits */ +#define IBLND_POSTRX_PEER_CREDIT 2 /* post: give peer back 1 credit */ +#define IBLND_POSTRX_RSRVD_CREDIT 3 /* post: give myself back 1 reserved + * credit */ -typedef struct kib_tx /* transmit message */ +typedef struct kib_tx /* transmit message */ { - struct list_head tx_list; /* queue on idle_txs ibc_tx_queue etc. */ - kib_tx_pool_t *tx_pool; /* pool I'm from */ - struct kib_conn *tx_conn; /* owning conn */ - short tx_sending; /* # tx callbacks outstanding */ - short tx_queued; /* queued for sending */ - short tx_waiting; /* waiting for peer */ - int tx_status; /* LNET completion status */ - unsigned long tx_deadline; /* completion deadline */ - __u64 tx_cookie; /* completion cookie */ - lnet_msg_t *tx_lntmsg[2]; /* lnet msgs to finalize on completion */ - kib_msg_t *tx_msg; /* message buffer (host vaddr) */ - __u64 tx_msgaddr; /* message buffer (I/O addr) */ - DECLARE_PCI_UNMAP_ADDR (tx_msgunmap); /* for dma_unmap_single() */ - int tx_nwrq; /* # send work items */ - struct ib_send_wr *tx_wrq; /* send work items... */ - struct ib_sge *tx_sge; /* ...and their memory */ - kib_rdma_desc_t *tx_rd; /* rdma descriptor */ - int tx_nfrags; /* # entries in... */ - struct scatterlist *tx_frags; /* dma_map_sg descriptor */ - __u64 *tx_pages; /* rdma phys page addrs */ + struct list_head tx_list; /* queue on idle_txs ibc_tx_queue + * etc. */ + kib_tx_pool_t *tx_pool; /* pool I'm from */ + struct kib_conn *tx_conn; /* owning conn */ + short tx_sending; /* # tx callbacks outstanding */ + short tx_queued; /* queued for sending */ + short tx_waiting; /* waiting for peer */ + int tx_status; /* LNET completion status */ + unsigned long tx_deadline; /* completion deadline */ + __u64 tx_cookie; /* completion cookie */ + lnet_msg_t *tx_lntmsg[2]; /* lnet msgs to finalize on + * completion */ + kib_msg_t *tx_msg; /* message buffer (host vaddr) */ + __u64 tx_msgaddr; /* message buffer (I/O addr) */ + DECLARE_PCI_UNMAP_ADDR (tx_msgunmap); /* for dma_unmap_single() */ + int tx_nwrq; /* # send work items */ + struct ib_send_wr *tx_wrq; /* send work items... */ + struct ib_sge *tx_sge; /* ...and their memory */ + kib_rdma_desc_t *tx_rd; /* rdma descriptor */ + int tx_nfrags; /* # entries in... */ + struct scatterlist *tx_frags; /* dma_map_sg descriptor */ + __u64 *tx_pages; /* rdma phys page addrs */ union { - kib_phys_mr_t *pmr; /* MR for physical buffer */ - kib_fmr_t fmr; /* FMR */ - } tx_u; - int tx_dmadir; /* dma direction */ + kib_phys_mr_t *pmr; /* MR for physical buffer */ + kib_fmr_t fmr; /* FMR */ + } tx_u; + int tx_dmadir; /* dma direction */ } kib_tx_t; typedef struct kib_connvars { - /* connection-in-progress variables */ - kib_msg_t cv_msg; + kib_msg_t cv_msg; /* connection-in-progress variables */ } kib_connvars_t; typedef struct kib_conn { - struct kib_sched_info *ibc_sched; /* scheduler information */ - struct kib_peer *ibc_peer; /* owning peer */ - kib_hca_dev_t *ibc_hdev; /* HCA bound on */ - struct list_head ibc_list; /* stash on peer's conn list */ - struct list_head ibc_sched_list; /* schedule for attention */ - __u16 ibc_version; /* version of connection */ - __u64 ibc_incarnation; /* which instance of the peer */ - atomic_t ibc_refcount; /* # users */ - int ibc_state; /* what's happening */ - int ibc_nsends_posted; /* # uncompleted sends */ - int ibc_noops_posted; /* # uncompleted NOOPs */ - int ibc_credits; /* # credits I have */ - int ibc_outstanding_credits; /* # credits to return */ - int ibc_reserved_credits;/* # ACK/DONE msg credits */ - int ibc_comms_error; /* set on comms error */ - unsigned int ibc_nrx:16; /* receive buffers owned */ - unsigned int ibc_scheduled:1; /* scheduled for attention */ - unsigned int ibc_ready:1; /* CQ callback fired */ - /* time of last send */ - unsigned long ibc_last_send; - /** link chain for kiblnd_check_conns only */ - struct list_head ibc_connd_list; - /** rxs completed before ESTABLISHED */ - struct list_head ibc_early_rxs; - /** IBLND_MSG_NOOPs for IBLND_MSG_VERSION_1 */ - struct list_head ibc_tx_noops; - struct list_head ibc_tx_queue; /* sends that need a credit */ - struct list_head ibc_tx_queue_nocred;/* sends that don't need a credit */ - struct list_head ibc_tx_queue_rsrvd; /* sends that need to reserve an ACK/DONE msg */ - struct list_head ibc_active_txs; /* active tx awaiting completion */ - spinlock_t ibc_lock; /* serialise */ - kib_rx_t *ibc_rxs; /* the rx descs */ - kib_pages_t *ibc_rx_pages; /* premapped rx msg pages */ - - struct rdma_cm_id *ibc_cmid; /* CM id */ - struct ib_cq *ibc_cq; /* completion queue */ - - kib_connvars_t *ibc_connvars; /* in-progress connection state */ + struct kib_sched_info *ibc_sched; /* scheduler information */ + struct kib_peer *ibc_peer; /* owning peer */ + kib_hca_dev_t *ibc_hdev; /* HCA bound on */ + struct list_head ibc_list; /* stash on peer's conn + * list */ + struct list_head ibc_sched_list; /* schedule for attention */ + __u16 ibc_version; /* version of connection */ + __u64 ibc_incarnation; /* which instance of the + * peer */ + atomic_t ibc_refcount; /* # users */ + int ibc_state; /* what's happening */ + int ibc_nsends_posted; /* # uncompleted sends */ + int ibc_noops_posted; /* # uncompleted NOOPs */ + int ibc_credits; /* # credits I have */ + int ibc_outstanding_credits; /* # credits to return */ + int ibc_reserved_credits; /* # ACK/DONE msg credits */ + int ibc_comms_error; /* set on comms error */ + unsigned int ibc_nrx:16; /* receive buffers owned */ + unsigned int ibc_scheduled:1; /* scheduled for attention + */ + unsigned int ibc_ready:1; /* CQ callback fired */ + unsigned long ibc_last_send; /* time of last send */ + struct list_head ibc_connd_list; /* link chain for + * kiblnd_check_conns only + */ + struct list_head ibc_early_rxs; /* rxs completed before + * ESTABLISHED */ + struct list_head ibc_tx_noops; /* IBLND_MSG_NOOPs for + * IBLND_MSG_VERSION_1 */ + struct list_head ibc_tx_queue; /* sends that need a credit + */ + struct list_head ibc_tx_queue_nocred; /* sends that don't need a + * credit */ + struct list_head ibc_tx_queue_rsrvd; /* sends that need to + * reserve an ACK/DONE msg + */ + struct list_head ibc_active_txs; /* active tx awaiting + * completion */ + spinlock_t ibc_lock; /* serialise */ + kib_rx_t *ibc_rxs; /* the rx descs */ + kib_pages_t *ibc_rx_pages; /* premapped rx msg pages */ + + struct rdma_cm_id *ibc_cmid; /* CM id */ + struct ib_cq *ibc_cq; /* completion queue */ + + kib_connvars_t *ibc_connvars; /* in-progress connection + * state */ } kib_conn_t; -#define IBLND_CONN_INIT 0 /* being initialised */ -#define IBLND_CONN_ACTIVE_CONNECT 1 /* active sending req */ -#define IBLND_CONN_PASSIVE_WAIT 2 /* passive waiting for rtu */ -#define IBLND_CONN_ESTABLISHED 3 /* connection established */ -#define IBLND_CONN_CLOSING 4 /* being closed */ -#define IBLND_CONN_DISCONNECTED 5 /* disconnected */ +#define IBLND_CONN_INIT 0 /* being initialised */ +#define IBLND_CONN_ACTIVE_CONNECT 1 /* active sending req */ +#define IBLND_CONN_PASSIVE_WAIT 2 /* passive waiting for rtu */ +#define IBLND_CONN_ESTABLISHED 3 /* connection established */ +#define IBLND_CONN_CLOSING 4 /* being closed */ +#define IBLND_CONN_DISCONNECTED 5 /* disconnected */ typedef struct kib_peer { - struct list_head ibp_list; /* stash on global peer list */ - lnet_nid_t ibp_nid; /* who's on the other end(s) */ - lnet_ni_t *ibp_ni; /* LNet interface */ - atomic_t ibp_refcount; /* # users */ - struct list_head ibp_conns; /* all active connections */ - struct list_head ibp_tx_queue; /* msgs waiting for a conn */ - __u16 ibp_version; /* version of peer */ - __u64 ibp_incarnation; /* incarnation of peer */ - int ibp_connecting; /* current active connection attempts */ - int ibp_accepting; /* current passive connection attempts */ - int ibp_error; /* errno on closing this peer */ - unsigned long ibp_last_alive; /* when (in jiffies) I was last alive */ + struct list_head ibp_list; /* stash on global peer list */ + lnet_nid_t ibp_nid; /* who's on the other end(s) */ + lnet_ni_t *ibp_ni; /* LNet interface */ + atomic_t ibp_refcount; /* # users */ + struct list_head ibp_conns; /* all active connections */ + struct list_head ibp_tx_queue; /* msgs waiting for a conn */ + __u16 ibp_version; /* version of peer */ + __u64 ibp_incarnation; /* incarnation of peer */ + int ibp_connecting; /* current active connection attempts + */ + int ibp_accepting; /* current passive connection attempts + */ + int ibp_error; /* errno on closing this peer */ + unsigned long ibp_last_alive; /* when (in jiffies) I was last alive + */ } kib_peer_t; -extern kib_data_t kiblnd_data; +extern kib_data_t kiblnd_data; extern void kiblnd_hdev_destroy(kib_hca_dev_t *hdev); @@ -941,8 +959,8 @@ static inline unsigned int kiblnd_sg_dma_len(struct ib_device *dev, * right because OFED1.2 defines it as const, to use it we have to add * (void *) cast to overcome "const" */ -#define KIBLND_CONN_PARAM(e) ((e)->param.conn.private_data) -#define KIBLND_CONN_PARAM_LEN(e) ((e)->param.conn.private_data_len) +#define KIBLND_CONN_PARAM(e) ((e)->param.conn.private_data) +#define KIBLND_CONN_PARAM_LEN(e) ((e)->param.conn.private_data_len) struct ib_mr *kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev, diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index dbf3749831f9..477aa8b76f32 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -44,9 +44,9 @@ static void kiblnd_tx_done(lnet_ni_t *ni, kib_tx_t *tx) { lnet_msg_t *lntmsg[2]; - kib_net_t *net = ni->ni_data; - int rc; - int i; + kib_net_t *net = ni->ni_data; + int rc; + int i; LASSERT(net != NULL); LASSERT(!in_interrupt()); @@ -102,10 +102,10 @@ kiblnd_txlist_done(lnet_ni_t *ni, struct list_head *txlist, int status) static kib_tx_t * kiblnd_get_idle_tx(lnet_ni_t *ni, lnet_nid_t target) { - kib_net_t *net = (kib_net_t *)ni->ni_data; - struct list_head *node; - kib_tx_t *tx; - kib_tx_poolset_t *tps; + kib_net_t *net = (kib_net_t *)ni->ni_data; + struct list_head *node; + kib_tx_t *tx; + kib_tx_poolset_t *tps; tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)]; node = kiblnd_pool_alloc_node(&tps->tps_poolset); @@ -130,9 +130,9 @@ kiblnd_get_idle_tx(lnet_ni_t *ni, lnet_nid_t target) static void kiblnd_drop_rx(kib_rx_t *rx) { - kib_conn_t *conn = rx->rx_conn; - struct kib_sched_info *sched = conn->ibc_sched; - unsigned long flags; + kib_conn_t *conn = rx->rx_conn; + struct kib_sched_info *sched = conn->ibc_sched; + unsigned long flags; spin_lock_irqsave(&sched->ibs_lock, flags); LASSERT(conn->ibc_nrx > 0); @@ -145,11 +145,11 @@ kiblnd_drop_rx(kib_rx_t *rx) int kiblnd_post_rx(kib_rx_t *rx, int credit) { - kib_conn_t *conn = rx->rx_conn; - kib_net_t *net = conn->ibc_peer->ibp_ni->ni_data; - struct ib_recv_wr *bad_wrq = NULL; - struct ib_mr *mr; - int rc; + kib_conn_t *conn = rx->rx_conn; + kib_net_t *net = conn->ibc_peer->ibp_ni->ni_data; + struct ib_recv_wr *bad_wrq = NULL; + struct ib_mr *mr; + int rc; LASSERT(net != NULL); LASSERT(!in_interrupt()); @@ -164,10 +164,10 @@ kiblnd_post_rx(kib_rx_t *rx, int credit) rx->rx_sge.addr = rx->rx_msgaddr; rx->rx_sge.length = IBLND_MSG_SIZE; - rx->rx_wrq.next = NULL; + rx->rx_wrq.next = NULL; rx->rx_wrq.sg_list = &rx->rx_sge; rx->rx_wrq.num_sge = 1; - rx->rx_wrq.wr_id = kiblnd_ptr2wreqid(rx, IBLND_WID_RX); + rx->rx_wrq.wr_id = kiblnd_ptr2wreqid(rx, IBLND_WID_RX); LASSERT(conn->ibc_state >= IBLND_CONN_INIT); LASSERT(rx->rx_nob >= 0); /* not posted */ @@ -212,7 +212,7 @@ kiblnd_post_rx(kib_rx_t *rx, int credit) static kib_tx_t * kiblnd_find_waiting_tx_locked(kib_conn_t *conn, int txtype, __u64 cookie) { - struct list_head *tmp; + struct list_head *tmp; list_for_each(tmp, &conn->ibc_active_txs) { kib_tx_t *tx = list_entry(tmp, kib_tx_t, tx_list); @@ -237,9 +237,9 @@ kiblnd_find_waiting_tx_locked(kib_conn_t *conn, int txtype, __u64 cookie) static void kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie) { - kib_tx_t *tx; - lnet_ni_t *ni = conn->ibc_peer->ibp_ni; - int idle; + kib_tx_t *tx; + lnet_ni_t *ni = conn->ibc_peer->ibp_ni; + int idle; spin_lock(&conn->ibc_lock); @@ -276,8 +276,8 @@ kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie) static void kiblnd_send_completion(kib_conn_t *conn, int type, int status, __u64 cookie) { - lnet_ni_t *ni = conn->ibc_peer->ibp_ni; - kib_tx_t *tx = kiblnd_get_idle_tx(ni, conn->ibc_peer->ibp_nid); + lnet_ni_t *ni = conn->ibc_peer->ibp_ni; + kib_tx_t *tx = kiblnd_get_idle_tx(ni, conn->ibc_peer->ibp_nid); if (tx == NULL) { CERROR("Can't get tx for completion %x for %s\n", @@ -295,14 +295,14 @@ kiblnd_send_completion(kib_conn_t *conn, int type, int status, __u64 cookie) static void kiblnd_handle_rx(kib_rx_t *rx) { - kib_msg_t *msg = rx->rx_msg; - kib_conn_t *conn = rx->rx_conn; - lnet_ni_t *ni = conn->ibc_peer->ibp_ni; - int credits = msg->ibm_credits; - kib_tx_t *tx; - int rc = 0; - int rc2; - int post_credit; + kib_msg_t *msg = rx->rx_msg; + kib_conn_t *conn = rx->rx_conn; + lnet_ni_t *ni = conn->ibc_peer->ibp_ni; + int credits = msg->ibm_credits; + kib_tx_t *tx; + int rc = 0; + int rc2; + int post_credit; LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED); @@ -456,12 +456,12 @@ kiblnd_handle_rx(kib_rx_t *rx) static void kiblnd_rx_complete(kib_rx_t *rx, int status, int nob) { - kib_msg_t *msg = rx->rx_msg; - kib_conn_t *conn = rx->rx_conn; - lnet_ni_t *ni = conn->ibc_peer->ibp_ni; - kib_net_t *net = ni->ni_data; - int rc; - int err = -EIO; + kib_msg_t *msg = rx->rx_msg; + kib_conn_t *conn = rx->rx_conn; + lnet_ni_t *ni = conn->ibc_peer->ibp_ni; + kib_net_t *net = ni->ni_data; + int rc; + int err = -EIO; LASSERT(net != NULL); LASSERT(rx->rx_nob < 0); /* was posted */ @@ -502,8 +502,8 @@ kiblnd_rx_complete(kib_rx_t *rx, int status, int nob) /* racing with connection establishment/teardown! */ if (conn->ibc_state < IBLND_CONN_ESTABLISHED) { - rwlock_t *g_lock = &kiblnd_data.kib_global_lock; - unsigned long flags; + rwlock_t *g_lock = &kiblnd_data.kib_global_lock; + unsigned long flags; write_lock_irqsave(g_lock, flags); /* must check holding global lock to eliminate race */ @@ -550,19 +550,19 @@ kiblnd_kvaddr_to_page(unsigned long vaddr) static int kiblnd_fmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) { - kib_hca_dev_t *hdev; - __u64 *pages = tx->tx_pages; - kib_fmr_poolset_t *fps; - int npages; - int size; - int cpt; - int rc; - int i; + kib_hca_dev_t *hdev; + __u64 *pages = tx->tx_pages; + kib_fmr_poolset_t *fps; + int npages; + int size; + int cpt; + int rc; + int i; LASSERT(tx->tx_pool != NULL); LASSERT(tx->tx_pool->tpo_pool.po_owner != NULL); - hdev = tx->tx_pool->tpo_hdev; + hdev = tx->tx_pool->tpo_hdev; for (i = 0, npages = 0; i < rd->rd_nfrags; i++) { for (size = 0; size < rd->rd_frags[i].rf_nob; @@ -586,7 +586,7 @@ kiblnd_fmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) rd->rd_key = (rd != tx->tx_rd) ? tx->tx_u.fmr.fmr_pfmr->fmr->rkey : tx->tx_u.fmr.fmr_pfmr->fmr->lkey; rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; - rd->rd_frags[0].rf_nob = nob; + rd->rd_frags[0].rf_nob = nob; rd->rd_nfrags = 1; return 0; @@ -595,11 +595,11 @@ kiblnd_fmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) static int kiblnd_pmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) { - kib_hca_dev_t *hdev; - kib_pmr_poolset_t *pps; - __u64 iova; - int cpt; - int rc; + kib_hca_dev_t *hdev; + kib_pmr_poolset_t *pps; + __u64 iova; + int cpt; + int rc; LASSERT(tx->tx_pool != NULL); LASSERT(tx->tx_pool->tpo_pool.po_owner != NULL); @@ -623,7 +623,7 @@ kiblnd_pmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) tx->tx_u.pmr->pmr_mr->lkey; rd->rd_nfrags = 1; rd->rd_frags[0].rf_addr = iova; - rd->rd_frags[0].rf_nob = nob; + rd->rd_frags[0].rf_nob = nob; return 0; } @@ -631,7 +631,7 @@ kiblnd_pmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob) void kiblnd_unmap_tx(lnet_ni_t *ni, kib_tx_t *tx) { - kib_net_t *net = ni->ni_data; + kib_net_t *net = ni->ni_data; LASSERT(net != NULL); @@ -655,20 +655,19 @@ int kiblnd_map_tx(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, int nfrags) { - kib_hca_dev_t *hdev = tx->tx_pool->tpo_hdev; - kib_net_t *net = ni->ni_data; - struct ib_mr *mr = NULL; - __u32 nob; - int i; + kib_hca_dev_t *hdev = tx->tx_pool->tpo_hdev; + kib_net_t *net = ni->ni_data; + struct ib_mr *mr = NULL; + __u32 nob; + int i; /* If rd is not tx_rd, it's going to get sent to a peer and I'm the * RDMA sink */ tx->tx_dmadir = (rd != tx->tx_rd) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; tx->tx_nfrags = nfrags; - rd->rd_nfrags = - kiblnd_dma_map_sg(hdev->ibh_ibdev, - tx->tx_frags, tx->tx_nfrags, tx->tx_dmadir); + rd->rd_nfrags = kiblnd_dma_map_sg(hdev->ibh_ibdev, tx->tx_frags, + tx->tx_nfrags, tx->tx_dmadir); for (i = 0, nob = 0; i < rd->rd_nfrags; i++) { rd->rd_frags[i].rf_nob = kiblnd_sg_dma_len( @@ -699,12 +698,12 @@ static int kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, unsigned int niov, struct kvec *iov, int offset, int nob) { - kib_net_t *net = ni->ni_data; - struct page *page; + kib_net_t *net = ni->ni_data; + struct page *page; struct scatterlist *sg; - unsigned long vaddr; - int fragnob; - int page_offset; + unsigned long vaddr; + int fragnob; + int page_offset; LASSERT(nob > 0); LASSERT(niov > 0); @@ -752,9 +751,9 @@ static int kiblnd_setup_rd_kiov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, int nkiov, lnet_kiov_t *kiov, int offset, int nob) { - kib_net_t *net = ni->ni_data; + kib_net_t *net = ni->ni_data; struct scatterlist *sg; - int fragnob; + int fragnob; CDEBUG(D_NET, "niov %d offset %d nob %d\n", nkiov, offset, nob); @@ -793,11 +792,11 @@ kiblnd_post_tx_locked(kib_conn_t *conn, kib_tx_t *tx, int credit) __releases(conn->ibc_lock) __acquires(conn->ibc_lock) { - kib_msg_t *msg = tx->tx_msg; - kib_peer_t *peer = conn->ibc_peer; - int ver = conn->ibc_version; - int rc; - int done; + kib_msg_t *msg = tx->tx_msg; + kib_peer_t *peer = conn->ibc_peer; + int ver = conn->ibc_version; + int rc; + int done; struct ib_send_wr *bad_wrq; LASSERT(tx->tx_queued); @@ -878,8 +877,7 @@ kiblnd_post_tx_locked(kib_conn_t *conn, kib_tx_t *tx, int credit) /* close_conn will launch failover */ rc = -ENETDOWN; } else { - rc = ib_post_send(conn->ibc_cmid->qp, - tx->tx_wrq, &bad_wrq); + rc = ib_post_send(conn->ibc_cmid->qp, tx->tx_wrq, &bad_wrq); } conn->ibc_last_send = jiffies; @@ -925,9 +923,9 @@ kiblnd_post_tx_locked(kib_conn_t *conn, kib_tx_t *tx, int credit) void kiblnd_check_sends(kib_conn_t *conn) { - int ver = conn->ibc_version; + int ver = conn->ibc_version; lnet_ni_t *ni = conn->ibc_peer->ibp_ni; - kib_tx_t *tx; + kib_tx_t *tx; /* Don't send anything until after the connection is established */ if (conn->ibc_state < IBLND_CONN_ESTABLISHED) { @@ -997,9 +995,9 @@ kiblnd_check_sends(kib_conn_t *conn) static void kiblnd_tx_complete(kib_tx_t *tx, int status) { - int failed = (status != IB_WC_SUCCESS); - kib_conn_t *conn = tx->tx_conn; - int idle; + int failed = (status != IB_WC_SUCCESS); + kib_conn_t *conn = tx->tx_conn; + int idle; LASSERT(tx->tx_sending > 0); @@ -1051,11 +1049,11 @@ kiblnd_tx_complete(kib_tx_t *tx, int status) void kiblnd_init_tx_msg(lnet_ni_t *ni, kib_tx_t *tx, int type, int body_nob) { - kib_hca_dev_t *hdev = tx->tx_pool->tpo_hdev; - struct ib_sge *sge = &tx->tx_sge[tx->tx_nwrq]; + kib_hca_dev_t *hdev = tx->tx_pool->tpo_hdev; + struct ib_sge *sge = &tx->tx_sge[tx->tx_nwrq]; struct ib_send_wr *wrq = &tx->tx_wrq[tx->tx_nwrq]; - int nob = offsetof(kib_msg_t, ibm_u) + body_nob; - struct ib_mr *mr; + int nob = offsetof(kib_msg_t, ibm_u) + body_nob; + struct ib_mr *mr; LASSERT(tx->tx_nwrq >= 0); LASSERT(tx->tx_nwrq < IBLND_MAX_RDMA_FRAGS + 1); @@ -1086,14 +1084,14 @@ int kiblnd_init_rdma(kib_conn_t *conn, kib_tx_t *tx, int type, int resid, kib_rdma_desc_t *dstrd, __u64 dstcookie) { - kib_msg_t *ibmsg = tx->tx_msg; - kib_rdma_desc_t *srcrd = tx->tx_rd; - struct ib_sge *sge = &tx->tx_sge[0]; + kib_msg_t *ibmsg = tx->tx_msg; + kib_rdma_desc_t *srcrd = tx->tx_rd; + struct ib_sge *sge = &tx->tx_sge[0]; struct ib_send_wr *wrq = &tx->tx_wrq[0]; - int rc = resid; - int srcidx; - int dstidx; - int wrknob; + int rc = resid; + int srcidx; + int dstidx; + int wrknob; LASSERT(!in_interrupt()); LASSERT(tx->tx_nwrq == 0); @@ -1144,7 +1142,7 @@ kiblnd_init_rdma(kib_conn_t *conn, kib_tx_t *tx, int type, wrq->send_flags = 0; wrq->wr.rdma.remote_addr = kiblnd_rd_frag_addr(dstrd, dstidx); - wrq->wr.rdma.rkey = kiblnd_rd_frag_key(dstrd, dstidx); + wrq->wr.rdma.rkey = kiblnd_rd_frag_key(dstrd, dstidx); srcidx = kiblnd_rd_consume_frag(srcrd, srcidx, wrknob); dstidx = kiblnd_rd_consume_frag(dstrd, dstidx, wrknob); @@ -1170,7 +1168,7 @@ kiblnd_init_rdma(kib_conn_t *conn, kib_tx_t *tx, int type, void kiblnd_queue_tx_locked(kib_tx_t *tx, kib_conn_t *conn) { - struct list_head *q; + struct list_head *q; LASSERT(tx->tx_nwrq > 0); /* work items set up */ LASSERT(!tx->tx_queued); /* not queued for sending already */ @@ -1271,11 +1269,11 @@ static void kiblnd_connect_peer(kib_peer_t *peer) { struct rdma_cm_id *cmid; - kib_dev_t *dev; - kib_net_t *net = peer->ibp_ni->ni_data; + kib_dev_t *dev; + kib_net_t *net = peer->ibp_ni->ni_data; struct sockaddr_in srcaddr; struct sockaddr_in dstaddr; - int rc; + int rc; LASSERT(net != NULL); LASSERT(peer->ibp_connecting > 0); @@ -1335,12 +1333,12 @@ kiblnd_connect_peer(kib_peer_t *peer) void kiblnd_launch_tx(lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid) { - kib_peer_t *peer; - kib_peer_t *peer2; - kib_conn_t *conn; - rwlock_t *g_lock = &kiblnd_data.kib_global_lock; - unsigned long flags; - int rc; + kib_peer_t *peer; + kib_peer_t *peer2; + kib_conn_t *conn; + rwlock_t *g_lock = &kiblnd_data.kib_global_lock; + unsigned long flags; + int rc; /* If I get here, I've committed to send, so I complete the tx with * failure on any problems */ @@ -1456,20 +1454,20 @@ kiblnd_launch_tx(lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid) int kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) { - lnet_hdr_t *hdr = &lntmsg->msg_hdr; - int type = lntmsg->msg_type; + lnet_hdr_t *hdr = &lntmsg->msg_hdr; + int type = lntmsg->msg_type; lnet_process_id_t target = lntmsg->msg_target; - int target_is_router = lntmsg->msg_target_is_router; - int routing = lntmsg->msg_routing; - unsigned int payload_niov = lntmsg->msg_niov; - struct kvec *payload_iov = lntmsg->msg_iov; - lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; - unsigned int payload_offset = lntmsg->msg_offset; - unsigned int payload_nob = lntmsg->msg_len; - kib_msg_t *ibmsg; - kib_tx_t *tx; - int nob; - int rc; + int target_is_router = lntmsg->msg_target_is_router; + int routing = lntmsg->msg_routing; + unsigned int payload_niov = lntmsg->msg_niov; + struct kvec *payload_iov = lntmsg->msg_iov; + lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; + unsigned int payload_offset = lntmsg->msg_offset; + unsigned int payload_nob = lntmsg->msg_len; + kib_msg_t *ibmsg; + kib_tx_t *tx; + int nob; + int rc; /* NB 'private' is different depending on what we're sending.... */ @@ -1628,13 +1626,13 @@ static void kiblnd_reply(lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg) { lnet_process_id_t target = lntmsg->msg_target; - unsigned int niov = lntmsg->msg_niov; - struct kvec *iov = lntmsg->msg_iov; - lnet_kiov_t *kiov = lntmsg->msg_kiov; - unsigned int offset = lntmsg->msg_offset; - unsigned int nob = lntmsg->msg_len; - kib_tx_t *tx; - int rc; + unsigned int niov = lntmsg->msg_niov; + struct kvec *iov = lntmsg->msg_iov; + lnet_kiov_t *kiov = lntmsg->msg_kiov; + unsigned int offset = lntmsg->msg_offset; + unsigned int nob = lntmsg->msg_len; + kib_tx_t *tx; + int rc; tx = kiblnd_get_idle_tx(ni, rx->rx_conn->ibc_peer->ibp_nid); if (tx == NULL) { @@ -1691,14 +1689,14 @@ kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov, unsigned int offset, unsigned int mlen, unsigned int rlen) { - kib_rx_t *rx = private; - kib_msg_t *rxmsg = rx->rx_msg; - kib_conn_t *conn = rx->rx_conn; - kib_tx_t *tx; - kib_msg_t *txmsg; - int nob; - int post_credit = IBLND_POSTRX_PEER_CREDIT; - int rc = 0; + kib_rx_t *rx = private; + kib_msg_t *rxmsg = rx->rx_msg; + kib_conn_t *conn = rx->rx_conn; + kib_tx_t *tx; + kib_msg_t *txmsg; + int nob; + int post_credit = IBLND_POSTRX_PEER_CREDIT; + int rc = 0; LASSERT(mlen <= rlen); LASSERT(!in_interrupt()); @@ -1828,8 +1826,8 @@ kiblnd_peer_alive(kib_peer_t *peer) static void kiblnd_peer_notify(kib_peer_t *peer) { - int error = 0; - unsigned long last_alive = 0; + int error = 0; + unsigned long last_alive = 0; unsigned long flags; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -1860,9 +1858,9 @@ kiblnd_close_conn_locked(kib_conn_t *conn, int error) * connection to be finished off by the connd. Otherwise the connd is * already dealing with it (either to set it up or tear it down). * Caller holds kib_global_lock exclusively in irq context */ - kib_peer_t *peer = conn->ibc_peer; - kib_dev_t *dev; - unsigned long flags; + kib_peer_t *peer = conn->ibc_peer; + kib_dev_t *dev; + unsigned long flags; LASSERT(error != 0 || conn->ibc_state >= IBLND_CONN_ESTABLISHED); @@ -1934,8 +1932,8 @@ kiblnd_close_conn(kib_conn_t *conn, int error) static void kiblnd_handle_early_rxs(kib_conn_t *conn) { - unsigned long flags; - kib_rx_t *rx; + unsigned long flags; + kib_rx_t *rx; kib_rx_t *tmp; LASSERT(!in_interrupt()); @@ -1957,9 +1955,9 @@ static void kiblnd_abort_txs(kib_conn_t *conn, struct list_head *txs) { LIST_HEAD(zombies); - struct list_head *tmp; - struct list_head *nxt; - kib_tx_t *tx; + struct list_head *tmp; + struct list_head *nxt; + kib_tx_t *tx; spin_lock(&conn->ibc_lock); @@ -2018,7 +2016,7 @@ void kiblnd_peer_connect_failed(kib_peer_t *peer, int active, int error) { LIST_HEAD(zombies); - unsigned long flags; + unsigned long flags; LASSERT(error != 0); LASSERT(!in_interrupt()); @@ -2071,12 +2069,12 @@ kiblnd_peer_connect_failed(kib_peer_t *peer, int active, int error) void kiblnd_connreq_done(kib_conn_t *conn, int status) { - kib_peer_t *peer = conn->ibc_peer; - kib_tx_t *tx; + kib_peer_t *peer = conn->ibc_peer; + kib_tx_t *tx; kib_tx_t *tmp; - struct list_head txs; - unsigned long flags; - int active; + struct list_head txs; + unsigned long flags; + int active; active = (conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); @@ -2166,7 +2164,7 @@ kiblnd_connreq_done(kib_conn_t *conn, int status) static void kiblnd_reject(struct rdma_cm_id *cmid, kib_rej_t *rej) { - int rc; + int rc; rc = rdma_reject(cmid, rej, sizeof(*rej)); @@ -2177,22 +2175,22 @@ kiblnd_reject(struct rdma_cm_id *cmid, kib_rej_t *rej) static int kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) { - rwlock_t *g_lock = &kiblnd_data.kib_global_lock; - kib_msg_t *reqmsg = priv; - kib_msg_t *ackmsg; - kib_dev_t *ibdev; - kib_peer_t *peer; - kib_peer_t *peer2; - kib_conn_t *conn; - lnet_ni_t *ni = NULL; - kib_net_t *net = NULL; - lnet_nid_t nid; + rwlock_t *g_lock = &kiblnd_data.kib_global_lock; + kib_msg_t *reqmsg = priv; + kib_msg_t *ackmsg; + kib_dev_t *ibdev; + kib_peer_t *peer; + kib_peer_t *peer2; + kib_conn_t *conn; + lnet_ni_t *ni = NULL; + kib_net_t *net = NULL; + lnet_nid_t nid; struct rdma_conn_param cp; - kib_rej_t rej; - int version = IBLND_MSG_VERSION; - unsigned long flags; - int rc; - struct sockaddr_in *peer_addr; + kib_rej_t rej; + int version = IBLND_MSG_VERSION; + unsigned long flags; + int rc; + struct sockaddr_in *peer_addr; LASSERT(!in_interrupt()); /* cmid inherits 'context' from the corresponding listener id */ @@ -2200,8 +2198,8 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) LASSERT(ibdev != NULL); memset(&rej, 0, sizeof(rej)); - rej.ibr_magic = IBLND_MSG_MAGIC; - rej.ibr_why = IBLND_REJECT_FATAL; + rej.ibr_magic = IBLND_MSG_MAGIC; + rej.ibr_why = IBLND_REJECT_FATAL; rej.ibr_cp.ibcp_max_msg_size = IBLND_MSG_SIZE; peer_addr = (struct sockaddr_in *)&(cmid->route.addr.dst_addr); @@ -2243,7 +2241,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) } nid = reqmsg->ibm_srcnid; - ni = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid)); + ni = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid)); if (ni != NULL) { net = (kib_net_t *)ni->ni_data; @@ -2394,7 +2392,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) * CM callback doesn't destroy cmid. */ conn->ibc_incarnation = reqmsg->ibm_srcstamp; - conn->ibc_credits = IBLND_MSG_QUEUE_SIZE(version); + conn->ibc_credits = IBLND_MSG_QUEUE_SIZE(version); conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(version); LASSERT(conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(version) <= IBLND_RX_MSGS(version)); @@ -2412,12 +2410,12 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) memset(&cp, 0, sizeof(cp)); cp.private_data = ackmsg; - cp.private_data_len = ackmsg->ibm_nob; + cp.private_data_len = ackmsg->ibm_nob; cp.responder_resources = 0; /* No atomic ops or RDMA reads */ - cp.initiator_depth = 0; + cp.initiator_depth = 0; cp.flow_control = 1; - cp.retry_count = *kiblnd_tunables.kib_retry_count; - cp.rnr_retry_count = *kiblnd_tunables.kib_rnr_retry_count; + cp.retry_count = *kiblnd_tunables.kib_retry_count; + cp.rnr_retry_count = *kiblnd_tunables.kib_rnr_retry_count; CDEBUG(D_NET, "Accept %s\n", libcfs_nid2str(nid)); @@ -2439,7 +2437,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) if (ni != NULL) lnet_ni_decref(ni); - rej.ibr_version = version; + rej.ibr_version = version; rej.ibr_cp.ibcp_queue_depth = IBLND_MSG_QUEUE_SIZE(version); rej.ibr_cp.ibcp_max_frags = IBLND_RDMA_FRAGS(version); kiblnd_reject(cmid, &rej); @@ -2451,10 +2449,10 @@ static void kiblnd_reconnect(kib_conn_t *conn, int version, __u64 incarnation, int why, kib_connparams_t *cp) { - kib_peer_t *peer = conn->ibc_peer; - char *reason; - int retry = 0; - unsigned long flags; + kib_peer_t *peer = conn->ibc_peer; + char *reason; + int retry = 0; + unsigned long flags; LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); LASSERT(peer->ibp_connecting > 0); /* 'conn' at least */ @@ -2513,7 +2511,7 @@ kiblnd_reconnect(kib_conn_t *conn, int version, static void kiblnd_rejected(kib_conn_t *conn, int reason, void *priv, int priv_nob) { - kib_peer_t *peer = conn->ibc_peer; + kib_peer_t *peer = conn->ibc_peer; LASSERT(!in_interrupt()); LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); @@ -2532,10 +2530,10 @@ kiblnd_rejected(kib_conn_t *conn, int reason, void *priv, int priv_nob) case IB_CM_REJ_CONSUMER_DEFINED: if (priv_nob >= offsetof(kib_rej_t, ibr_padding)) { - kib_rej_t *rej = priv; - kib_connparams_t *cp = NULL; - int flip = 0; - __u64 incarnation = -1; + kib_rej_t *rej = priv; + kib_connparams_t *cp = NULL; + int flip = 0; + __u64 incarnation = -1; /* NB. default incarnation is -1 because: * a) V1 will ignore dst incarnation in connreq. @@ -2652,13 +2650,13 @@ kiblnd_rejected(kib_conn_t *conn, int reason, void *priv, int priv_nob) static void kiblnd_check_connreply(kib_conn_t *conn, void *priv, int priv_nob) { - kib_peer_t *peer = conn->ibc_peer; - lnet_ni_t *ni = peer->ibp_ni; - kib_net_t *net = ni->ni_data; - kib_msg_t *msg = priv; - int ver = conn->ibc_version; - int rc = kiblnd_unpack_msg(msg, priv_nob); - unsigned long flags; + kib_peer_t *peer = conn->ibc_peer; + lnet_ni_t *ni = peer->ibp_ni; + kib_net_t *net = ni->ni_data; + kib_msg_t *msg = priv; + int ver = conn->ibc_version; + int rc = kiblnd_unpack_msg(msg, priv_nob); + unsigned long flags; LASSERT(net != NULL); @@ -2726,8 +2724,8 @@ kiblnd_check_connreply(kib_conn_t *conn, void *priv, int priv_nob) goto failed; } - conn->ibc_incarnation = msg->ibm_srcstamp; - conn->ibc_credits = + conn->ibc_incarnation = msg->ibm_srcstamp; + conn->ibc_credits = conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(ver); LASSERT(conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(ver) <= IBLND_RX_MSGS(ver)); @@ -2749,20 +2747,20 @@ kiblnd_check_connreply(kib_conn_t *conn, void *priv, int priv_nob) static int kiblnd_active_connect(struct rdma_cm_id *cmid) { - kib_peer_t *peer = (kib_peer_t *)cmid->context; - kib_conn_t *conn; - kib_msg_t *msg; - struct rdma_conn_param cp; - int version; - __u64 incarnation; - unsigned long flags; - int rc; + kib_peer_t *peer = (kib_peer_t *)cmid->context; + kib_conn_t *conn; + kib_msg_t *msg; + struct rdma_conn_param cp; + int version; + __u64 incarnation; + unsigned long flags; + int rc; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); incarnation = peer->ibp_incarnation; - version = (peer->ibp_version == 0) ? IBLND_MSG_VERSION : - peer->ibp_version; + version = (peer->ibp_version == 0) ? IBLND_MSG_VERSION : + peer->ibp_version; read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); @@ -2793,8 +2791,8 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) cp.private_data_len = msg->ibm_nob; cp.responder_resources = 0; /* No atomic ops or RDMA reads */ cp.initiator_depth = 0; - cp.flow_control = 1; - cp.retry_count = *kiblnd_tunables.kib_retry_count; + cp.flow_control = 1; + cp.retry_count = *kiblnd_tunables.kib_retry_count; cp.rnr_retry_count = *kiblnd_tunables.kib_rnr_retry_count; LASSERT(cmid->context == (void *)conn); @@ -2814,9 +2812,9 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) int kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event) { - kib_peer_t *peer; - kib_conn_t *conn; - int rc; + kib_peer_t *peer; + kib_conn_t *conn; + int rc; switch (event->event) { default: @@ -2983,8 +2981,8 @@ kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event) static int kiblnd_check_txs_locked(kib_conn_t *conn, struct list_head *txs) { - kib_tx_t *tx; - struct list_head *ttmp; + kib_tx_t *tx; + struct list_head *ttmp; list_for_each(ttmp, txs) { tx = list_entry(ttmp, kib_tx_t, tx_list); @@ -3022,13 +3020,13 @@ kiblnd_check_conns(int idx) { LIST_HEAD(closes); LIST_HEAD(checksends); - struct list_head *peers = &kiblnd_data.kib_peers[idx]; - struct list_head *ptmp; - kib_peer_t *peer; - kib_conn_t *conn; + struct list_head *peers = &kiblnd_data.kib_peers[idx]; + struct list_head *ptmp; + kib_peer_t *peer; + kib_conn_t *conn; kib_conn_t *tmp; - struct list_head *ctmp; - unsigned long flags; + struct list_head *ctmp; + unsigned long flags; /* NB. We expect to have a look at all the peers and not find any * RDMAs to time out, so we just use a shared lock while we @@ -3114,14 +3112,14 @@ kiblnd_disconnect_conn(kib_conn_t *conn) int kiblnd_connd(void *arg) { - wait_queue_t wait; - unsigned long flags; - kib_conn_t *conn; - int timeout; - int i; - int dropped_lock; - int peer_index = 0; - unsigned long deadline = jiffies; + wait_queue_t wait; + unsigned long flags; + kib_conn_t *conn; + int timeout; + int i; + int dropped_lock; + int peer_index = 0; + unsigned long deadline = jiffies; cfs_block_allsigs(); @@ -3169,7 +3167,7 @@ kiblnd_connd(void *arg) if (timeout <= 0) { const int n = 4; const int p = 1; - int chunk = kiblnd_data.kib_peer_hash_size; + int chunk = kiblnd_data.kib_peer_hash_size; spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags); dropped_lock = 1; @@ -3273,9 +3271,9 @@ kiblnd_cq_completion(struct ib_cq *cq, void *arg) * consuming my CQ I could be called after all completions have * occurred. But in this case, ibc_nrx == 0 && ibc_nsends_posted == 0 * and this CQ is about to be destroyed so I NOOP. */ - kib_conn_t *conn = (kib_conn_t *)arg; - struct kib_sched_info *sched = conn->ibc_sched; - unsigned long flags; + kib_conn_t *conn = (kib_conn_t *)arg; + struct kib_sched_info *sched = conn->ibc_sched; + unsigned long flags; LASSERT(cq == conn->ibc_cq); @@ -3309,15 +3307,15 @@ kiblnd_cq_event(struct ib_event *event, void *arg) int kiblnd_scheduler(void *arg) { - long id = (long)arg; - struct kib_sched_info *sched; - kib_conn_t *conn; - wait_queue_t wait; - unsigned long flags; - struct ib_wc wc; - int did_something; - int busy_loops = 0; - int rc; + long id = (long)arg; + struct kib_sched_info *sched; + kib_conn_t *conn; + wait_queue_t wait; + unsigned long flags; + struct ib_wc wc; + int did_something; + int busy_loops = 0; + int rc; cfs_block_allsigs(); @@ -3432,11 +3430,11 @@ kiblnd_scheduler(void *arg) int kiblnd_failover_thread(void *arg) { - rwlock_t *glock = &kiblnd_data.kib_global_lock; - kib_dev_t *dev; - wait_queue_t wait; - unsigned long flags; - int rc; + rwlock_t *glock = &kiblnd_data.kib_global_lock; + kib_dev_t *dev; + wait_queue_t wait; + unsigned long flags; + int rc; LASSERT(*kiblnd_tunables.kib_dev_failover != 0); @@ -3446,8 +3444,8 @@ kiblnd_failover_thread(void *arg) write_lock_irqsave(glock, flags); while (!kiblnd_data.kib_shutdown) { - int do_failover = 0; - int long_sleep; + int do_failover = 0; + int long_sleep; list_for_each_entry(dev, &kiblnd_data.kib_failed_devs, ibd_fail_list) { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index eedf01afd57f..b0e00361cfce 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -150,30 +150,30 @@ module_param(use_privileged_port, int, 0644); MODULE_PARM_DESC(use_privileged_port, "use privileged port when initiating connection"); kib_tunables_t kiblnd_tunables = { - .kib_dev_failover = &dev_failover, - .kib_service = &service, - .kib_cksum = &cksum, - .kib_timeout = &timeout, - .kib_keepalive = &keepalive, - .kib_ntx = &ntx, - .kib_credits = &credits, - .kib_peertxcredits = &peer_credits, - .kib_peercredits_hiw = &peer_credits_hiw, - .kib_peerrtrcredits = &peer_buffer_credits, - .kib_peertimeout = &peer_timeout, - .kib_default_ipif = &ipif_name, - .kib_retry_count = &retry_count, - .kib_rnr_retry_count = &rnr_retry_count, - .kib_concurrent_sends = &concurrent_sends, - .kib_ib_mtu = &ib_mtu, - .kib_map_on_demand = &map_on_demand, - .kib_fmr_pool_size = &fmr_pool_size, - .kib_fmr_flush_trigger = &fmr_flush_trigger, - .kib_fmr_cache = &fmr_cache, - .kib_pmr_pool_size = &pmr_pool_size, - .kib_require_priv_port = &require_privileged_port, - .kib_use_priv_port = &use_privileged_port, - .kib_nscheds = &nscheds + .kib_dev_failover = &dev_failover, + .kib_service = &service, + .kib_cksum = &cksum, + .kib_timeout = &timeout, + .kib_keepalive = &keepalive, + .kib_ntx = &ntx, + .kib_credits = &credits, + .kib_peertxcredits = &peer_credits, + .kib_peercredits_hiw = &peer_credits_hiw, + .kib_peerrtrcredits = &peer_buffer_credits, + .kib_peertimeout = &peer_timeout, + .kib_default_ipif = &ipif_name, + .kib_retry_count = &retry_count, + .kib_rnr_retry_count = &rnr_retry_count, + .kib_concurrent_sends = &concurrent_sends, + .kib_ib_mtu = &ib_mtu, + .kib_map_on_demand = &map_on_demand, + .kib_fmr_pool_size = &fmr_pool_size, + .kib_fmr_flush_trigger = &fmr_flush_trigger, + .kib_fmr_cache = &fmr_cache, + .kib_pmr_pool_size = &pmr_pool_size, + .kib_require_priv_port = &require_privileged_port, + .kib_use_priv_port = &use_privileged_port, + .kib_nscheds = &nscheds }; int diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 7586b7e4040b..4128a92218a9 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -49,8 +49,8 @@ ksock_nal_data_t ksocknal_data; static ksock_interface_t * ksocknal_ip2iface(lnet_ni_t *ni, __u32 ip) { - ksock_net_t *net = ni->ni_data; - int i; + ksock_net_t *net = ni->ni_data; + int i; ksock_interface_t *iface; for (i = 0; i < net->ksnn_ninterfaces; i++) { @@ -102,8 +102,8 @@ ksocknal_destroy_route(ksock_route_t *route) static int ksocknal_create_peer(ksock_peer_t **peerp, lnet_ni_t *ni, lnet_process_id_t id) { - ksock_net_t *net = ni->ni_data; - ksock_peer_t *peer; + ksock_net_t *net = ni->ni_data; + ksock_peer_t *peer; LASSERT(id.nid != LNET_NID_ANY); LASSERT(id.pid != LNET_PID_ANY); @@ -149,7 +149,7 @@ ksocknal_create_peer(ksock_peer_t **peerp, lnet_ni_t *ni, lnet_process_id_t id) void ksocknal_destroy_peer(ksock_peer_t *peer) { - ksock_net_t *net = peer->ksnp_ni->ni_data; + ksock_net_t *net = peer->ksnp_ni->ni_data; CDEBUG(D_NET, "peer %s %p deleted\n", libcfs_id2str(peer->ksnp_id), peer); @@ -175,9 +175,9 @@ ksocknal_destroy_peer(ksock_peer_t *peer) ksock_peer_t * ksocknal_find_peer_locked(lnet_ni_t *ni, lnet_process_id_t id) { - struct list_head *peer_list = ksocknal_nid2peerlist(id.nid); - struct list_head *tmp; - ksock_peer_t *peer; + struct list_head *peer_list = ksocknal_nid2peerlist(id.nid); + struct list_head *tmp; + ksock_peer_t *peer; list_for_each(tmp, peer_list) { @@ -203,7 +203,7 @@ ksocknal_find_peer_locked(lnet_ni_t *ni, lnet_process_id_t id) ksock_peer_t * ksocknal_find_peer(lnet_ni_t *ni, lnet_process_id_t id) { - ksock_peer_t *peer; + ksock_peer_t *peer; read_lock(&ksocknal_data.ksnd_global_lock); peer = ksocknal_find_peer_locked(ni, id); @@ -217,8 +217,8 @@ ksocknal_find_peer(lnet_ni_t *ni, lnet_process_id_t id) static void ksocknal_unlink_peer_locked(ksock_peer_t *peer) { - int i; - __u32 ip; + int i; + __u32 ip; ksock_interface_t *iface; for (i = 0; i < peer->ksnp_n_passive_ips; i++) { @@ -249,13 +249,13 @@ ksocknal_get_peer_info(lnet_ni_t *ni, int index, lnet_process_id_t *id, __u32 *myip, __u32 *peer_ip, int *port, int *conn_count, int *share_count) { - ksock_peer_t *peer; - struct list_head *ptmp; - ksock_route_t *route; - struct list_head *rtmp; - int i; - int j; - int rc = -ENOENT; + ksock_peer_t *peer; + struct list_head *ptmp; + ksock_route_t *route; + struct list_head *rtmp; + int i; + int j; + int rc = -ENOENT; read_lock(&ksocknal_data.ksnd_global_lock); @@ -322,8 +322,8 @@ ksocknal_get_peer_info(lnet_ni_t *ni, int index, static void ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn) { - ksock_peer_t *peer = route->ksnr_peer; - int type = conn->ksnc_type; + ksock_peer_t *peer = route->ksnr_peer; + int type = conn->ksnc_type; ksock_interface_t *iface; conn->ksnc_route = route; @@ -366,9 +366,9 @@ ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn) static void ksocknal_add_route_locked(ksock_peer_t *peer, ksock_route_t *route) { - struct list_head *tmp; - ksock_conn_t *conn; - ksock_route_t *route2; + struct list_head *tmp; + ksock_conn_t *conn; + ksock_route_t *route2; LASSERT(!peer->ksnp_closing); LASSERT(route->ksnr_peer == NULL); @@ -407,11 +407,11 @@ ksocknal_add_route_locked(ksock_peer_t *peer, ksock_route_t *route) static void ksocknal_del_route_locked(ksock_route_t *route) { - ksock_peer_t *peer = route->ksnr_peer; + ksock_peer_t *peer = route->ksnr_peer; ksock_interface_t *iface; - ksock_conn_t *conn; - struct list_head *ctmp; - struct list_head *cnxt; + ksock_conn_t *conn; + struct list_head *ctmp; + struct list_head *cnxt; LASSERT(!route->ksnr_deleted); @@ -447,12 +447,12 @@ ksocknal_del_route_locked(ksock_route_t *route) int ksocknal_add_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ipaddr, int port) { - struct list_head *tmp; - ksock_peer_t *peer; - ksock_peer_t *peer2; - ksock_route_t *route; - ksock_route_t *route2; - int rc; + struct list_head *tmp; + ksock_peer_t *peer; + ksock_peer_t *peer2; + ksock_route_t *route; + ksock_route_t *route2; + int rc; if (id.nid == LNET_NID_ANY || id.pid == LNET_PID_ANY) @@ -509,11 +509,11 @@ ksocknal_add_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ipaddr, int port) static void ksocknal_del_peer_locked(ksock_peer_t *peer, __u32 ip) { - ksock_conn_t *conn; - ksock_route_t *route; - struct list_head *tmp; - struct list_head *nxt; - int nshared; + ksock_conn_t *conn; + ksock_route_t *route; + struct list_head *tmp; + struct list_head *nxt; + int nshared; LASSERT(!peer->ksnp_closing); @@ -565,13 +565,13 @@ static int ksocknal_del_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ip) { LIST_HEAD(zombies); - struct list_head *ptmp; - struct list_head *pnxt; - ksock_peer_t *peer; - int lo; - int hi; - int i; - int rc = -ENOENT; + struct list_head *ptmp; + struct list_head *pnxt; + ksock_peer_t *peer; + int lo; + int hi; + int i; + int rc = -ENOENT; write_lock_bh(&ksocknal_data.ksnd_global_lock); @@ -623,11 +623,11 @@ ksocknal_del_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ip) static ksock_conn_t * ksocknal_get_conn_by_idx(lnet_ni_t *ni, int index) { - ksock_peer_t *peer; - struct list_head *ptmp; - ksock_conn_t *conn; - struct list_head *ctmp; - int i; + ksock_peer_t *peer; + struct list_head *ptmp; + ksock_conn_t *conn; + struct list_head *ctmp; + int i; read_lock(&ksocknal_data.ksnd_global_lock); @@ -661,8 +661,8 @@ static ksock_sched_t * ksocknal_choose_scheduler_locked(unsigned int cpt) { struct ksock_sched_info *info = ksocknal_data.ksnd_sched_info[cpt]; - ksock_sched_t *sched; - int i; + ksock_sched_t *sched; + int i; LASSERT(info->ksi_nthreads > 0); @@ -683,9 +683,9 @@ ksocknal_choose_scheduler_locked(unsigned int cpt) static int ksocknal_local_ipvec(lnet_ni_t *ni, __u32 *ipaddrs) { - ksock_net_t *net = ni->ni_data; - int i; - int nip; + ksock_net_t *net = ni->ni_data; + int i; + int nip; read_lock(&ksocknal_data.ksnd_global_lock); @@ -711,12 +711,12 @@ ksocknal_local_ipvec(lnet_ni_t *ni, __u32 *ipaddrs) static int ksocknal_match_peerip(ksock_interface_t *iface, __u32 *ips, int nips) { - int best_netmatch = 0; - int best_xor = 0; - int best = -1; - int this_xor; - int this_netmatch; - int i; + int best_netmatch = 0; + int best_xor = 0; + int best = -1; + int this_xor; + int this_netmatch; + int i; for (i = 0; i < nips; i++) { if (ips[i] == 0) @@ -743,19 +743,19 @@ ksocknal_match_peerip(ksock_interface_t *iface, __u32 *ips, int nips) static int ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips) { - rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; - ksock_net_t *net = peer->ksnp_ni->ni_data; - ksock_interface_t *iface; - ksock_interface_t *best_iface; - int n_ips; - int i; - int j; - int k; - __u32 ip; - __u32 xor; - int this_netmatch; - int best_netmatch; - int best_npeers; + rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; + ksock_net_t *net = peer->ksnp_ni->ni_data; + ksock_interface_t *iface; + ksock_interface_t *best_iface; + int n_ips; + int i; + int j; + int k; + __u32 ip; + __u32 xor; + int this_netmatch; + int best_netmatch; + int best_npeers; /* CAVEAT EMPTOR: We do all our interface matching with an * exclusive hold of global lock at IRQ priority. We're only @@ -846,19 +846,19 @@ static void ksocknal_create_routes(ksock_peer_t *peer, int port, __u32 *peer_ipaddrs, int npeer_ipaddrs) { - ksock_route_t *newroute = NULL; - rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; - lnet_ni_t *ni = peer->ksnp_ni; - ksock_net_t *net = ni->ni_data; - struct list_head *rtmp; - ksock_route_t *route; - ksock_interface_t *iface; - ksock_interface_t *best_iface; - int best_netmatch; - int this_netmatch; - int best_nroutes; - int i; - int j; + ksock_route_t *newroute = NULL; + rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; + lnet_ni_t *ni = peer->ksnp_ni; + ksock_net_t *net = ni->ni_data; + struct list_head *rtmp; + ksock_route_t *route; + ksock_interface_t *iface; + ksock_interface_t *best_iface; + int best_netmatch; + int this_netmatch; + int best_nroutes; + int i; + int j; /* CAVEAT EMPTOR: We do all our interface matching with an * exclusive hold of global lock at IRQ priority. We're only @@ -963,12 +963,12 @@ ksocknal_create_routes(ksock_peer_t *peer, int port, int ksocknal_accept(lnet_ni_t *ni, struct socket *sock) { - ksock_connreq_t *cr; - int rc; - __u32 peer_ip; - int peer_port; + ksock_connreq_t *cr; + int rc; + __u32 peer_ip; + int peer_port; - rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port); + rc = lnet_sock_getaddr(sock, 1, &peer_ip, &peer_port); LASSERT(rc == 0); /* we succeeded before */ LIBCFS_ALLOC(cr, sizeof(*cr)); @@ -994,7 +994,7 @@ ksocknal_accept(lnet_ni_t *ni, struct socket *sock) static int ksocknal_connecting(ksock_peer_t *peer, __u32 ipaddr) { - ksock_route_t *route; + ksock_route_t *route; list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { @@ -1008,23 +1008,23 @@ int ksocknal_create_conn(lnet_ni_t *ni, ksock_route_t *route, struct socket *sock, int type) { - rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; + rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; LIST_HEAD(zombies); - lnet_process_id_t peerid; - struct list_head *tmp; - __u64 incarnation; - ksock_conn_t *conn; - ksock_conn_t *conn2; - ksock_peer_t *peer = NULL; - ksock_peer_t *peer2; - ksock_sched_t *sched; + lnet_process_id_t peerid; + struct list_head *tmp; + __u64 incarnation; + ksock_conn_t *conn; + ksock_conn_t *conn2; + ksock_peer_t *peer = NULL; + ksock_peer_t *peer2; + ksock_sched_t *sched; ksock_hello_msg_t *hello; - int cpt; - ksock_tx_t *tx; - ksock_tx_t *txtmp; - int rc; - int active; - char *warn = NULL; + int cpt; + ksock_tx_t *tx; + ksock_tx_t *txtmp; + int rc; + int active; + char *warn = NULL; active = (route != NULL); @@ -1378,15 +1378,15 @@ ksocknal_create_conn(lnet_ni_t *ni, ksock_route_t *route, ksocknal_txlist_done(ni, &zombies, 1); ksocknal_peer_decref(peer); - failed_1: +failed_1: if (hello != NULL) LIBCFS_FREE(hello, offsetof(ksock_hello_msg_t, kshm_ips[LNET_MAX_INTERFACES])); LIBCFS_FREE(conn, sizeof(*conn)); - failed_0: - libcfs_sock_release(sock); +failed_0: + sock_release(sock); return rc; } @@ -1396,10 +1396,10 @@ ksocknal_close_conn_locked(ksock_conn_t *conn, int error) /* This just does the immmediate housekeeping, and queues the * connection for the reaper to terminate. * Caller holds ksnd_global_lock exclusively in irq context */ - ksock_peer_t *peer = conn->ksnc_peer; - ksock_route_t *route; - ksock_conn_t *conn2; - struct list_head *tmp; + ksock_peer_t *peer = conn->ksnc_peer; + ksock_route_t *route; + ksock_conn_t *conn2; + struct list_head *tmp; LASSERT(peer->ksnp_error == 0); LASSERT(!conn->ksnc_closing); @@ -1479,7 +1479,7 @@ ksocknal_close_conn_locked(ksock_conn_t *conn, int error) void ksocknal_peer_failed(ksock_peer_t *peer) { - int notify = 0; + int notify = 0; unsigned long last_alive = 0; /* There has been a connection failure or comms error; but I'll only @@ -1506,9 +1506,9 @@ ksocknal_peer_failed(ksock_peer_t *peer) void ksocknal_finalize_zcreq(ksock_conn_t *conn) { - ksock_peer_t *peer = conn->ksnc_peer; - ksock_tx_t *tx; - ksock_tx_t *tmp; + ksock_peer_t *peer = conn->ksnc_peer; + ksock_tx_t *tx; + ksock_tx_t *tmp; LIST_HEAD(zlist); /* NB safe to finalize TXs because closing of socket will @@ -1546,9 +1546,9 @@ ksocknal_terminate_conn(ksock_conn_t *conn) * disengage the socket from its callbacks and close it. * ksnc_refcount will eventually hit zero, and then the reaper will * destroy it. */ - ksock_peer_t *peer = conn->ksnc_peer; - ksock_sched_t *sched = conn->ksnc_scheduler; - int failed = 0; + ksock_peer_t *peer = conn->ksnc_peer; + ksock_sched_t *sched = conn->ksnc_scheduler; + int failed = 0; LASSERT(conn->ksnc_closing); @@ -1617,7 +1617,7 @@ ksocknal_queue_zombie_conn(ksock_conn_t *conn) void ksocknal_destroy_conn(ksock_conn_t *conn) { - unsigned long last_rcv; + unsigned long last_rcv; /* Final coup-de-grace of the reaper */ CDEBUG(D_NET, "connection %p\n", conn); @@ -1677,10 +1677,10 @@ ksocknal_destroy_conn(ksock_conn_t *conn) int ksocknal_close_peer_conns_locked(ksock_peer_t *peer, __u32 ipaddr, int why) { - ksock_conn_t *conn; - struct list_head *ctmp; - struct list_head *cnxt; - int count = 0; + ksock_conn_t *conn; + struct list_head *ctmp; + struct list_head *cnxt; + int count = 0; list_for_each_safe(ctmp, cnxt, &peer->ksnp_conns) { conn = list_entry(ctmp, ksock_conn_t, ksnc_list); @@ -1698,9 +1698,9 @@ ksocknal_close_peer_conns_locked(ksock_peer_t *peer, __u32 ipaddr, int why) int ksocknal_close_conn_and_siblings(ksock_conn_t *conn, int why) { - ksock_peer_t *peer = conn->ksnc_peer; - __u32 ipaddr = conn->ksnc_ipaddr; - int count; + ksock_peer_t *peer = conn->ksnc_peer; + __u32 ipaddr = conn->ksnc_ipaddr; + int count; write_lock_bh(&ksocknal_data.ksnd_global_lock); @@ -1714,13 +1714,13 @@ ksocknal_close_conn_and_siblings(ksock_conn_t *conn, int why) int ksocknal_close_matching_conns(lnet_process_id_t id, __u32 ipaddr) { - ksock_peer_t *peer; - struct list_head *ptmp; - struct list_head *pnxt; - int lo; - int hi; - int i; - int count = 0; + ksock_peer_t *peer; + struct list_head *ptmp; + struct list_head *pnxt; + int lo; + int hi; + int i; + int count = 0; write_lock_bh(&ksocknal_data.ksnd_global_lock); @@ -1762,7 +1762,7 @@ ksocknal_notify(lnet_ni_t *ni, lnet_nid_t gw_nid, int alive) { /* The router is telling me she's been notified of a change in * gateway state.... */ - lnet_process_id_t id = {0}; + lnet_process_id_t id = {0}; id.nid = gw_nid; id.pid = LNET_PID_ANY; @@ -1783,20 +1783,20 @@ ksocknal_notify(lnet_ni_t *ni, lnet_nid_t gw_nid, int alive) void ksocknal_query(lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when) { - int connect = 1; - unsigned long last_alive = 0; - unsigned long now = cfs_time_current(); - ksock_peer_t *peer = NULL; - rwlock_t *glock = &ksocknal_data.ksnd_global_lock; - lnet_process_id_t id = {.nid = nid, .pid = LUSTRE_SRV_LNET_PID}; + int connect = 1; + unsigned long last_alive = 0; + unsigned long now = cfs_time_current(); + ksock_peer_t *peer = NULL; + rwlock_t *glock = &ksocknal_data.ksnd_global_lock; + lnet_process_id_t id = {.nid = nid, .pid = LUSTRE_SRV_LNET_PID}; read_lock(glock); peer = ksocknal_find_peer_locked(ni, id); if (peer != NULL) { - struct list_head *tmp; - ksock_conn_t *conn; - int bufnob; + struct list_head *tmp; + ksock_conn_t *conn; + int bufnob; list_for_each(tmp, &peer->ksnp_conns) { conn = list_entry(tmp, ksock_conn_t, ksnc_list); @@ -1844,10 +1844,10 @@ ksocknal_query(lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when) static void ksocknal_push_peer(ksock_peer_t *peer) { - int index; - int i; - struct list_head *tmp; - ksock_conn_t *conn; + int index; + int i; + struct list_head *tmp; + ksock_conn_t *conn; for (index = 0; ; index++) { read_lock(&ksocknal_data.ksnd_global_lock); @@ -1877,12 +1877,12 @@ ksocknal_push_peer(ksock_peer_t *peer) static int ksocknal_push(lnet_ni_t *ni, lnet_process_id_t id) { - ksock_peer_t *peer; - struct list_head *tmp; - int index; - int i; - int j; - int rc = -ENOENT; + ksock_peer_t *peer; + struct list_head *tmp; + int index; + int i; + int j; + int rc = -ENOENT; for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { for (j = 0; ; j++) { @@ -1926,15 +1926,15 @@ ksocknal_push(lnet_ni_t *ni, lnet_process_id_t id) static int ksocknal_add_interface(lnet_ni_t *ni, __u32 ipaddress, __u32 netmask) { - ksock_net_t *net = ni->ni_data; + ksock_net_t *net = ni->ni_data; ksock_interface_t *iface; - int rc; - int i; - int j; - struct list_head *ptmp; - ksock_peer_t *peer; - struct list_head *rtmp; - ksock_route_t *route; + int rc; + int i; + int j; + struct list_head *ptmp; + ksock_peer_t *peer; + struct list_head *rtmp; + ksock_route_t *route; if (ipaddress == 0 || netmask == 0) @@ -1988,12 +1988,12 @@ ksocknal_add_interface(lnet_ni_t *ni, __u32 ipaddress, __u32 netmask) static void ksocknal_peer_del_interface_locked(ksock_peer_t *peer, __u32 ipaddr) { - struct list_head *tmp; - struct list_head *nxt; - ksock_route_t *route; - ksock_conn_t *conn; - int i; - int j; + struct list_head *tmp; + struct list_head *nxt; + ksock_route_t *route; + ksock_conn_t *conn; + int i; + int j; for (i = 0; i < peer->ksnp_n_passive_ips; i++) if (peer->ksnp_passive_ips[i] == ipaddr) { @@ -2029,14 +2029,14 @@ ksocknal_peer_del_interface_locked(ksock_peer_t *peer, __u32 ipaddr) static int ksocknal_del_interface(lnet_ni_t *ni, __u32 ipaddress) { - ksock_net_t *net = ni->ni_data; - int rc = -ENOENT; - struct list_head *tmp; - struct list_head *nxt; - ksock_peer_t *peer; - __u32 this_ip; - int i; - int j; + ksock_net_t *net = ni->ni_data; + int rc = -ENOENT; + struct list_head *tmp; + struct list_head *nxt; + ksock_peer_t *peer; + __u32 this_ip; + int i; + int j; write_lock_bh(&ksocknal_data.ksnd_global_lock); @@ -2114,11 +2114,11 @@ ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg) data->ioc_u32[0]); /* IP address */ case IOC_LIBCFS_GET_PEER: { - __u32 myip = 0; - __u32 ip = 0; - int port = 0; - int conn_count = 0; - int share_count = 0; + __u32 myip = 0; + __u32 ip = 0; + int port = 0; + int conn_count = 0; + int share_count = 0; rc = ksocknal_get_peer_info(ni, data->ioc_count, &id, &myip, &ip, &port, @@ -2150,9 +2150,9 @@ ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg) data->ioc_u32[0]); /* IP */ case IOC_LIBCFS_GET_CONN: { - int txmem; - int rxmem; - int nagle; + int txmem; + int rxmem; + int nagle; ksock_conn_t *conn = ksocknal_get_conn_by_idx(ni, data->ioc_count); if (conn == NULL) @@ -2207,8 +2207,8 @@ ksocknal_free_buffers(void) LASSERT(atomic_read(&ksocknal_data.ksnd_nactive_txs) == 0); if (ksocknal_data.ksnd_sched_info != NULL) { - struct ksock_sched_info *info; - int i; + struct ksock_sched_info *info; + int i; cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) { if (info->ksi_scheds != NULL) { @@ -2227,8 +2227,8 @@ ksocknal_free_buffers(void) spin_lock(&ksocknal_data.ksnd_tx_lock); if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) { - struct list_head zlist; - ksock_tx_t *tx; + struct list_head zlist; + ksock_tx_t *tx; list_add(&zlist, &ksocknal_data.ksnd_idle_noop_txs); list_del_init(&ksocknal_data.ksnd_idle_noop_txs); @@ -2248,9 +2248,9 @@ static void ksocknal_base_shutdown(void) { struct ksock_sched_info *info; - ksock_sched_t *sched; - int i; - int j; + ksock_sched_t *sched; + int i; + int j; CDEBUG(D_MALLOC, "before NAL cleanup: kmem %d\n", atomic_read(&libcfs_kmemory)); @@ -2351,8 +2351,8 @@ static int ksocknal_base_startup(void) { struct ksock_sched_info *info; - int rc; - int i; + int rc; + int i; LASSERT(ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING); LASSERT(ksocknal_data.ksnd_nnets == 0); @@ -2398,8 +2398,8 @@ ksocknal_base_startup(void) goto failed; cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) { - ksock_sched_t *sched; - int nthrs; + ksock_sched_t *sched; + int nthrs; nthrs = cfs_cpt_weight(lnet_cpt_table(), i); if (*ksocknal_tunables.ksnd_nscheds > 0) { @@ -2430,9 +2430,9 @@ ksocknal_base_startup(void) } } - ksocknal_data.ksnd_connd_starting = 0; - ksocknal_data.ksnd_connd_failed_stamp = 0; - ksocknal_data.ksnd_connd_starting_stamp = get_seconds(); + ksocknal_data.ksnd_connd_starting = 0; + ksocknal_data.ksnd_connd_failed_stamp = 0; + ksocknal_data.ksnd_connd_starting_stamp = get_seconds(); /* must have at least 2 connds to remain responsive to accepts while * connecting */ if (*ksocknal_tunables.ksnd_nconnds < SOCKNAL_CONND_RESV + 1) @@ -2482,9 +2482,9 @@ ksocknal_base_startup(void) static void ksocknal_debug_peerhash(lnet_ni_t *ni) { - ksock_peer_t *peer = NULL; - struct list_head *tmp; - int i; + ksock_peer_t *peer = NULL; + struct list_head *tmp; + int i; read_lock(&ksocknal_data.ksnd_global_lock); @@ -2536,12 +2536,12 @@ ksocknal_debug_peerhash(lnet_ni_t *ni) void ksocknal_shutdown(lnet_ni_t *ni) { - ksock_net_t *net = ni->ni_data; - int i; + ksock_net_t *net = ni->ni_data; + int i; lnet_process_id_t anyid = {0}; - anyid.nid = LNET_NID_ANY; - anyid.pid = LNET_PID_ANY; + anyid.nid = LNET_NID_ANY; + anyid.pid = LNET_PID_ANY; LASSERT(ksocknal_data.ksnd_init == SOCKNAL_INIT_ALL); LASSERT(ksocknal_data.ksnd_nnets > 0); @@ -2588,27 +2588,27 @@ ksocknal_shutdown(lnet_ni_t *ni) static int ksocknal_enumerate_interfaces(ksock_net_t *net) { - char **names; - int i; - int j; - int rc; - int n; + char **names; + int i; + int j; + int rc; + int n; - n = libcfs_ipif_enumerate(&names); + n = lnet_ipif_enumerate(&names); if (n <= 0) { CERROR("Can't enumerate interfaces: %d\n", n); return n; } for (i = j = 0; i < n; i++) { - int up; - __u32 ip; - __u32 mask; + int up; + __u32 ip; + __u32 mask; if (!strcmp(names[i], "lo")) /* skip the loopback IF */ continue; - rc = libcfs_ipif_query(names[i], &up, &ip, &mask); + rc = lnet_ipif_query(names[i], &up, &ip, &mask); if (rc != 0) { CWARN("Can't get interface %s info: %d\n", names[i], rc); @@ -2634,7 +2634,7 @@ ksocknal_enumerate_interfaces(ksock_net_t *net) j++; } - libcfs_ipif_free_enumeration(names, n); + lnet_ipif_free_enumeration(names, n); if (j == 0) CERROR("Can't find any usable interfaces\n"); @@ -2645,15 +2645,15 @@ ksocknal_enumerate_interfaces(ksock_net_t *net) static int ksocknal_search_new_ipif(ksock_net_t *net) { - int new_ipif = 0; - int i; + int new_ipif = 0; + int i; for (i = 0; i < net->ksnn_ninterfaces; i++) { - char *ifnam = &net->ksnn_interfaces[i].ksni_name[0]; - char *colon = strchr(ifnam, ':'); - int found = 0; - ksock_net_t *tmp; - int j; + char *ifnam = &net->ksnn_interfaces[i].ksni_name[0]; + char *colon = strchr(ifnam, ':'); + int found = 0; + ksock_net_t *tmp; + int j; if (colon != NULL) /* ignore alias device */ *colon = 0; @@ -2687,9 +2687,9 @@ ksocknal_search_new_ipif(ksock_net_t *net) static int ksocknal_start_schedulers(struct ksock_sched_info *info) { - int nthrs; - int rc = 0; - int i; + int nthrs; + int rc = 0; + int i; if (info->ksi_nthreads == 0) { if (*ksocknal_tunables.ksnd_nscheds > 0) { @@ -2708,9 +2708,9 @@ ksocknal_start_schedulers(struct ksock_sched_info *info) } for (i = 0; i < nthrs; i++) { - long id; - char name[20]; - ksock_sched_t *sched; + long id; + char name[20]; + ksock_sched_t *sched; id = KSOCK_THREAD_ID(info->ksi_cpt, info->ksi_nthreads + i); sched = &info->ksi_scheds[KSOCK_THREAD_SID(id)]; snprintf(name, sizeof(name), "socknal_sd%02d_%02d", @@ -2733,14 +2733,14 @@ ksocknal_start_schedulers(struct ksock_sched_info *info) static int ksocknal_net_start_threads(ksock_net_t *net, __u32 *cpts, int ncpts) { - int newif = ksocknal_search_new_ipif(net); - int rc; - int i; + int newif = ksocknal_search_new_ipif(net); + int rc; + int i; LASSERT(ncpts > 0 && ncpts <= cfs_cpt_number(lnet_cpt_table())); for (i = 0; i < ncpts; i++) { - struct ksock_sched_info *info; + struct ksock_sched_info *info; int cpt = (cpts == NULL) ? i : cpts[i]; LASSERT(cpt < cfs_cpt_number(lnet_cpt_table())); @@ -2759,9 +2759,9 @@ ksocknal_net_start_threads(ksock_net_t *net, __u32 *cpts, int ncpts) int ksocknal_startup(lnet_ni_t *ni) { - ksock_net_t *net; - int rc; - int i; + ksock_net_t *net; + int rc; + int i; LASSERT(ni->ni_lnd == &the_ksocklnd); @@ -2791,13 +2791,12 @@ ksocknal_startup(lnet_ni_t *ni) net->ksnn_ninterfaces = 1; } else { for (i = 0; i < LNET_MAX_INTERFACES; i++) { - int up; + int up; if (ni->ni_interfaces[i] == NULL) break; - rc = libcfs_ipif_query( - ni->ni_interfaces[i], &up, + rc = lnet_ipif_query(ni->ni_interfaces[i], &up, &net->ksnn_interfaces[i].ksni_ipaddr, &net->ksnn_interfaces[i].ksni_netmask); @@ -2851,7 +2850,7 @@ ksocknal_module_fini(void) static int __init ksocknal_module_init(void) { - int rc; + int rc; /* check ksnr_connected/connecting field large enough */ CLASSERT(SOCKLND_CONN_NTYPES <= 4); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index c54c9955164e..06531c1d2ffb 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -36,15 +36,15 @@ #include "../../../include/linux/lnet/socklnd.h" #include "../../../include/linux/lnet/lnet-sysctl.h" -#define SOCKNAL_PEER_HASH_SIZE 101 /* # peer lists */ -#define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */ -#define SOCKNAL_INSANITY_RECONN 5000 /* connd is trying on reconn infinitely */ -#define SOCKNAL_ENOMEM_RETRY CFS_TICK /* jiffies between retries */ +#define SOCKNAL_PEER_HASH_SIZE 101 /* # peer lists */ +#define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */ +#define SOCKNAL_INSANITY_RECONN 5000 /* connd is trying on reconn infinitely */ +#define SOCKNAL_ENOMEM_RETRY CFS_TICK /* jiffies between retries */ -#define SOCKNAL_SINGLE_FRAG_TX 0 /* disable multi-fragment sends */ -#define SOCKNAL_SINGLE_FRAG_RX 0 /* disable multi-fragment receives */ +#define SOCKNAL_SINGLE_FRAG_TX 0 /* disable multi-fragment sends */ +#define SOCKNAL_SINGLE_FRAG_RX 0 /* disable multi-fragment receives */ -#define SOCKNAL_VERSION_DEBUG 0 /* enable protocol version debugging */ +#define SOCKNAL_VERSION_DEBUG 0 /* enable protocol version debugging */ /* risk kmap deadlock on multi-frag I/O (backs off to single-frag if disabled). * no risk if we're not running on a CONFIG_HIGHMEM platform. */ @@ -58,33 +58,31 @@ struct ksock_sched_info; typedef struct /* per scheduler state */ { - spinlock_t kss_lock; /* serialise */ - struct list_head kss_rx_conns; /* conn waiting to be read */ - /* conn waiting to be written */ - struct list_head kss_tx_conns; - /* zombie noop tx list */ - struct list_head kss_zombie_noop_txs; - wait_queue_head_t kss_waitq; /* where scheduler sleeps */ - /* # connections assigned to this scheduler */ - int kss_nconns; - struct ksock_sched_info *kss_info; /* owner of it */ - struct page *kss_rx_scratch_pgs[LNET_MAX_IOV]; - struct kvec kss_scratch_iov[LNET_MAX_IOV]; + spinlock_t kss_lock; /* serialise */ + struct list_head kss_rx_conns; /* conn waiting to be read */ + struct list_head kss_tx_conns; /* conn waiting to be written */ + struct list_head kss_zombie_noop_txs; /* zombie noop tx list */ + wait_queue_head_t kss_waitq; /* where scheduler sleeps */ + int kss_nconns; /* # connections assigned to + * this scheduler */ + struct ksock_sched_info *kss_info; /* owner of it */ + struct page *kss_rx_scratch_pgs[LNET_MAX_IOV]; + struct kvec kss_scratch_iov[LNET_MAX_IOV]; } ksock_sched_t; struct ksock_sched_info { - int ksi_nthreads_max; /* max allowed threads */ - int ksi_nthreads; /* number of threads */ - int ksi_cpt; /* CPT id */ - ksock_sched_t *ksi_scheds; /* array of schedulers */ + int ksi_nthreads_max; /* max allowed threads */ + int ksi_nthreads; /* number of threads */ + int ksi_cpt; /* CPT id */ + ksock_sched_t *ksi_scheds; /* array of schedulers */ }; -#define KSOCK_CPT_SHIFT 16 -#define KSOCK_THREAD_ID(cpt, sid) (((cpt) << KSOCK_CPT_SHIFT) | (sid)) -#define KSOCK_THREAD_CPT(id) ((id) >> KSOCK_CPT_SHIFT) -#define KSOCK_THREAD_SID(id) ((id) & ((1UL << KSOCK_CPT_SHIFT) - 1)) +#define KSOCK_CPT_SHIFT 16 +#define KSOCK_THREAD_ID(cpt, sid) (((cpt) << KSOCK_CPT_SHIFT) | (sid)) +#define KSOCK_THREAD_CPT(id) ((id) >> KSOCK_CPT_SHIFT) +#define KSOCK_THREAD_SID(id) ((id) & ((1UL << KSOCK_CPT_SHIFT) - 1)) -typedef struct /* in-use interface */ +typedef struct /* in-use interface */ { __u32 ksni_ipaddr; /* interface's IP address */ __u32 ksni_netmask; /* interface's network mask */ @@ -94,35 +92,48 @@ typedef struct /* in-use interface */ } ksock_interface_t; typedef struct { - /* "stuck" socket timeout (seconds) */ - int *ksnd_timeout; - /* # scheduler threads in each pool while starting */ - int *ksnd_nscheds; - int *ksnd_nconnds; /* # connection daemons */ - int *ksnd_nconnds_max; /* max # connection daemons */ - int *ksnd_min_reconnectms; /* first connection retry after (ms)... */ - int *ksnd_max_reconnectms; /* ...exponentially increasing to this */ - int *ksnd_eager_ack; /* make TCP ack eagerly? */ - int *ksnd_typed_conns; /* drive sockets by type? */ - int *ksnd_min_bulk; /* smallest "large" message */ - int *ksnd_tx_buffer_size; /* socket tx buffer size */ - int *ksnd_rx_buffer_size; /* socket rx buffer size */ - int *ksnd_nagle; /* enable NAGLE? */ - int *ksnd_round_robin; /* round robin for multiple interfaces */ - int *ksnd_keepalive; /* # secs for sending keepalive NOOP */ - int *ksnd_keepalive_idle; /* # idle secs before 1st probe */ - int *ksnd_keepalive_count; /* # probes */ - int *ksnd_keepalive_intvl; /* time between probes */ - int *ksnd_credits; /* # concurrent sends */ - int *ksnd_peertxcredits; /* # concurrent sends to 1 peer */ - int *ksnd_peerrtrcredits; /* # per-peer router buffer credits */ - int *ksnd_peertimeout; /* seconds to consider peer dead */ - int *ksnd_enable_csum; /* enable check sum */ - int *ksnd_inject_csum_error; /* set non-zero to inject checksum error */ - int *ksnd_nonblk_zcack; /* always send zc-ack on non-blocking connection */ - unsigned int *ksnd_zc_min_payload; /* minimum zero copy payload size */ - int *ksnd_zc_recv; /* enable ZC receive (for Chelsio TOE) */ - int *ksnd_zc_recv_min_nfrags; /* minimum # of fragments to enable ZC receive */ + int *ksnd_timeout; /* "stuck" socket timeout + * (seconds) */ + int *ksnd_nscheds; /* # scheduler threads in each + * pool while starting */ + int *ksnd_nconnds; /* # connection daemons */ + int *ksnd_nconnds_max; /* max # connection daemons */ + int *ksnd_min_reconnectms; /* first connection retry after + * (ms)... */ + int *ksnd_max_reconnectms; /* ...exponentially increasing to + * this */ + int *ksnd_eager_ack; /* make TCP ack eagerly? */ + int *ksnd_typed_conns; /* drive sockets by type? */ + int *ksnd_min_bulk; /* smallest "large" message */ + int *ksnd_tx_buffer_size; /* socket tx buffer size */ + int *ksnd_rx_buffer_size; /* socket rx buffer size */ + int *ksnd_nagle; /* enable NAGLE? */ + int *ksnd_round_robin; /* round robin for multiple + * interfaces */ + int *ksnd_keepalive; /* # secs for sending keepalive + * NOOP */ + int *ksnd_keepalive_idle; /* # idle secs before 1st probe + */ + int *ksnd_keepalive_count; /* # probes */ + int *ksnd_keepalive_intvl; /* time between probes */ + int *ksnd_credits; /* # concurrent sends */ + int *ksnd_peertxcredits; /* # concurrent sends to 1 peer + */ + int *ksnd_peerrtrcredits; /* # per-peer router buffer + * credits */ + int *ksnd_peertimeout; /* seconds to consider peer dead + */ + int *ksnd_enable_csum; /* enable check sum */ + int *ksnd_inject_csum_error; /* set non-zero to inject + * checksum error */ + int *ksnd_nonblk_zcack; /* always send zc-ack on + * non-blocking connection */ + unsigned int *ksnd_zc_min_payload; /* minimum zero copy payload + * size */ + int *ksnd_zc_recv; /* enable ZC receive (for + * Chelsio TOE) */ + int *ksnd_zc_recv_min_nfrags; /* minimum # of fragments to + * enable ZC receive */ } ksock_tunables_t; typedef struct { @@ -141,55 +152,67 @@ typedef struct { #define SOCKNAL_CONND_RESV 1 typedef struct { - int ksnd_init; /* initialisation state */ - int ksnd_nnets; /* # networks set up */ - struct list_head ksnd_nets; /* list of nets */ - /* stabilize peer/conn ops */ - rwlock_t ksnd_global_lock; - /* hash table of all my known peers */ - struct list_head *ksnd_peers; - int ksnd_peer_hash_size; /* size of ksnd_peers */ - - int ksnd_nthreads; /* # live threads */ - int ksnd_shuttingdown; /* tell threads to exit */ - /* schedulers information */ - struct ksock_sched_info **ksnd_sched_info; - - atomic_t ksnd_nactive_txs; /* #active txs */ - - struct list_head ksnd_deathrow_conns; /* conns to close: reaper_lock*/ - struct list_head ksnd_zombie_conns; /* conns to free: reaper_lock */ - struct list_head ksnd_enomem_conns; /* conns to retry: reaper_lock*/ - wait_queue_head_t ksnd_reaper_waitq; /* reaper sleeps here */ - unsigned long ksnd_reaper_waketime;/* when reaper will wake */ - spinlock_t ksnd_reaper_lock; /* serialise */ - - int ksnd_enomem_tx; /* test ENOMEM sender */ - int ksnd_stall_tx; /* test sluggish sender */ - int ksnd_stall_rx; /* test sluggish receiver */ - - struct list_head ksnd_connd_connreqs; /* incoming connection requests */ - struct list_head ksnd_connd_routes; /* routes waiting to be connected */ - wait_queue_head_t ksnd_connd_waitq; /* connds sleep here */ - int ksnd_connd_connecting;/* # connds connecting */ - /** time stamp of the last failed connecting attempt */ - long ksnd_connd_failed_stamp; - /** # starting connd */ - unsigned ksnd_connd_starting; - /** time stamp of the last starting connd */ - long ksnd_connd_starting_stamp; - /** # running connd */ - unsigned ksnd_connd_running; - spinlock_t ksnd_connd_lock; /* serialise */ - - struct list_head ksnd_idle_noop_txs; /* list head for freed noop tx */ - spinlock_t ksnd_tx_lock; /* serialise, g_lock unsafe */ + int ksnd_init; /* initialisation state + */ + int ksnd_nnets; /* # networks set up */ + struct list_head ksnd_nets; /* list of nets */ + rwlock_t ksnd_global_lock; /* stabilize peer/conn + * ops */ + struct list_head *ksnd_peers; /* hash table of all my + * known peers */ + int ksnd_peer_hash_size; /* size of ksnd_peers */ + + int ksnd_nthreads; /* # live threads */ + int ksnd_shuttingdown; /* tell threads to exit + */ + struct ksock_sched_info **ksnd_sched_info; /* schedulers info */ + + atomic_t ksnd_nactive_txs; /* #active txs */ + + struct list_head ksnd_deathrow_conns; /* conns to close: + * reaper_lock*/ + struct list_head ksnd_zombie_conns; /* conns to free: + * reaper_lock */ + struct list_head ksnd_enomem_conns; /* conns to retry: + * reaper_lock*/ + wait_queue_head_t ksnd_reaper_waitq; /* reaper sleeps here */ + unsigned long ksnd_reaper_waketime; /* when reaper will wake + */ + spinlock_t ksnd_reaper_lock; /* serialise */ + + int ksnd_enomem_tx; /* test ENOMEM sender */ + int ksnd_stall_tx; /* test sluggish sender + */ + int ksnd_stall_rx; /* test sluggish + * receiver */ + + struct list_head ksnd_connd_connreqs; /* incoming connection + * requests */ + struct list_head ksnd_connd_routes; /* routes waiting to be + * connected */ + wait_queue_head_t ksnd_connd_waitq; /* connds sleep here */ + int ksnd_connd_connecting; /* # connds connecting + */ + long ksnd_connd_failed_stamp;/* time stamp of the + * last failed + * connecting attempt */ + unsigned ksnd_connd_starting; /* # starting connd */ + long ksnd_connd_starting_stamp;/* time stamp of the + * last starting connd + */ + unsigned ksnd_connd_running; /* # running connd */ + spinlock_t ksnd_connd_lock; /* serialise */ + + struct list_head ksnd_idle_noop_txs; /* list head for freed + * noop tx */ + spinlock_t ksnd_tx_lock; /* serialise, g_lock + * unsafe */ } ksock_nal_data_t; -#define SOCKNAL_INIT_NOTHING 0 -#define SOCKNAL_INIT_DATA 1 -#define SOCKNAL_INIT_ALL 2 +#define SOCKNAL_INIT_NOTHING 0 +#define SOCKNAL_INIT_DATA 1 +#define SOCKNAL_INIT_ALL 2 /* A packet just assembled for transmission is represented by 1 or more * struct iovec fragments (the first frag contains the portals header), @@ -200,43 +223,45 @@ typedef struct { * received into either struct iovec or lnet_kiov_t fragments, depending on * what the header matched or whether the message needs forwarding. */ -struct ksock_conn; /* forward ref */ -struct ksock_peer; /* forward ref */ -struct ksock_route; /* forward ref */ -struct ksock_proto; /* forward ref */ +struct ksock_conn; /* forward ref */ +struct ksock_peer; /* forward ref */ +struct ksock_route; /* forward ref */ +struct ksock_proto; /* forward ref */ -typedef struct /* transmit packet */ +typedef struct /* transmit packet */ { - struct list_head tx_list; /* queue on conn for transmission etc */ - struct list_head tx_zc_list; /* queue on peer for ZC request */ - atomic_t tx_refcount; /* tx reference count */ - int tx_nob; /* # packet bytes */ - int tx_resid; /* residual bytes */ - int tx_niov; /* # packet iovec frags */ - struct kvec *tx_iov; /* packet iovec frags */ - int tx_nkiov; /* # packet page frags */ - unsigned short tx_zc_aborted; /* aborted ZC request */ - unsigned short tx_zc_capable:1; /* payload is large enough for ZC */ - unsigned short tx_zc_checked:1; /* Have I checked if I should ZC? */ - unsigned short tx_nonblk:1; /* it's a non-blocking ACK */ - lnet_kiov_t *tx_kiov; /* packet page frags */ - struct ksock_conn *tx_conn; /* owning conn */ - lnet_msg_t *tx_lnetmsg; /* lnet message for lnet_finalize() */ - unsigned long tx_deadline; /* when (in jiffies) tx times out */ - ksock_msg_t tx_msg; /* socklnd message buffer */ - int tx_desc_size; /* size of this descriptor */ + struct list_head tx_list; /* queue on conn for transmission etc + */ + struct list_head tx_zc_list; /* queue on peer for ZC request */ + atomic_t tx_refcount; /* tx reference count */ + int tx_nob; /* # packet bytes */ + int tx_resid; /* residual bytes */ + int tx_niov; /* # packet iovec frags */ + struct kvec *tx_iov; /* packet iovec frags */ + int tx_nkiov; /* # packet page frags */ + unsigned short tx_zc_aborted; /* aborted ZC request */ + unsigned short tx_zc_capable:1; /* payload is large enough for ZC */ + unsigned short tx_zc_checked:1; /* Have I checked if I should ZC? */ + unsigned short tx_nonblk:1; /* it's a non-blocking ACK */ + lnet_kiov_t *tx_kiov; /* packet page frags */ + struct ksock_conn *tx_conn; /* owning conn */ + lnet_msg_t *tx_lnetmsg; /* lnet message for lnet_finalize() + */ + unsigned long tx_deadline; /* when (in jiffies) tx times out */ + ksock_msg_t tx_msg; /* socklnd message buffer */ + int tx_desc_size; /* size of this descriptor */ union { struct { - struct kvec iov; /* virt hdr */ - lnet_kiov_t kiov[0]; /* paged payload */ - } paged; + struct kvec iov; /* virt hdr */ + lnet_kiov_t kiov[0]; /* paged payload */ + } paged; struct { - struct kvec iov[1]; /* virt hdr + payload */ - } virt; - } tx_frags; + struct kvec iov[1]; /* virt hdr + payload */ + } virt; + } tx_frags; } ksock_tx_t; -#define KSOCK_NOOP_TX_SIZE ((int)offsetof(ksock_tx_t, tx_frags.paged.kiov[0])) +#define KSOCK_NOOP_TX_SIZE ((int)offsetof(ksock_tx_t, tx_frags.paged.kiov[0])) /* network zero copy callback descriptor embedded in ksock_tx_t */ @@ -247,148 +272,189 @@ typedef union { lnet_kiov_t kiov[LNET_MAX_IOV]; } ksock_rxiovspace_t; -#define SOCKNAL_RX_KSM_HEADER 1 /* reading ksock message header */ -#define SOCKNAL_RX_LNET_HEADER 2 /* reading lnet message header */ -#define SOCKNAL_RX_PARSE 3 /* Calling lnet_parse() */ -#define SOCKNAL_RX_PARSE_WAIT 4 /* waiting to be told to read the body */ -#define SOCKNAL_RX_LNET_PAYLOAD 5 /* reading lnet payload (to deliver here) */ -#define SOCKNAL_RX_SLOP 6 /* skipping body */ +#define SOCKNAL_RX_KSM_HEADER 1 /* reading ksock message header */ +#define SOCKNAL_RX_LNET_HEADER 2 /* reading lnet message header */ +#define SOCKNAL_RX_PARSE 3 /* Calling lnet_parse() */ +#define SOCKNAL_RX_PARSE_WAIT 4 /* waiting to be told to read the body */ +#define SOCKNAL_RX_LNET_PAYLOAD 5 /* reading lnet payload (to deliver here) */ +#define SOCKNAL_RX_SLOP 6 /* skipping body */ typedef struct ksock_conn { - struct ksock_peer *ksnc_peer; /* owning peer */ - struct ksock_route *ksnc_route; /* owning route */ - struct list_head ksnc_list; /* stash on peer's conn list */ - struct socket *ksnc_sock; /* actual socket */ - void *ksnc_saved_data_ready; /* socket's original data_ready() callback */ - void *ksnc_saved_write_space; /* socket's original write_space() callback */ - atomic_t ksnc_conn_refcount; /* conn refcount */ - atomic_t ksnc_sock_refcount; /* sock refcount */ - ksock_sched_t *ksnc_scheduler; /* who schedules this connection */ - __u32 ksnc_myipaddr; /* my IP */ - __u32 ksnc_ipaddr; /* peer's IP */ - int ksnc_port; /* peer's port */ - signed int ksnc_type:3; /* type of connection, - * should be signed value */ - unsigned int ksnc_closing:1; /* being shut down */ - unsigned int ksnc_flip:1; /* flip or not, only for V2.x */ - unsigned int ksnc_zc_capable:1; /* enable to ZC */ - struct ksock_proto *ksnc_proto; /* protocol for the connection */ + struct ksock_peer *ksnc_peer; /* owning peer */ + struct ksock_route *ksnc_route; /* owning route */ + struct list_head ksnc_list; /* stash on peer's conn list */ + struct socket *ksnc_sock; /* actual socket */ + void *ksnc_saved_data_ready; /* socket's original + * data_ready() callback */ + void *ksnc_saved_write_space; /* socket's original + * write_space() callback */ + atomic_t ksnc_conn_refcount;/* conn refcount */ + atomic_t ksnc_sock_refcount;/* sock refcount */ + ksock_sched_t *ksnc_scheduler; /* who schedules this connection + */ + __u32 ksnc_myipaddr; /* my IP */ + __u32 ksnc_ipaddr; /* peer's IP */ + int ksnc_port; /* peer's port */ + signed int ksnc_type:3; /* type of connection, should be + * signed value */ + unsigned int ksnc_closing:1; /* being shut down */ + unsigned int ksnc_flip:1; /* flip or not, only for V2.x */ + unsigned int ksnc_zc_capable:1; /* enable to ZC */ + struct ksock_proto *ksnc_proto; /* protocol for the connection */ /* reader */ - struct list_head ksnc_rx_list; /* where I enq waiting input or a forwarding descriptor */ - unsigned long ksnc_rx_deadline; /* when (in jiffies) receive times out */ - __u8 ksnc_rx_started; /* started receiving a message */ - __u8 ksnc_rx_ready; /* data ready to read */ - __u8 ksnc_rx_scheduled;/* being progressed */ - __u8 ksnc_rx_state; /* what is being read */ - int ksnc_rx_nob_left; /* # bytes to next hdr/body */ - int ksnc_rx_nob_wanted; /* bytes actually wanted */ - int ksnc_rx_niov; /* # iovec frags */ - struct kvec *ksnc_rx_iov; /* the iovec frags */ - int ksnc_rx_nkiov; /* # page frags */ - lnet_kiov_t *ksnc_rx_kiov; /* the page frags */ - ksock_rxiovspace_t ksnc_rx_iov_space;/* space for frag descriptors */ - __u32 ksnc_rx_csum; /* partial checksum for incoming data */ - void *ksnc_cookie; /* rx lnet_finalize passthru arg */ - ksock_msg_t ksnc_msg; /* incoming message buffer: - * V2.x message takes the - * whole struct - * V1.x message is a bare - * lnet_hdr_t, it's stored in - * ksnc_msg.ksm_u.lnetmsg */ + struct list_head ksnc_rx_list; /* where I enq waiting input or a + * forwarding descriptor */ + unsigned long ksnc_rx_deadline; /* when (in jiffies) receive times + * out */ + __u8 ksnc_rx_started; /* started receiving a message */ + __u8 ksnc_rx_ready; /* data ready to read */ + __u8 ksnc_rx_scheduled; /* being progressed */ + __u8 ksnc_rx_state; /* what is being read */ + int ksnc_rx_nob_left; /* # bytes to next hdr/body */ + int ksnc_rx_nob_wanted;/* bytes actually wanted */ + int ksnc_rx_niov; /* # iovec frags */ + struct kvec *ksnc_rx_iov; /* the iovec frags */ + int ksnc_rx_nkiov; /* # page frags */ + lnet_kiov_t *ksnc_rx_kiov; /* the page frags */ + ksock_rxiovspace_t ksnc_rx_iov_space; /* space for frag descriptors */ + __u32 ksnc_rx_csum; /* partial checksum for incoming + * data */ + void *ksnc_cookie; /* rx lnet_finalize passthru arg + */ + ksock_msg_t ksnc_msg; /* incoming message buffer: + * V2.x message takes the + * whole struct + * V1.x message is a bare + * lnet_hdr_t, it's stored in + * ksnc_msg.ksm_u.lnetmsg */ /* WRITER */ - struct list_head ksnc_tx_list; /* where I enq waiting for output space */ - struct list_head ksnc_tx_queue; /* packets waiting to be sent */ - ksock_tx_t *ksnc_tx_carrier; /* next TX that can carry a LNet message or ZC-ACK */ - unsigned long ksnc_tx_deadline; /* when (in jiffies) tx times out */ - int ksnc_tx_bufnob; /* send buffer marker */ - atomic_t ksnc_tx_nob; /* # bytes queued */ - int ksnc_tx_ready; /* write space */ - int ksnc_tx_scheduled; /* being progressed */ - unsigned long ksnc_tx_last_post; /* time stamp of the last posted TX */ + struct list_head ksnc_tx_list; /* where I enq waiting for output + * space */ + struct list_head ksnc_tx_queue; /* packets waiting to be sent */ + ksock_tx_t *ksnc_tx_carrier; /* next TX that can carry a LNet + * message or ZC-ACK */ + unsigned long ksnc_tx_deadline; /* when (in jiffies) tx times out + */ + int ksnc_tx_bufnob; /* send buffer marker */ + atomic_t ksnc_tx_nob; /* # bytes queued */ + int ksnc_tx_ready; /* write space */ + int ksnc_tx_scheduled; /* being progressed */ + unsigned long ksnc_tx_last_post; /* time stamp of the last posted + * TX */ } ksock_conn_t; typedef struct ksock_route { - struct list_head ksnr_list; /* chain on peer route list */ - struct list_head ksnr_connd_list; /* chain on ksnr_connd_routes */ - struct ksock_peer *ksnr_peer; /* owning peer */ - atomic_t ksnr_refcount; /* # users */ - unsigned long ksnr_timeout; /* when (in jiffies) reconnection can happen next */ - long ksnr_retry_interval; /* how long between retries */ - __u32 ksnr_myipaddr; /* my IP */ - __u32 ksnr_ipaddr; /* IP address to connect to */ - int ksnr_port; /* port to connect to */ - unsigned int ksnr_scheduled:1; /* scheduled for attention */ - unsigned int ksnr_connecting:1;/* connection establishment in progress */ - unsigned int ksnr_connected:4; /* connections established by type */ - unsigned int ksnr_deleted:1; /* been removed from peer? */ - unsigned int ksnr_share_count; /* created explicitly? */ - int ksnr_conn_count; /* # conns established by this route */ + struct list_head ksnr_list; /* chain on peer route list */ + struct list_head ksnr_connd_list; /* chain on ksnr_connd_routes */ + struct ksock_peer *ksnr_peer; /* owning peer */ + atomic_t ksnr_refcount; /* # users */ + unsigned long ksnr_timeout; /* when (in jiffies) reconnection + * can happen next */ + long ksnr_retry_interval; /* how long between retries */ + __u32 ksnr_myipaddr; /* my IP */ + __u32 ksnr_ipaddr; /* IP address to connect to */ + int ksnr_port; /* port to connect to */ + unsigned int ksnr_scheduled:1; /* scheduled for attention */ + unsigned int ksnr_connecting:1; /* connection establishment in + * progress */ + unsigned int ksnr_connected:4; /* connections established by + * type */ + unsigned int ksnr_deleted:1; /* been removed from peer? */ + unsigned int ksnr_share_count; /* created explicitly? */ + int ksnr_conn_count; /* # conns established by this + * route */ } ksock_route_t; -#define SOCKNAL_KEEPALIVE_PING 1 /* cookie for keepalive ping */ +#define SOCKNAL_KEEPALIVE_PING 1 /* cookie for keepalive ping */ typedef struct ksock_peer { - struct list_head ksnp_list; /* stash on global peer list */ - unsigned long ksnp_last_alive; /* when (in jiffies) I was last alive */ - lnet_process_id_t ksnp_id; /* who's on the other end(s) */ - atomic_t ksnp_refcount; /* # users */ - int ksnp_sharecount; /* lconf usage counter */ - int ksnp_closing; /* being closed */ - int ksnp_accepting;/* # passive connections pending */ - int ksnp_error; /* errno on closing last conn */ - __u64 ksnp_zc_next_cookie;/* ZC completion cookie */ - __u64 ksnp_incarnation; /* latest known peer incarnation */ - struct ksock_proto *ksnp_proto; /* latest known peer protocol */ - struct list_head ksnp_conns; /* all active connections */ - struct list_head ksnp_routes; /* routes */ - struct list_head ksnp_tx_queue; /* waiting packets */ - spinlock_t ksnp_lock; /* serialize, g_lock unsafe */ - struct list_head ksnp_zc_req_list; /* zero copy requests wait for ACK */ - unsigned long ksnp_send_keepalive; /* time to send keepalive */ - lnet_ni_t *ksnp_ni; /* which network */ - int ksnp_n_passive_ips; /* # of... */ - __u32 ksnp_passive_ips[LNET_MAX_INTERFACES]; /* preferred local interfaces */ + struct list_head ksnp_list; /* stash on global peer list */ + unsigned long ksnp_last_alive; /* when (in jiffies) I was last + * alive */ + lnet_process_id_t ksnp_id; /* who's on the other end(s) */ + atomic_t ksnp_refcount; /* # users */ + int ksnp_sharecount; /* lconf usage counter */ + int ksnp_closing; /* being closed */ + int ksnp_accepting; /* # passive connections pending + */ + int ksnp_error; /* errno on closing last conn */ + __u64 ksnp_zc_next_cookie; /* ZC completion cookie */ + __u64 ksnp_incarnation; /* latest known peer incarnation + */ + struct ksock_proto *ksnp_proto; /* latest known peer protocol */ + struct list_head ksnp_conns; /* all active connections */ + struct list_head ksnp_routes; /* routes */ + struct list_head ksnp_tx_queue; /* waiting packets */ + spinlock_t ksnp_lock; /* serialize, g_lock unsafe */ + struct list_head ksnp_zc_req_list; /* zero copy requests wait for + * ACK */ + unsigned long ksnp_send_keepalive; /* time to send keepalive */ + lnet_ni_t *ksnp_ni; /* which network */ + int ksnp_n_passive_ips; /* # of... */ + + /* preferred local interfaces */ + __u32 ksnp_passive_ips[LNET_MAX_INTERFACES]; } ksock_peer_t; typedef struct ksock_connreq { - struct list_head ksncr_list; /* stash on ksnd_connd_connreqs */ - lnet_ni_t *ksncr_ni; /* chosen NI */ - struct socket *ksncr_sock; /* accepted socket */ + struct list_head ksncr_list; /* stash on ksnd_connd_connreqs */ + lnet_ni_t *ksncr_ni; /* chosen NI */ + struct socket *ksncr_sock; /* accepted socket */ } ksock_connreq_t; extern ksock_nal_data_t ksocknal_data; extern ksock_tunables_t ksocknal_tunables; -#define SOCKNAL_MATCH_NO 0 /* TX can't match type of connection */ -#define SOCKNAL_MATCH_YES 1 /* TX matches type of connection */ -#define SOCKNAL_MATCH_MAY 2 /* TX can be sent on the connection, but not preferred */ +#define SOCKNAL_MATCH_NO 0 /* TX can't match type of connection */ +#define SOCKNAL_MATCH_YES 1 /* TX matches type of connection */ +#define SOCKNAL_MATCH_MAY 2 /* TX can be sent on the connection, but not + * preferred */ typedef struct ksock_proto { - int pro_version; /* version number of protocol */ - int (*pro_send_hello)(ksock_conn_t *, ksock_hello_msg_t *); /* handshake function */ - int (*pro_recv_hello)(ksock_conn_t *, ksock_hello_msg_t *, int);/* handshake function */ - void (*pro_pack)(ksock_tx_t *); /* message pack */ - void (*pro_unpack)(ksock_msg_t *); /* message unpack */ - ksock_tx_t *(*pro_queue_tx_msg)(ksock_conn_t *, ksock_tx_t *); /* queue tx on the connection */ - int (*pro_queue_tx_zcack)(ksock_conn_t *, ksock_tx_t *, __u64); /* queue ZC ack on the connection */ - int (*pro_handle_zcreq)(ksock_conn_t *, __u64, int); /* handle ZC request */ - int (*pro_handle_zcack)(ksock_conn_t *, __u64, __u64); /* handle ZC ACK */ - int (*pro_match_tx)(ksock_conn_t *, ksock_tx_t *, int); /* msg type matches the connection type: - * return value: - * return MATCH_NO : no - * return MATCH_YES : matching type - * return MATCH_MAY : can be backup */ + /* version number of protocol */ + int pro_version; + + /* handshake function */ + int (*pro_send_hello)(ksock_conn_t *, ksock_hello_msg_t *); + + /* handshake function */ + int (*pro_recv_hello)(ksock_conn_t *, ksock_hello_msg_t *, int); + + /* message pack */ + void (*pro_pack)(ksock_tx_t *); + + /* message unpack */ + void (*pro_unpack)(ksock_msg_t *); + + /* queue tx on the connection */ + ksock_tx_t *(*pro_queue_tx_msg)(ksock_conn_t *, ksock_tx_t *); + + /* queue ZC ack on the connection */ + int (*pro_queue_tx_zcack)(ksock_conn_t *, ksock_tx_t *, __u64); + + /* handle ZC request */ + int (*pro_handle_zcreq)(ksock_conn_t *, __u64, int); + + /* handle ZC ACK */ + int (*pro_handle_zcack)(ksock_conn_t *, __u64, __u64); + + /* msg type matches the connection type: + * return value: + * return MATCH_NO : no + * return MATCH_YES : matching type + * return MATCH_MAY : can be backup */ + int (*pro_match_tx)(ksock_conn_t *, ksock_tx_t *, int); } ksock_proto_t; extern ksock_proto_t ksocknal_protocol_v1x; extern ksock_proto_t ksocknal_protocol_v2x; extern ksock_proto_t ksocknal_protocol_v3x; -#define KSOCK_PROTO_V1_MAJOR LNET_PROTO_TCP_VERSION_MAJOR -#define KSOCK_PROTO_V1_MINOR LNET_PROTO_TCP_VERSION_MINOR -#define KSOCK_PROTO_V1 KSOCK_PROTO_V1_MAJOR +#define KSOCK_PROTO_V1_MAJOR LNET_PROTO_TCP_VERSION_MAJOR +#define KSOCK_PROTO_V1_MINOR LNET_PROTO_TCP_VERSION_MINOR +#define KSOCK_PROTO_V1 KSOCK_PROTO_V1_MAJOR #ifndef CPU_MASK_NONE #define CPU_MASK_NONE 0UL @@ -434,7 +500,7 @@ ksocknal_conn_decref(ksock_conn_t *conn) static inline int ksocknal_connsock_addref(ksock_conn_t *conn) { - int rc = -ESHUTDOWN; + int rc = -ESHUTDOWN; read_lock(&ksocknal_data.ksnd_global_lock); if (!conn->ksnc_closing) { @@ -453,7 +519,7 @@ ksocknal_connsock_decref(ksock_conn_t *conn) LASSERT(atomic_read(&conn->ksnc_sock_refcount) > 0); if (atomic_dec_and_test(&conn->ksnc_sock_refcount)) { LASSERT(conn->ksnc_closing); - libcfs_sock_release(conn->ksnc_sock); + sock_release(conn->ksnc_sock); conn->ksnc_sock = NULL; ksocknal_finalize_zcreq(conn); } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index fa7ad883bda9..fe2a83a540cd 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -75,13 +75,13 @@ ksocknal_alloc_tx_noop(__u64 cookie, int nonblk) return NULL; } - tx->tx_conn = NULL; - tx->tx_lnetmsg = NULL; - tx->tx_kiov = NULL; - tx->tx_nkiov = 0; - tx->tx_iov = tx->tx_frags.virt.iov; - tx->tx_niov = 1; - tx->tx_nonblk = nonblk; + tx->tx_conn = NULL; + tx->tx_lnetmsg = NULL; + tx->tx_kiov = NULL; + tx->tx_nkiov = 0; + tx->tx_iov = tx->tx_frags.virt.iov; + tx->tx_niov = 1; + tx->tx_nonblk = nonblk; socklnd_init_msg(&tx->tx_msg, KSOCK_MSG_NOOP); tx->tx_msg.ksm_zc_cookies[1] = cookie; @@ -110,11 +110,11 @@ ksocknal_free_tx (ksock_tx_t *tx) static int ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx) { - struct kvec *iov = tx->tx_iov; - int nob; - int rc; + struct kvec *iov = tx->tx_iov; + int nob; + int rc; - LASSERT (tx->tx_niov > 0); + LASSERT(tx->tx_niov > 0); /* Never touch tx->tx_iov inside ksocknal_lib_send_iov() */ rc = ksocknal_lib_send_iov(conn, tx); @@ -128,7 +128,7 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx) /* "consume" iov */ do { - LASSERT (tx->tx_niov > 0); + LASSERT(tx->tx_niov > 0); if (nob < (int) iov->iov_len) { iov->iov_base = (void *)((char *)iov->iov_base + nob); @@ -147,12 +147,12 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx) static int ksocknal_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx) { - lnet_kiov_t *kiov = tx->tx_kiov; - int nob; - int rc; + lnet_kiov_t *kiov = tx->tx_kiov; + int nob; + int rc; - LASSERT (tx->tx_niov == 0); - LASSERT (tx->tx_nkiov > 0); + LASSERT(tx->tx_niov == 0); + LASSERT(tx->tx_nkiov > 0); /* Never touch tx->tx_kiov inside ksocknal_lib_send_kiov() */ rc = ksocknal_lib_send_kiov(conn, tx); @@ -185,15 +185,15 @@ ksocknal_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx) static int ksocknal_transmit (ksock_conn_t *conn, ksock_tx_t *tx) { - int rc; - int bufnob; + int rc; + int bufnob; if (ksocknal_data.ksnd_stall_tx != 0) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(cfs_time_seconds(ksocknal_data.ksnd_stall_tx)); } - LASSERT (tx->tx_resid != 0); + LASSERT(tx->tx_resid != 0); rc = ksocknal_connsock_addref(conn); if (rc != 0) { @@ -252,10 +252,10 @@ static int ksocknal_recv_iov (ksock_conn_t *conn) { struct kvec *iov = conn->ksnc_rx_iov; - int nob; - int rc; + int nob; + int rc; - LASSERT (conn->ksnc_rx_niov > 0); + LASSERT(conn->ksnc_rx_niov > 0); /* Never touch conn->ksnc_rx_iov or change connection * status inside ksocknal_lib_recv_iov */ @@ -277,7 +277,7 @@ ksocknal_recv_iov (ksock_conn_t *conn) conn->ksnc_rx_nob_left -= nob; do { - LASSERT (conn->ksnc_rx_niov > 0); + LASSERT(conn->ksnc_rx_niov > 0); if (nob < (int)iov->iov_len) { iov->iov_len -= nob; @@ -296,10 +296,10 @@ ksocknal_recv_iov (ksock_conn_t *conn) static int ksocknal_recv_kiov (ksock_conn_t *conn) { - lnet_kiov_t *kiov = conn->ksnc_rx_kiov; - int nob; - int rc; - LASSERT (conn->ksnc_rx_nkiov > 0); + lnet_kiov_t *kiov = conn->ksnc_rx_kiov; + int nob; + int rc; + LASSERT(conn->ksnc_rx_nkiov > 0); /* Never touch conn->ksnc_rx_kiov or change connection * status inside ksocknal_lib_recv_iov */ @@ -321,7 +321,7 @@ ksocknal_recv_kiov (ksock_conn_t *conn) conn->ksnc_rx_nob_left -= nob; do { - LASSERT (conn->ksnc_rx_nkiov > 0); + LASSERT(conn->ksnc_rx_nkiov > 0); if (nob < (int) kiov->kiov_len) { kiov->kiov_offset += nob; @@ -343,7 +343,7 @@ ksocknal_receive (ksock_conn_t *conn) /* Return 1 on success, 0 on EOF, < 0 on error. * Caller checks ksnc_rx_nob_wanted to determine * progress/completion. */ - int rc; + int rc; if (ksocknal_data.ksnd_stall_rx != 0) { set_current_state(TASK_UNINTERRUPTIBLE); @@ -388,8 +388,8 @@ ksocknal_receive (ksock_conn_t *conn) void ksocknal_tx_done (lnet_ni_t *ni, ksock_tx_t *tx) { - lnet_msg_t *lnetmsg = tx->tx_lnetmsg; - int rc = (tx->tx_resid == 0 && !tx->tx_zc_aborted) ? 0 : -EIO; + lnet_msg_t *lnetmsg = tx->tx_lnetmsg; + int rc = (tx->tx_resid == 0 && !tx->tx_zc_aborted) ? 0 : -EIO; LASSERT(ni != NULL || tx->tx_conn != NULL); @@ -410,7 +410,7 @@ ksocknal_txlist_done (lnet_ni_t *ni, struct list_head *txlist, int error) ksock_tx_t *tx; while (!list_empty (txlist)) { - tx = list_entry (txlist->next, ksock_tx_t, tx_list); + tx = list_entry(txlist->next, ksock_tx_t, tx_list); if (error && tx->tx_lnetmsg != NULL) { CNETERR("Deleting packet type %d len %d %s->%s\n", @@ -422,18 +422,18 @@ ksocknal_txlist_done (lnet_ni_t *ni, struct list_head *txlist, int error) CNETERR("Deleting noop packet\n"); } - list_del (&tx->tx_list); + list_del(&tx->tx_list); - LASSERT (atomic_read(&tx->tx_refcount) == 1); - ksocknal_tx_done (ni, tx); + LASSERT(atomic_read(&tx->tx_refcount) == 1); + ksocknal_tx_done(ni, tx); } } static void ksocknal_check_zc_req(ksock_tx_t *tx) { - ksock_conn_t *conn = tx->tx_conn; - ksock_peer_t *peer = conn->ksnc_peer; + ksock_conn_t *conn = tx->tx_conn; + ksock_peer_t *peer = conn->ksnc_peer; /* Set tx_msg.ksm_zc_cookies[0] to a unique non-zero cookie and add tx * to ksnp_zc_req_list if some fragment of this message should be sent @@ -441,8 +441,8 @@ ksocknal_check_zc_req(ksock_tx_t *tx) * she has received this message to tell us we can signal completion. * tx_msg.ksm_zc_cookies[0] remains non-zero while tx is on * ksnp_zc_req_list. */ - LASSERT (tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); - LASSERT (tx->tx_zc_capable); + LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); + LASSERT(tx->tx_zc_capable); tx->tx_zc_checked = 1; @@ -461,7 +461,7 @@ ksocknal_check_zc_req(ksock_tx_t *tx) tx->tx_deadline = cfs_time_shift(*ksocknal_tunables.ksnd_timeout); - LASSERT (tx->tx_msg.ksm_zc_cookies[0] == 0); + LASSERT(tx->tx_msg.ksm_zc_cookies[0] == 0); tx->tx_msg.ksm_zc_cookies[0] = peer->ksnp_zc_next_cookie++; @@ -476,7 +476,7 @@ ksocknal_check_zc_req(ksock_tx_t *tx) static void ksocknal_uncheck_zc_req(ksock_tx_t *tx) { - ksock_peer_t *peer = tx->tx_conn->ksnc_peer; + ksock_peer_t *peer = tx->tx_conn->ksnc_peer; LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); LASSERT(tx->tx_zc_capable); @@ -502,14 +502,14 @@ ksocknal_uncheck_zc_req(ksock_tx_t *tx) static int ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx) { - int rc; + int rc; if (tx->tx_zc_capable && !tx->tx_zc_checked) ksocknal_check_zc_req(tx); rc = ksocknal_transmit (conn, tx); - CDEBUG (D_NET, "send(%d) %d\n", tx->tx_resid, rc); + CDEBUG(D_NET, "send(%d) %d\n", tx->tx_resid, rc); if (tx->tx_resid == 0) { /* Sent everything OK */ @@ -546,7 +546,7 @@ ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx) } /* Actual error */ - LASSERT (rc < 0); + LASSERT(rc < 0); if (!conn->ksnc_closing) { switch (rc) { @@ -582,9 +582,9 @@ ksocknal_launch_connection_locked (ksock_route_t *route) /* called holding write lock on ksnd_global_lock */ - LASSERT (!route->ksnr_scheduled); - LASSERT (!route->ksnr_connecting); - LASSERT ((ksocknal_route_mask() & ~route->ksnr_connected) != 0); + LASSERT(!route->ksnr_scheduled); + LASSERT(!route->ksnr_connecting); + LASSERT((ksocknal_route_mask() & ~route->ksnr_connected) != 0); route->ksnr_scheduled = 1; /* scheduling conn for connd */ ksocknal_route_addref(route); /* extra ref for connd */ @@ -617,22 +617,22 @@ ksocknal_launch_all_connections_locked (ksock_peer_t *peer) ksock_conn_t * ksocknal_find_conn_locked(ksock_peer_t *peer, ksock_tx_t *tx, int nonblk) { - struct list_head *tmp; - ksock_conn_t *conn; - ksock_conn_t *typed = NULL; - ksock_conn_t *fallback = NULL; - int tnob = 0; - int fnob = 0; + struct list_head *tmp; + ksock_conn_t *conn; + ksock_conn_t *typed = NULL; + ksock_conn_t *fallback = NULL; + int tnob = 0; + int fnob = 0; list_for_each (tmp, &peer->ksnp_conns) { ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list); - int nob = atomic_read(&c->ksnc_tx_nob) + - c->ksnc_sock->sk->sk_wmem_queued; - int rc; + int nob = atomic_read(&c->ksnc_tx_nob) + + c->ksnc_sock->sk->sk_wmem_queued; + int rc; - LASSERT (!c->ksnc_closing); - LASSERT (c->ksnc_proto != NULL && - c->ksnc_proto->pro_match_tx != NULL); + LASSERT(!c->ksnc_closing); + LASSERT(c->ksnc_proto != NULL && + c->ksnc_proto->pro_match_tx != NULL); rc = c->ksnc_proto->pro_match_tx(c, tx, nonblk); @@ -656,7 +656,7 @@ ksocknal_find_conn_locked(ksock_peer_t *peer, ksock_tx_t *tx, int nonblk) (fnob == nob && *ksocknal_tunables.ksnd_round_robin && cfs_time_after(fallback->ksnc_tx_last_post, c->ksnc_tx_last_post))) { fallback = c; - fnob = nob; + fnob = nob; } break; } @@ -685,9 +685,9 @@ void ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn) { ksock_sched_t *sched = conn->ksnc_scheduler; - ksock_msg_t *msg = &tx->tx_msg; - ksock_tx_t *ztx = NULL; - int bufnob = 0; + ksock_msg_t *msg = &tx->tx_msg; + ksock_tx_t *ztx = NULL; + int bufnob = 0; /* called holding global lock (read or irq-write) and caller may * not have dropped this lock between finding conn and calling me, @@ -708,11 +708,11 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn) * * We always expect at least 1 mapped fragment containing the * complete ksocknal message header. */ - LASSERT (lnet_iov_nob (tx->tx_niov, tx->tx_iov) + - lnet_kiov_nob(tx->tx_nkiov, tx->tx_kiov) == - (unsigned int)tx->tx_nob); - LASSERT (tx->tx_niov >= 1); - LASSERT (tx->tx_resid == tx->tx_nob); + LASSERT(lnet_iov_nob (tx->tx_niov, tx->tx_iov) + + lnet_kiov_nob(tx->tx_nkiov, tx->tx_kiov) == + (unsigned int)tx->tx_nob); + LASSERT(tx->tx_niov >= 1); + LASSERT(tx->tx_resid == tx->tx_nob); CDEBUG (D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n", tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type: @@ -739,8 +739,8 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn) if (msg->ksm_type == KSOCK_MSG_NOOP) { /* The packet is noop ZC ACK, try to piggyback the ack_cookie * on a normal packet so I don't need to send it */ - LASSERT (msg->ksm_zc_cookies[1] != 0); - LASSERT (conn->ksnc_proto->pro_queue_tx_zcack != NULL); + LASSERT(msg->ksm_zc_cookies[1] != 0); + LASSERT(conn->ksnc_proto->pro_queue_tx_zcack != NULL); if (conn->ksnc_proto->pro_queue_tx_zcack(conn, tx, 0)) ztx = tx; /* ZC ACK piggybacked on ztx release tx later */ @@ -748,8 +748,8 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn) } else { /* It's a normal packet - can it piggback a noop zc-ack that * has been queued already? */ - LASSERT (msg->ksm_zc_cookies[1] == 0); - LASSERT (conn->ksnc_proto->pro_queue_tx_msg != NULL); + LASSERT(msg->ksm_zc_cookies[1] == 0); + LASSERT(conn->ksnc_proto->pro_queue_tx_msg != NULL); ztx = conn->ksnc_proto->pro_queue_tx_msg(conn, tx); /* ztx will be released later */ @@ -777,14 +777,14 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn) ksock_route_t * ksocknal_find_connectable_route_locked (ksock_peer_t *peer) { - unsigned long now = cfs_time_current(); - struct list_head *tmp; + unsigned long now = cfs_time_current(); + struct list_head *tmp; ksock_route_t *route; list_for_each (tmp, &peer->ksnp_routes) { route = list_entry (tmp, ksock_route_t, ksnr_list); - LASSERT (!route->ksnr_connecting || route->ksnr_scheduled); + LASSERT(!route->ksnr_connecting || route->ksnr_scheduled); if (route->ksnr_scheduled) /* connections being established */ continue; @@ -813,13 +813,13 @@ ksocknal_find_connectable_route_locked (ksock_peer_t *peer) ksock_route_t * ksocknal_find_connecting_route_locked (ksock_peer_t *peer) { - struct list_head *tmp; - ksock_route_t *route; + struct list_head *tmp; + ksock_route_t *route; list_for_each (tmp, &peer->ksnp_routes) { route = list_entry (tmp, ksock_route_t, ksnr_list); - LASSERT (!route->ksnr_connecting || route->ksnr_scheduled); + LASSERT(!route->ksnr_connecting || route->ksnr_scheduled); if (route->ksnr_scheduled) return route; @@ -831,13 +831,13 @@ ksocknal_find_connecting_route_locked (ksock_peer_t *peer) int ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id) { - ksock_peer_t *peer; - ksock_conn_t *conn; - rwlock_t *g_lock; - int retry; - int rc; + ksock_peer_t *peer; + ksock_conn_t *conn; + rwlock_t *g_lock; + int retry; + int rc; - LASSERT (tx->tx_conn == NULL); + LASSERT(tx->tx_conn == NULL); g_lock = &ksocknal_data.ksnd_global_lock; @@ -922,17 +922,17 @@ ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id) int ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) { - int mpflag = 1; - int type = lntmsg->msg_type; + int mpflag = 1; + int type = lntmsg->msg_type; lnet_process_id_t target = lntmsg->msg_target; - unsigned int payload_niov = lntmsg->msg_niov; - struct kvec *payload_iov = lntmsg->msg_iov; - lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; - unsigned int payload_offset = lntmsg->msg_offset; - unsigned int payload_nob = lntmsg->msg_len; - ksock_tx_t *tx; - int desc_size; - int rc; + unsigned int payload_niov = lntmsg->msg_niov; + struct kvec *payload_iov = lntmsg->msg_iov; + lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; + unsigned int payload_offset = lntmsg->msg_offset; + unsigned int payload_nob = lntmsg->msg_len; + ksock_tx_t *tx; + int desc_size; + int rc; /* NB 'private' is different depending on what we're sending. * Just ignore it... */ @@ -940,8 +940,8 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) CDEBUG(D_NET, "sending %u bytes in %d frags to %s\n", payload_nob, payload_niov, libcfs_id2str(target)); - LASSERT (payload_nob == 0 || payload_niov > 0); - LASSERT (payload_niov <= LNET_MAX_IOV); + LASSERT(payload_nob == 0 || payload_niov > 0); + LASSERT(payload_niov <= LNET_MAX_IOV); /* payload is either all vaddrs or all pages */ LASSERT (!(payload_kiov != NULL && payload_iov != NULL)); LASSERT (!in_interrupt ()); @@ -1028,9 +1028,9 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip) { static char ksocknal_slop_buffer[4096]; - int nob; - unsigned int niov; - int skipped; + int nob; + unsigned int niov; + int skipped; LASSERT(conn->ksnc_proto != NULL); @@ -1063,7 +1063,7 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip) conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space; conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg; - conn->ksnc_rx_iov[0].iov_len = sizeof (lnet_hdr_t); + conn->ksnc_rx_iov[0].iov_len = sizeof (lnet_hdr_t); break; default: @@ -1108,18 +1108,18 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip) static int ksocknal_process_receive (ksock_conn_t *conn) { - lnet_hdr_t *lhdr; + lnet_hdr_t *lhdr; lnet_process_id_t *id; - int rc; + int rc; LASSERT (atomic_read(&conn->ksnc_conn_refcount) > 0); /* NB: sched lock NOT held */ /* SOCKNAL_RX_LNET_HEADER is here for backward compatibility */ - LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_KSM_HEADER || - conn->ksnc_rx_state == SOCKNAL_RX_LNET_PAYLOAD || - conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER || - conn->ksnc_rx_state == SOCKNAL_RX_SLOP); + LASSERT(conn->ksnc_rx_state == SOCKNAL_RX_KSM_HEADER || + conn->ksnc_rx_state == SOCKNAL_RX_LNET_PAYLOAD || + conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER || + conn->ksnc_rx_state == SOCKNAL_RX_SLOP); again: if (conn->ksnc_rx_nob_wanted != 0) { rc = ksocknal_receive(conn); @@ -1229,7 +1229,7 @@ ksocknal_process_receive (ksock_conn_t *conn) if ((conn->ksnc_peer->ksnp_id.pid & LNET_PID_USERFLAG) != 0) { /* Userspace peer */ lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr; - id = &conn->ksnc_peer->ksnp_id; + id = &conn->ksnc_peer->ksnp_id; /* Substitute process ID assigned at connection time */ lhdr->src_pid = cpu_to_le32(id->pid); @@ -1277,7 +1277,7 @@ ksocknal_process_receive (ksock_conn_t *conn) LASSERT(conn->ksnc_proto != &ksocknal_protocol_v1x); lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr; - id = &conn->ksnc_peer->ksnp_id; + id = &conn->ksnc_peer->ksnp_id; rc = conn->ksnc_proto->pro_handle_zcreq(conn, conn->ksnc_msg.ksm_zc_cookies[0], @@ -1305,7 +1305,7 @@ ksocknal_process_receive (ksock_conn_t *conn) } /* Not Reached */ - LBUG (); + LBUG(); return -EINVAL; /* keep gcc happy */ } @@ -1314,15 +1314,15 @@ ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov, unsigned int offset, unsigned int mlen, unsigned int rlen) { - ksock_conn_t *conn = (ksock_conn_t *)private; + ksock_conn_t *conn = (ksock_conn_t *)private; ksock_sched_t *sched = conn->ksnc_scheduler; - LASSERT (mlen <= rlen); - LASSERT (niov <= LNET_MAX_IOV); + LASSERT(mlen <= rlen); + LASSERT(niov <= LNET_MAX_IOV); conn->ksnc_cookie = msg; conn->ksnc_rx_nob_wanted = mlen; - conn->ksnc_rx_nob_left = rlen; + conn->ksnc_rx_nob_left = rlen; if (mlen == 0 || iov != NULL) { conn->ksnc_rx_nkiov = 0; @@ -1333,18 +1333,18 @@ ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, niov, iov, offset, mlen); } else { conn->ksnc_rx_niov = 0; - conn->ksnc_rx_iov = NULL; + conn->ksnc_rx_iov = NULL; conn->ksnc_rx_kiov = conn->ksnc_rx_iov_space.kiov; conn->ksnc_rx_nkiov = lnet_extract_kiov(LNET_MAX_IOV, conn->ksnc_rx_kiov, niov, kiov, offset, mlen); } - LASSERT (mlen == - lnet_iov_nob (conn->ksnc_rx_niov, conn->ksnc_rx_iov) + - lnet_kiov_nob (conn->ksnc_rx_nkiov, conn->ksnc_rx_kiov)); + LASSERT(mlen == + lnet_iov_nob(conn->ksnc_rx_niov, conn->ksnc_rx_iov) + + lnet_kiov_nob(conn->ksnc_rx_nkiov, conn->ksnc_rx_kiov)); - LASSERT (conn->ksnc_rx_scheduled); + LASSERT(conn->ksnc_rx_scheduled); spin_lock_bh(&sched->kss_lock); @@ -1370,7 +1370,7 @@ ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, static inline int ksocknal_sched_cansleep(ksock_sched_t *sched) { - int rc; + int rc; spin_lock_bh(&sched->kss_lock); @@ -1384,13 +1384,13 @@ ksocknal_sched_cansleep(ksock_sched_t *sched) int ksocknal_scheduler(void *arg) { - struct ksock_sched_info *info; - ksock_sched_t *sched; - ksock_conn_t *conn; - ksock_tx_t *tx; - int rc; - int nloops = 0; - long id = (long)arg; + struct ksock_sched_info *info; + ksock_sched_t *sched; + ksock_conn_t *conn; + ksock_tx_t *tx; + int rc; + int nloops = 0; + long id = (long)arg; info = ksocknal_data.ksnd_sched_info[KSOCK_THREAD_CPT(id)]; sched = &info->ksi_scheds[KSOCK_THREAD_SID(id)]; @@ -1455,7 +1455,7 @@ int ksocknal_scheduler(void *arg) } if (!list_empty (&sched->kss_tx_conns)) { - LIST_HEAD (zlist); + LIST_HEAD(zlist); if (!list_empty(&sched->kss_zombie_noop_txs)) { list_add(&zlist, @@ -1513,9 +1513,9 @@ int ksocknal_scheduler(void *arg) /* Do nothing; after a short timeout, this * conn will be reposted on kss_tx_conns. */ } else if (conn->ksnc_tx_ready && - !list_empty (&conn->ksnc_tx_queue)) { + !list_empty(&conn->ksnc_tx_queue)) { /* reschedule for tx */ - list_add_tail (&conn->ksnc_tx_list, + list_add_tail(&conn->ksnc_tx_list, &sched->kss_tx_conns); } else { conn->ksnc_tx_scheduled = 0; @@ -1606,7 +1606,7 @@ void ksocknal_write_callback (ksock_conn_t *conn) static ksock_proto_t * ksocknal_parse_proto_version (ksock_hello_msg_t *hello) { - __u32 version = 0; + __u32 version = 0; if (hello->kshm_magic == LNET_PROTO_MAGIC) version = hello->kshm_version; @@ -1634,8 +1634,8 @@ ksocknal_parse_proto_version (ksock_hello_msg_t *hello) if (hello->kshm_magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) { lnet_magicversion_t *hmv = (lnet_magicversion_t *)hello; - CLASSERT (sizeof (lnet_magicversion_t) == - offsetof (ksock_hello_msg_t, kshm_src_nid)); + CLASSERT(sizeof (lnet_magicversion_t) == + offsetof (ksock_hello_msg_t, kshm_src_nid)); if (hmv->version_major == cpu_to_le16 (KSOCK_PROTO_V1_MAJOR) && hmv->version_minor == cpu_to_le16 (KSOCK_PROTO_V1_MINOR)) @@ -1650,19 +1650,19 @@ ksocknal_send_hello (lnet_ni_t *ni, ksock_conn_t *conn, lnet_nid_t peer_nid, ksock_hello_msg_t *hello) { /* CAVEAT EMPTOR: this byte flips 'ipaddrs' */ - ksock_net_t *net = (ksock_net_t *)ni->ni_data; + ksock_net_t *net = (ksock_net_t *)ni->ni_data; - LASSERT (hello->kshm_nips <= LNET_MAX_INTERFACES); + LASSERT(hello->kshm_nips <= LNET_MAX_INTERFACES); /* rely on caller to hold a ref on socket so it wouldn't disappear */ - LASSERT (conn->ksnc_proto != NULL); + LASSERT(conn->ksnc_proto != NULL); - hello->kshm_src_nid = ni->ni_nid; - hello->kshm_dst_nid = peer_nid; - hello->kshm_src_pid = the_lnet.ln_pid; + hello->kshm_src_nid = ni->ni_nid; + hello->kshm_dst_nid = peer_nid; + hello->kshm_src_pid = the_lnet.ln_pid; hello->kshm_src_incarnation = net->ksnn_incarnation; - hello->kshm_ctype = conn->ksnc_type; + hello->kshm_ctype = conn->ksnc_type; return conn->ksnc_proto->pro_send_hello(conn, hello); } @@ -1693,21 +1693,21 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, * EALREADY lost connection race * EPROTO protocol version mismatch */ - struct socket *sock = conn->ksnc_sock; - int active = (conn->ksnc_proto != NULL); - int timeout; - int proto_match; - int rc; - ksock_proto_t *proto; - lnet_process_id_t recv_id; + struct socket *sock = conn->ksnc_sock; + int active = (conn->ksnc_proto != NULL); + int timeout; + int proto_match; + int rc; + ksock_proto_t *proto; + lnet_process_id_t recv_id; /* socket type set on active connections - not set on passive */ - LASSERT (!active == !(conn->ksnc_type != SOCKLND_CONN_NONE)); + LASSERT(!active == !(conn->ksnc_type != SOCKLND_CONN_NONE)); timeout = active ? *ksocknal_tunables.ksnd_timeout : lnet_acceptor_timeout(); - rc = libcfs_sock_read(sock, &hello->kshm_magic, sizeof (hello->kshm_magic), timeout); + rc = lnet_sock_read(sock, &hello->kshm_magic, sizeof (hello->kshm_magic), timeout); if (rc != 0) { CERROR("Error %d reading HELLO from %pI4h\n", rc, &conn->ksnc_ipaddr); @@ -1726,12 +1726,12 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, return -EPROTO; } - rc = libcfs_sock_read(sock, &hello->kshm_version, - sizeof(hello->kshm_version), timeout); + rc = lnet_sock_read(sock, &hello->kshm_version, + sizeof(hello->kshm_version), timeout); if (rc != 0) { CERROR("Error %d reading HELLO from %pI4h\n", rc, &conn->ksnc_ipaddr); - LASSERT (rc < 0); + LASSERT(rc < 0); return rc; } @@ -1765,7 +1765,7 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, if (rc != 0) { CERROR("Error %d reading or checking hello from from %pI4h\n", rc, &conn->ksnc_ipaddr); - LASSERT (rc < 0); + LASSERT(rc < 0); return rc; } @@ -1830,22 +1830,22 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, static int ksocknal_connect (ksock_route_t *route) { - LIST_HEAD (zombies); - ksock_peer_t *peer = route->ksnr_peer; - int type; - int wanted; - struct socket *sock; - unsigned long deadline; - int retry_later = 0; - int rc = 0; + LIST_HEAD(zombies); + ksock_peer_t *peer = route->ksnr_peer; + int type; + int wanted; + struct socket *sock; + unsigned long deadline; + int retry_later = 0; + int rc = 0; deadline = cfs_time_add(cfs_time_current(), cfs_time_seconds(*ksocknal_tunables.ksnd_timeout)); write_lock_bh(&ksocknal_data.ksnd_global_lock); - LASSERT (route->ksnr_scheduled); - LASSERT (!route->ksnr_connecting); + LASSERT(route->ksnr_scheduled); + LASSERT(!route->ksnr_connecting); route->ksnr_connecting = 1; @@ -2101,7 +2101,7 @@ static ksock_route_t * ksocknal_connd_get_route_locked(signed long *timeout_p) { ksock_route_t *route; - unsigned long now; + unsigned long now; now = cfs_time_current(); @@ -2124,13 +2124,13 @@ ksocknal_connd_get_route_locked(signed long *timeout_p) int ksocknal_connd (void *arg) { - spinlock_t *connd_lock = &ksocknal_data.ksnd_connd_lock; - ksock_connreq_t *cr; - wait_queue_t wait; - int nloops = 0; - int cons_retry = 0; + spinlock_t *connd_lock = &ksocknal_data.ksnd_connd_lock; + ksock_connreq_t *cr; + wait_queue_t wait; + int nloops = 0; + int cons_retry = 0; - cfs_block_allsigs (); + cfs_block_allsigs(); init_waitqueue_entry(&wait, current); @@ -2144,7 +2144,7 @@ ksocknal_connd (void *arg) ksock_route_t *route = NULL; long sec = get_seconds(); long timeout = MAX_SCHEDULE_TIMEOUT; - int dropped_lock = 0; + int dropped_lock = 0; if (ksocknal_connd_check_stop(sec, &timeout)) { /* wakeup another one to check stop */ @@ -2236,15 +2236,15 @@ static ksock_conn_t * ksocknal_find_timed_out_conn (ksock_peer_t *peer) { /* We're called with a shared lock on ksnd_global_lock */ - ksock_conn_t *conn; - struct list_head *ctmp; + ksock_conn_t *conn; + struct list_head *ctmp; list_for_each (ctmp, &peer->ksnp_conns) { - int error; + int error; conn = list_entry (ctmp, ksock_conn_t, ksnc_list); /* Don't need the {get,put}connsock dance to deref ksnc_sock */ - LASSERT (!conn->ksnc_closing); + LASSERT(!conn->ksnc_closing); /* SOCK_ERROR will reset error code of socket in * some platform (like Darwin8.x) */ @@ -2313,8 +2313,8 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) static inline void ksocknal_flush_stale_txs(ksock_peer_t *peer) { - ksock_tx_t *tx; - LIST_HEAD (stale_txs); + ksock_tx_t *tx; + LIST_HEAD(stale_txs); write_lock_bh(&ksocknal_data.ksnd_global_lock); @@ -2338,9 +2338,9 @@ ksocknal_flush_stale_txs(ksock_peer_t *peer) static int ksocknal_send_keepalive_locked(ksock_peer_t *peer) { - ksock_sched_t *sched; - ksock_conn_t *conn; - ksock_tx_t *tx; + ksock_sched_t *sched; + ksock_conn_t *conn; + ksock_tx_t *tx; if (list_empty(&peer->ksnp_conns)) /* last_alive will be updated by create_conn */ return 0; @@ -2399,10 +2399,10 @@ ksocknal_send_keepalive_locked(ksock_peer_t *peer) static void ksocknal_check_peer_timeouts (int idx) { - struct list_head *peers = &ksocknal_data.ksnd_peers[idx]; - ksock_peer_t *peer; - ksock_conn_t *conn; - ksock_tx_t *tx; + struct list_head *peers = &ksocknal_data.ksnd_peers[idx]; + ksock_peer_t *peer; + ksock_conn_t *conn; + ksock_tx_t *tx; again: /* NB. We expect to have a look at all the peers and not find any @@ -2411,9 +2411,9 @@ ksocknal_check_peer_timeouts (int idx) read_lock(&ksocknal_data.ksnd_global_lock); list_for_each_entry(peer, peers, ksnp_list) { - unsigned long deadline = 0; - int resid = 0; - int n = 0; + unsigned long deadline = 0; + int resid = 0; + int n = 0; if (ksocknal_send_keepalive_locked(peer) != 0) { read_unlock(&ksocknal_data.ksnd_global_lock); @@ -2476,8 +2476,8 @@ ksocknal_check_peer_timeouts (int idx) tx = list_entry(peer->ksnp_zc_req_list.next, ksock_tx_t, tx_zc_list); deadline = tx->tx_deadline; - resid = tx->tx_resid; - conn = tx->tx_conn; + resid = tx->tx_resid; + conn = tx->tx_conn; ksocknal_conn_addref(conn); spin_unlock(&peer->ksnp_lock); @@ -2499,17 +2499,17 @@ ksocknal_check_peer_timeouts (int idx) int ksocknal_reaper (void *arg) { - wait_queue_t wait; - ksock_conn_t *conn; - ksock_sched_t *sched; - struct list_head enomem_conns; - int nenomem_conns; - long timeout; - int i; - int peer_index = 0; - unsigned long deadline = cfs_time_current(); - - cfs_block_allsigs (); + wait_queue_t wait; + ksock_conn_t *conn; + ksock_sched_t *sched; + struct list_head enomem_conns; + int nenomem_conns; + long timeout; + int i; + int peer_index = 0; + unsigned long deadline = cfs_time_current(); + + cfs_block_allsigs(); INIT_LIST_HEAD(&enomem_conns); init_waitqueue_entry(&wait, current); @@ -2580,7 +2580,7 @@ ksocknal_reaper (void *arg) cfs_time_current())) <= 0) { const int n = 4; const int p = 1; - int chunk = ksocknal_data.ksnd_peer_hash_size; + int chunk = ksocknal_data.ksnd_peer_hash_size; /* Time to check for timeouts on a few more peers: I do * checks every 'p' seconds on a proportion of the peer diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c index f5e8ab06070c..34c6a728b71b 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c @@ -39,9 +39,8 @@ int ksocknal_lib_get_conn_addrs(ksock_conn_t *conn) { - int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1, - &conn->ksnc_ipaddr, - &conn->ksnc_port); + int rc = lnet_sock_getaddr(conn->ksnc_sock, 1, &conn->ksnc_ipaddr, + &conn->ksnc_port); /* Didn't need the {get,put}connsock dance to deref ksnc_sock... */ LASSERT(!conn->ksnc_closing); @@ -51,8 +50,7 @@ ksocknal_lib_get_conn_addrs(ksock_conn_t *conn) return rc; } - rc = libcfs_sock_getaddr(conn->ksnc_sock, 0, - &conn->ksnc_myipaddr, NULL); + rc = lnet_sock_getaddr(conn->ksnc_sock, 0, &conn->ksnc_myipaddr, NULL); if (rc != 0) { CERROR("Error %d getting sock local IP\n", rc); return rc; @@ -64,7 +62,7 @@ ksocknal_lib_get_conn_addrs(ksock_conn_t *conn) int ksocknal_lib_zc_capable(ksock_conn_t *conn) { - int caps = conn->ksnc_sock->sk->sk_route_caps; + int caps = conn->ksnc_sock->sk->sk_route_caps; if (conn->ksnc_proto == &ksocknal_protocol_v1x) return 0; @@ -78,8 +76,8 @@ int ksocknal_lib_send_iov(ksock_conn_t *conn, ksock_tx_t *tx) { struct socket *sock = conn->ksnc_sock; - int nob; - int rc; + int nob; + int rc; if (*ksocknal_tunables.ksnd_enable_csum && /* checksum enabled */ conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection */ @@ -92,15 +90,15 @@ ksocknal_lib_send_iov(ksock_conn_t *conn, ksock_tx_t *tx) { #if SOCKNAL_SINGLE_FRAG_TX - struct kvec scratch; - struct kvec *scratchiov = &scratch; - unsigned int niov = 1; + struct kvec scratch; + struct kvec *scratchiov = &scratch; + unsigned int niov = 1; #else - struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; - unsigned int niov = tx->tx_niov; + struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; + unsigned int niov = tx->tx_niov; #endif struct msghdr msg = {.msg_flags = MSG_DONTWAIT}; - int i; + int i; for (nob = i = 0; i < niov; i++) { scratchiov[i] = tx->tx_iov[i]; @@ -120,9 +118,9 @@ int ksocknal_lib_send_kiov(ksock_conn_t *conn, ksock_tx_t *tx) { struct socket *sock = conn->ksnc_sock; - lnet_kiov_t *kiov = tx->tx_kiov; - int rc; - int nob; + lnet_kiov_t *kiov = tx->tx_kiov; + int rc; + int nob; /* Not NOOP message */ LASSERT(tx->tx_lnetmsg != NULL); @@ -131,11 +129,11 @@ ksocknal_lib_send_kiov(ksock_conn_t *conn, ksock_tx_t *tx) * or leave them alone. */ if (tx->tx_msg.ksm_zc_cookies[0] != 0) { /* Zero copy is enabled */ - struct sock *sk = sock->sk; - struct page *page = kiov->kiov_page; - int offset = kiov->kiov_offset; - int fragsize = kiov->kiov_len; - int msgflg = MSG_DONTWAIT; + struct sock *sk = sock->sk; + struct page *page = kiov->kiov_page; + int offset = kiov->kiov_offset; + int fragsize = kiov->kiov_len; + int msgflg = MSG_DONTWAIT; CDEBUG(D_NET, "page %p + offset %x for %d\n", page, offset, kiov->kiov_len); @@ -153,18 +151,18 @@ ksocknal_lib_send_kiov(ksock_conn_t *conn, ksock_tx_t *tx) } } else { #if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK - struct kvec scratch; + struct kvec scratch; struct kvec *scratchiov = &scratch; - unsigned int niov = 1; + unsigned int niov = 1; #else #ifdef CONFIG_HIGHMEM #warning "XXX risk of kmap deadlock on multiple frags..." #endif struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; - unsigned int niov = tx->tx_nkiov; + unsigned int niov = tx->tx_nkiov; #endif struct msghdr msg = {.msg_flags = MSG_DONTWAIT}; - int i; + int i; for (nob = i = 0; i < niov; i++) { scratchiov[i].iov_base = kmap(kiov[i].kiov_page) + @@ -187,7 +185,7 @@ ksocknal_lib_send_kiov(ksock_conn_t *conn, ksock_tx_t *tx) void ksocknal_lib_eager_ack(ksock_conn_t *conn) { - int opt = 1; + int opt = 1; struct socket *sock = conn->ksnc_sock; /* Remind the socket to ACK eagerly. If I don't, the socket might @@ -203,23 +201,23 @@ int ksocknal_lib_recv_iov(ksock_conn_t *conn) { #if SOCKNAL_SINGLE_FRAG_RX - struct kvec scratch; + struct kvec scratch; struct kvec *scratchiov = &scratch; - unsigned int niov = 1; + unsigned int niov = 1; #else struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; - unsigned int niov = conn->ksnc_rx_niov; + unsigned int niov = conn->ksnc_rx_niov; #endif struct kvec *iov = conn->ksnc_rx_iov; struct msghdr msg = { - .msg_flags = 0 + .msg_flags = 0 }; - int nob; - int i; - int rc; - int fragnob; - int sum; - __u32 saved_csum; + int nob; + int i; + int rc; + int fragnob; + int sum; + __u32 saved_csum; /* NB we can't trust socket ops to either consume our iovs * or leave them alone. */ @@ -271,9 +269,9 @@ static void * ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov, struct kvec *iov, struct page **pages) { - void *addr; - int nob; - int i; + void *addr; + int nob; + int i; if (!*ksocknal_tunables.ksnd_zc_recv || pages == NULL) return NULL; @@ -307,29 +305,29 @@ int ksocknal_lib_recv_kiov(ksock_conn_t *conn) { #if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK - struct kvec scratch; - struct kvec *scratchiov = &scratch; - struct page **pages = NULL; - unsigned int niov = 1; + struct kvec scratch; + struct kvec *scratchiov = &scratch; + struct page **pages = NULL; + unsigned int niov = 1; #else #ifdef CONFIG_HIGHMEM #warning "XXX risk of kmap deadlock on multiple frags..." #endif - struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; - struct page **pages = conn->ksnc_scheduler->kss_rx_scratch_pgs; - unsigned int niov = conn->ksnc_rx_nkiov; + struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; + struct page **pages = conn->ksnc_scheduler->kss_rx_scratch_pgs; + unsigned int niov = conn->ksnc_rx_nkiov; #endif lnet_kiov_t *kiov = conn->ksnc_rx_kiov; struct msghdr msg = { - .msg_flags = 0 + .msg_flags = 0 }; - int nob; - int i; - int rc; - void *base; - void *addr; - int sum; - int fragnob; + int nob; + int i; + int rc; + void *base; + void *addr; + int sum; + int fragnob; int n; /* NB we can't trust socket ops to either consume our iovs @@ -357,10 +355,10 @@ ksocknal_lib_recv_kiov(ksock_conn_t *conn) for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) { LASSERT(i < niov); - /* Dang! have to kmap again because I have nowhere to stash the - * mapped address. But by doing it while the page is still - * mapped, the kernel just bumps the map count and returns me - * the address it stashed. */ + /* Dang! have to kmap again because I have nowhere to + * stash the mapped address. But by doing it while the + * page is still mapped, the kernel just bumps the map + * count and returns me the address it stashed. */ base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset; fragnob = kiov[i].kiov_len; if (fragnob > sum) @@ -386,9 +384,9 @@ ksocknal_lib_recv_kiov(ksock_conn_t *conn) void ksocknal_lib_csum_tx(ksock_tx_t *tx) { - int i; - __u32 csum; - void *base; + int i; + __u32 csum; + void *base; LASSERT(tx->tx_iov[0].iov_base == &tx->tx_msg); LASSERT(tx->tx_conn != NULL); @@ -426,8 +424,8 @@ int ksocknal_lib_get_conn_tunables(ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle) { struct socket *sock = conn->ksnc_sock; - int len; - int rc; + int len; + int rc; rc = ksocknal_connsock_addref(conn); if (rc != 0) { @@ -436,7 +434,7 @@ ksocknal_lib_get_conn_tunables(ksock_conn_t *conn, int *txmem, int *rxmem, int * return -ESHUTDOWN; } - rc = libcfs_sock_getbuf(sock, txmem, rxmem); + rc = lnet_sock_getbuf(sock, txmem, rxmem); if (rc == 0) { len = sizeof(*nagle); rc = kernel_getsockopt(sock, SOL_TCP, TCP_NODELAY, @@ -456,13 +454,13 @@ ksocknal_lib_get_conn_tunables(ksock_conn_t *conn, int *txmem, int *rxmem, int * int ksocknal_lib_setup_sock(struct socket *sock) { - int rc; - int option; - int keep_idle; - int keep_intvl; - int keep_count; - int do_keepalive; - struct linger linger; + int rc; + int option; + int keep_idle; + int keep_intvl; + int keep_count; + int do_keepalive; + struct linger linger; sock->sk->sk_allocation = GFP_NOFS; @@ -498,9 +496,8 @@ ksocknal_lib_setup_sock(struct socket *sock) } } - rc = libcfs_sock_setbuf(sock, - *ksocknal_tunables.ksnd_tx_buffer_size, - *ksocknal_tunables.ksnd_rx_buffer_size); + rc = lnet_sock_setbuf(sock, *ksocknal_tunables.ksnd_tx_buffer_size, + *ksocknal_tunables.ksnd_rx_buffer_size); if (rc != 0) { CERROR("Can't set buffer tx %d, rx %d buffers: %d\n", *ksocknal_tunables.ksnd_tx_buffer_size, @@ -555,11 +552,11 @@ ksocknal_lib_setup_sock(struct socket *sock) void ksocknal_lib_push_conn(ksock_conn_t *conn) { - struct sock *sk; + struct sock *sk; struct tcp_sock *tp; - int nonagle; - int val = 1; - int rc; + int nonagle; + int val = 1; + int rc; rc = ksocknal_connsock_addref(conn); if (rc != 0) /* being shut down */ @@ -592,7 +589,7 @@ extern void ksocknal_write_callback(ksock_conn_t *conn); static void ksocknal_data_ready(struct sock *sk) { - ksock_conn_t *conn; + ksock_conn_t *conn; /* interleave correctly with closing sockets... */ LASSERT(!in_irq()); @@ -611,9 +608,9 @@ ksocknal_data_ready(struct sock *sk) static void ksocknal_write_space(struct sock *sk) { - ksock_conn_t *conn; - int wspace; - int min_wpace; + ksock_conn_t *conn; + int wspace; + int min_wpace; /* interleave correctly with closing sockets... */ LASSERT(!in_irq()); @@ -689,7 +686,7 @@ ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn) int ksocknal_lib_memory_pressure(ksock_conn_t *conn) { - int rc = 0; + int rc = 0; ksock_sched_t *sched; sched = conn->ksnc_scheduler; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c index 86b88db1cf20..c3ac67698125 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c @@ -145,40 +145,37 @@ ksock_tunables_t ksocknal_tunables; int ksocknal_tunables_init(void) { - /* initialize ksocknal_tunables structure */ - ksocknal_tunables.ksnd_timeout = &sock_timeout; - ksocknal_tunables.ksnd_nscheds = &nscheds; - ksocknal_tunables.ksnd_nconnds = &nconnds; - ksocknal_tunables.ksnd_nconnds_max = &nconnds_max; + ksocknal_tunables.ksnd_timeout = &sock_timeout; + ksocknal_tunables.ksnd_nscheds = &nscheds; + ksocknal_tunables.ksnd_nconnds = &nconnds; + ksocknal_tunables.ksnd_nconnds_max = &nconnds_max; ksocknal_tunables.ksnd_min_reconnectms = &min_reconnectms; ksocknal_tunables.ksnd_max_reconnectms = &max_reconnectms; - ksocknal_tunables.ksnd_eager_ack = &eager_ack; - ksocknal_tunables.ksnd_typed_conns = &typed_conns; - ksocknal_tunables.ksnd_min_bulk = &min_bulk; + ksocknal_tunables.ksnd_eager_ack = &eager_ack; + ksocknal_tunables.ksnd_typed_conns = &typed_conns; + ksocknal_tunables.ksnd_min_bulk = &min_bulk; ksocknal_tunables.ksnd_tx_buffer_size = &tx_buffer_size; ksocknal_tunables.ksnd_rx_buffer_size = &rx_buffer_size; - ksocknal_tunables.ksnd_nagle = &nagle; - ksocknal_tunables.ksnd_round_robin = &round_robin; - ksocknal_tunables.ksnd_keepalive = &keepalive; + ksocknal_tunables.ksnd_nagle = &nagle; + ksocknal_tunables.ksnd_round_robin = &round_robin; + ksocknal_tunables.ksnd_keepalive = &keepalive; ksocknal_tunables.ksnd_keepalive_idle = &keepalive_idle; ksocknal_tunables.ksnd_keepalive_count = &keepalive_count; ksocknal_tunables.ksnd_keepalive_intvl = &keepalive_intvl; - ksocknal_tunables.ksnd_credits = &credits; + ksocknal_tunables.ksnd_credits = &credits; ksocknal_tunables.ksnd_peertxcredits = &peer_credits; ksocknal_tunables.ksnd_peerrtrcredits = &peer_buffer_credits; - ksocknal_tunables.ksnd_peertimeout = &peer_timeout; - ksocknal_tunables.ksnd_enable_csum = &enable_csum; + ksocknal_tunables.ksnd_peertimeout = &peer_timeout; + ksocknal_tunables.ksnd_enable_csum = &enable_csum; ksocknal_tunables.ksnd_inject_csum_error = &inject_csum_error; ksocknal_tunables.ksnd_nonblk_zcack = &nonblk_zcack; ksocknal_tunables.ksnd_zc_min_payload = &zc_min_payload; - ksocknal_tunables.ksnd_zc_recv = &zc_recv; + ksocknal_tunables.ksnd_zc_recv = &zc_recv; ksocknal_tunables.ksnd_zc_recv_min_nfrags = &zc_recv_min_nfrags; - - #if SOCKNAL_VERSION_DEBUG - ksocknal_tunables.ksnd_protocol = &protocol; + ksocknal_tunables.ksnd_protocol = &protocol; #endif if (*ksocknal_tunables.ksnd_zc_min_payload < (2 << 10)) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index 8596581f54ff..986bce4c9f3b 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -52,7 +52,7 @@ ksocknal_queue_tx_msg_v1(ksock_conn_t *conn, ksock_tx_t *tx_msg) void ksocknal_next_tx_carrier(ksock_conn_t *conn) { - ksock_tx_t *tx = conn->ksnc_tx_carrier; + ksock_tx_t *tx = conn->ksnc_tx_carrier; /* Called holding BH lock: conn->ksnc_scheduler->kss_lock */ LASSERT(!list_empty(&conn->ksnc_tx_queue)); @@ -119,7 +119,7 @@ ksocknal_queue_tx_zcack_v2(ksock_conn_t *conn, static ksock_tx_t * ksocknal_queue_tx_msg_v2(ksock_conn_t *conn, ksock_tx_t *tx_msg) { - ksock_tx_t *tx = conn->ksnc_tx_carrier; + ksock_tx_t *tx = conn->ksnc_tx_carrier; /* * Enqueue tx_msg: @@ -361,10 +361,10 @@ ksocknal_match_tx_v3(ksock_conn_t *conn, ksock_tx_t *tx, int nonblk) static int ksocknal_handle_zcreq(ksock_conn_t *c, __u64 cookie, int remote) { - ksock_peer_t *peer = c->ksnc_peer; - ksock_conn_t *conn; - ksock_tx_t *tx; - int rc; + ksock_peer_t *peer = c->ksnc_peer; + ksock_conn_t *conn; + ksock_tx_t *tx; + int rc; read_lock(&ksocknal_data.ksnd_global_lock); @@ -405,11 +405,11 @@ ksocknal_handle_zcreq(ksock_conn_t *c, __u64 cookie, int remote) static int ksocknal_handle_zcack(ksock_conn_t *conn, __u64 cookie1, __u64 cookie2) { - ksock_peer_t *peer = conn->ksnc_peer; - ksock_tx_t *tx; - ksock_tx_t *tmp; + ksock_peer_t *peer = conn->ksnc_peer; + ksock_tx_t *tx; + ksock_tx_t *tmp; LIST_HEAD(zlist); - int count; + int count; if (cookie1 == 0) cookie1 = cookie2; @@ -452,11 +452,11 @@ ksocknal_handle_zcack(ksock_conn_t *conn, __u64 cookie1, __u64 cookie2) static int ksocknal_send_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello) { - struct socket *sock = conn->ksnc_sock; - lnet_hdr_t *hdr; + struct socket *sock = conn->ksnc_sock; + lnet_hdr_t *hdr; lnet_magicversion_t *hmv; - int rc; - int i; + int rc; + int i; CLASSERT(sizeof(lnet_magicversion_t) == offsetof(lnet_hdr_t, src_nid)); @@ -470,7 +470,7 @@ ksocknal_send_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello) /* Re-organize V2.x message header to V1.x (lnet_hdr_t) * header and send out */ - hmv->magic = cpu_to_le32 (LNET_PROTO_TCP_MAGIC); + hmv->magic = cpu_to_le32 (LNET_PROTO_TCP_MAGIC); hmv->version_major = cpu_to_le16 (KSOCK_PROTO_V1_MAJOR); hmv->version_minor = cpu_to_le16 (KSOCK_PROTO_V1_MINOR); @@ -488,16 +488,14 @@ ksocknal_send_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello) LNET_UNLOCK(); } - hdr->src_nid = cpu_to_le64 (hello->kshm_src_nid); - hdr->src_pid = cpu_to_le32 (hello->kshm_src_pid); - hdr->type = cpu_to_le32 (LNET_MSG_HELLO); + hdr->src_nid = cpu_to_le64 (hello->kshm_src_nid); + hdr->src_pid = cpu_to_le32 (hello->kshm_src_pid); + hdr->type = cpu_to_le32 (LNET_MSG_HELLO); hdr->payload_length = cpu_to_le32 (hello->kshm_nips * sizeof(__u32)); hdr->msg.hello.type = cpu_to_le32 (hello->kshm_ctype); hdr->msg.hello.incarnation = cpu_to_le64 (hello->kshm_src_incarnation); - rc = libcfs_sock_write(sock, hdr, sizeof(*hdr), - lnet_acceptor_timeout()); - + rc = lnet_sock_write(sock, hdr, sizeof(*hdr), lnet_acceptor_timeout()); if (rc != 0) { CNETERR("Error %d sending HELLO hdr to %pI4h/%d\n", rc, &conn->ksnc_ipaddr, conn->ksnc_port); @@ -511,9 +509,9 @@ ksocknal_send_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello) hello->kshm_ips[i] = __cpu_to_le32 (hello->kshm_ips[i]); } - rc = libcfs_sock_write(sock, hello->kshm_ips, - hello->kshm_nips * sizeof(__u32), - lnet_acceptor_timeout()); + rc = lnet_sock_write(sock, hello->kshm_ips, + hello->kshm_nips * sizeof(__u32), + lnet_acceptor_timeout()); if (rc != 0) { CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", rc, hello->kshm_nips, @@ -529,7 +527,7 @@ static int ksocknal_send_hello_v2(ksock_conn_t *conn, ksock_hello_msg_t *hello) { struct socket *sock = conn->ksnc_sock; - int rc; + int rc; hello->kshm_magic = LNET_PROTO_MAGIC; hello->kshm_version = conn->ksnc_proto->pro_version; @@ -544,9 +542,8 @@ ksocknal_send_hello_v2(ksock_conn_t *conn, ksock_hello_msg_t *hello) LNET_UNLOCK(); } - rc = libcfs_sock_write(sock, hello, offsetof(ksock_hello_msg_t, kshm_ips), - lnet_acceptor_timeout()); - + rc = lnet_sock_write(sock, hello, offsetof(ksock_hello_msg_t, kshm_ips), + lnet_acceptor_timeout()); if (rc != 0) { CNETERR("Error %d sending HELLO hdr to %pI4h/%d\n", rc, &conn->ksnc_ipaddr, conn->ksnc_port); @@ -556,9 +553,9 @@ ksocknal_send_hello_v2(ksock_conn_t *conn, ksock_hello_msg_t *hello) if (hello->kshm_nips == 0) return 0; - rc = libcfs_sock_write(sock, hello->kshm_ips, - hello->kshm_nips * sizeof(__u32), - lnet_acceptor_timeout()); + rc = lnet_sock_write(sock, hello->kshm_ips, + hello->kshm_nips * sizeof(__u32), + lnet_acceptor_timeout()); if (rc != 0) { CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", rc, hello->kshm_nips, @@ -572,10 +569,10 @@ static int ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout) { - struct socket *sock = conn->ksnc_sock; - lnet_hdr_t *hdr; - int rc; - int i; + struct socket *sock = conn->ksnc_sock; + lnet_hdr_t *hdr; + int rc; + int i; LIBCFS_ALLOC(hdr, sizeof(*hdr)); if (hdr == NULL) { @@ -583,9 +580,9 @@ ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, return -ENOMEM; } - rc = libcfs_sock_read(sock, &hdr->src_nid, - sizeof(*hdr) - offsetof(lnet_hdr_t, src_nid), - timeout); + rc = lnet_sock_read(sock, &hdr->src_nid, + sizeof(*hdr) - offsetof(lnet_hdr_t, src_nid), + timeout); if (rc != 0) { CERROR("Error %d reading rest of HELLO hdr from %pI4h\n", rc, &conn->ksnc_ipaddr); @@ -602,12 +599,12 @@ ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, goto out; } - hello->kshm_src_nid = le64_to_cpu(hdr->src_nid); - hello->kshm_src_pid = le32_to_cpu(hdr->src_pid); + hello->kshm_src_nid = le64_to_cpu(hdr->src_nid); + hello->kshm_src_pid = le32_to_cpu(hdr->src_pid); hello->kshm_src_incarnation = le64_to_cpu(hdr->msg.hello.incarnation); - hello->kshm_ctype = le32_to_cpu(hdr->msg.hello.type); - hello->kshm_nips = le32_to_cpu(hdr->payload_length) / - sizeof(__u32); + hello->kshm_ctype = le32_to_cpu(hdr->msg.hello.type); + hello->kshm_nips = le32_to_cpu(hdr->payload_length) / + sizeof(__u32); if (hello->kshm_nips > LNET_MAX_INTERFACES) { CERROR("Bad nips %d from ip %pI4h\n", @@ -619,8 +616,8 @@ ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, if (hello->kshm_nips == 0) goto out; - rc = libcfs_sock_read(sock, hello->kshm_ips, - hello->kshm_nips * sizeof(__u32), timeout); + rc = lnet_sock_read(sock, hello->kshm_ips, + hello->kshm_nips * sizeof(__u32), timeout); if (rc != 0) { CERROR("Error %d reading IPs from ip %pI4h\n", rc, &conn->ksnc_ipaddr); @@ -647,19 +644,19 @@ out: static int ksocknal_recv_hello_v2(ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout) { - struct socket *sock = conn->ksnc_sock; - int rc; - int i; + struct socket *sock = conn->ksnc_sock; + int rc; + int i; if (hello->kshm_magic == LNET_PROTO_MAGIC) conn->ksnc_flip = 0; else conn->ksnc_flip = 1; - rc = libcfs_sock_read(sock, &hello->kshm_src_nid, - offsetof(ksock_hello_msg_t, kshm_ips) - - offsetof(ksock_hello_msg_t, kshm_src_nid), - timeout); + rc = lnet_sock_read(sock, &hello->kshm_src_nid, + offsetof(ksock_hello_msg_t, kshm_ips) - + offsetof(ksock_hello_msg_t, kshm_src_nid), + timeout); if (rc != 0) { CERROR("Error %d reading HELLO from %pI4h\n", rc, &conn->ksnc_ipaddr); @@ -687,8 +684,8 @@ ksocknal_recv_hello_v2(ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout if (hello->kshm_nips == 0) return 0; - rc = libcfs_sock_read(sock, hello->kshm_ips, - hello->kshm_nips * sizeof(__u32), timeout); + rc = lnet_sock_read(sock, hello->kshm_ips, + hello->kshm_nips * sizeof(__u32), timeout); if (rc != 0) { CERROR("Error %d reading IPs from ip %pI4h\n", rc, &conn->ksnc_ipaddr); @@ -746,9 +743,9 @@ ksocknal_pack_msg_v2(ksock_tx_t *tx) static void ksocknal_unpack_msg_v1(ksock_msg_t *msg) { - msg->ksm_csum = 0; - msg->ksm_type = KSOCK_MSG_LNET; - msg->ksm_zc_cookies[0] = msg->ksm_zc_cookies[1] = 0; + msg->ksm_csum = 0; + msg->ksm_type = KSOCK_MSG_LNET; + msg->ksm_zc_cookies[0] = msg->ksm_zc_cookies[1] = 0; } static void @@ -758,40 +755,40 @@ ksocknal_unpack_msg_v2(ksock_msg_t *msg) } ksock_proto_t ksocknal_protocol_v1x = { - .pro_version = KSOCK_PROTO_V1, - .pro_send_hello = ksocknal_send_hello_v1, - .pro_recv_hello = ksocknal_recv_hello_v1, - .pro_pack = ksocknal_pack_msg_v1, - .pro_unpack = ksocknal_unpack_msg_v1, - .pro_queue_tx_msg = ksocknal_queue_tx_msg_v1, - .pro_handle_zcreq = NULL, - .pro_handle_zcack = NULL, - .pro_queue_tx_zcack = NULL, - .pro_match_tx = ksocknal_match_tx + .pro_version = KSOCK_PROTO_V1, + .pro_send_hello = ksocknal_send_hello_v1, + .pro_recv_hello = ksocknal_recv_hello_v1, + .pro_pack = ksocknal_pack_msg_v1, + .pro_unpack = ksocknal_unpack_msg_v1, + .pro_queue_tx_msg = ksocknal_queue_tx_msg_v1, + .pro_handle_zcreq = NULL, + .pro_handle_zcack = NULL, + .pro_queue_tx_zcack = NULL, + .pro_match_tx = ksocknal_match_tx }; ksock_proto_t ksocknal_protocol_v2x = { - .pro_version = KSOCK_PROTO_V2, - .pro_send_hello = ksocknal_send_hello_v2, - .pro_recv_hello = ksocknal_recv_hello_v2, - .pro_pack = ksocknal_pack_msg_v2, - .pro_unpack = ksocknal_unpack_msg_v2, - .pro_queue_tx_msg = ksocknal_queue_tx_msg_v2, - .pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v2, - .pro_handle_zcreq = ksocknal_handle_zcreq, - .pro_handle_zcack = ksocknal_handle_zcack, - .pro_match_tx = ksocknal_match_tx + .pro_version = KSOCK_PROTO_V2, + .pro_send_hello = ksocknal_send_hello_v2, + .pro_recv_hello = ksocknal_recv_hello_v2, + .pro_pack = ksocknal_pack_msg_v2, + .pro_unpack = ksocknal_unpack_msg_v2, + .pro_queue_tx_msg = ksocknal_queue_tx_msg_v2, + .pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v2, + .pro_handle_zcreq = ksocknal_handle_zcreq, + .pro_handle_zcack = ksocknal_handle_zcack, + .pro_match_tx = ksocknal_match_tx }; ksock_proto_t ksocknal_protocol_v3x = { - .pro_version = KSOCK_PROTO_V3, - .pro_send_hello = ksocknal_send_hello_v2, - .pro_recv_hello = ksocknal_recv_hello_v2, - .pro_pack = ksocknal_pack_msg_v2, - .pro_unpack = ksocknal_unpack_msg_v2, - .pro_queue_tx_msg = ksocknal_queue_tx_msg_v2, - .pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v3, - .pro_handle_zcreq = ksocknal_handle_zcreq, - .pro_handle_zcack = ksocknal_handle_zcack, - .pro_match_tx = ksocknal_match_tx_v3 + .pro_version = KSOCK_PROTO_V3, + .pro_send_hello = ksocknal_send_hello_v2, + .pro_recv_hello = ksocknal_recv_hello_v2, + .pro_pack = ksocknal_pack_msg_v2, + .pro_unpack = ksocknal_unpack_msg_v2, + .pro_queue_tx_msg = ksocknal_queue_tx_msg_v2, + .pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v3, + .pro_handle_zcreq = ksocknal_handle_zcreq, + .pro_handle_zcack = ksocknal_handle_zcack, + .pro_match_tx = ksocknal_match_tx_v3 }; diff --git a/drivers/staging/lustre/lnet/lnet/Makefile b/drivers/staging/lustre/lnet/lnet/Makefile index 336b8ea4fdf6..52492fb10f85 100644 --- a/drivers/staging/lustre/lnet/lnet/Makefile +++ b/drivers/staging/lustre/lnet/lnet/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_LNET) += lnet.o -lnet-y := api-ni.o config.o lib-me.o lib-msg.o lib-eq.o \ - lib-md.o lib-ptl.o lib-move.o module.o lo.o router.o \ - router_proc.o acceptor.o peer.o +lnet-y := api-ni.o config.o \ + lib-me.o lib-msg.o lib-eq.o lib-md.o lib-ptl.o \ + lib-socket.o lib-move.o module.o lo.o \ + router.o router_proc.o acceptor.o peer.o diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 72fd1bf70ca0..be850353d02d 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -35,9 +35,9 @@ */ #define DEBUG_SUBSYSTEM S_LNET +#include <linux/completion.h> #include "../../include/linux/lnet/lib-lnet.h" - static int accept_port = 988; static int accept_backlog = 127; static int accept_timeout = 5; @@ -143,10 +143,10 @@ lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, __u32 local_ip, __u32 peer_ip, int peer_port) { lnet_acceptor_connreq_t cr; - struct socket *sock; - int rc; - int port; - int fatal; + struct socket *sock; + int rc; + int port; + int fatal; CLASSERT(sizeof(cr) <= 16); /* not too big to be on the stack */ @@ -155,9 +155,8 @@ lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, --port) { /* Iterate through reserved ports. */ - rc = libcfs_sock_connect(&sock, &fatal, - local_ip, port, - peer_ip, peer_port); + rc = lnet_sock_connect(&sock, &fatal, local_ip, port, peer_ip, + peer_port); if (rc != 0) { if (fatal) goto failed; @@ -184,8 +183,7 @@ lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, lnet_net_unlock(LNET_LOCK_EX); } - rc = libcfs_sock_write(sock, &cr, sizeof(cr), - accept_timeout); + rc = lnet_sock_write(sock, &cr, sizeof(cr), accept_timeout); if (rc != 0) goto failed_sock; @@ -197,7 +195,7 @@ lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, goto failed; failed_sock: - libcfs_sock_release(sock); + sock_release(sock); failed: lnet_connect_console_error(rc, peer_nid, peer_ip, peer_port); return rc; @@ -211,16 +209,16 @@ static int lnet_accept(struct socket *sock, __u32 magic) { lnet_acceptor_connreq_t cr; - __u32 peer_ip; - int peer_port; - int rc; - int flip; - lnet_ni_t *ni; - char *str; + __u32 peer_ip; + int peer_port; + int rc; + int flip; + lnet_ni_t *ni; + char *str; LASSERT(sizeof(cr) <= 16); /* not too big for the stack */ - rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port); + rc = lnet_sock_getaddr(sock, 1, &peer_ip, &peer_port); LASSERT(rc == 0); /* we succeeded before */ if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) { @@ -234,8 +232,8 @@ lnet_accept(struct socket *sock, __u32 magic) memset(&cr, 0, sizeof(cr)); cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC; cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION; - rc = libcfs_sock_write(sock, &cr, sizeof(cr), - accept_timeout); + rc = lnet_sock_write(sock, &cr, sizeof(cr), + accept_timeout); if (rc != 0) CERROR("Error sending magic+version in response to LNET magic from %pI4h: %d\n", @@ -257,9 +255,8 @@ lnet_accept(struct socket *sock, __u32 magic) flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC); - rc = libcfs_sock_read(sock, &cr.acr_version, - sizeof(cr.acr_version), - accept_timeout); + rc = lnet_sock_read(sock, &cr.acr_version, sizeof(cr.acr_version), + accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request version from %pI4h\n", rc, &peer_ip); @@ -280,19 +277,17 @@ lnet_accept(struct socket *sock, __u32 magic) cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC; cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION; - rc = libcfs_sock_write(sock, &cr, sizeof(cr), - accept_timeout); - + rc = lnet_sock_write(sock, &cr, sizeof(cr), accept_timeout); if (rc != 0) CERROR("Error sending magic+version in response to version %d from %pI4h: %d\n", peer_version, &peer_ip, rc); return -EPROTO; } - rc = libcfs_sock_read(sock, &cr.acr_nid, - sizeof(cr) - - offsetof(lnet_acceptor_connreq_t, acr_nid), - accept_timeout); + rc = lnet_sock_read(sock, &cr.acr_nid, + sizeof(cr) - + offsetof(lnet_acceptor_connreq_t, acr_nid), + accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request from %pI4h\n", rc, &peer_ip); @@ -333,18 +328,18 @@ static int lnet_acceptor(void *arg) { struct socket *newsock; - int rc; - __u32 magic; - __u32 peer_ip; - int peer_port; - int secure = (int)((long_ptr_t)arg); + int rc; + __u32 magic; + __u32 peer_ip; + int peer_port; + int secure = (int)((long_ptr_t)arg); LASSERT(lnet_acceptor_state.pta_sock == NULL); cfs_block_allsigs(); - rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock, - 0, accept_port, accept_backlog); + rc = lnet_sock_listen(&lnet_acceptor_state.pta_sock, 0, accept_port, + accept_backlog); if (rc != 0) { if (rc == -EADDRINUSE) LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port %d: port already in use\n", @@ -367,7 +362,7 @@ lnet_acceptor(void *arg) while (!lnet_acceptor_state.pta_shutdown) { - rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock); + rc = lnet_sock_accept(&newsock, lnet_acceptor_state.pta_sock); if (rc != 0) { if (rc != -EAGAIN) { CWARN("Accept error %d: pausing...\n", rc); @@ -377,13 +372,13 @@ lnet_acceptor(void *arg) continue; } - /* maybe we're waken up with libcfs_sock_abort_accept() */ + /* maybe the LNet acceptor thread has been waken */ if (lnet_acceptor_state.pta_shutdown) { - libcfs_sock_release(newsock); + sock_release(newsock); break; } - rc = libcfs_sock_getaddr(newsock, 1, &peer_ip, &peer_port); + rc = lnet_sock_getaddr(newsock, 1, &peer_ip, &peer_port); if (rc != 0) { CERROR("Can't determine new connection's address\n"); goto failed; @@ -395,8 +390,8 @@ lnet_acceptor(void *arg) goto failed; } - rc = libcfs_sock_read(newsock, &magic, sizeof(magic), - accept_timeout); + rc = lnet_sock_read(newsock, &magic, sizeof(magic), + accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request from %pI4h\n", rc, &peer_ip); @@ -410,10 +405,10 @@ lnet_acceptor(void *arg) continue; failed: - libcfs_sock_release(newsock); + sock_release(newsock); } - libcfs_sock_release(lnet_acceptor_state.pta_sock); + sock_release(lnet_acceptor_state.pta_sock); lnet_acceptor_state.pta_sock = NULL; CDEBUG(D_NET, "Acceptor stopping\n"); @@ -444,7 +439,7 @@ accept2secure(const char *acc, long *sec) int lnet_acceptor_start(void) { - int rc; + int rc; long rc2; long secure; @@ -493,7 +488,7 @@ lnet_acceptor_stop(void) return; lnet_acceptor_state.pta_shutdown = 1; - libcfs_sock_abort_accept(lnet_acceptor_state.pta_sock); + wake_up_all(sk_sleep(lnet_acceptor_state.pta_sock->sk)); /* block until acceptor signals exit */ wait_for_completion(&lnet_acceptor_state.pta_signal); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 4a14e5109821..9fc3bf6cb052 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -41,7 +41,7 @@ #define D_LNI D_CONSOLE -lnet_t the_lnet; /* THE state of the network */ +lnet_t the_lnet; /* THE state of the network */ EXPORT_SYMBOL(the_lnet); @@ -70,8 +70,8 @@ lnet_get_routes(void) static char * lnet_get_networks(void) { - char *nets; - int rc; + char *nets; + int rc; if (*networks != 0 && *ip2nets != 0) { LCONSOLE_ERROR_MSG(0x101, "Please specify EITHER 'networks' or 'ip2nets' but not both at once\n"); @@ -98,17 +98,11 @@ lnet_init_locks(void) mutex_init(&the_lnet.ln_api_mutex); } -static void -lnet_fini_locks(void) -{ -} - - static int lnet_create_remote_nets_table(void) { - int i; - struct list_head *hash; + int i; + struct list_head *hash; LASSERT(the_lnet.ln_remote_nets_hash == NULL); LASSERT(the_lnet.ln_remote_nets_hbits > 0); @@ -153,8 +147,6 @@ lnet_destroy_locks(void) cfs_percpt_lock_free(the_lnet.ln_net_lock); the_lnet.ln_net_lock = NULL; } - - lnet_fini_locks(); } static int @@ -273,8 +265,8 @@ static void lnet_assert_wire_constants(void) static lnd_t * lnet_find_lnd_by_type(int type) { - lnd_t *lnd; - struct list_head *tmp; + lnd_t *lnd; + struct list_head *tmp; /* holding lnd mutex */ list_for_each(tmp, &the_lnet.ln_lnds) { @@ -290,7 +282,7 @@ lnet_find_lnd_by_type(int type) void lnet_register_lnd(lnd_t *lnd) { - LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex); + mutex_lock(&the_lnet.ln_lnd_mutex); LASSERT(the_lnet.ln_init); LASSERT(libcfs_isknown_lnd(lnd->lnd_type)); @@ -301,14 +293,14 @@ lnet_register_lnd(lnd_t *lnd) CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type)); - LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex); + mutex_unlock(&the_lnet.ln_lnd_mutex); } EXPORT_SYMBOL(lnet_register_lnd); void lnet_unregister_lnd(lnd_t *lnd) { - LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex); + mutex_lock(&the_lnet.ln_lnd_mutex); LASSERT(the_lnet.ln_init); LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd); @@ -317,7 +309,7 @@ lnet_unregister_lnd(lnd_t *lnd) list_del(&lnd->lnd_list); CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type)); - LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex); + mutex_unlock(&the_lnet.ln_lnd_mutex); } EXPORT_SYMBOL(lnet_unregister_lnd); @@ -325,7 +317,7 @@ void lnet_counters_get(lnet_counters_t *counters) { lnet_counters_t *ctr; - int i; + int i; memset(counters, 0, sizeof(*counters)); @@ -353,7 +345,7 @@ void lnet_counters_reset(void) { lnet_counters_t *counters; - int i; + int i; lnet_net_lock(LNET_LOCK_EX); @@ -364,56 +356,6 @@ lnet_counters_reset(void) } EXPORT_SYMBOL(lnet_counters_reset); -#ifdef LNET_USE_LIB_FREELIST - -int -lnet_freelist_init(lnet_freelist_t *fl, int n, int size) -{ - char *space; - - LASSERT(n > 0); - - size += offsetof(lnet_freeobj_t, fo_contents); - - LIBCFS_ALLOC(space, n * size); - if (space == NULL) - return -ENOMEM; - - INIT_LIST_HEAD(&fl->fl_list); - fl->fl_objs = space; - fl->fl_nobjs = n; - fl->fl_objsize = size; - - do { - memset(space, 0, size); - list_add((struct list_head *)space, &fl->fl_list); - space += size; - } while (--n != 0); - - return 0; -} - -void -lnet_freelist_fini(lnet_freelist_t *fl) -{ - struct list_head *el; - int count; - - if (fl->fl_nobjs == 0) - return; - - count = 0; - for (el = fl->fl_list.next; el != &fl->fl_list; el = el->next) - count++; - - LASSERT(count == fl->fl_nobjs); - - LIBCFS_FREE(fl->fl_objs, fl->fl_nobjs * fl->fl_objsize); - memset(fl, 0, sizeof(*fl)); -} - -#endif /* LNET_USE_LIB_FREELIST */ - static __u64 lnet_create_interface_cookie(void) { @@ -441,7 +383,7 @@ lnet_res_type2str(int type) static void lnet_res_container_cleanup(struct lnet_res_container *rec) { - int count = 0; + int count = 0; if (rec->rec_type == 0) /* not set yet, it's uninitialized */ return; @@ -470,9 +412,6 @@ lnet_res_container_cleanup(struct lnet_res_container *rec) count, lnet_res_type2str(rec->rec_type)); } -#ifdef LNET_USE_LIB_FREELIST - lnet_freelist_fini(&rec->rec_freelist); -#endif if (rec->rec_lh_hash != NULL) { LIBCFS_FREE(rec->rec_lh_hash, LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0])); @@ -483,23 +422,15 @@ lnet_res_container_cleanup(struct lnet_res_container *rec) } static int -lnet_res_container_setup(struct lnet_res_container *rec, - int cpt, int type, int objnum, int objsz) +lnet_res_container_setup(struct lnet_res_container *rec, int cpt, int type) { - int rc = 0; - int i; + int rc = 0; + int i; LASSERT(rec->rec_type == 0); rec->rec_type = type; INIT_LIST_HEAD(&rec->rec_active); - -#ifdef LNET_USE_LIB_FREELIST - memset(&rec->rec_freelist, 0, sizeof(rec->rec_freelist)); - rc = lnet_freelist_init(&rec->rec_freelist, objnum, objsz); - if (rc != 0) - goto out; -#endif rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type; /* Arbitrary choice of hash table size */ @@ -525,8 +456,8 @@ out: static void lnet_res_containers_destroy(struct lnet_res_container **recs) { - struct lnet_res_container *rec; - int i; + struct lnet_res_container *rec; + int i; cfs_percpt_for_each(rec, i, recs) lnet_res_container_cleanup(rec); @@ -535,12 +466,12 @@ lnet_res_containers_destroy(struct lnet_res_container **recs) } static struct lnet_res_container ** -lnet_res_containers_create(int type, int objnum, int objsz) +lnet_res_containers_create(int type) { - struct lnet_res_container **recs; - struct lnet_res_container *rec; - int rc; - int i; + struct lnet_res_container **recs; + struct lnet_res_container *rec; + int rc; + int i; recs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*rec)); if (recs == NULL) { @@ -550,7 +481,7 @@ lnet_res_containers_create(int type, int objnum, int objsz) } cfs_percpt_for_each(rec, i, recs) { - rc = lnet_res_container_setup(rec, i, type, objnum, objsz); + rc = lnet_res_container_setup(rec, i, type); if (rc != 0) { lnet_res_containers_destroy(recs); return NULL; @@ -564,9 +495,9 @@ lnet_libhandle_t * lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie) { /* ALWAYS called with lnet_res_lock held */ - struct list_head *head; - lnet_libhandle_t *lh; - unsigned int hash; + struct list_head *head; + lnet_libhandle_t *lh; + unsigned int hash; if ((cookie & LNET_COOKIE_MASK) != rec->rec_type) return NULL; @@ -586,8 +517,8 @@ void lnet_res_lh_initialize(struct lnet_res_container *rec, lnet_libhandle_t *lh) { /* ALWAYS called with lnet_res_lock held */ - unsigned int ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS; - unsigned int hash; + unsigned int ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS; + unsigned int hash; lh->lh_cookie = rec->rec_lh_cookie; rec->rec_lh_cookie += 1 << ibits; @@ -605,7 +536,7 @@ lnet_prepare(lnet_pid_t requested_pid) { /* Prepare to bring up the network */ struct lnet_res_container **recs; - int rc = 0; + int rc = 0; LASSERT(the_lnet.ln_refcount == 0); @@ -643,13 +574,11 @@ lnet_prepare(lnet_pid_t requested_pid) goto failed; rc = lnet_res_container_setup(&the_lnet.ln_eq_container, 0, - LNET_COOKIE_TYPE_EQ, LNET_FL_MAX_EQS, - sizeof(lnet_eq_t)); + LNET_COOKIE_TYPE_EQ); if (rc != 0) goto failed; - recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME, LNET_FL_MAX_MES, - sizeof(lnet_me_t)); + recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME); if (recs == NULL) { rc = -ENOMEM; goto failed; @@ -657,8 +586,7 @@ lnet_prepare(lnet_pid_t requested_pid) the_lnet.ln_me_containers = recs; - recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD, LNET_FL_MAX_MDS, - sizeof(lnet_libmd_t)); + recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD); if (recs == NULL) { rc = -ENOMEM; goto failed; @@ -725,8 +653,8 @@ lnet_unprepare(void) lnet_ni_t * lnet_net2ni_locked(__u32 net, int cpt) { - struct list_head *tmp; - lnet_ni_t *ni; + struct list_head *tmp; + lnet_ni_t *ni; LASSERT(cpt != LNET_LOCK_EX); @@ -758,8 +686,8 @@ EXPORT_SYMBOL(lnet_net2ni); static unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) { - __u64 key = nid; - unsigned int val; + __u64 key = nid; + unsigned int val; LASSERT(number >= 1 && number <= LNET_CPT_NUMBER); @@ -801,8 +729,8 @@ lnet_cpt_of_nid_locked(lnet_nid_t nid) int lnet_cpt_of_nid(lnet_nid_t nid) { - int cpt; - int cpt2; + int cpt; + int cpt2; if (LNET_CPT_NUMBER == 1) return 0; /* the only one */ @@ -821,8 +749,8 @@ EXPORT_SYMBOL(lnet_cpt_of_nid); int lnet_islocalnet(__u32 net) { - struct lnet_ni *ni; - int cpt; + struct lnet_ni *ni; + int cpt; cpt = lnet_net_lock_current(); @@ -838,8 +766,8 @@ lnet_islocalnet(__u32 net) lnet_ni_t * lnet_nid2ni_locked(lnet_nid_t nid, int cpt) { - struct lnet_ni *ni; - struct list_head *tmp; + struct lnet_ni *ni; + struct list_head *tmp; LASSERT(cpt != LNET_LOCK_EX); @@ -858,8 +786,8 @@ lnet_nid2ni_locked(lnet_nid_t nid, int cpt) int lnet_islocalnid(lnet_nid_t nid) { - struct lnet_ni *ni; - int cpt; + struct lnet_ni *ni; + int cpt; cpt = lnet_net_lock_current(); ni = lnet_nid2ni_locked(nid, cpt); @@ -874,10 +802,10 @@ int lnet_count_acceptor_nis(void) { /* Return the # of NIs that need the acceptor. */ - int count = 0; - struct list_head *tmp; - struct lnet_ni *ni; - int cpt; + int count = 0; + struct list_head *tmp; + struct lnet_ni *ni; + int cpt; cpt = lnet_net_lock_current(); list_for_each(tmp, &the_lnet.ln_nis) { @@ -895,7 +823,7 @@ lnet_count_acceptor_nis(void) static int lnet_ni_tq_credits(lnet_ni_t *ni) { - int credits; + int credits; LASSERT(ni->ni_ncpts >= 1); @@ -912,9 +840,9 @@ lnet_ni_tq_credits(lnet_ni_t *ni) static void lnet_shutdown_lndnis(void) { - int i; - int islo; - lnet_ni_t *ni; + int i; + int islo; + lnet_ni_t *ni; /* NB called holding the global mutex */ @@ -968,8 +896,8 @@ lnet_shutdown_lndnis(void) * and shut them down in guaranteed thread context */ i = 2; while (!list_empty(&the_lnet.ln_nis_zombie)) { - int *ref; - int j; + int *ref; + int j; ni = list_entry(the_lnet.ln_nis_zombie.next, lnet_ni_t, ni_list); @@ -1029,15 +957,15 @@ lnet_shutdown_lndnis(void) static int lnet_startup_lndnis(void) { - lnd_t *lnd; - struct lnet_ni *ni; - struct lnet_tx_queue *tq; - struct list_head nilist; - int i; - int rc = 0; - int lnd_type; - int nicount = 0; - char *nets = lnet_get_networks(); + lnd_t *lnd; + struct lnet_ni *ni; + struct lnet_tx_queue *tq; + struct list_head nilist; + int i; + int rc = 0; + int lnd_type; + int nicount = 0; + char *nets = lnet_get_networks(); INIT_LIST_HEAD(&nilist); @@ -1063,18 +991,18 @@ lnet_startup_lndnis(void) goto failed; } - LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex); + mutex_lock(&the_lnet.ln_lnd_mutex); lnd = lnet_find_lnd_by_type(lnd_type); if (lnd == NULL) { - LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex); + mutex_unlock(&the_lnet.ln_lnd_mutex); rc = request_module("%s", libcfs_lnd2modname(lnd_type)); - LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex); + mutex_lock(&the_lnet.ln_lnd_mutex); lnd = lnet_find_lnd_by_type(lnd_type); if (lnd == NULL) { - LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex); + mutex_unlock(&the_lnet.ln_lnd_mutex); CERROR("Can't load LND %s, module %s, rc=%d\n", libcfs_lnd2str(lnd_type), libcfs_lnd2modname(lnd_type), rc); @@ -1090,7 +1018,7 @@ lnet_startup_lndnis(void) rc = (lnd->lnd_startup)(ni); - LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex); + mutex_unlock(&the_lnet.ln_lnd_mutex); if (rc != 0) { LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n", @@ -1181,7 +1109,7 @@ lnet_startup_lndnis(void) int LNetInit(void) { - int rc; + int rc; lnet_assert_wire_constants(); LASSERT(!the_lnet.ln_init); @@ -1277,10 +1205,10 @@ EXPORT_SYMBOL(LNetFini); int LNetNIInit(lnet_pid_t requested_pid) { - int im_a_router = 0; - int rc; + int im_a_router = 0; + int rc; - LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex); + mutex_lock(&the_lnet.ln_api_mutex); LASSERT(the_lnet.ln_init); CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount); @@ -1351,7 +1279,7 @@ LNetNIInit(lnet_pid_t requested_pid) failed0: LASSERT(rc < 0); out: - LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex); + mutex_unlock(&the_lnet.ln_api_mutex); return rc; } EXPORT_SYMBOL(LNetNIInit); @@ -1368,7 +1296,7 @@ EXPORT_SYMBOL(LNetNIInit); int LNetNIFini(void) { - LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex); + mutex_lock(&the_lnet.ln_api_mutex); LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -1391,7 +1319,7 @@ LNetNIFini(void) lnet_unprepare(); } - LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex); + mutex_unlock(&the_lnet.ln_api_mutex); return 0; } EXPORT_SYMBOL(LNetNIFini); @@ -1413,9 +1341,9 @@ int LNetCtl(unsigned int cmd, void *arg) { struct libcfs_ioctl_data *data = arg; - lnet_process_id_t id = {0}; - lnet_ni_t *ni; - int rc; + lnet_process_id_t id = {0}; + lnet_ni_t *ni; + int rc; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -1531,10 +1459,10 @@ EXPORT_SYMBOL(LNetCtl); int LNetGetId(unsigned int index, lnet_process_id_t *id) { - struct lnet_ni *ni; - struct list_head *tmp; - int cpt; - int rc = -ENOENT; + struct lnet_ni *ni; + struct list_head *tmp; + int cpt; + int rc = -ENOENT; LASSERT(the_lnet.ln_init); @@ -1575,11 +1503,11 @@ EXPORT_SYMBOL(LNetSnprintHandle); static int lnet_create_ping_info(void) { - int i; - int n; - int rc; - unsigned int infosz; - lnet_ni_t *ni; + int i; + int n; + int rc; + unsigned int infosz; + lnet_ni_t *ni; lnet_process_id_t id; lnet_ping_info_t *pinfo; @@ -1633,7 +1561,7 @@ lnet_create_ping_info(void) static void lnet_destroy_ping_info(void) { - struct lnet_ni *ni; + struct lnet_ni *ni; lnet_net_lock(0); @@ -1654,12 +1582,12 @@ lnet_destroy_ping_info(void) int lnet_ping_target_init(void) { - lnet_md_t md = { NULL }; - lnet_handle_me_t meh; + lnet_md_t md = { NULL }; + lnet_handle_me_t meh; lnet_process_id_t id; - int rc; - int rc2; - int infosz; + int rc; + int rc2; + int infosz; rc = lnet_create_ping_info(); if (rc != 0) @@ -1722,11 +1650,11 @@ lnet_ping_target_init(void) void lnet_ping_target_fini(void) { - lnet_event_t event; - int rc; - int which; - int timeout_ms = 1000; - sigset_t blocked = cfs_block_allsigs(); + lnet_event_t event; + int rc; + int which; + int timeout_ms = 1000; + sigset_t blocked = cfs_block_allsigs(); LNetMDUnlink(the_lnet.ln_ping_target_md); /* NB md could be busy; this just starts the unlink */ @@ -1759,22 +1687,22 @@ lnet_ping_target_fini(void) int lnet_ping(lnet_process_id_t id, int timeout_ms, lnet_process_id_t *ids, int n_ids) { - lnet_handle_eq_t eqh; - lnet_handle_md_t mdh; - lnet_event_t event; - lnet_md_t md = { NULL }; - int which; - int unlinked = 0; - int replied = 0; - const int a_long_time = 60000; /* mS */ - int infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]); - lnet_ping_info_t *info; - lnet_process_id_t tmpid; - int i; - int nob; - int rc; - int rc2; - sigset_t blocked; + lnet_handle_eq_t eqh; + lnet_handle_md_t mdh; + lnet_event_t event; + lnet_md_t md = { NULL }; + int which; + int unlinked = 0; + int replied = 0; + const int a_long_time = 60000; /* mS */ + int infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]); + lnet_ping_info_t *info; + lnet_process_id_t tmpid; + int i; + int nob; + int rc; + int rc2; + sigset_t blocked; if (n_ids <= 0 || id.nid == LNET_NID_ANY || diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 2dc4c4a1afd0..efbb74a9e4e6 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -38,9 +38,9 @@ #include "../../include/linux/lnet/lib-lnet.h" struct lnet_text_buf_t { /* tmp struct for parsing routes */ - struct list_head ltb_list; /* stash on lists */ - int ltb_size; /* allocated size */ - char ltb_text[0]; /* text buffer */ + struct list_head ltb_list; /* stash on lists */ + int ltb_size; /* allocated size */ + char ltb_text[0]; /* text buffer */ }; static int lnet_tbnob; /* track text buf allocation */ @@ -80,8 +80,8 @@ lnet_issep(char c) static int lnet_net_unique(__u32 net, struct list_head *nilist) { - struct list_head *tmp; - lnet_ni_t *ni; + struct list_head *tmp; + lnet_ni_t *ni; list_for_each(tmp, nilist) { ni = list_entry(tmp, lnet_ni_t, ni_list); @@ -111,10 +111,10 @@ lnet_ni_free(struct lnet_ni *ni) static lnet_ni_t * lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) { - struct lnet_tx_queue *tq; - struct lnet_ni *ni; - int rc; - int i; + struct lnet_tx_queue *tq; + struct lnet_ni *ni; + int rc; + int i; if (!lnet_net_unique(net, nilist)) { LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", @@ -178,13 +178,13 @@ int lnet_parse_networks(struct list_head *nilist, char *networks) { struct cfs_expr_list *el = NULL; - int tokensize = strlen(networks) + 1; - char *tokens; - char *str; - char *tmp; - struct lnet_ni *ni; - __u32 net; - int nnets = 0; + int tokensize = strlen(networks) + 1; + char *tokens; + char *str; + char *tmp; + struct lnet_ni *ni; + __u32 net; + int nnets = 0; if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) { /* _WAY_ conservative */ @@ -210,12 +210,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) goto failed; while (str != NULL && *str != 0) { - char *comma = strchr(str, ','); - char *bracket = strchr(str, '('); - char *square = strchr(str, '['); - char *iface; - int niface; - int rc; + char *comma = strchr(str, ','); + char *bracket = strchr(str, '('); + char *square = strchr(str, '['); + char *iface; + int niface; + int rc; /* NB we don't check interface conflicts here; it's the LNDs * responsibility (if it cares at all) */ @@ -369,7 +369,7 @@ static struct lnet_text_buf_t * lnet_new_text_buf(int str_len) { struct lnet_text_buf_t *ltb; - int nob; + int nob; /* NB allocate space for the terminating 0 */ nob = offsetof(struct lnet_text_buf_t, ltb_text[str_len + 1]); @@ -404,7 +404,7 @@ lnet_free_text_buf(struct lnet_text_buf_t *ltb) static void lnet_free_text_bufs(struct list_head *tbs) { - struct lnet_text_buf_t *ltb; + struct lnet_text_buf_t *ltb; while (!list_empty(tbs)) { ltb = list_entry(tbs->next, struct lnet_text_buf_t, ltb_list); @@ -417,11 +417,11 @@ lnet_free_text_bufs(struct list_head *tbs) static int lnet_str2tbs_sep(struct list_head *tbs, char *str) { - struct list_head pending; - char *sep; - int nob; - int i; - struct lnet_text_buf_t *ltb; + struct list_head pending; + char *sep; + int nob; + int i; + struct lnet_text_buf_t *ltb; INIT_LIST_HEAD(&pending); @@ -477,8 +477,8 @@ lnet_expand1tb(struct list_head *list, char *str, char *sep1, char *sep2, char *item, int itemlen) { - int len1 = (int)(sep1 - str); - int len2 = strlen(sep2 + 1); + int len1 = (int)(sep1 - str); + int len2 = strlen(sep2 + 1); struct lnet_text_buf_t *ltb; LASSERT(*sep1 == '['); @@ -500,18 +500,18 @@ lnet_expand1tb(struct list_head *list, static int lnet_str2tbs_expand(struct list_head *tbs, char *str) { - char num[16]; - struct list_head pending; - char *sep; - char *sep2; - char *parsed; - char *enditem; - int lo; - int hi; - int stride; - int i; - int nob; - int scanned; + char num[16]; + struct list_head pending; + char *sep; + char *sep2; + char *parsed; + char *enditem; + int lo; + int hi; + int stride; + int i; + int nob; + int scanned; INIT_LIST_HEAD(&pending); @@ -584,8 +584,8 @@ lnet_str2tbs_expand(struct list_head *tbs, char *str) static int lnet_parse_hops(char *str, unsigned int *hops) { - int len = strlen(str); - int nob = len; + int len = strlen(str); + int nob = len; return (sscanf(str, "%u%n", hops, &nob) >= 1 && nob == len && @@ -597,9 +597,9 @@ lnet_parse_hops(char *str, unsigned int *hops) static int lnet_parse_priority(char *str, unsigned int *priority, char **token) { - int nob; + int nob; char *sep; - int len; + int len; sep = strchr(str, LNET_PRIORITY_SEPARATOR); if (sep == NULL) { @@ -628,23 +628,23 @@ static int lnet_parse_route(char *str, int *im_a_router) { /* static scratch buffer OK (single threaded) */ - static char cmd[LNET_SINGLE_TEXTBUF_NOB]; - - struct list_head nets; - struct list_head gateways; - struct list_head *tmp1; - struct list_head *tmp2; - __u32 net; - lnet_nid_t nid; - struct lnet_text_buf_t *ltb; - int rc; - char *sep; - char *token = str; - int ntokens = 0; - int myrc = -1; - unsigned int hops; - int got_hops = 0; - unsigned int priority = 0; + static char cmd[LNET_SINGLE_TEXTBUF_NOB]; + + struct list_head nets; + struct list_head gateways; + struct list_head *tmp1; + struct list_head *tmp2; + __u32 net; + lnet_nid_t nid; + struct lnet_text_buf_t *ltb; + int rc; + char *sep; + char *token = str; + int ntokens = 0; + int myrc = -1; + unsigned int hops; + int got_hops = 0; + unsigned int priority = 0; INIT_LIST_HEAD(&gateways); INIT_LIST_HEAD(&nets); @@ -772,7 +772,7 @@ lnet_parse_route(char *str, int *im_a_router) static int lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router) { - struct lnet_text_buf_t *ltb; + struct lnet_text_buf_t *ltb; while (!list_empty(tbs)) { ltb = list_entry(tbs->next, struct lnet_text_buf_t, ltb_list); @@ -792,8 +792,8 @@ lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router) int lnet_parse_routes(char *routes, int *im_a_router) { - struct list_head tbs; - int rc = 0; + struct list_head tbs; + int rc = 0; *im_a_router = 0; @@ -814,8 +814,8 @@ static int lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip) { LIST_HEAD(list); - int rc; - int i; + int rc; + int i; rc = cfs_ip_addr_parse(token, len, &list); if (rc != 0) @@ -834,13 +834,13 @@ lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip) { static char tokens[LNET_SINGLE_TEXTBUF_NOB]; - int matched = 0; - int ntokens = 0; - int len; + int matched = 0; + int ntokens = 0; + int len; char *net = NULL; char *sep; char *token; - int rc; + int rc; LASSERT(strlen(net_entry) < sizeof(tokens)); @@ -889,8 +889,8 @@ lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip) static __u32 lnet_netspec2net(char *netspec) { - char *bracket = strchr(netspec, '('); - __u32 net; + char *bracket = strchr(netspec, '('); + __u32 net; if (bracket != NULL) *bracket = 0; @@ -906,15 +906,15 @@ lnet_netspec2net(char *netspec) static int lnet_splitnets(char *source, struct list_head *nets) { - int offset = 0; - int offset2; - int len; - struct lnet_text_buf_t *tb; - struct lnet_text_buf_t *tb2; - struct list_head *t; - char *sep; - char *bracket; - __u32 net; + int offset = 0; + int offset2; + int len; + struct lnet_text_buf_t *tb; + struct lnet_text_buf_t *tb2; + struct list_head *t; + char *sep; + char *bracket; + __u32 net; LASSERT(!list_empty(nets)); LASSERT(nets->next == nets->prev); /* single entry */ @@ -986,22 +986,22 @@ lnet_splitnets(char *source, struct list_head *nets) static int lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) { - static char networks[LNET_SINGLE_TEXTBUF_NOB]; - static char source[LNET_SINGLE_TEXTBUF_NOB]; - - struct list_head raw_entries; - struct list_head matched_nets; - struct list_head current_nets; - struct list_head *t; - struct list_head *t2; - struct lnet_text_buf_t *tb; - struct lnet_text_buf_t *tb2; - __u32 net1; - __u32 net2; - int len; - int count; - int dup; - int rc; + static char networks[LNET_SINGLE_TEXTBUF_NOB]; + static char source[LNET_SINGLE_TEXTBUF_NOB]; + + struct list_head raw_entries; + struct list_head matched_nets; + struct list_head current_nets; + struct list_head *t; + struct list_head *t2; + struct lnet_text_buf_t *tb; + struct lnet_text_buf_t *tb2; + __u32 net1; + __u32 net2; + int len; + int count; + int dup; + int rc; INIT_LIST_HEAD(&raw_entries); if (lnet_str2tbs_sep(&raw_entries, ip2nets) < 0) { @@ -1112,15 +1112,15 @@ lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip) static int lnet_ipaddr_enumerate(__u32 **ipaddrsp) { - int up; - __u32 netmask; - __u32 *ipaddrs; - __u32 *ipaddrs2; - int nip; - char **ifnames; - int nif = libcfs_ipif_enumerate(&ifnames); - int i; - int rc; + int up; + __u32 netmask; + __u32 *ipaddrs; + __u32 *ipaddrs2; + int nip; + char **ifnames; + int nif = lnet_ipif_enumerate(&ifnames); + int i; + int rc; if (nif <= 0) return nif; @@ -1128,7 +1128,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) LIBCFS_ALLOC(ipaddrs, nif * sizeof(*ipaddrs)); if (ipaddrs == NULL) { CERROR("Can't allocate ipaddrs[%d]\n", nif); - libcfs_ipif_free_enumeration(ifnames, nif); + lnet_ipif_free_enumeration(ifnames, nif); return -ENOMEM; } @@ -1136,8 +1136,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) if (!strcmp(ifnames[i], "lo")) continue; - rc = libcfs_ipif_query(ifnames[i], &up, - &ipaddrs[nip], &netmask); + rc = lnet_ipif_query(ifnames[i], &up, &ipaddrs[nip], &netmask); if (rc != 0) { CWARN("Can't query interface %s: %d\n", ifnames[i], rc); @@ -1153,7 +1152,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) nip++; } - libcfs_ipif_free_enumeration(ifnames, nif); + lnet_ipif_free_enumeration(ifnames, nif); if (nip == nif) { *ipaddrsp = ipaddrs; @@ -1178,9 +1177,9 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) int lnet_parse_ip2nets(char **networksp, char *ip2nets) { - __u32 *ipaddrs = NULL; - int nip = lnet_ipaddr_enumerate(&ipaddrs); - int rc; + __u32 *ipaddrs = NULL; + int nip = lnet_ipaddr_enumerate(&ipaddrs); + int rc; if (nip < 0) { LCONSOLE_ERROR_MSG(0x117, @@ -1215,14 +1214,14 @@ lnet_parse_ip2nets(char **networksp, char *ip2nets) int lnet_set_ip_niaddr(lnet_ni_t *ni) { - __u32 net = LNET_NIDNET(ni->ni_nid); + __u32 net = LNET_NIDNET(ni->ni_nid); char **names; - int n; - __u32 ip; - __u32 netmask; - int up; - int i; - int rc; + int n; + __u32 ip; + __u32 netmask; + int up; + int i; + int rc; /* Convenience for LNDs that use the IP address of a local interface as * the local address part of their NID */ @@ -1237,8 +1236,7 @@ lnet_set_ip_niaddr(lnet_ni_t *ni) return -EPERM; } - rc = libcfs_ipif_query(ni->ni_interfaces[0], - &up, &ip, &netmask); + rc = lnet_ipif_query(ni->ni_interfaces[0], &up, &ip, &netmask); if (rc != 0) { CERROR("Net %s can't query interface %s: %d\n", libcfs_net2str(net), ni->ni_interfaces[0], rc); @@ -1255,7 +1253,7 @@ lnet_set_ip_niaddr(lnet_ni_t *ni) return 0; } - n = libcfs_ipif_enumerate(&names); + n = lnet_ipif_enumerate(&names); if (n <= 0) { CERROR("Net %s can't enumerate interfaces: %d\n", libcfs_net2str(net), n); @@ -1266,8 +1264,7 @@ lnet_set_ip_niaddr(lnet_ni_t *ni) if (!strcmp(names[i], "lo")) /* skip the loopback IF */ continue; - rc = libcfs_ipif_query(names[i], &up, &ip, &netmask); - + rc = lnet_ipif_query(names[i], &up, &ip, &netmask); if (rc != 0) { CWARN("Net %s can't query interface %s: %d\n", libcfs_net2str(net), names[i], rc); @@ -1280,13 +1277,13 @@ lnet_set_ip_niaddr(lnet_ni_t *ni) continue; } - libcfs_ipif_free_enumeration(names, n); + lnet_ipif_free_enumeration(names, n); ni->ni_nid = LNET_MKNID(net, ip); return 0; } CERROR("Net %s can't find any interfaces\n", libcfs_net2str(net)); - libcfs_ipif_free_enumeration(names, n); + lnet_ipif_free_enumeration(names, n); return -ENOENT; } EXPORT_SYMBOL(lnet_set_ip_niaddr); diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c index 5470148f5b64..f19ce9ae6a9a 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-eq.c +++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c @@ -70,7 +70,7 @@ int LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback, lnet_handle_eq_t *handle) { - lnet_eq_t *eq; + lnet_eq_t *eq; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -79,7 +79,7 @@ LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback, * overflow, they don't skip entries, so the queue has the same * apparent capacity at all times */ - count = cfs_power2_roundup(count); + count = roundup_pow_of_two(count); if (callback != LNET_EQ_HANDLER_NONE && count != 0) CWARN("EQ callback is guaranteed to get every event, do you still want to set eqcount %d for polling event which will have locking overhead? Please contact with developer to confirm\n", count); @@ -151,13 +151,13 @@ EXPORT_SYMBOL(LNetEQAlloc); int LNetEQFree(lnet_handle_eq_t eqh) { - struct lnet_eq *eq; - lnet_event_t *events = NULL; - int **refs = NULL; - int *ref; - int rc = 0; - int size = 0; - int i; + struct lnet_eq *eq; + lnet_event_t *events = NULL; + int **refs = NULL; + int *ref; + int rc = 0; + int size = 0; + int i; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -185,13 +185,13 @@ LNetEQFree(lnet_handle_eq_t eqh) } /* stash for free after lock dropped */ - events = eq->eq_events; - size = eq->eq_size; - refs = eq->eq_refs; + events = eq->eq_events; + size = eq->eq_size; + refs = eq->eq_refs; lnet_res_lh_invalidate(&eq->eq_lh); list_del(&eq->eq_list); - lnet_eq_free_locked(eq); + lnet_eq_free(eq); out: lnet_eq_wait_unlock(); lnet_res_unlock(LNET_LOCK_EX); @@ -237,9 +237,9 @@ lnet_eq_enqueue_event(lnet_eq_t *eq, lnet_event_t *ev) static int lnet_eq_dequeue_event(lnet_eq_t *eq, lnet_event_t *ev) { - int new_index = eq->eq_deq_seq & (eq->eq_size - 1); - lnet_event_t *new_event = &eq->eq_events[new_index]; - int rc; + int new_index = eq->eq_deq_seq & (eq->eq_size - 1); + lnet_event_t *new_event = &eq->eq_events[new_index]; + int rc; /* must called with lnet_eq_wait_lock hold */ if (LNET_SEQ_GT(eq->eq_deq_seq, new_event->sequence)) @@ -323,10 +323,10 @@ static int lnet_eq_wait_locked(int *timeout_ms) __must_hold(&the_lnet.ln_eq_wait_lock) { - int tms = *timeout_ms; - int wait; - wait_queue_t wl; - unsigned long now; + int tms = *timeout_ms; + int wait; + wait_queue_t wl; + unsigned long now; if (tms == 0) return -1; /* don't want to wait and no new event */ @@ -392,9 +392,9 @@ int LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, int timeout_ms, lnet_event_t *event, int *which) { - int wait = 1; - int rc; - int i; + int wait = 1; + int rc; + int i; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index 89d660fefd48..758f5bedef7e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -74,7 +74,7 @@ lnet_md_unlink(lnet_libmd_t *md) CDEBUG(D_NET, "Unlinking md %p\n", md); if (md->md_eq != NULL) { - int cpt = lnet_cpt_of_cookie(md->md_lh.lh_cookie); + int cpt = lnet_cpt_of_cookie(md->md_lh.lh_cookie); LASSERT(*md->md_eq->eq_refs[cpt] > 0); (*md->md_eq->eq_refs[cpt])--; @@ -82,15 +82,15 @@ lnet_md_unlink(lnet_libmd_t *md) LASSERT(!list_empty(&md->md_list)); list_del_init(&md->md_list); - lnet_md_free_locked(md); + lnet_md_free(md); } static int lnet_md_build(lnet_libmd_t *lmd, lnet_md_t *umd, int unlink) { - int i; + int i; unsigned int niov; - int total_length = 0; + int total_length = 0; lmd->md_me = NULL; lmd->md_start = umd->start; @@ -268,10 +268,10 @@ LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd, { LIST_HEAD(matches); LIST_HEAD(drops); - struct lnet_me *me; - struct lnet_libmd *md; - int cpt; - int rc; + struct lnet_me *me; + struct lnet_libmd *md; + int cpt; + int rc; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -320,7 +320,7 @@ LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd, return 0; failed: - lnet_md_free_locked(md); + lnet_md_free(md); lnet_res_unlock(cpt); return rc; @@ -346,9 +346,9 @@ EXPORT_SYMBOL(LNetMDAttach); int LNetMDBind(lnet_md_t umd, lnet_unlink_t unlink, lnet_handle_md_t *handle) { - lnet_libmd_t *md; - int cpt; - int rc; + lnet_libmd_t *md; + int cpt; + int rc; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -381,7 +381,7 @@ LNetMDBind(lnet_md_t umd, lnet_unlink_t unlink, lnet_handle_md_t *handle) return 0; failed: - lnet_md_free_locked(md); + lnet_md_free(md); lnet_res_unlock(cpt); return rc; @@ -421,9 +421,9 @@ EXPORT_SYMBOL(LNetMDBind); int LNetMDUnlink(lnet_handle_md_t mdh) { - lnet_event_t ev; - lnet_libmd_t *md; - int cpt; + lnet_event_t ev; + lnet_libmd_t *md; + int cpt; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); diff --git a/drivers/staging/lustre/lnet/lnet/lib-me.c b/drivers/staging/lustre/lnet/lnet/lib-me.c index a3f929244711..42fc99ef9f80 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-me.c +++ b/drivers/staging/lustre/lnet/lnet/lib-me.c @@ -80,8 +80,8 @@ LNetMEAttach(unsigned int portal, lnet_handle_me_t *handle) { struct lnet_match_table *mtable; - struct lnet_me *me; - struct list_head *head; + struct lnet_me *me; + struct list_head *head; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -151,10 +151,10 @@ LNetMEInsert(lnet_handle_me_t current_meh, lnet_unlink_t unlink, lnet_ins_pos_t pos, lnet_handle_me_t *handle) { - struct lnet_me *current_me; - struct lnet_me *new_me; - struct lnet_portal *ptl; - int cpt; + struct lnet_me *current_me; + struct lnet_me *new_me; + struct lnet_portal *ptl; + int cpt; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -172,7 +172,7 @@ LNetMEInsert(lnet_handle_me_t current_meh, current_me = lnet_handle2me(¤t_meh); if (current_me == NULL) { - lnet_me_free_locked(new_me); + lnet_me_free(new_me); lnet_res_unlock(cpt); return -ENOENT; @@ -183,7 +183,7 @@ LNetMEInsert(lnet_handle_me_t current_meh, ptl = the_lnet.ln_portals[current_me->me_portal]; if (lnet_ptl_is_unique(ptl)) { /* nosense to insertion on unique portal */ - lnet_me_free_locked(new_me); + lnet_me_free(new_me); lnet_res_unlock(cpt); return -EPERM; } @@ -228,10 +228,10 @@ EXPORT_SYMBOL(LNetMEInsert); int LNetMEUnlink(lnet_handle_me_t meh) { - lnet_me_t *me; - lnet_libmd_t *md; - lnet_event_t ev; - int cpt; + lnet_me_t *me; + lnet_libmd_t *md; + lnet_event_t ev; + int cpt; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -276,7 +276,7 @@ lnet_me_unlink(lnet_me_t *me) } lnet_res_lh_invalidate(&me->me_lh); - lnet_me_free_locked(me); + lnet_me_free(me); } #if 0 diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index c2fb70e5fc4e..433faae9a2ff 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -49,10 +49,10 @@ MODULE_PARM_DESC(local_nid_dist_zero, "Reserved"); int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold) { - lnet_test_peer_t *tp; - struct list_head *el; - struct list_head *next; - struct list_head cull; + lnet_test_peer_t *tp; + struct list_head *el; + struct list_head *next; + struct list_head cull; LASSERT(the_lnet.ln_init); @@ -103,10 +103,10 @@ static int fail_peer(lnet_nid_t nid, int outgoing) { lnet_test_peer_t *tp; - struct list_head *el; - struct list_head *next; - struct list_head cull; - int fail = 0; + struct list_head *el; + struct list_head *next; + struct list_head cull; + int fail = 0; INIT_LIST_HEAD(&cull); @@ -175,7 +175,7 @@ lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset, unsigned int nob) { /* NB diov, siov are READ-ONLY */ - unsigned int this_nob; + unsigned int this_nob; if (nob == 0) return; @@ -236,8 +236,8 @@ lnet_extract_iov(int dst_niov, struct kvec *dst, /* Initialise 'dst' to the subset of 'src' starting at 'offset', * for exactly 'len' bytes, and return the number of entries. * NB not destructive to 'src' */ - unsigned int frag_len; - unsigned int niov; + unsigned int frag_len; + unsigned int niov; if (len == 0) /* no data => */ return 0; /* no frags */ @@ -279,7 +279,7 @@ EXPORT_SYMBOL(lnet_extract_iov); unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *kiov) { - unsigned int nob = 0; + unsigned int nob = 0; while (niov-- > 0) nob += (kiov++)->kiov_len; @@ -294,9 +294,9 @@ lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset, unsigned int nob) { /* NB diov, siov are READ-ONLY */ - unsigned int this_nob; - char *daddr = NULL; - char *saddr = NULL; + unsigned int this_nob; + char *daddr = NULL; + char *saddr = NULL; if (nob == 0) return; @@ -376,8 +376,8 @@ lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov, unsigned int iovoffset, unsigned int kiovoffset, unsigned int nob) { /* NB iov, kiov are READ-ONLY */ - unsigned int this_nob; - char *addr = NULL; + unsigned int this_nob; + char *addr = NULL; if (nob == 0) return; @@ -447,8 +447,8 @@ lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov, unsigned int nob) { /* NB kiov, iov are READ-ONLY */ - unsigned int this_nob; - char *addr = NULL; + unsigned int this_nob; + char *addr = NULL; if (nob == 0) return; @@ -518,8 +518,8 @@ lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst, /* Initialise 'dst' to the subset of 'src' starting at 'offset', * for exactly 'len' bytes, and return the number of entries. * NB not destructive to 'src' */ - unsigned int frag_len; - unsigned int niov; + unsigned int frag_len; + unsigned int niov; if (len == 0) /* no data => */ return 0; /* no frags */ @@ -565,10 +565,10 @@ static void lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, unsigned int offset, unsigned int mlen, unsigned int rlen) { - unsigned int niov = 0; + unsigned int niov = 0; struct kvec *iov = NULL; - lnet_kiov_t *kiov = NULL; - int rc; + lnet_kiov_t *kiov = NULL; + int rc; LASSERT(!in_interrupt()); LASSERT(mlen == 0 || msg != NULL); @@ -642,8 +642,8 @@ lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target, static void lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) { - void *priv = msg->msg_private; - int rc; + void *priv = msg->msg_private; + int rc; LASSERT(!in_interrupt()); LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || @@ -657,7 +657,7 @@ lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) static int lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) { - int rc; + int rc; LASSERT(!msg->msg_sending); LASSERT(msg->msg_receiving); @@ -700,7 +700,7 @@ lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp) static inline int lnet_peer_is_alive(lnet_peer_t *lp, unsigned long now) { - int alive; + int alive; unsigned long deadline; LASSERT(lnet_peer_aliveness_enabled(lp)); @@ -785,10 +785,10 @@ lnet_peer_alive_locked(lnet_peer_t *lp) static int lnet_post_send_locked(lnet_msg_t *msg, int do_send) { - lnet_peer_t *lp = msg->msg_txpeer; - lnet_ni_t *ni = lp->lp_ni; - int cpt = msg->msg_tx_cpt; - struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; + lnet_peer_t *lp = msg->msg_txpeer; + lnet_ni_t *ni = lp->lp_ni; + int cpt = msg->msg_tx_cpt; + struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; /* non-lnet_send() callers have checked before */ LASSERT(!do_send || msg->msg_tx_delayed); @@ -871,8 +871,8 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) static lnet_rtrbufpool_t * lnet_msg2bufpool(lnet_msg_t *msg) { - lnet_rtrbufpool_t *rbp; - int cpt; + lnet_rtrbufpool_t *rbp; + int cpt; LASSERT(msg->msg_rx_committed); @@ -894,9 +894,9 @@ lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv) /* lnet_parse is going to lnet_net_unlock immediately after this, so it * sets do_recv FALSE and I don't do the unlock/send/lock bit. I * return EAGAIN if msg blocked and 0 if received or OK to receive */ - lnet_peer_t *lp = msg->msg_rxpeer; - lnet_rtrbufpool_t *rbp; - lnet_rtrbuf_t *rb; + lnet_peer_t *lp = msg->msg_rxpeer; + lnet_rtrbufpool_t *rbp; + lnet_rtrbuf_t *rb; LASSERT(msg->msg_iov == NULL); LASSERT(msg->msg_kiov == NULL); @@ -967,11 +967,11 @@ lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv) void lnet_return_tx_credits_locked(lnet_msg_t *msg) { - lnet_peer_t *txpeer = msg->msg_txpeer; - lnet_msg_t *msg2; + lnet_peer_t *txpeer = msg->msg_txpeer; + lnet_msg_t *msg2; if (msg->msg_txcredit) { - struct lnet_ni *ni = txpeer->lp_ni; + struct lnet_ni *ni = txpeer->lp_ni; struct lnet_tx_queue *tq = ni->ni_tx_queues[msg->msg_tx_cpt]; /* give back NI txcredits */ @@ -1025,12 +1025,12 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg) void lnet_return_rx_credits_locked(lnet_msg_t *msg) { - lnet_peer_t *rxpeer = msg->msg_rxpeer; - lnet_msg_t *msg2; + lnet_peer_t *rxpeer = msg->msg_rxpeer; + lnet_msg_t *msg2; if (msg->msg_rtrcredit) { /* give back global router credits */ - lnet_rtrbuf_t *rb; + lnet_rtrbuf_t *rb; lnet_rtrbufpool_t *rbp; /* NB If a msg ever blocks for a buffer in rbp_msgs, it stays @@ -1122,13 +1122,13 @@ lnet_compare_routes(lnet_route_t *r1, lnet_route_t *r2) static lnet_peer_t * lnet_find_route_locked(lnet_ni_t *ni, lnet_nid_t target, lnet_nid_t rtr_nid) { - lnet_remotenet_t *rnet; - lnet_route_t *rtr; - lnet_route_t *rtr_best; - lnet_route_t *rtr_last; - struct lnet_peer *lp_best; - struct lnet_peer *lp; - int rc; + lnet_remotenet_t *rnet; + lnet_route_t *rtr; + lnet_route_t *rtr_best; + lnet_route_t *rtr_last; + struct lnet_peer *lp_best; + struct lnet_peer *lp; + int rc; /* If @rtr_nid is not LNET_NID_ANY, return the gateway with * rtr_nid nid, otherwise find the best gateway I can use */ @@ -1182,13 +1182,13 @@ lnet_find_route_locked(lnet_ni_t *ni, lnet_nid_t target, lnet_nid_t rtr_nid) int lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid) { - lnet_nid_t dst_nid = msg->msg_target.nid; - struct lnet_ni *src_ni; - struct lnet_ni *local_ni; - struct lnet_peer *lp; - int cpt; - int cpt2; - int rc; + lnet_nid_t dst_nid = msg->msg_target.nid; + struct lnet_ni *src_ni; + struct lnet_ni *local_ni; + struct lnet_peer *lp; + int cpt; + int cpt2; + int rc; /* NB: rtr_nid is set to LNET_NID_ANY for all current use-cases, * but we might want to use pre-determined router for ACK/REPLY @@ -1364,7 +1364,7 @@ lnet_drop_message(lnet_ni_t *ni, int cpt, void *private, unsigned int nob) static void lnet_recv_put(lnet_ni_t *ni, lnet_msg_t *msg) { - lnet_hdr_t *hdr = &msg->msg_hdr; + lnet_hdr_t *hdr = &msg->msg_hdr; if (msg->msg_wanted != 0) lnet_setpayloadbuffer(msg); @@ -1383,9 +1383,9 @@ lnet_recv_put(lnet_ni_t *ni, lnet_msg_t *msg) static int lnet_parse_put(lnet_ni_t *ni, lnet_msg_t *msg) { - lnet_hdr_t *hdr = &msg->msg_hdr; - struct lnet_match_info info; - int rc; + lnet_hdr_t *hdr = &msg->msg_hdr; + struct lnet_match_info info; + int rc; /* Convert put fields to host byte order */ hdr->msg.put.match_bits = le64_to_cpu(hdr->msg.put.match_bits); @@ -1433,24 +1433,24 @@ lnet_parse_put(lnet_ni_t *ni, lnet_msg_t *msg) static int lnet_parse_get(lnet_ni_t *ni, lnet_msg_t *msg, int rdma_get) { - struct lnet_match_info info; - lnet_hdr_t *hdr = &msg->msg_hdr; - lnet_handle_wire_t reply_wmd; - int rc; + struct lnet_match_info info; + lnet_hdr_t *hdr = &msg->msg_hdr; + lnet_handle_wire_t reply_wmd; + int rc; /* Convert get fields to host byte order */ - hdr->msg.get.match_bits = le64_to_cpu(hdr->msg.get.match_bits); - hdr->msg.get.ptl_index = le32_to_cpu(hdr->msg.get.ptl_index); - hdr->msg.get.sink_length = le32_to_cpu(hdr->msg.get.sink_length); - hdr->msg.get.src_offset = le32_to_cpu(hdr->msg.get.src_offset); - - info.mi_id.nid = hdr->src_nid; - info.mi_id.pid = hdr->src_pid; - info.mi_opc = LNET_MD_OP_GET; - info.mi_portal = hdr->msg.get.ptl_index; - info.mi_rlength = hdr->msg.get.sink_length; - info.mi_roffset = hdr->msg.get.src_offset; - info.mi_mbits = hdr->msg.get.match_bits; + hdr->msg.get.match_bits = le64_to_cpu(hdr->msg.get.match_bits); + hdr->msg.get.ptl_index = le32_to_cpu(hdr->msg.get.ptl_index); + hdr->msg.get.sink_length = le32_to_cpu(hdr->msg.get.sink_length); + hdr->msg.get.src_offset = le32_to_cpu(hdr->msg.get.src_offset); + + info.mi_id.nid = hdr->src_nid; + info.mi_id.pid = hdr->src_pid; + info.mi_opc = LNET_MD_OP_GET; + info.mi_portal = hdr->msg.get.ptl_index; + info.mi_rlength = hdr->msg.get.sink_length; + info.mi_roffset = hdr->msg.get.src_offset; + info.mi_mbits = hdr->msg.get.match_bits; rc = lnet_ptl_match_md(&info, msg); if (rc == LNET_MATCHMD_DROP) { @@ -1497,13 +1497,13 @@ lnet_parse_get(lnet_ni_t *ni, lnet_msg_t *msg, int rdma_get) static int lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg) { - void *private = msg->msg_private; - lnet_hdr_t *hdr = &msg->msg_hdr; + void *private = msg->msg_private; + lnet_hdr_t *hdr = &msg->msg_hdr; lnet_process_id_t src = {0}; - lnet_libmd_t *md; - int rlength; - int mlength; - int cpt; + lnet_libmd_t *md; + int rlength; + int mlength; + int cpt; cpt = lnet_cpt_of_cookie(hdr->msg.reply.dst_wmd.wh_object_cookie); lnet_res_lock(cpt); @@ -1562,10 +1562,10 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg) static int lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg) { - lnet_hdr_t *hdr = &msg->msg_hdr; + lnet_hdr_t *hdr = &msg->msg_hdr; lnet_process_id_t src = {0}; - lnet_libmd_t *md; - int cpt; + lnet_libmd_t *md; + int cpt; src.nid = hdr->src_nid; src.pid = hdr->src_pid; @@ -1612,7 +1612,7 @@ lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg) static int lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg) { - int rc = 0; + int rc = 0; if (msg->msg_rxpeer->lp_rtrcredits <= 0 || lnet_msg2bufpool(msg)->rbp_credits <= 0) { @@ -1713,15 +1713,15 @@ int lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, void *private, int rdma_req) { - int rc = 0; - int cpt; - int for_me; - struct lnet_msg *msg; - lnet_pid_t dest_pid; - lnet_nid_t dest_nid; - lnet_nid_t src_nid; - __u32 payload_length; - __u32 type; + int rc = 0; + int cpt; + int for_me; + struct lnet_msg *msg; + lnet_pid_t dest_pid; + lnet_nid_t dest_nid; + lnet_nid_t src_nid; + __u32 payload_length; + __u32 type; LASSERT(!in_interrupt()); @@ -1945,8 +1945,8 @@ void lnet_drop_delayed_msg_list(struct list_head *head, char *reason) { while (!list_empty(head)) { - lnet_process_id_t id = {0}; - lnet_msg_t *msg; + lnet_process_id_t id = {0}; + lnet_msg_t *msg; msg = list_entry(head->next, lnet_msg_t, msg_list); list_del(&msg->msg_list); @@ -1986,8 +1986,8 @@ void lnet_recv_delayed_msg_list(struct list_head *head) { while (!list_empty(head)) { - lnet_msg_t *msg; - lnet_process_id_t id; + lnet_msg_t *msg; + lnet_process_id_t id; msg = list_entry(head->next, lnet_msg_t, msg_list); list_del(&msg->msg_list); @@ -2063,10 +2063,10 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack, __u64 match_bits, unsigned int offset, __u64 hdr_data) { - struct lnet_msg *msg; - struct lnet_libmd *md; - int cpt; - int rc; + struct lnet_msg *msg; + struct lnet_libmd *md; + int cpt; + int rc; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -2153,10 +2153,10 @@ lnet_create_reply_msg(lnet_ni_t *ni, lnet_msg_t *getmsg) * CAVEAT EMPTOR: 'getmsg' is the original GET, which is freed when * lnet_finalize() is called on it, so the LND must call this first */ - struct lnet_msg *msg = lnet_msg_alloc(); - struct lnet_libmd *getmd = getmsg->msg_md; - lnet_process_id_t peer_id = getmsg->msg_target; - int cpt; + struct lnet_msg *msg = lnet_msg_alloc(); + struct lnet_libmd *getmd = getmsg->msg_md; + lnet_process_id_t peer_id = getmsg->msg_target; + int cpt; LASSERT(!getmsg->msg_target_is_router); LASSERT(!getmsg->msg_routing); @@ -2263,10 +2263,10 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh, lnet_process_id_t target, unsigned int portal, __u64 match_bits, unsigned int offset) { - struct lnet_msg *msg; - struct lnet_libmd *md; - int cpt; - int rc; + struct lnet_msg *msg; + struct lnet_libmd *md; + int cpt; + int rc; LASSERT(the_lnet.ln_init); LASSERT(the_lnet.ln_refcount > 0); @@ -2353,14 +2353,14 @@ EXPORT_SYMBOL(LNetGet); int LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) { - struct list_head *e; - struct lnet_ni *ni; - lnet_remotenet_t *rnet; - __u32 dstnet = LNET_NIDNET(dstnid); - int hops; - int cpt; - __u32 order = 2; - struct list_head *rn_list; + struct list_head *e; + struct lnet_ni *ni; + lnet_remotenet_t *rnet; + __u32 dstnet = LNET_NIDNET(dstnid); + int hops; + int cpt; + __u32 order = 2; + struct list_head *rn_list; /* if !local_nid_dist_zero, I don't return a distance of 0 ever * (when lustre sees a distance of 0, it substitutes 0@lo), so I @@ -2434,27 +2434,3 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) return -EHOSTUNREACH; } EXPORT_SYMBOL(LNetDist); - -/** - * Set the number of asynchronous messages expected from a target process. - * - * This function is only meaningful for userspace callers. It's a no-op when - * called from kernel. - * - * Asynchronous messages are those that can come from a target when the - * userspace process is not waiting for IO to complete; e.g., AST callbacks - * from Lustre servers. Specifying the expected number of such messages - * allows them to be eagerly received when user process is not running in - * LNet; otherwise network errors may occur. - * - * \param id Process ID of the target process. - * \param nasync Number of asynchronous messages expected from the target. - * - * \return 0 on success, and an error code otherwise. - */ -int -LNetSetAsync(lnet_process_id_t id, int nasync) -{ - return 0; -} -EXPORT_SYMBOL(LNetSetAsync); diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index a46ccbf6608f..43977e8dffbb 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -60,8 +60,8 @@ lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev) void lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type) { - lnet_hdr_t *hdr = &msg->msg_hdr; - lnet_event_t *ev = &msg->msg_ev; + lnet_hdr_t *hdr = &msg->msg_hdr; + lnet_event_t *ev = &msg->msg_ev; LASSERT(!msg->msg_routing); @@ -73,7 +73,7 @@ lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type) ev->target.pid = le32_to_cpu(hdr->dest_pid); ev->initiator.nid = LNET_NID_ANY; ev->initiator.pid = the_lnet.ln_pid; - ev->sender = LNET_NID_ANY; + ev->sender = LNET_NID_ANY; } else { /* event for passive message */ @@ -82,9 +82,9 @@ lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type) ev->initiator.pid = hdr->src_pid; ev->initiator.nid = hdr->src_nid; ev->rlength = hdr->payload_length; - ev->sender = msg->msg_from; - ev->mlength = msg->msg_wanted; - ev->offset = msg->msg_offset; + ev->sender = msg->msg_from; + ev->mlength = msg->msg_wanted; + ev->offset = msg->msg_offset; } switch (ev_type) { @@ -137,7 +137,7 @@ void lnet_msg_commit(lnet_msg_t *msg, int cpt) { struct lnet_msg_container *container = the_lnet.ln_msg_containers[cpt]; - lnet_counters_t *counters = the_lnet.ln_counters[cpt]; + lnet_counters_t *counters = the_lnet.ln_counters[cpt]; /* routed message can be committed for both receiving and sending */ LASSERT(!msg->msg_tx_committed); @@ -170,7 +170,7 @@ static void lnet_msg_decommit_tx(lnet_msg_t *msg, int status) { lnet_counters_t *counters; - lnet_event_t *ev = &msg->msg_ev; + lnet_event_t *ev = &msg->msg_ev; LASSERT(msg->msg_tx_committed); if (status != 0) @@ -219,8 +219,8 @@ lnet_msg_decommit_tx(lnet_msg_t *msg, int status) static void lnet_msg_decommit_rx(lnet_msg_t *msg, int status) { - lnet_counters_t *counters; - lnet_event_t *ev = &msg->msg_ev; + lnet_counters_t *counters; + lnet_event_t *ev = &msg->msg_ev; LASSERT(!msg->msg_tx_committed); /* decommitted or never committed */ LASSERT(msg->msg_rx_committed); @@ -273,7 +273,7 @@ lnet_msg_decommit_rx(lnet_msg_t *msg, int status) void lnet_msg_decommit(lnet_msg_t *msg, int cpt, int status) { - int cpt2 = cpt; + int cpt2 = cpt; LASSERT(msg->msg_tx_committed || msg->msg_rx_committed); LASSERT(msg->msg_onactivelist); @@ -335,8 +335,8 @@ lnet_msg_attach_md(lnet_msg_t *msg, lnet_libmd_t *md, void lnet_msg_detach_md(lnet_msg_t *msg, int status) { - lnet_libmd_t *md = msg->msg_md; - int unlink; + lnet_libmd_t *md = msg->msg_md; + int unlink; /* Now it's safe to drop my caller's ref */ md->md_refcount--; @@ -359,8 +359,8 @@ static int lnet_complete_msg_locked(lnet_msg_t *msg, int cpt) { lnet_handle_wire_t ack_wmd; - int rc; - int status = msg->msg_ev.status; + int rc; + int status = msg->msg_ev.status; LASSERT(msg->msg_onactivelist); @@ -427,18 +427,18 @@ lnet_complete_msg_locked(lnet_msg_t *msg, int cpt) } lnet_msg_decommit(msg, cpt, status); - lnet_msg_free_locked(msg); + lnet_msg_free(msg); return 0; } void lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int status) { - struct lnet_msg_container *container; - int my_slot; - int cpt; - int rc; - int i; + struct lnet_msg_container *container; + int my_slot; + int cpt; + int rc; + int i; LASSERT(!in_interrupt()); @@ -534,7 +534,7 @@ EXPORT_SYMBOL(lnet_finalize); void lnet_msg_container_cleanup(struct lnet_msg_container *container) { - int count = 0; + int count = 0; if (container->msc_init == 0) return; @@ -568,7 +568,7 @@ lnet_msg_container_cleanup(struct lnet_msg_container *container) int lnet_msg_container_setup(struct lnet_msg_container *container, int cpt) { - int rc; + int rc; container->msc_init = 1; @@ -608,7 +608,7 @@ void lnet_msg_containers_destroy(void) { struct lnet_msg_container *container; - int i; + int i; if (the_lnet.ln_msg_containers == NULL) return; @@ -624,8 +624,8 @@ int lnet_msg_containers_create(void) { struct lnet_msg_container *container; - int rc; - int i; + int rc; + int i; the_lnet.ln_msg_containers = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*container)); diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 3ba0da919b41..84707c5cb464 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -39,7 +39,7 @@ #include "../../include/linux/lnet/lib-lnet.h" /* NB: add /proc interfaces in upcoming patches */ -int portal_rotor = LNET_PTL_ROTOR_HASH_RT; +int portal_rotor = LNET_PTL_ROTOR_HASH_RT; module_param(portal_rotor, int, 0644); MODULE_PARM_DESC(portal_rotor, "redirect PUTs to different cpu-partitions"); @@ -47,8 +47,8 @@ static int lnet_ptl_match_type(unsigned int index, lnet_process_id_t match_id, __u64 mbits, __u64 ignore_bits) { - struct lnet_portal *ptl = the_lnet.ln_portals[index]; - int unique; + struct lnet_portal *ptl = the_lnet.ln_portals[index]; + int unique; unique = ignore_bits == 0 && match_id.nid != LNET_NID_ANY && @@ -89,7 +89,7 @@ static void lnet_ptl_enable_mt(struct lnet_portal *ptl, int cpt) { struct lnet_match_table *mtable = ptl->ptl_mtables[cpt]; - int i; + int i; /* with hold of both lnet_res_lock(cpt) and lnet_ptl_lock */ LASSERT(lnet_ptl_is_wildcard(ptl)); @@ -114,7 +114,7 @@ static void lnet_ptl_disable_mt(struct lnet_portal *ptl, int cpt) { struct lnet_match_table *mtable = ptl->ptl_mtables[cpt]; - int i; + int i; /* with hold of both lnet_res_lock(cpt) and lnet_ptl_lock */ LASSERT(lnet_ptl_is_wildcard(ptl)); @@ -141,9 +141,9 @@ lnet_try_match_md(lnet_libmd_t *md, { /* ALWAYS called holding the lnet_res_lock, and can't lnet_res_unlock; * lnet_match_blocked_msg() relies on this to avoid races */ - unsigned int offset; - unsigned int mlength; - lnet_me_t *me = md->md_me; + unsigned int offset; + unsigned int mlength; + lnet_me_t *me = md->md_me; /* MD exhausted */ if (lnet_md_exhausted(md)) @@ -227,7 +227,7 @@ struct lnet_match_table * lnet_mt_of_attach(unsigned int index, lnet_process_id_t id, __u64 mbits, __u64 ignore_bits, lnet_ins_pos_t pos) { - struct lnet_portal *ptl; + struct lnet_portal *ptl; struct lnet_match_table *mtable; /* NB: called w/o lock */ @@ -261,11 +261,11 @@ static struct lnet_match_table * lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) { struct lnet_match_table *mtable; - struct lnet_portal *ptl; - unsigned int nmaps; - unsigned int rotor; - unsigned int cpt; - bool routed; + struct lnet_portal *ptl; + unsigned int nmaps; + unsigned int rotor; + unsigned int cpt; + bool routed; /* NB: called w/o lock */ LASSERT(info->mi_portal < the_lnet.ln_nportals); @@ -312,8 +312,8 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) static int lnet_mt_test_exhausted(struct lnet_match_table *mtable, int pos) { - __u64 *bmap; - int i; + __u64 *bmap; + int i; if (!lnet_ptl_is_wildcard(the_lnet.ln_portals[mtable->mt_portal])) return 0; @@ -337,7 +337,7 @@ lnet_mt_test_exhausted(struct lnet_match_table *mtable, int pos) static void lnet_mt_set_exhausted(struct lnet_match_table *mtable, int pos, int exhausted) { - __u64 *bmap; + __u64 *bmap; LASSERT(lnet_ptl_is_wildcard(the_lnet.ln_portals[mtable->mt_portal])); LASSERT(pos <= LNET_MT_HASH_IGNORE); @@ -373,11 +373,11 @@ int lnet_mt_match_md(struct lnet_match_table *mtable, struct lnet_match_info *info, struct lnet_msg *msg) { - struct list_head *head; - lnet_me_t *me; - lnet_me_t *tmp; - int exhausted = 0; - int rc; + struct list_head *head; + lnet_me_t *me; + lnet_me_t *tmp; + int exhausted = 0; + int rc; /* any ME with ignore bits? */ if (!list_empty(&mtable->mt_mhash[LNET_MT_HASH_IGNORE])) @@ -428,7 +428,7 @@ lnet_mt_match_md(struct lnet_match_table *mtable, static int lnet_ptl_match_early(struct lnet_portal *ptl, struct lnet_msg *msg) { - int rc; + int rc; /* message arrived before any buffer posting on this portal, * simply delay or drop this message */ @@ -461,9 +461,9 @@ static int lnet_ptl_match_delay(struct lnet_portal *ptl, struct lnet_match_info *info, struct lnet_msg *msg) { - int first = ptl->ptl_mt_maps[0]; /* read w/o lock */ - int rc = 0; - int i; + int first = ptl->ptl_mt_maps[0]; /* read w/o lock */ + int rc = 0; + int i; /* steal buffer from other CPTs, and delay it if nothing to steal, * this function is more expensive than a regular match, but we @@ -472,7 +472,7 @@ lnet_ptl_match_delay(struct lnet_portal *ptl, for (i = 0; i < LNET_CPT_NUMBER; i++) { struct lnet_match_table *mtable; - int cpt; + int cpt; cpt = (first + i) % LNET_CPT_NUMBER; mtable = ptl->ptl_mtables[cpt]; @@ -536,8 +536,8 @@ int lnet_ptl_match_md(struct lnet_match_info *info, struct lnet_msg *msg) { struct lnet_match_table *mtable; - struct lnet_portal *ptl; - int rc; + struct lnet_portal *ptl; + int rc; CDEBUG(D_NET, "Request from %s of length %d into portal %d MB=%#llx\n", libcfs_id2str(info->mi_id), info->mi_rlength, info->mi_portal, @@ -622,13 +622,13 @@ void lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md, struct list_head *matches, struct list_head *drops) { - struct lnet_portal *ptl = the_lnet.ln_portals[me->me_portal]; + struct lnet_portal *ptl = the_lnet.ln_portals[me->me_portal]; struct lnet_match_table *mtable; - struct list_head *head; - lnet_msg_t *tmp; - lnet_msg_t *msg; - int exhausted = 0; - int cpt; + struct list_head *head; + lnet_msg_t *tmp; + lnet_msg_t *msg; + int exhausted = 0; + int cpt; LASSERT(md->md_refcount == 0); /* a brand new MD */ @@ -647,20 +647,20 @@ lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md, head = &ptl->ptl_msg_stealing; again: list_for_each_entry_safe(msg, tmp, head, msg_list) { - struct lnet_match_info info; - lnet_hdr_t *hdr; - int rc; + struct lnet_match_info info; + lnet_hdr_t *hdr; + int rc; LASSERT(msg->msg_rx_delayed || head == &ptl->ptl_msg_stealing); - hdr = &msg->msg_hdr; - info.mi_id.nid = hdr->src_nid; - info.mi_id.pid = hdr->src_pid; - info.mi_opc = LNET_MD_OP_PUT; - info.mi_portal = hdr->msg.put.ptl_index; - info.mi_rlength = hdr->payload_length; - info.mi_roffset = hdr->msg.put.offset; - info.mi_mbits = hdr->msg.put.match_bits; + hdr = &msg->msg_hdr; + info.mi_id.nid = hdr->src_nid; + info.mi_id.pid = hdr->src_pid; + info.mi_opc = LNET_MD_OP_PUT; + info.mi_portal = hdr->msg.put.ptl_index; + info.mi_rlength = hdr->payload_length; + info.mi_roffset = hdr->msg.put.offset; + info.mi_mbits = hdr->msg.put.match_bits; rc = lnet_try_match_md(md, &info, msg); @@ -715,7 +715,7 @@ static void lnet_ptl_cleanup(struct lnet_portal *ptl) { struct lnet_match_table *mtable; - int i; + int i; if (ptl->ptl_mtables == NULL) /* uninitialized portal */ return; @@ -723,9 +723,9 @@ lnet_ptl_cleanup(struct lnet_portal *ptl) LASSERT(list_empty(&ptl->ptl_msg_delayed)); LASSERT(list_empty(&ptl->ptl_msg_stealing)); cfs_percpt_for_each(mtable, i, ptl->ptl_mtables) { - struct list_head *mhash; - lnet_me_t *me; - int j; + struct list_head *mhash; + lnet_me_t *me; + int j; if (mtable->mt_mhash == NULL) /* uninitialized match-table */ continue; @@ -753,9 +753,9 @@ static int lnet_ptl_setup(struct lnet_portal *ptl, int index) { struct lnet_match_table *mtable; - struct list_head *mhash; - int i; - int j; + struct list_head *mhash; + int i; + int j; ptl->ptl_mtables = cfs_percpt_alloc(lnet_cpt_table(), sizeof(struct lnet_match_table)); @@ -798,7 +798,7 @@ lnet_ptl_setup(struct lnet_portal *ptl, int index) void lnet_portals_destroy(void) { - int i; + int i; if (the_lnet.ln_portals == NULL) return; @@ -813,8 +813,8 @@ lnet_portals_destroy(void) int lnet_portals_create(void) { - int size; - int i; + int size; + int i; size = offsetof(struct lnet_portal, ptl_mt_maps[LNET_CPT_NUMBER]); @@ -898,8 +898,8 @@ EXPORT_SYMBOL(LNetSetLazyPortal); int LNetClearLazyPortal(int portal) { - struct lnet_portal *ptl; - LIST_HEAD (zombies); + struct lnet_portal *ptl; + LIST_HEAD(zombies); if (portal < 0 || portal >= the_lnet.ln_nportals) return -EINVAL; diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index f2462e7f04bc..6f7ef4c737cd 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,33 +23,49 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2015 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. + * Lustre is a trademark of Seagate, Inc. */ #define DEBUG_SUBSYSTEM S_LNET -#include "../../../include/linux/libcfs/libcfs.h" - #include <linux/if.h> #include <linux/in.h> +#include <linux/net.h> #include <linux/file.h> +#include <linux/pagemap.h> /* For sys_open & sys_close */ #include <linux/syscalls.h> +#include <net/sock.h> + +#include "../../include/linux/libcfs/libcfs.h" +#include "../../include/linux/lnet/lib-lnet.h" + +static int +kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg) +{ + mm_segment_t oldfs = get_fs(); + int err; + + set_fs(KERNEL_DS); + err = filp->f_op->unlocked_ioctl(filp, cmd, arg); + set_fs(oldfs); + + return err; +} static int -libcfs_sock_ioctl(int cmd, unsigned long arg) +lnet_sock_ioctl(int cmd, unsigned long arg) { - mm_segment_t oldmm = get_fs(); - struct socket *sock; - int rc; - struct file *sock_filp; + struct file *sock_filp; + struct socket *sock; + int rc; - rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock); + rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock); if (rc != 0) { - CERROR ("Can't create socket: %d\n", rc); + CERROR("Can't create socket: %d\n", rc); return rc; } @@ -64,10 +76,7 @@ libcfs_sock_ioctl(int cmd, unsigned long arg) goto out; } - set_fs(KERNEL_DS); - if (sock_filp->f_op->unlocked_ioctl) - rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg); - set_fs(oldmm); + rc = kernel_sock_unlocked_ioctl(sock_filp, cmd, arg); fput(sock_filp); out: @@ -75,12 +84,12 @@ out: } int -libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) +lnet_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask) { - struct ifreq ifr; - int nob; - int rc; - __u32 val; + struct ifreq ifr; + int nob; + int rc; + __u32 val; nob = strnlen(name, IFNAMSIZ); if (nob == IFNAMSIZ) { @@ -88,11 +97,10 @@ libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) return -EINVAL; } - CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ); + CLASSERT(sizeof(ifr.ifr_name) >= IFNAMSIZ); strcpy(ifr.ifr_name, name); - rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr); - + rc = lnet_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get flags for interface %s\n", name); return rc; @@ -104,13 +112,11 @@ libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) *ip = *mask = 0; return 0; } - *up = 1; strcpy(ifr.ifr_name, name); ifr.ifr_addr.sa_family = AF_INET; - rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr); - + rc = lnet_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get IP address for interface %s\n", name); return rc; @@ -121,8 +127,7 @@ libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) strcpy(ifr.ifr_name, name); ifr.ifr_addr.sa_family = AF_INET; - rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr); - + rc = lnet_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get netmask for interface %s\n", name); return rc; @@ -133,23 +138,21 @@ libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) return 0; } - -EXPORT_SYMBOL(libcfs_ipif_query); +EXPORT_SYMBOL(lnet_ipif_query); int -libcfs_ipif_enumerate (char ***namesp) +lnet_ipif_enumerate(char ***namesp) { /* Allocate and fill in 'names', returning # interfaces/error */ - char **names; - int toobig; - int nalloc; - int nfound; - struct ifreq *ifr; - struct ifconf ifc; - int rc; - int nob; - int i; - + char **names; + int toobig; + int nalloc; + int nfound; + struct ifreq *ifr; + struct ifconf ifc; + int rc; + int nob; + int i; nalloc = 16; /* first guess at max interfaces */ toobig = 0; @@ -163,7 +166,8 @@ libcfs_ipif_enumerate (char ***namesp) LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr)); if (ifr == NULL) { - CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc); + CERROR("ENOMEM enumerating up to %d interfaces\n", + nalloc); rc = -ENOMEM; goto out0; } @@ -171,17 +175,16 @@ libcfs_ipif_enumerate (char ***namesp) ifc.ifc_buf = (char *)ifr; ifc.ifc_len = nalloc * sizeof(*ifr); - rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc); - + rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc); if (rc < 0) { - CERROR ("Error %d enumerating interfaces\n", rc); + CERROR("Error %d enumerating interfaces\n", rc); goto out1; } - LASSERT (rc == 0); + LASSERT(rc == 0); nfound = ifc.ifc_len/sizeof(*ifr); - LASSERT (nfound <= nalloc); + LASSERT(nfound <= nalloc); if (nfound < nalloc || toobig) break; @@ -200,8 +203,7 @@ libcfs_ipif_enumerate (char ***namesp) } for (i = 0; i < nfound; i++) { - - nob = strnlen (ifr[i].ifr_name, IFNAMSIZ); + nob = strnlen(ifr[i].ifr_name, IFNAMSIZ); if (nob == IFNAMSIZ) { /* no space for terminating NULL */ CERROR("interface name %.*s too long (%d max)\n", @@ -223,41 +225,39 @@ libcfs_ipif_enumerate (char ***namesp) *namesp = names; rc = nfound; - out2: +out2: if (rc < 0) - libcfs_ipif_free_enumeration(names, nfound); - out1: + lnet_ipif_free_enumeration(names, nfound); +out1: LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); - out0: +out0: return rc; } - -EXPORT_SYMBOL(libcfs_ipif_enumerate); +EXPORT_SYMBOL(lnet_ipif_enumerate); void -libcfs_ipif_free_enumeration (char **names, int n) +lnet_ipif_free_enumeration(char **names, int n) { - int i; + int i; - LASSERT (n > 0); + LASSERT(n > 0); for (i = 0; i < n && names[i] != NULL; i++) LIBCFS_FREE(names[i], IFNAMSIZ); LIBCFS_FREE(names, n * sizeof(*names)); } - -EXPORT_SYMBOL(libcfs_ipif_free_enumeration); +EXPORT_SYMBOL(lnet_ipif_free_enumeration); int -libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) +lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout) { - int rc; - long ticks = timeout * HZ; - unsigned long then; + int rc; + long ticks = timeout * HZ; + unsigned long then; struct timeval tv; - LASSERT (nob > 0); + LASSERT(nob > 0); /* Caller may pass a zero timeout if she thinks the socket buffer is * empty enough to take the whole message immediately */ @@ -277,7 +277,7 @@ libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) .tv_usec = ((ticks % HZ) * 1000000) / HZ }; rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, - (char *)&tv, sizeof(tv)); + (char *)&tv, sizeof(tv)); if (rc != 0) { CERROR("Can't set socket send timeout %ld.%06d: %d\n", (long)tv.tv_sec, (int)tv.tv_usec, rc); @@ -296,7 +296,7 @@ libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) return rc; if (rc == 0) { - CERROR ("Unexpected zero rc\n"); + CERROR("Unexpected zero rc\n"); return -ECONNABORTED; } @@ -306,21 +306,20 @@ libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) buffer = ((char *)buffer) + rc; nob -= rc; } - return 0; } -EXPORT_SYMBOL(libcfs_sock_write); +EXPORT_SYMBOL(lnet_sock_write); int -libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout) +lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout) { - int rc; - long ticks = timeout * HZ; - unsigned long then; + int rc; + long ticks = timeout * HZ; + unsigned long then; struct timeval tv; - LASSERT (nob > 0); - LASSERT (ticks > 0); + LASSERT(nob > 0); + LASSERT(ticks > 0); for (;;) { struct kvec iov = { @@ -328,7 +327,7 @@ libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout) .iov_len = nob }; struct msghdr msg = { - .msg_flags = 0 + .msg_flags = 0 }; /* Set receive timeout to remaining time */ @@ -337,7 +336,7 @@ libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout) .tv_usec = ((ticks % HZ) * 1000000) / HZ }; rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, - (char *)&tv, sizeof(tv)); + (char *)&tv, sizeof(tv)); if (rc != 0) { CERROR("Can't set socket recv timeout %ld.%06d: %d\n", (long)tv.tv_sec, (int)tv.tv_usec, rc); @@ -364,31 +363,30 @@ libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout) return -ETIMEDOUT; } } - -EXPORT_SYMBOL(libcfs_sock_read); +EXPORT_SYMBOL(lnet_sock_read); static int -libcfs_sock_create (struct socket **sockp, int *fatal, - __u32 local_ip, int local_port) +lnet_sock_create(struct socket **sockp, int *fatal, __u32 local_ip, + int local_port) { - struct sockaddr_in locaddr; - struct socket *sock; - int rc; - int option; + struct sockaddr_in locaddr; + struct socket *sock; + int rc; + int option; /* All errors are fatal except bind failure if the port is in use */ *fatal = 1; - rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock); + rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock); *sockp = sock; if (rc != 0) { - CERROR ("Can't create socket: %d\n", rc); + CERROR("Can't create socket: %d\n", rc); return rc; } option = 1; rc = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&option, sizeof (option)); + (char *)&option, sizeof(option)); if (rc != 0) { CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc); goto failed; @@ -401,8 +399,8 @@ libcfs_sock_create (struct socket **sockp, int *fatal, locaddr.sin_addr.s_addr = (local_ip == 0) ? INADDR_ANY : htonl(local_ip); - rc = sock->ops->bind(sock, (struct sockaddr *)&locaddr, - sizeof(locaddr)); + rc = kernel_bind(sock, (struct sockaddr *)&locaddr, + sizeof(locaddr)); if (rc == -EADDRINUSE) { CDEBUG(D_NET, "Port %d already in use\n", local_port); *fatal = 0; @@ -414,27 +412,26 @@ libcfs_sock_create (struct socket **sockp, int *fatal, goto failed; } } - return 0; - failed: +failed: sock_release(sock); return rc; } int -libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize) +lnet_sock_setbuf(struct socket *sock, int txbufsize, int rxbufsize) { - int option; - int rc; + int option; + int rc; if (txbufsize != 0) { option = txbufsize; rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUF, - (char *)&option, sizeof (option)); + (char *)&option, sizeof(option)); if (rc != 0) { - CERROR ("Can't set send buffer %d: %d\n", - option, rc); + CERROR("Can't set send buffer %d: %d\n", + option, rc); return rc; } } @@ -442,70 +439,65 @@ libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize) if (rxbufsize != 0) { option = rxbufsize; rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, - (char *)&option, sizeof (option)); + (char *)&option, sizeof(option)); if (rc != 0) { - CERROR ("Can't set receive buffer %d: %d\n", - option, rc); + CERROR("Can't set receive buffer %d: %d\n", + option, rc); return rc; } } - return 0; } - -EXPORT_SYMBOL(libcfs_sock_setbuf); +EXPORT_SYMBOL(lnet_sock_setbuf); int -libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port) +lnet_sock_getaddr(struct socket *sock, bool remote, __u32 *ip, int *port) { struct sockaddr_in sin; - int len = sizeof (sin); - int rc; + int len = sizeof(sin); + int rc; - rc = sock->ops->getname (sock, (struct sockaddr *)&sin, &len, - remote ? 2 : 0); + if (remote) + rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &len); + else + rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &len); if (rc != 0) { - CERROR ("Error %d getting sock %s IP/port\n", - rc, remote ? "peer" : "local"); + CERROR("Error %d getting sock %s IP/port\n", + rc, remote ? "peer" : "local"); return rc; } if (ip != NULL) - *ip = ntohl (sin.sin_addr.s_addr); + *ip = ntohl(sin.sin_addr.s_addr); if (port != NULL) - *port = ntohs (sin.sin_port); + *port = ntohs(sin.sin_port); return 0; } - -EXPORT_SYMBOL(libcfs_sock_getaddr); +EXPORT_SYMBOL(lnet_sock_getaddr); int -libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize) +lnet_sock_getbuf(struct socket *sock, int *txbufsize, int *rxbufsize) { - - if (txbufsize != NULL) { + if (txbufsize != NULL) *txbufsize = sock->sk->sk_sndbuf; - } - if (rxbufsize != NULL) { + if (rxbufsize != NULL) *rxbufsize = sock->sk->sk_rcvbuf; - } return 0; } - -EXPORT_SYMBOL(libcfs_sock_getbuf); +EXPORT_SYMBOL(lnet_sock_getbuf); int -libcfs_sock_listen (struct socket **sockp, - __u32 local_ip, int local_port, int backlog) +lnet_sock_listen(struct socket **sockp, __u32 local_ip, int local_port, + int backlog) { - int fatal; - int rc; + int fatal; + int rc; - rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port); + rc = lnet_sock_create(sockp, &fatal, local_ip, local_port); if (rc != 0) { if (!fatal) CERROR("Can't create socket: port %d already in use\n", @@ -513,7 +505,7 @@ libcfs_sock_listen (struct socket **sockp, return rc; } - rc = (*sockp)->ops->listen(*sockp, backlog); + rc = kernel_listen(*sockp, backlog); if (rc == 0) return 0; @@ -521,15 +513,14 @@ libcfs_sock_listen (struct socket **sockp, sock_release(*sockp); return rc; } - -EXPORT_SYMBOL(libcfs_sock_listen); +EXPORT_SYMBOL(lnet_sock_listen); int -libcfs_sock_accept (struct socket **newsockp, struct socket *sock) +lnet_sock_accept(struct socket **newsockp, struct socket *sock) { - wait_queue_t wait; + wait_queue_t wait; struct socket *newsock; - int rc; + int rc; init_waitqueue_entry(&wait, current); @@ -560,41 +551,30 @@ libcfs_sock_accept (struct socket **newsockp, struct socket *sock) *newsockp = newsock; return 0; - failed: +failed: sock_release(newsock); return rc; } - -EXPORT_SYMBOL(libcfs_sock_accept); - -void -libcfs_sock_abort_accept (struct socket *sock) -{ - wake_up_all(sk_sleep(sock->sk)); -} - -EXPORT_SYMBOL(libcfs_sock_abort_accept); +EXPORT_SYMBOL(lnet_sock_accept); int -libcfs_sock_connect (struct socket **sockp, int *fatal, - __u32 local_ip, int local_port, - __u32 peer_ip, int peer_port) +lnet_sock_connect(struct socket **sockp, int *fatal, __u32 local_ip, + int local_port, __u32 peer_ip, int peer_port) { - struct sockaddr_in srvaddr; - int rc; + struct sockaddr_in srvaddr; + int rc; - rc = libcfs_sock_create(sockp, fatal, local_ip, local_port); + rc = lnet_sock_create(sockp, fatal, local_ip, local_port); if (rc != 0) return rc; - memset (&srvaddr, 0, sizeof (srvaddr)); + memset(&srvaddr, 0, sizeof(srvaddr)); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(peer_port); srvaddr.sin_addr.s_addr = htonl(peer_ip); - rc = (*sockp)->ops->connect(*sockp, - (struct sockaddr *)&srvaddr, sizeof(srvaddr), - 0); + rc = kernel_connect(*sockp, (struct sockaddr *)&srvaddr, + sizeof(srvaddr), 0); if (rc == 0) return 0; @@ -605,19 +585,10 @@ libcfs_sock_connect (struct socket **sockp, int *fatal, *fatal = !(rc == -EADDRNOTAVAIL); CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET, - "Error %d connecting %pI4h/%d -> %pI4h/%d\n", rc, - &local_ip, local_port, &peer_ip, peer_port); + "Error %d connecting %pI4h/%d -> %pI4h/%d\n", rc, + &local_ip, local_port, &peer_ip, peer_port); sock_release(*sockp); return rc; } - -EXPORT_SYMBOL(libcfs_sock_connect); - -void -libcfs_sock_release (struct socket *sock) -{ - sock_release(sock); -} - -EXPORT_SYMBOL(libcfs_sock_release); +EXPORT_SYMBOL(lnet_sock_connect); diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c index f708c2e649d7..2a137f46800f 100644 --- a/drivers/staging/lustre/lnet/lnet/lo.c +++ b/drivers/staging/lustre/lnet/lnet/lo.c @@ -111,7 +111,7 @@ lnd_t the_lolnd = { /* .lnd_type = */ LOLND, /* .lnd_startup = */ lolnd_startup, /* .lnd_shutdown = */ lolnd_shutdown, - /* .lnt_ctl = */ NULL, + /* .lnt_ctl = */ NULL, /* .lnd_send = */ lolnd_send, /* .lnd_recv = */ lolnd_recv, /* .lnd_eager_recv = */ NULL, diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index 72b7fbc83718..6881b9cf32ce 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -47,9 +47,9 @@ static int lnet_configure(void *arg) { /* 'arg' only there so I can be passed to cfs_create_thread() */ - int rc = 0; + int rc = 0; - LNET_MUTEX_LOCK(&lnet_config_mutex); + mutex_lock(&lnet_config_mutex); if (!the_lnet.ln_niinit_self) { rc = LNetNIInit(LUSTRE_SRV_LNET_PID); @@ -59,34 +59,34 @@ lnet_configure(void *arg) } } - LNET_MUTEX_UNLOCK(&lnet_config_mutex); + mutex_unlock(&lnet_config_mutex); return rc; } static int lnet_unconfigure(void) { - int refcount; + int refcount; - LNET_MUTEX_LOCK(&lnet_config_mutex); + mutex_lock(&lnet_config_mutex); if (the_lnet.ln_niinit_self) { the_lnet.ln_niinit_self = 0; LNetNIFini(); } - LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex); + mutex_lock(&the_lnet.ln_api_mutex); refcount = the_lnet.ln_refcount; - LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex); + mutex_unlock(&the_lnet.ln_api_mutex); - LNET_MUTEX_UNLOCK(&lnet_config_mutex); + mutex_unlock(&lnet_config_mutex); return (refcount == 0) ? 0 : -EBUSY; } static int lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) { - int rc; + int rc; switch (cmd) { case IOC_LIBCFS_CONFIGURE: @@ -113,7 +113,7 @@ static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl); static int __init init_lnet(void) { - int rc; + int rc; mutex_init(&lnet_config_mutex); @@ -147,7 +147,7 @@ fini_lnet(void) } MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>"); -MODULE_DESCRIPTION("Portals v3.1"); +MODULE_DESCRIPTION("LNet v3.1"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0.0"); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 45b5742f1bd2..1fceed3c8fc0 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -43,10 +43,10 @@ int lnet_peer_tables_create(void) { - struct lnet_peer_table *ptable; - struct list_head *hash; - int i; - int j; + struct lnet_peer_table *ptable; + struct list_head *hash; + int i; + int j; the_lnet.ln_peer_tables = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*ptable)); @@ -77,10 +77,10 @@ lnet_peer_tables_create(void) void lnet_peer_tables_destroy(void) { - struct lnet_peer_table *ptable; - struct list_head *hash; - int i; - int j; + struct lnet_peer_table *ptable; + struct list_head *hash; + int i; + int j; if (the_lnet.ln_peer_tables == NULL) return; @@ -106,9 +106,9 @@ lnet_peer_tables_destroy(void) void lnet_peer_tables_cleanup(void) { - struct lnet_peer_table *ptable; - int i; - int j; + struct lnet_peer_table *ptable; + int i; + int j; LASSERT(the_lnet.ln_shutdown); /* i.e. no new peers */ @@ -133,7 +133,7 @@ lnet_peer_tables_cleanup(void) cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { LIST_HEAD(deathrow); - lnet_peer_t *lp; + lnet_peer_t *lp; lnet_net_lock(i); @@ -186,8 +186,8 @@ lnet_destroy_peer_locked(lnet_peer_t *lp) lnet_peer_t * lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) { - struct list_head *peers; - lnet_peer_t *lp; + struct list_head *peers; + lnet_peer_t *lp; LASSERT(!the_lnet.ln_shutdown); @@ -205,11 +205,11 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt) { - struct lnet_peer_table *ptable; - lnet_peer_t *lp = NULL; - lnet_peer_t *lp2; - int cpt2; - int rc = 0; + struct lnet_peer_table *ptable; + lnet_peer_t *lp = NULL; + lnet_peer_t *lp2; + int cpt2; + int rc = 0; *lpp = NULL; if (the_lnet.ln_shutdown) /* it's shutting down */ @@ -287,8 +287,8 @@ lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt) goto out; } - lp->lp_txcredits = - lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits; + lp->lp_txcredits = + lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits; lp->lp_rtrcredits = lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); @@ -308,10 +308,10 @@ out: void lnet_debug_peer(lnet_nid_t nid) { - char *aliveness = "NA"; - lnet_peer_t *lp; - int rc; - int cpt; + char *aliveness = "NA"; + lnet_peer_t *lp; + int rc; + int cpt; cpt = lnet_cpt_of_nid(nid); lnet_net_lock(cpt); diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 8510bae4822a..96886a2b4571 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -139,8 +139,8 @@ lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, static void lnet_ni_notify_locked(lnet_ni_t *ni, lnet_peer_t *lp) { - int alive; - int notifylnd; + int alive; + int notifylnd; /* Notify only in 1 thread at any time to ensure ordered notification. * NB individual events can be missed; the only guarantee is that you @@ -152,7 +152,7 @@ lnet_ni_notify_locked(lnet_ni_t *ni, lnet_peer_t *lp) lp->lp_notifying = 1; while (lp->lp_notify) { - alive = lp->lp_alive; + alive = lp->lp_alive; notifylnd = lp->lp_notifylnd; lp->lp_notifylnd = 0; @@ -228,9 +228,9 @@ lnet_rtr_decref_locked(lnet_peer_t *lp) lnet_remotenet_t * lnet_find_net_locked(__u32 net) { - lnet_remotenet_t *rnet; - struct list_head *tmp; - struct list_head *rn_list; + lnet_remotenet_t *rnet; + struct list_head *tmp; + struct list_head *rn_list; LASSERT(!the_lnet.ln_shutdown); @@ -276,9 +276,9 @@ static void lnet_shuffle_seed(void) static void lnet_add_route_to_rnet(lnet_remotenet_t *rnet, lnet_route_t *route) { - unsigned int len = 0; - unsigned int offset = 0; - struct list_head *e; + unsigned int len = 0; + unsigned int offset = 0; + struct list_head *e; lnet_shuffle_seed(); @@ -304,13 +304,13 @@ int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway, unsigned int priority) { - struct list_head *e; - lnet_remotenet_t *rnet; - lnet_remotenet_t *rnet2; - lnet_route_t *route; - lnet_ni_t *ni; - int add_route; - int rc; + struct list_head *e; + lnet_remotenet_t *rnet; + lnet_remotenet_t *rnet2; + lnet_route_t *route; + lnet_ni_t *ni; + int add_route; + int rc; CDEBUG(D_NET, "Add route: net %s hops %u priority %u gw %s\n", libcfs_net2str(net), hops, priority, libcfs_nid2str(gateway)); @@ -416,14 +416,14 @@ lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway, int lnet_check_routes(void) { - lnet_remotenet_t *rnet; - lnet_route_t *route; - lnet_route_t *route2; - struct list_head *e1; - struct list_head *e2; - int cpt; - struct list_head *rn_list; - int i; + lnet_remotenet_t *rnet; + lnet_route_t *route; + lnet_route_t *route2; + struct list_head *e1; + struct list_head *e2; + int cpt; + struct list_head *rn_list; + int i; cpt = lnet_net_lock_current(); @@ -434,9 +434,9 @@ lnet_check_routes(void) route2 = NULL; list_for_each(e2, &rnet->lrn_routes) { - lnet_nid_t nid1; - lnet_nid_t nid2; - int net; + lnet_nid_t nid1; + lnet_nid_t nid2; + int net; route = list_entry(e2, lnet_route_t, lr_list); @@ -472,14 +472,14 @@ lnet_check_routes(void) int lnet_del_route(__u32 net, lnet_nid_t gw_nid) { - struct lnet_peer *gateway; - lnet_remotenet_t *rnet; - lnet_route_t *route; - struct list_head *e1; - struct list_head *e2; - int rc = -ENOENT; - struct list_head *rn_list; - int idx = 0; + struct lnet_peer *gateway; + lnet_remotenet_t *rnet; + lnet_route_t *route; + struct list_head *e1; + struct list_head *e2; + int rc = -ENOENT; + struct list_head *rn_list; + int idx = 0; CDEBUG(D_NET, "Del route: net %s : gw %s\n", libcfs_net2str(net), libcfs_nid2str(gw_nid)); @@ -554,13 +554,13 @@ int lnet_get_route(int idx, __u32 *net, __u32 *hops, lnet_nid_t *gateway, __u32 *alive, __u32 *priority) { - struct list_head *e1; - struct list_head *e2; - lnet_remotenet_t *rnet; - lnet_route_t *route; - int cpt; - int i; - struct list_head *rn_list; + struct list_head *e1; + struct list_head *e2; + lnet_remotenet_t *rnet; + lnet_route_t *route; + int cpt; + int i; + struct list_head *rn_list; cpt = lnet_net_lock_current(); @@ -574,11 +574,11 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, lr_list); if (idx-- == 0) { - *net = rnet->lrn_net; - *hops = route->lr_hops; + *net = rnet->lrn_net; + *hops = route->lr_hops; *priority = route->lr_priority; *gateway = route->lr_gateway->lp_nid; - *alive = route->lr_gateway->lp_alive; + *alive = route->lr_gateway->lp_alive; lnet_net_unlock(cpt); return 0; } @@ -593,7 +593,7 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, void lnet_swap_pinginfo(lnet_ping_info_t *info) { - int i; + int i; lnet_ni_status_t *stat; __swab32s(&info->pi_magic); @@ -614,9 +614,9 @@ lnet_swap_pinginfo(lnet_ping_info_t *info) static void lnet_parse_rc_info(lnet_rc_data_t *rcd) { - lnet_ping_info_t *info = rcd->rcd_pinginfo; - struct lnet_peer *gw = rcd->rcd_gateway; - lnet_route_t *rtr; + lnet_ping_info_t *info = rcd->rcd_pinginfo; + struct lnet_peer *gw = rcd->rcd_gateway; + lnet_route_t *rtr; if (!gw->lp_alive) return; @@ -643,14 +643,14 @@ lnet_parse_rc_info(lnet_rc_data_t *rcd) return; /* can't carry NI status info */ list_for_each_entry(rtr, &gw->lp_routes, lr_gwlist) { - int ptl_status = LNET_NI_STATUS_INVALID; - int down = 0; - int up = 0; - int i; + int ptl_status = LNET_NI_STATUS_INVALID; + int down = 0; + int up = 0; + int i; for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) { lnet_ni_status_t *stat = &info->pi_ni[i]; - lnet_nid_t nid = stat->ns_nid; + lnet_nid_t nid = stat->ns_nid; if (nid == LNET_NID_ANY) { CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n", @@ -699,8 +699,8 @@ lnet_parse_rc_info(lnet_rc_data_t *rcd) static void lnet_router_checker_event(lnet_event_t *event) { - lnet_rc_data_t *rcd = event->md.user_ptr; - struct lnet_peer *lp; + lnet_rc_data_t *rcd = event->md.user_ptr; + struct lnet_peer *lp; LASSERT(rcd != NULL); @@ -752,14 +752,14 @@ lnet_router_checker_event(lnet_event_t *event) static void lnet_wait_known_routerstate(void) { - lnet_peer_t *rtr; - struct list_head *entry; - int all_known; + lnet_peer_t *rtr; + struct list_head *entry; + int all_known; LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING); for (;;) { - int cpt = lnet_net_lock_current(); + int cpt = lnet_net_lock_current(); all_known = 1; list_for_each(entry, &the_lnet.ln_routers) { @@ -799,9 +799,9 @@ lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net) static void lnet_update_ni_status_locked(void) { - lnet_ni_t *ni; - long now; - int timeout; + lnet_ni_t *ni; + long now; + int timeout; LASSERT(the_lnet.ln_routing); @@ -860,10 +860,10 @@ lnet_destroy_rc_data(lnet_rc_data_t *rcd) static lnet_rc_data_t * lnet_create_rc_data_locked(lnet_peer_t *gateway) { - lnet_rc_data_t *rcd = NULL; - lnet_ping_info_t *pi; - int rc; - int i; + lnet_rc_data_t *rcd = NULL; + lnet_ping_info_t *pi; + int rc; + int i; lnet_net_unlock(gateway->lp_cpt); @@ -943,8 +943,8 @@ static void lnet_ping_router_locked(lnet_peer_t *rtr) { lnet_rc_data_t *rcd = NULL; - unsigned long now = cfs_time_current(); - int secs; + unsigned long now = cfs_time_current(); + int secs; lnet_peer_addref_locked(rtr); @@ -979,9 +979,9 @@ lnet_ping_router_locked(lnet_peer_t *rtr) if (secs != 0 && !rtr->lp_ping_notsent && cfs_time_after(now, cfs_time_add(rtr->lp_ping_timestamp, cfs_time_seconds(secs)))) { - int rc; + int rc; lnet_process_id_t id; - lnet_handle_md_t mdh; + lnet_handle_md_t mdh; id.nid = rtr->lp_nid; id.pid = LUSTRE_SRV_LNET_PID; @@ -1013,8 +1013,8 @@ lnet_ping_router_locked(lnet_peer_t *rtr) int lnet_router_checker_start(void) { - int rc; - int eqsz; + int rc; + int eqsz; LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_SHUTDOWN); @@ -1085,11 +1085,11 @@ lnet_router_checker_stop(void) static void lnet_prune_rc_data(int wait_unlink) { - lnet_rc_data_t *rcd; - lnet_rc_data_t *tmp; - lnet_peer_t *lp; - struct list_head head; - int i = 2; + lnet_rc_data_t *rcd; + lnet_rc_data_t *tmp; + lnet_peer_t *lp; + struct list_head head; + int i = 2; if (likely(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING && list_empty(&the_lnet.ln_rcd_deathrow) && @@ -1169,17 +1169,17 @@ lnet_prune_rc_data(int wait_unlink) static int lnet_router_checker(void *arg) { - lnet_peer_t *rtr; - struct list_head *entry; + lnet_peer_t *rtr; + struct list_head *entry; cfs_block_allsigs(); LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING); while (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING) { - __u64 version; - int cpt; - int cpt2; + __u64 version; + int cpt; + int cpt2; cpt = lnet_net_lock_current(); rescan: @@ -1245,11 +1245,11 @@ lnet_destroy_rtrbuf(lnet_rtrbuf_t *rb, int npages) static lnet_rtrbuf_t * lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt) { - int npages = rbp->rbp_npages; - int sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]); - struct page *page; + int npages = rbp->rbp_npages; + int sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]); + struct page *page; lnet_rtrbuf_t *rb; - int i; + int i; LIBCFS_CPT_ALLOC(rb, lnet_cpt_table(), cpt, sz); if (rb == NULL) @@ -1280,9 +1280,9 @@ lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt) static void lnet_rtrpool_free_bufs(lnet_rtrbufpool_t *rbp) { - int npages = rbp->rbp_npages; - int nbuffers = 0; - lnet_rtrbuf_t *rb; + int npages = rbp->rbp_npages; + int nbuffers = 0; + lnet_rtrbuf_t *rb; if (rbp->rbp_nbuffers == 0) /* not initialized or already freed */ return; @@ -1310,7 +1310,7 @@ static int lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt) { lnet_rtrbuf_t *rb; - int i; + int i; if (rbp->rbp_nbuffers != 0) { LASSERT(rbp->rbp_nbuffers == nbufs); @@ -1355,7 +1355,7 @@ void lnet_rtrpools_free(void) { lnet_rtrbufpool_t *rtrp; - int i; + int i; if (the_lnet.ln_rtrpools == NULL) /* uninitialized or freed */ return; @@ -1373,7 +1373,7 @@ lnet_rtrpools_free(void) static int lnet_nrb_tiny_calculate(int npages) { - int nrbs = LNET_NRB_TINY; + int nrbs = LNET_NRB_TINY; if (tiny_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, @@ -1392,7 +1392,7 @@ lnet_nrb_tiny_calculate(int npages) static int lnet_nrb_small_calculate(int npages) { - int nrbs = LNET_NRB_SMALL; + int nrbs = LNET_NRB_SMALL; if (small_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, @@ -1411,7 +1411,7 @@ lnet_nrb_small_calculate(int npages) static int lnet_nrb_large_calculate(int npages) { - int nrbs = LNET_NRB_LARGE; + int nrbs = LNET_NRB_LARGE; if (large_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, @@ -1431,13 +1431,13 @@ int lnet_rtrpools_alloc(int im_a_router) { lnet_rtrbufpool_t *rtrp; - int large_pages; - int small_pages = 1; - int nrb_tiny; - int nrb_small; - int nrb_large; - int rc; - int i; + int large_pages; + int small_pages = 1; + int nrb_tiny; + int nrb_small; + int nrb_large; + int rc; + int i; large_pages = (LNET_MTU + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; @@ -1507,9 +1507,9 @@ lnet_rtrpools_alloc(int im_a_router) int lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when) { - struct lnet_peer *lp = NULL; - unsigned long now = cfs_time_current(); - int cpt = lnet_cpt_of_nid(nid); + struct lnet_peer *lp = NULL; + unsigned long now = cfs_time_current(); + int cpt = lnet_cpt_of_nid(nid); LASSERT(!in_interrupt ()); @@ -1591,13 +1591,13 @@ void lnet_router_checker(void) { static time_t last; - static int running; + static int running; - time_t now = get_seconds(); - int interval = now - last; - int rc; - __u64 version; - lnet_peer_t *rtr; + time_t now = get_seconds(); + int interval = now - last; + int rc; + __u64 version; + lnet_peer_t *rtr; /* It's no use to call me again within a sec - all intervals and * timeouts are measured in seconds */ @@ -1625,7 +1625,7 @@ lnet_router_checker(void) /* consume all pending events */ while (1) { - int i; + int i; lnet_event_t ev; /* NB ln_rc_eqh must be the 1st in 'eventqs' otherwise the diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index c055afc86eb4..ee902dc43823 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -112,11 +112,11 @@ static int proc_call_handler(void *data, int write, loff_t *ppos, static int __proc_lnet_stats(void *data, int write, loff_t pos, void __user *buffer, int nob) { - int rc; + int rc; lnet_counters_t *ctrs; - int len; - char *tmpstr; - const int tmpsiz = 256; /* 7 %u and 4 %llu */ + int len; + char *tmpstr; + const int tmpsiz = 256; /* 7 %u and 4 %llu */ if (write) { lnet_counters_reset(); @@ -167,13 +167,13 @@ static int proc_lnet_stats(struct ctl_table *table, int write, static int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - const int tmpsiz = 256; - char *tmpstr; - char *s; - int rc = 0; - int len; - int ver; - int off; + const int tmpsiz = 256; + char *tmpstr; + char *s; + int rc = 0; + int len; + int ver; + int off; CLASSERT(sizeof(loff_t) >= 4); @@ -205,13 +205,13 @@ static int proc_lnet_routes(struct ctl_table *table, int write, lnet_net_unlock(0); *ppos = LNET_PROC_POS_MAKE(0, ver, 0, off); } else { - struct list_head *n; - struct list_head *r; - lnet_route_t *route = NULL; - lnet_remotenet_t *rnet = NULL; - int skip = off - 1; - struct list_head *rn_list; - int i; + struct list_head *n; + struct list_head *r; + lnet_route_t *route = NULL; + lnet_remotenet_t *rnet = NULL; + int skip = off - 1; + struct list_head *rn_list; + int i; lnet_net_lock(0); @@ -251,11 +251,11 @@ static int proc_lnet_routes(struct ctl_table *table, int write, } if (route != NULL) { - __u32 net = rnet->lrn_net; - unsigned int hops = route->lr_hops; - unsigned int priority = route->lr_priority; - lnet_nid_t nid = route->lr_gateway->lp_nid; - int alive = route->lr_gateway->lp_alive; + __u32 net = rnet->lrn_net; + unsigned int hops = route->lr_hops; + unsigned int priority = route->lr_priority; + lnet_nid_t nid = route->lr_gateway->lp_nid; + int alive = route->lr_gateway->lp_alive; s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4u %8u %7s %s\n", @@ -293,13 +293,13 @@ static int proc_lnet_routes(struct ctl_table *table, int write, static int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int rc = 0; - char *tmpstr; - char *s; - const int tmpsiz = 256; - int len; - int ver; - int off; + int rc = 0; + char *tmpstr; + char *s; + const int tmpsiz = 256; + int len; + int ver; + int off; off = LNET_PROC_HOFF_GET(*ppos); ver = LNET_PROC_VER_GET(*ppos); @@ -328,9 +328,9 @@ static int proc_lnet_routers(struct ctl_table *table, int write, lnet_net_unlock(0); *ppos = LNET_PROC_POS_MAKE(0, ver, 0, off); } else { - struct list_head *r; - struct lnet_peer *peer = NULL; - int skip = off - 1; + struct list_head *r; + struct lnet_peer *peer = NULL; + int skip = off - 1; lnet_net_lock(0); @@ -360,14 +360,14 @@ static int proc_lnet_routers(struct ctl_table *table, int write, lnet_nid_t nid = peer->lp_nid; unsigned long now = cfs_time_current(); unsigned long deadline = peer->lp_ping_deadline; - int nrefs = peer->lp_refcount; - int nrtrrefs = peer->lp_rtr_refcount; + int nrefs = peer->lp_refcount; + int nrtrrefs = peer->lp_rtr_refcount; int alive_cnt = peer->lp_alive_count; - int alive = peer->lp_alive; - int pingsent = !peer->lp_ping_notsent; + int alive = peer->lp_alive; + int pingsent = !peer->lp_ping_notsent; int last_ping = cfs_duration_sec(cfs_time_sub(now, peer->lp_ping_timestamp)); - int down_ni = 0; + int down_ni = 0; lnet_route_t *rtr; if ((peer->lp_ping_feats & @@ -428,16 +428,16 @@ static int proc_lnet_routers(struct ctl_table *table, int write, static int proc_lnet_peers(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - const int tmpsiz = 256; - struct lnet_peer_table *ptable; - char *tmpstr; - char *s; - int cpt = LNET_PROC_CPT_GET(*ppos); - int ver = LNET_PROC_VER_GET(*ppos); - int hash = LNET_PROC_HASH_GET(*ppos); - int hoff = LNET_PROC_HOFF_GET(*ppos); - int rc = 0; - int len; + const int tmpsiz = 256; + struct lnet_peer_table *ptable; + char *tmpstr; + char *s; + int cpt = LNET_PROC_CPT_GET(*ppos); + int ver = LNET_PROC_VER_GET(*ppos); + int hash = LNET_PROC_HASH_GET(*ppos); + int hoff = LNET_PROC_HOFF_GET(*ppos); + int rc = 0; + int len; CLASSERT(LNET_PROC_HASH_BITS >= LNET_PEER_HASH_BITS); LASSERT(!write); @@ -465,9 +465,9 @@ static int proc_lnet_peers(struct ctl_table *table, int write, hoff++; } else { - struct lnet_peer *peer; - struct list_head *p; - int skip; + struct lnet_peer *peer; + struct list_head *p; + int skip; again: p = NULL; peer = NULL; @@ -521,23 +521,23 @@ static int proc_lnet_peers(struct ctl_table *table, int write, } if (peer != NULL) { - lnet_nid_t nid = peer->lp_nid; - int nrefs = peer->lp_refcount; - int lastalive = -1; - char *aliveness = "NA"; - int maxcr = peer->lp_ni->ni_peertxcredits; - int txcr = peer->lp_txcredits; - int mintxcr = peer->lp_mintxcredits; - int rtrcr = peer->lp_rtrcredits; - int minrtrcr = peer->lp_minrtrcredits; - int txqnob = peer->lp_txqnob; + lnet_nid_t nid = peer->lp_nid; + int nrefs = peer->lp_refcount; + int lastalive = -1; + char *aliveness = "NA"; + int maxcr = peer->lp_ni->ni_peertxcredits; + int txcr = peer->lp_txcredits; + int mintxcr = peer->lp_mintxcredits; + int rtrcr = peer->lp_rtrcredits; + int minrtrcr = peer->lp_minrtrcredits; + int txqnob = peer->lp_txqnob; if (lnet_isrouter(peer) || lnet_peer_aliveness_enabled(peer)) aliveness = peer->lp_alive ? "up" : "down"; if (lnet_peer_aliveness_enabled(peer)) { - unsigned long now = cfs_time_current(); + unsigned long now = cfs_time_current(); long delta; delta = cfs_time_sub(now, peer->lp_last_alive); @@ -595,13 +595,13 @@ static int proc_lnet_peers(struct ctl_table *table, int write, static int __proc_lnet_buffers(void *data, int write, loff_t pos, void __user *buffer, int nob) { - char *s; - char *tmpstr; - int tmpsiz; - int idx; - int len; - int rc; - int i; + char *s; + char *tmpstr; + int tmpsiz; + int idx; + int len; + int rc; + int i; LASSERT(!write); @@ -660,11 +660,11 @@ static int proc_lnet_buffers(struct ctl_table *table, int write, static int proc_lnet_nis(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int tmpsiz = 128 * LNET_CPT_NUMBER; - int rc = 0; - char *tmpstr; - char *s; - int len; + int tmpsiz = 128 * LNET_CPT_NUMBER; + int rc = 0; + char *tmpstr; + char *s; + int len; LASSERT(!write); @@ -684,9 +684,9 @@ static int proc_lnet_nis(struct ctl_table *table, int write, "rtr", "max", "tx", "min"); LASSERT(tmpstr + tmpsiz - s > 0); } else { - struct list_head *n; - lnet_ni_t *ni = NULL; - int skip = *ppos - 1; + struct list_head *n; + lnet_ni_t *ni = NULL; + int skip = *ppos - 1; lnet_net_lock(0); @@ -705,12 +705,12 @@ static int proc_lnet_nis(struct ctl_table *table, int write, } if (ni != NULL) { - struct lnet_tx_queue *tq; - char *stat; - long now = get_seconds(); - int last_alive = -1; - int i; - int j; + struct lnet_tx_queue *tq; + char *stat; + long now = get_seconds(); + int last_alive = -1; + int i; + int j; if (the_lnet.ln_routing) last_alive = now - ni->ni_last_alive; @@ -777,9 +777,9 @@ static int proc_lnet_nis(struct ctl_table *table, int write, } struct lnet_portal_rotors { - int pr_value; - const char *pr_name; - const char *pr_desc; + int pr_value; + const char *pr_name; + const char *pr_desc; }; static struct lnet_portal_rotors portal_rotors[] = { @@ -815,11 +815,11 @@ extern int portal_rotor; static int __proc_lnet_portal_rotor(void *data, int write, loff_t pos, void __user *buffer, int nob) { - const int buf_len = 128; - char *buf; - char *tmp; - int rc; - int i; + const int buf_len = 128; + char *buf; + char *tmp; + int rc; + int i; LIBCFS_ALLOC(buf, buf_len); if (buf == NULL) @@ -887,38 +887,38 @@ static struct ctl_table lnet_table[] = { * to go via /proc for portability. */ { - .procname = "stats", - .mode = 0644, + .procname = "stats", + .mode = 0644, .proc_handler = &proc_lnet_stats, }, { - .procname = "routes", - .mode = 0444, + .procname = "routes", + .mode = 0444, .proc_handler = &proc_lnet_routes, }, { - .procname = "routers", - .mode = 0444, + .procname = "routers", + .mode = 0444, .proc_handler = &proc_lnet_routers, }, { - .procname = "peers", - .mode = 0444, + .procname = "peers", + .mode = 0444, .proc_handler = &proc_lnet_peers, }, { - .procname = "buffers", - .mode = 0444, + .procname = "buffers", + .mode = 0444, .proc_handler = &proc_lnet_buffers, }, { - .procname = "nis", - .mode = 0444, + .procname = "nis", + .mode = 0444, .proc_handler = &proc_lnet_nis, }, { - .procname = "portal_rotor", - .mode = 0644, + .procname = "portal_rotor", + .mode = 0644, .proc_handler = &proc_lnet_portal_rotor, }, { diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 658f4584fff8..de11f1bc8be7 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -91,7 +91,7 @@ brw_client_init(sfw_test_instance_t *tsi) len = npg * PAGE_CACHE_SIZE; } else { - test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; + test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; /* I should never get this step if it's unknown feature * because make_session will reject unknown feature */ @@ -223,7 +223,7 @@ bad_data: static void brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { - int i; + int i; struct page *pg; for (i = 0; i < bk->bk_niov; i++) { @@ -235,7 +235,7 @@ brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) static int brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { - int i; + int i; struct page *pg; for (i = 0; i < bk->bk_niov; i++) { @@ -254,16 +254,16 @@ static int brw_client_prep_rpc(sfw_test_unit_t *tsu, lnet_process_id_t dest, srpc_client_rpc_t **rpcpp) { - srpc_bulk_t *bulk = tsu->tsu_private; + srpc_bulk_t *bulk = tsu->tsu_private; sfw_test_instance_t *tsi = tsu->tsu_instance; - sfw_session_t *sn = tsi->tsi_batch->bat_session; - srpc_client_rpc_t *rpc; - srpc_brw_reqst_t *req; - int flags; - int npg; - int len; - int opc; - int rc; + sfw_session_t *sn = tsi->tsi_batch->bat_session; + srpc_client_rpc_t *rpc; + srpc_brw_reqst_t *req; + int flags; + int npg; + int len; + int opc; + int rc; LASSERT(sn != NULL); LASSERT(bulk != NULL); @@ -277,7 +277,7 @@ brw_client_prep_rpc(sfw_test_unit_t *tsu, len = npg * PAGE_CACHE_SIZE; } else { - test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; + test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; /* I should never get this step if it's unknown feature * because make_session will reject unknown feature */ @@ -311,12 +311,12 @@ brw_client_prep_rpc(sfw_test_unit_t *tsu, static void brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) { - __u64 magic = BRW_MAGIC; + __u64 magic = BRW_MAGIC; sfw_test_instance_t *tsi = tsu->tsu_instance; - sfw_session_t *sn = tsi->tsi_batch->bat_session; - srpc_msg_t *msg = &rpc->crpc_replymsg; - srpc_brw_reply_t *reply = &msg->msg_body.brw_reply; - srpc_brw_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst; + sfw_session_t *sn = tsi->tsi_batch->bat_session; + srpc_msg_t *msg = &rpc->crpc_replymsg; + srpc_brw_reply_t *reply = &msg->msg_body.brw_reply; + srpc_brw_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst; LASSERT(sn != NULL); @@ -380,10 +380,10 @@ brw_server_rpc_done(srpc_server_rpc_t *rpc) static int brw_bulk_ready(srpc_server_rpc_t *rpc, int status) { - __u64 magic = BRW_MAGIC; + __u64 magic = BRW_MAGIC; srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply; srpc_brw_reqst_t *reqst; - srpc_msg_t *reqstmsg; + srpc_msg_t *reqstmsg; LASSERT(rpc->srpc_bulk != NULL); LASSERT(rpc->srpc_reqstbuf != NULL); @@ -416,13 +416,13 @@ brw_bulk_ready(srpc_server_rpc_t *rpc, int status) static int brw_server_handle(struct srpc_server_rpc *rpc) { - struct srpc_service *sv = rpc->srpc_scd->scd_svc; - srpc_msg_t *replymsg = &rpc->srpc_replymsg; - srpc_msg_t *reqstmsg = &rpc->srpc_reqstbuf->buf_msg; + struct srpc_service *sv = rpc->srpc_scd->scd_svc; + srpc_msg_t *replymsg = &rpc->srpc_replymsg; + srpc_msg_t *reqstmsg = &rpc->srpc_reqstbuf->buf_msg; srpc_brw_reply_t *reply = &replymsg->msg_body.brw_reply; srpc_brw_reqst_t *reqst = &reqstmsg->msg_body.brw_reqst; - int npg; - int rc; + int npg; + int rc; LASSERT(sv->sv_id == SRPC_SERVICE_BRW); @@ -490,17 +490,17 @@ brw_server_handle(struct srpc_server_rpc *rpc) sfw_test_client_ops_t brw_test_client; void brw_init_test_client(void) { - brw_test_client.tso_init = brw_client_init; - brw_test_client.tso_fini = brw_client_fini; - brw_test_client.tso_prep_rpc = brw_client_prep_rpc; - brw_test_client.tso_done_rpc = brw_client_done_rpc; + brw_test_client.tso_init = brw_client_init; + brw_test_client.tso_fini = brw_client_fini; + brw_test_client.tso_prep_rpc = brw_client_prep_rpc; + brw_test_client.tso_done_rpc = brw_client_done_rpc; }; srpc_service_t brw_test_service; void brw_init_test_service(void) { - brw_test_service.sv_id = SRPC_SERVICE_BRW; + brw_test_service.sv_id = SRPC_SERVICE_BRW; brw_test_service.sv_name = "brw_test"; brw_test_service.sv_handler = brw_server_handle; brw_test_service.sv_bulk_ready = brw_bulk_ready; diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index 045fe295ad54..1a7870e91f23 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -48,11 +48,11 @@ static int lst_session_new_ioctl(lstio_session_new_args_t *args) { - char *name; - int rc; + char *name; + int rc; if (args->lstio_ses_idp == NULL || /* address for output sid */ - args->lstio_ses_key == 0 || /* no key is specified */ + args->lstio_ses_key == 0 || /* no key is specified */ args->lstio_ses_namep == NULL || /* session name */ args->lstio_ses_nmlen <= 0 || args->lstio_ses_nmlen > LST_NAME_SIZE) @@ -96,12 +96,12 @@ lst_session_info_ioctl(lstio_session_info_args_t *args) { /* no checking of key */ - if (args->lstio_ses_idp == NULL || /* address for output sid */ - args->lstio_ses_keyp == NULL || /* address for output key */ + if (args->lstio_ses_idp == NULL || /* address for output sid */ + args->lstio_ses_keyp == NULL || /* address for output key */ args->lstio_ses_featp == NULL || /* address for output features */ args->lstio_ses_ndinfo == NULL || /* address for output ndinfo */ - args->lstio_ses_namep == NULL || /* address for output name */ - args->lstio_ses_nmlen <= 0 || + args->lstio_ses_namep == NULL || /* address for output name */ + args->lstio_ses_nmlen <= 0 || args->lstio_ses_nmlen > LST_NAME_SIZE) return -EINVAL; @@ -197,8 +197,8 @@ out: static int lst_group_add_ioctl(lstio_group_add_args_t *args) { - char *name; - int rc; + char *name; + int rc; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -324,8 +324,8 @@ static int lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) { unsigned feats; - int rc; - char *name; + int rc; + char *name; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -385,10 +385,10 @@ lst_group_list_ioctl(lstio_group_list_args_t *args) static int lst_group_info_ioctl(lstio_group_info_args_t *args) { - char *name; - int ndent; - int index; - int rc; + char *name; + int ndent; + int index; + int rc; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -449,8 +449,8 @@ lst_group_info_ioctl(lstio_group_info_args_t *args) static int lst_batch_add_ioctl(lstio_batch_add_args_t *args) { - int rc; - char *name; + int rc; + char *name; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -483,8 +483,8 @@ lst_batch_add_ioctl(lstio_batch_add_args_t *args) static int lst_batch_run_ioctl(lstio_batch_run_args_t *args) { - int rc; - char *name; + int rc; + char *name; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -518,8 +518,8 @@ lst_batch_run_ioctl(lstio_batch_run_args_t *args) static int lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) { - int rc; - char *name; + int rc; + char *name; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -613,10 +613,10 @@ lst_batch_list_ioctl(lstio_batch_list_args_t *args) static int lst_batch_info_ioctl(lstio_batch_info_args_t *args) { - char *name; - int rc; - int index; - int ndent; + char *name; + int rc; + int index; + int ndent; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -678,8 +678,8 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args) static int lst_stat_query_ioctl(lstio_stat_args_t *args) { - int rc; - char *name; + int rc; + char *name; /* TODO: not finished */ if (args->lstio_sta_key != console_session.ses_key) diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 77f02b76128e..a1a4e08f7391 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -117,8 +117,8 @@ static int lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats, int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp) { - lstcon_rpc_t *crpc = NULL; - int rc; + lstcon_rpc_t *crpc = NULL; + int rc; spin_lock(&console_session.ses_rpc_lock); @@ -151,7 +151,7 @@ void lstcon_rpc_put(lstcon_rpc_t *crpc) { srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk; - int i; + int i; LASSERT(list_empty(&crpc->crp_link)); @@ -336,8 +336,8 @@ lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans) int lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout) { - lstcon_rpc_t *crpc; - int rc; + lstcon_rpc_t *crpc; + int rc; if (list_empty(&trans->tas_rpcs_list)) return 0; @@ -386,8 +386,8 @@ lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout) static int lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp) { - lstcon_node_t *nd = crpc->crp_node; - srpc_client_rpc_t *rpc = crpc->crp_rpc; + lstcon_node_t *nd = crpc->crp_node; + srpc_client_rpc_t *rpc = crpc->crp_rpc; srpc_generic_reply_t *rep; LASSERT(nd != NULL && rpc != NULL); @@ -423,9 +423,9 @@ lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp) void lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat) { - lstcon_rpc_t *crpc; - srpc_msg_t *rep; - int error; + lstcon_rpc_t *crpc; + srpc_msg_t *rep; + int error; LASSERT(stat != NULL); @@ -470,16 +470,16 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans, struct list_head *head_up, lstcon_rpc_readent_func_t readent) { - struct list_head tmp; - struct list_head *next; - lstcon_rpc_ent_t *ent; + struct list_head tmp; + struct list_head *next; + lstcon_rpc_ent_t *ent; srpc_generic_reply_t *rep; - lstcon_rpc_t *crpc; - srpc_msg_t *msg; - lstcon_node_t *nd; - long dur; - struct timeval tv; - int error; + lstcon_rpc_t *crpc; + srpc_msg_t *msg; + lstcon_node_t *nd; + long dur; + struct timeval tv; + int error; LASSERT(head_up != NULL); @@ -544,9 +544,9 @@ void lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans) { srpc_client_rpc_t *rpc; - lstcon_rpc_t *crpc; - lstcon_rpc_t *tmp; - int count = 0; + lstcon_rpc_t *crpc; + lstcon_rpc_t *tmp; + int count = 0; list_for_each_entry_safe(crpc, tmp, &trans->tas_rpcs_list, crp_link) { @@ -601,7 +601,7 @@ lstcon_sesrpc_prep(lstcon_node_t *nd, int transop, { srpc_mksn_reqst_t *msrq; srpc_rmsn_reqst_t *rsrq; - int rc; + int rc; switch (transop) { case LST_TRANS_SESNEW: @@ -638,7 +638,7 @@ int lstcon_dbgrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc) { srpc_debug_reqst_t *drq; - int rc; + int rc; rc = lstcon_rpc_prep(nd, SRPC_SERVICE_DEBUG, feats, 0, 0, crpc); if (rc != 0) @@ -707,7 +707,7 @@ static lnet_process_id_packed_t * lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov) { lnet_process_id_packed_t *pid; - int i; + int i; i = idx / SFW_ID_PER_PAGE; @@ -723,11 +723,11 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx, int dist, int span, int nkiov, lnet_kiov_t *kiov) { lnet_process_id_packed_t *pid; - lstcon_ndlink_t *ndl; - lstcon_node_t *nd; - int start; - int end; - int i = 0; + lstcon_ndlink_t *ndl; + lstcon_node_t *nd; + int start; + int end; + int i = 0; LASSERT(dist >= 1); LASSERT(span >= 1); @@ -777,8 +777,8 @@ lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req) { test_ping_req_t *prq = &req->tsr_u.ping; - prq->png_size = param->png_size; - prq->png_flags = param->png_flags; + prq->png_size = param->png_size; + prq->png_flags = param->png_flags; /* TODO dest */ return 0; } @@ -788,9 +788,10 @@ lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) { test_bulk_req_t *brq = &req->tsr_u.bulk_v0; - brq->blk_opc = param->blk_opc; - brq->blk_npg = (param->blk_size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE; - brq->blk_flags = param->blk_flags; + brq->blk_opc = param->blk_opc; + brq->blk_npg = (param->blk_size + PAGE_CACHE_SIZE - 1) / + PAGE_CACHE_SIZE; + brq->blk_flags = param->blk_flags; return 0; } @@ -816,7 +817,7 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, lstcon_group_t *dgrp = test->tes_dst_grp; srpc_test_reqst_t *trq; srpc_bulk_t *bulk; - int i; + int i; int npg = 0; int nob = 0; int rc = 0; @@ -835,8 +836,10 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, trq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.tes_reqst; if (transop == LST_TRANS_TSBSRVADD) { - int ndist = (sgrp->grp_nnode + test->tes_dist - 1) / test->tes_dist; - int nspan = (dgrp->grp_nnode + test->tes_span - 1) / test->tes_span; + int ndist = (sgrp->grp_nnode + test->tes_dist - 1) / + test->tes_dist; + int nspan = (dgrp->grp_nnode + test->tes_span - 1) / + test->tes_span; int nmax = (ndist + nspan - 1) / nspan; trq->tsr_ndest = 0; @@ -851,7 +854,8 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, LASSERT(nob > 0); len = (feats & LST_FEAT_BULK_LEN) == 0 ? - PAGE_CACHE_SIZE : min_t(int, nob, PAGE_CACHE_SIZE); + PAGE_CACHE_SIZE : + min_t(int, nob, PAGE_CACHE_SIZE); nob -= len; bulk->bk_iovs[i].kiov_offset = 0; @@ -883,8 +887,8 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, trq->tsr_loop = test->tes_loop; } - trq->tsr_sid = console_session.ses_id; - trq->tsr_bid = test->tes_hdr.tsb_id; + trq->tsr_sid = console_session.ses_id; + trq->tsr_bid = test->tes_hdr.tsb_id; trq->tsr_concur = test->tes_concur; trq->tsr_is_client = (transop == LST_TRANS_TSBCLIADD) ? 1 : 0; trq->tsr_stop_onerr = !!test->tes_stop_onerr; @@ -966,7 +970,7 @@ lstcon_rpc_stat_reply(lstcon_rpc_trans_t *trans, srpc_msg_t *msg, srpc_batch_reply_t *bat_rep; srpc_test_reply_t *test_rep; srpc_stat_reply_t *stat_rep; - int rc = 0; + int rc = 0; switch (trans->tas_opc) { case LST_TRANS_SESNEW: @@ -1084,11 +1088,11 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist, lstcon_rpc_trans_t **transpp) { lstcon_rpc_trans_t *trans; - lstcon_ndlink_t *ndl; - lstcon_node_t *nd; - lstcon_rpc_t *rpc; - unsigned feats; - int rc; + lstcon_ndlink_t *ndl; + lstcon_node_t *nd; + lstcon_rpc_t *rpc; + unsigned feats; + int rc; /* Creating session RPG for list of nodes */ @@ -1165,16 +1169,16 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist, static void lstcon_rpc_pinger(void *arg) { - stt_timer_t *ptimer = (stt_timer_t *)arg; + stt_timer_t *ptimer = (stt_timer_t *)arg; lstcon_rpc_trans_t *trans; - lstcon_rpc_t *crpc; - srpc_msg_t *rep; + lstcon_rpc_t *crpc; + srpc_msg_t *rep; srpc_debug_reqst_t *drq; - lstcon_ndlink_t *ndl; - lstcon_node_t *nd; - time_t intv; - int count = 0; - int rc; + lstcon_ndlink_t *ndl; + lstcon_node_t *nd; + time_t intv; + int count = 0; + int rc; /* RPC pinger is a special case of transaction, * it's called by timer at 8 seconds interval. @@ -1283,8 +1287,8 @@ lstcon_rpc_pinger(void *arg) int lstcon_rpc_pinger_start(void) { - stt_timer_t *ptimer; - int rc; + stt_timer_t *ptimer; + int rc; LASSERT(list_empty(&console_session.ses_rpc_freelist)); LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0); @@ -1324,9 +1328,9 @@ void lstcon_rpc_cleanup_wait(void) { lstcon_rpc_trans_t *trans; - lstcon_rpc_t *crpc; - struct list_head *pacer; - struct list_head zlist; + lstcon_rpc_t *crpc; + struct list_head *pacer; + struct list_head zlist; /* Called with hold of global mutex */ diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h index 2353889c6eac..7d33cf9e9d99 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.h +++ b/drivers/staging/lustre/lnet/selftest/conrpc.h @@ -64,31 +64,29 @@ struct lstcon_test; struct lstcon_node; typedef struct lstcon_rpc { - struct list_head crp_link; /* chain on rpc transaction */ + struct list_head crp_link; /* chain on rpc transaction */ srpc_client_rpc_t *crp_rpc; /* client rpc */ - struct lstcon_node *crp_node; /* destination node */ + struct lstcon_node *crp_node; /* destination node */ struct lstcon_rpc_trans *crp_trans; /* conrpc transaction */ - unsigned int crp_posted:1; /* rpc is posted */ - unsigned int crp_finished:1; /* rpc is finished */ - unsigned int crp_unpacked:1; /* reply is unpacked */ + unsigned int crp_posted:1; /* rpc is posted */ + unsigned int crp_finished:1; /* rpc is finished */ + unsigned int crp_unpacked:1; /* reply is unpacked */ /** RPC is embedded in other structure and can't free it */ - unsigned int crp_embedded:1; - int crp_status; /* console rpc errors */ - unsigned long crp_stamp; /* replied time stamp */ + unsigned int crp_embedded:1; + int crp_status; /* console rpc errors */ + unsigned long crp_stamp; /* replied time stamp */ } lstcon_rpc_t; typedef struct lstcon_rpc_trans { - struct list_head tas_olink; /* link chain on owner list */ - struct list_head tas_link; /* link chain on global list */ - int tas_opc; /* operation code of transaction */ - /* features mask is uptodate */ - unsigned tas_feats_updated; - /* test features mask */ - unsigned tas_features; - wait_queue_head_t tas_waitq; /* wait queue head */ - atomic_t tas_remaining; /* # of un-scheduled rpcs */ - struct list_head tas_rpcs_list; /* queued requests */ + struct list_head tas_olink; /* link chain on owner list */ + struct list_head tas_link; /* link chain on global list */ + int tas_opc; /* operation code of transaction */ + unsigned tas_feats_updated; /* features mask is uptodate */ + unsigned tas_features; /* test features mask */ + wait_queue_head_t tas_waitq; /* wait queue head */ + atomic_t tas_remaining; /* # of un-scheduled rpcs */ + struct list_head tas_rpcs_list; /* queued requests */ } lstcon_rpc_trans_t; #define LST_TRANS_PRIVATE 0x1000 diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 2b5f53c7a730..f47c8f27f975 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -59,7 +59,7 @@ do { \ (p)->nle_nnode++; \ } while (0) -lstcon_session_t console_session; +lstcon_session_t console_session; static void lstcon_node_get(lstcon_node_t *nd) @@ -73,7 +73,7 @@ static int lstcon_node_find(lnet_process_id_t id, lstcon_node_t **ndpp, int create) { lstcon_ndlink_t *ndl; - unsigned int idx = LNET_NIDADDR(id.nid) % LST_GLOBAL_HASHSIZE; + unsigned int idx = LNET_NIDADDR(id.nid) % LST_GLOBAL_HASHSIZE; LASSERT(id.nid != LNET_NID_ANY); @@ -117,7 +117,7 @@ lstcon_node_find(lnet_process_id_t id, lstcon_node_t **ndpp, int create) static void lstcon_node_put(lstcon_node_t *nd) { - lstcon_ndlink_t *ndl; + lstcon_ndlink_t *ndl; LASSERT(nd->nd_ref > 0); @@ -140,10 +140,10 @@ static int lstcon_ndlink_find(struct list_head *hash, lnet_process_id_t id, lstcon_ndlink_t **ndlpp, int create) { - unsigned int idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE; + unsigned int idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE; lstcon_ndlink_t *ndl; - lstcon_node_t *nd; - int rc; + lstcon_node_t *nd; + int rc; if (id.nid == LNET_NID_ANY) return -EINVAL; @@ -197,7 +197,7 @@ static int lstcon_group_alloc(char *name, lstcon_group_t **grpp) { lstcon_group_t *grp; - int i; + int i; LIBCFS_ALLOC(grp, offsetof(lstcon_group_t, grp_ndl_hash[LST_NODE_HASHSIZE])); @@ -243,7 +243,7 @@ lstcon_group_drain(lstcon_group_t *grp, int keep) static void lstcon_group_decref(lstcon_group_t *grp) { - int i; + int i; if (--grp->grp_ref > 0) return; @@ -264,7 +264,7 @@ lstcon_group_decref(lstcon_group_t *grp) static int lstcon_group_find(const char *name, lstcon_group_t **grpp) { - lstcon_group_t *grp; + lstcon_group_t *grp; list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) { if (strncmp(grp->grp_name, name, LST_NAME_SIZE) != 0) @@ -288,7 +288,7 @@ static int lstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id, lstcon_ndlink_t **ndlpp, int create) { - int rc; + int rc; rc = lstcon_ndlink_find(&grp->grp_ndl_hash[0], id, ndlpp, create); if (rc != 0) @@ -404,12 +404,12 @@ lstcon_group_nodes_add(lstcon_group_t *grp, int count, lnet_process_id_t *ids_up, unsigned *featp, struct list_head *result_up) { - lstcon_rpc_trans_t *trans; - lstcon_ndlink_t *ndl; - lstcon_group_t *tmp; - lnet_process_id_t id; - int i; - int rc; + lstcon_rpc_trans_t *trans; + lstcon_ndlink_t *ndl; + lstcon_group_t *tmp; + lnet_process_id_t id; + int i; + int rc; rc = lstcon_group_alloc(NULL, &tmp); if (rc != 0) { @@ -471,12 +471,12 @@ lstcon_group_nodes_remove(lstcon_group_t *grp, int count, lnet_process_id_t *ids_up, struct list_head *result_up) { - lstcon_rpc_trans_t *trans; - lstcon_ndlink_t *ndl; - lstcon_group_t *tmp; - lnet_process_id_t id; - int rc; - int i; + lstcon_rpc_trans_t *trans; + lstcon_ndlink_t *ndl; + lstcon_group_t *tmp; + lnet_process_id_t id; + int rc; + int i; /* End session and remove node from the group */ @@ -525,7 +525,7 @@ int lstcon_group_add(char *name) { lstcon_group_t *grp; - int rc; + int rc; rc = (lstcon_group_find(name, &grp) == 0)? -EEXIST: 0; if (rc != 0) { @@ -549,8 +549,8 @@ int lstcon_nodes_add(char *name, int count, lnet_process_id_t *ids_up, unsigned *featp, struct list_head *result_up) { - lstcon_group_t *grp; - int rc; + lstcon_group_t *grp; + int rc; LASSERT(count > 0); LASSERT(ids_up != NULL); @@ -580,8 +580,8 @@ int lstcon_group_del(char *name) { lstcon_rpc_trans_t *trans; - lstcon_group_t *grp; - int rc; + lstcon_group_t *grp; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) { @@ -621,7 +621,7 @@ int lstcon_group_clean(char *name, int args) { lstcon_group_t *grp = NULL; - int rc; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) { @@ -654,7 +654,7 @@ lstcon_nodes_remove(char *name, int count, lnet_process_id_t *ids_up, struct list_head *result_up) { lstcon_group_t *grp = NULL; - int rc; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) { @@ -682,9 +682,9 @@ lstcon_nodes_remove(char *name, int count, int lstcon_group_refresh(char *name, struct list_head *result_up) { - lstcon_rpc_trans_t *trans; - lstcon_group_t *grp; - int rc; + lstcon_rpc_trans_t *trans; + lstcon_group_t *grp; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) { @@ -743,10 +743,10 @@ static int lstcon_nodes_getent(struct list_head *head, int *index_p, int *count_p, lstcon_node_ent_t *dents_up) { - lstcon_ndlink_t *ndl; - lstcon_node_t *nd; - int count = 0; - int index = 0; + lstcon_ndlink_t *ndl; + lstcon_node_t *nd; + int count = 0; + int index = 0; LASSERT(index_p != NULL && count_p != NULL); LASSERT(dents_up != NULL); @@ -784,9 +784,9 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, int *index_p, int *count_p, lstcon_node_ent_t *dents_up) { lstcon_ndlist_ent_t *gentp; - lstcon_group_t *grp; - lstcon_ndlink_t *ndl; - int rc; + lstcon_group_t *grp; + lstcon_ndlink_t *ndl; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) { @@ -828,7 +828,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, static int lstcon_batch_find(const char *name, lstcon_batch_t **batpp) { - lstcon_batch_t *bat; + lstcon_batch_t *bat; list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) { if (strncmp(bat->bat_name, name, LST_NAME_SIZE) == 0) { @@ -843,9 +843,9 @@ lstcon_batch_find(const char *name, lstcon_batch_t **batpp) int lstcon_batch_add(char *name) { - lstcon_batch_t *bat; - int i; - int rc; + lstcon_batch_t *bat; + int i; + int rc; rc = (lstcon_batch_find(name, &bat) == 0)? -EEXIST: 0; if (rc != 0) { @@ -903,7 +903,7 @@ lstcon_batch_add(char *name) int lstcon_batch_list(int index, int len, char *name_up) { - lstcon_batch_t *bat; + lstcon_batch_t *bat; LASSERT(name_up != NULL); LASSERT(index >= 0); @@ -924,12 +924,12 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t *ent_up, int server, lstcon_node_ent_t *dents_up) { lstcon_test_batch_ent_t *entp; - struct list_head *clilst; - struct list_head *srvlst; - lstcon_test_t *test = NULL; - lstcon_batch_t *bat; - lstcon_ndlink_t *ndl; - int rc; + struct list_head *clilst; + struct list_head *srvlst; + lstcon_test_t *test = NULL; + lstcon_batch_t *bat; + lstcon_ndlink_t *ndl; + int rc; rc = lstcon_batch_find(name, &bat); if (rc != 0) { @@ -1018,7 +1018,7 @@ lstcon_batch_op(lstcon_batch_t *bat, int transop, struct list_head *result_up) { lstcon_rpc_trans_t *trans; - int rc; + int rc; rc = lstcon_rpc_trans_ndlist(&bat->bat_cli_list, &bat->bat_trans_list, transop, @@ -1041,7 +1041,7 @@ int lstcon_batch_run(char *name, int timeout, struct list_head *result_up) { lstcon_batch_t *bat; - int rc; + int rc; if (lstcon_batch_find(name, &bat) != 0) { CDEBUG(D_NET, "Can't find batch %s\n", name); @@ -1063,7 +1063,7 @@ int lstcon_batch_stop(char *name, int force, struct list_head *result_up) { lstcon_batch_t *bat; - int rc; + int rc; if (lstcon_batch_find(name, &bat) != 0) { CDEBUG(D_NET, "Can't find batch %s\n", name); @@ -1084,9 +1084,9 @@ lstcon_batch_stop(char *name, int force, struct list_head *result_up) static void lstcon_batch_destroy(lstcon_batch_t *bat) { - lstcon_ndlink_t *ndl; - lstcon_test_t *test; - int i; + lstcon_ndlink_t *ndl; + lstcon_test_t *test; + int i; list_del(&bat->bat_link); @@ -1137,11 +1137,11 @@ lstcon_batch_destroy(lstcon_batch_t *bat) static int lstcon_testrpc_condition(int transop, lstcon_node_t *nd, void *arg) { - lstcon_test_t *test; - lstcon_batch_t *batch; - lstcon_ndlink_t *ndl; - struct list_head *hash; - struct list_head *head; + lstcon_test_t *test; + lstcon_batch_t *batch; + lstcon_ndlink_t *ndl; + struct list_head *hash; + struct list_head *head; test = (lstcon_test_t *)arg; LASSERT(test != NULL); @@ -1181,10 +1181,10 @@ lstcon_testrpc_condition(int transop, lstcon_node_t *nd, void *arg) static int lstcon_test_nodes_add(lstcon_test_t *test, struct list_head *result_up) { - lstcon_rpc_trans_t *trans; - lstcon_group_t *grp; - int transop; - int rc; + lstcon_rpc_trans_t *trans; + lstcon_group_t *grp; + int transop; + int rc; LASSERT(test->tes_src_grp != NULL); LASSERT(test->tes_dst_grp != NULL); @@ -1251,8 +1251,8 @@ lstcon_verify_batch(const char *name, lstcon_batch_t **batch) static int lstcon_verify_group(const char *name, lstcon_group_t **grp) { - int rc; - lstcon_ndlink_t *ndl; + int rc; + lstcon_ndlink_t *ndl; rc = lstcon_group_find(name, grp); if (rc != 0) { @@ -1398,13 +1398,13 @@ lstcon_test_batch_query(char *name, int testidx, int client, int timeout, struct list_head *result_up) { lstcon_rpc_trans_t *trans; - struct list_head *translist; - struct list_head *ndlist; - lstcon_tsb_hdr_t *hdr; - lstcon_batch_t *batch; - lstcon_test_t *test = NULL; - int transop; - int rc; + struct list_head *translist; + struct list_head *ndlist; + lstcon_tsb_hdr_t *hdr; + lstcon_batch_t *batch; + lstcon_test_t *test = NULL; + int transop; + int rc; rc = lstcon_batch_find(name, &batch); if (rc != 0) { @@ -1460,9 +1460,9 @@ lstcon_statrpc_readent(int transop, srpc_msg_t *msg, lstcon_rpc_ent_t *ent_up) { srpc_stat_reply_t *rep = &msg->msg_body.stat_reply; - sfw_counters_t *sfwk_stat; - srpc_counters_t *srpc_stat; - lnet_counters_t *lnet_stat; + sfw_counters_t *sfwk_stat; + srpc_counters_t *srpc_stat; + lnet_counters_t *lnet_stat; if (rep->str_status != 0) return 0; @@ -1483,9 +1483,9 @@ static int lstcon_ndlist_stat(struct list_head *ndlist, int timeout, struct list_head *result_up) { - struct list_head head; + struct list_head head; lstcon_rpc_trans_t *trans; - int rc; + int rc; INIT_LIST_HEAD(&head); @@ -1508,8 +1508,8 @@ lstcon_ndlist_stat(struct list_head *ndlist, int lstcon_group_stat(char *grp_name, int timeout, struct list_head *result_up) { - lstcon_group_t *grp; - int rc; + lstcon_group_t *grp; + int rc; rc = lstcon_group_find(grp_name, &grp); if (rc != 0) { @@ -1528,11 +1528,11 @@ int lstcon_nodes_stat(int count, lnet_process_id_t *ids_up, int timeout, struct list_head *result_up) { - lstcon_ndlink_t *ndl; - lstcon_group_t *tmp; - lnet_process_id_t id; - int i; - int rc; + lstcon_ndlink_t *ndl; + lstcon_group_t *tmp; + lnet_process_id_t id; + int i; + int rc; rc = lstcon_group_alloc(NULL, &tmp); if (rc != 0) { @@ -1604,7 +1604,7 @@ lstcon_batch_debug(int timeout, char *name, int client, struct list_head *result_up) { lstcon_batch_t *bat; - int rc; + int rc; rc = lstcon_batch_find(name, &bat); if (rc != 0) @@ -1622,7 +1622,7 @@ lstcon_group_debug(int timeout, char *name, struct list_head *result_up) { lstcon_group_t *grp; - int rc; + int rc; rc = lstcon_group_find(name, &grp); if (rc != 0) @@ -1640,11 +1640,11 @@ lstcon_nodes_debug(int timeout, int count, lnet_process_id_t *ids_up, struct list_head *result_up) { - lnet_process_id_t id; - lstcon_ndlink_t *ndl; - lstcon_group_t *grp; - int i; - int rc; + lnet_process_id_t id; + lstcon_ndlink_t *ndl; + lstcon_group_t *grp; + int i; + int rc; rc = lstcon_group_alloc(NULL, &grp); if (rc != 0) { @@ -1689,7 +1689,7 @@ lstcon_session_match(lst_sid_t sid) static void lstcon_new_session_id(lst_sid_t *sid) { - lnet_process_id_t id; + lnet_process_id_t id; LASSERT(console_session.ses_state == LST_SESSION_NONE); @@ -1704,8 +1704,8 @@ int lstcon_session_new(char *name, int key, unsigned feats, int timeout, int force, lst_sid_t *sid_up) { - int rc = 0; - int i; + int rc = 0; + int i; if (console_session.ses_state != LST_SESSION_NONE) { /* session exists */ @@ -1733,9 +1733,9 @@ lstcon_session_new(char *name, int key, unsigned feats, lstcon_new_session_id(&console_session.ses_id); - console_session.ses_key = key; - console_session.ses_state = LST_SESSION_ACTIVE; - console_session.ses_force = !!force; + console_session.ses_key = key; + console_session.ses_state = LST_SESSION_ACTIVE; + console_session.ses_force = !!force; console_session.ses_features = feats; console_session.ses_feats_updated = 0; console_session.ses_timeout = (timeout <= 0) ? @@ -1770,8 +1770,8 @@ lstcon_session_info(lst_sid_t *sid_up, int *key_up, unsigned *featp, lstcon_ndlist_ent_t *ndinfo_up, char *name_up, int len) { lstcon_ndlist_ent_t *entp; - lstcon_ndlink_t *ndl; - int rc = 0; + lstcon_ndlink_t *ndl; + int rc = 0; if (console_session.ses_state != LST_SESSION_ACTIVE) return -ESRCH; @@ -1802,9 +1802,9 @@ int lstcon_session_end(void) { lstcon_rpc_trans_t *trans; - lstcon_group_t *grp; - lstcon_batch_t *bat; - int rc = 0; + lstcon_group_t *grp; + lstcon_batch_t *bat; + int rc = 0; LASSERT(console_session.ses_state == LST_SESSION_ACTIVE); @@ -1894,13 +1894,13 @@ lstcon_session_feats_check(unsigned feats) static int lstcon_acceptor_handle(srpc_server_rpc_t *rpc) { - srpc_msg_t *rep = &rpc->srpc_replymsg; - srpc_msg_t *req = &rpc->srpc_reqstbuf->buf_msg; + srpc_msg_t *rep = &rpc->srpc_replymsg; + srpc_msg_t *req = &rpc->srpc_reqstbuf->buf_msg; srpc_join_reqst_t *jreq = &req->msg_body.join_reqst; srpc_join_reply_t *jrep = &rep->msg_body.join_reply; - lstcon_group_t *grp = NULL; - lstcon_ndlink_t *ndl; - int rc = 0; + lstcon_group_t *grp = NULL; + lstcon_ndlink_t *ndl; + int rc = 0; sfw_unpack_message(req); @@ -1978,9 +1978,9 @@ srpc_service_t lstcon_acceptor_service; static void lstcon_init_acceptor_service(void) { /* initialize selftest console acceptor service table */ - lstcon_acceptor_service.sv_name = "join session"; - lstcon_acceptor_service.sv_handler = lstcon_acceptor_handle; - lstcon_acceptor_service.sv_id = SRPC_SERVICE_JOIN; + lstcon_acceptor_service.sv_name = "join session"; + lstcon_acceptor_service.sv_handler = lstcon_acceptor_handle; + lstcon_acceptor_service.sv_id = SRPC_SERVICE_JOIN; lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX; } @@ -1992,19 +1992,19 @@ static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry); int lstcon_console_init(void) { - int i; - int rc; + int i; + int rc; memset(&console_session, 0, sizeof(lstcon_session_t)); - console_session.ses_id = LST_INVALID_SID; - console_session.ses_state = LST_SESSION_NONE; - console_session.ses_timeout = 0; - console_session.ses_force = 0; - console_session.ses_expired = 0; - console_session.ses_feats_updated = 0; - console_session.ses_features = LST_FEATS_MASK; - console_session.ses_laststamp = get_seconds(); + console_session.ses_id = LST_INVALID_SID; + console_session.ses_state = LST_SESSION_NONE; + console_session.ses_timeout = 0; + console_session.ses_force = 0; + console_session.ses_expired = 0; + console_session.ses_feats_updated = 0; + console_session.ses_features = LST_FEATS_MASK; + console_session.ses_laststamp = get_seconds(); mutex_init(&console_session.ses_mutex); @@ -2062,7 +2062,7 @@ out: int lstcon_console_fini(void) { - int i; + int i; libcfs_deregister_ioctl(&lstcon_ioctl_handler); diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h index e41ca89f10ba..c4cf0aed80e1 100644 --- a/drivers/staging/lustre/lnet/selftest/console.h +++ b/drivers/staging/lustre/lnet/selftest/console.h @@ -52,119 +52,121 @@ #include "conrpc.h" typedef struct lstcon_node { - lnet_process_id_t nd_id; /* id of the node */ - int nd_ref; /* reference count */ - int nd_state; /* state of the node */ - int nd_timeout; /* session timeout */ - unsigned long nd_stamp; /* timestamp of last replied RPC */ - struct lstcon_rpc nd_ping; /* ping rpc */ -} lstcon_node_t; /*** node descriptor */ + lnet_process_id_t nd_id; /* id of the node */ + int nd_ref; /* reference count */ + int nd_state; /* state of the node */ + int nd_timeout; /* session timeout */ + unsigned long nd_stamp; /* timestamp of last replied RPC */ + struct lstcon_rpc nd_ping; /* ping rpc */ +} lstcon_node_t; /* node descriptor */ typedef struct { - struct list_head ndl_link; /* chain on list */ - struct list_head ndl_hlink; /* chain on hash */ - lstcon_node_t *ndl_node; /* pointer to node */ -} lstcon_ndlink_t; /*** node link descriptor */ + struct list_head ndl_link; /* chain on list */ + struct list_head ndl_hlink; /* chain on hash */ + lstcon_node_t *ndl_node; /* pointer to node */ +} lstcon_ndlink_t; /* node link descriptor */ typedef struct { - struct list_head grp_link; /* chain on global group list */ - int grp_ref; /* reference count */ - int grp_userland; /* has userland nodes */ - int grp_nnode; /* # of nodes */ - char grp_name[LST_NAME_SIZE]; /* group name */ + struct list_head grp_link; /* chain on global group list + */ + int grp_ref; /* reference count */ + int grp_userland; /* has userland nodes */ + int grp_nnode; /* # of nodes */ + char grp_name[LST_NAME_SIZE]; /* group name */ - struct list_head grp_trans_list; /* transaction list */ - struct list_head grp_ndl_list; /* nodes list */ - struct list_head grp_ndl_hash[0];/* hash table for nodes */ -} lstcon_group_t; /*** (alias of nodes) group descriptor */ + struct list_head grp_trans_list; /* transaction list */ + struct list_head grp_ndl_list; /* nodes list */ + struct list_head grp_ndl_hash[0]; /* hash table for nodes */ +} lstcon_group_t; /* (alias of nodes) group descriptor */ -#define LST_BATCH_IDLE 0xB0 /* idle batch */ -#define LST_BATCH_RUNNING 0xB1 /* running batch */ +#define LST_BATCH_IDLE 0xB0 /* idle batch */ +#define LST_BATCH_RUNNING 0xB1 /* running batch */ typedef struct lstcon_tsb_hdr { - lst_bid_t tsb_id; /* batch ID */ - int tsb_index; /* test index */ + lst_bid_t tsb_id; /* batch ID */ + int tsb_index; /* test index */ } lstcon_tsb_hdr_t; typedef struct { - lstcon_tsb_hdr_t bat_hdr; /* test_batch header */ - struct list_head bat_link; /* chain on session's batches list */ - int bat_ntest; /* # of test */ - int bat_state; /* state of the batch */ - int bat_arg; /* parameter for run|stop, timeout for run, force for stop */ - char bat_name[LST_NAME_SIZE]; /* name of batch */ - - struct list_head bat_test_list; /* list head of tests (lstcon_test_t) */ - struct list_head bat_trans_list; /* list head of transaction */ - struct list_head bat_cli_list; /* list head of client nodes (lstcon_node_t) */ - struct list_head *bat_cli_hash; /* hash table of client nodes */ - struct list_head bat_srv_list; /* list head of server nodes */ - struct list_head *bat_srv_hash; /* hash table of server nodes */ -} lstcon_batch_t; /*** (tests ) batch descriptor */ + lstcon_tsb_hdr_t bat_hdr; /* test_batch header */ + struct list_head bat_link; /* chain on session's batches list */ + int bat_ntest; /* # of test */ + int bat_state; /* state of the batch */ + int bat_arg; /* parameter for run|stop, timeout + * for run, force for stop */ + char bat_name[LST_NAME_SIZE];/* name of batch */ + + struct list_head bat_test_list; /* list head of tests (lstcon_test_t) + */ + struct list_head bat_trans_list; /* list head of transaction */ + struct list_head bat_cli_list; /* list head of client nodes + * (lstcon_node_t) */ + struct list_head *bat_cli_hash; /* hash table of client nodes */ + struct list_head bat_srv_list; /* list head of server nodes */ + struct list_head *bat_srv_hash; /* hash table of server nodes */ +} lstcon_batch_t; /* (tests ) batch descriptor */ typedef struct lstcon_test { - lstcon_tsb_hdr_t tes_hdr; /* test batch header */ - struct list_head tes_link; /* chain on batch's tests list */ - lstcon_batch_t *tes_batch; /* pointer to batch */ + lstcon_tsb_hdr_t tes_hdr; /* test batch header */ + struct list_head tes_link; /* chain on batch's tests list */ + lstcon_batch_t *tes_batch; /* pointer to batch */ - int tes_type; /* type of the test, i.e: bulk, ping */ - int tes_stop_onerr; /* stop on error */ - int tes_oneside; /* one-sided test */ - int tes_concur; /* concurrency */ - int tes_loop; /* loop count */ - int tes_dist; /* nodes distribution of target group */ - int tes_span; /* nodes span of target group */ - int tes_cliidx; /* client index, used for RPC creating */ + int tes_type; /* type of the test, i.e: bulk, ping */ + int tes_stop_onerr; /* stop on error */ + int tes_oneside; /* one-sided test */ + int tes_concur; /* concurrency */ + int tes_loop; /* loop count */ + int tes_dist; /* nodes distribution of target group */ + int tes_span; /* nodes span of target group */ + int tes_cliidx; /* client index, used for RPC creating */ - struct list_head tes_trans_list; /* transaction list */ - lstcon_group_t *tes_src_grp; /* group run the test */ - lstcon_group_t *tes_dst_grp; /* target group */ + struct list_head tes_trans_list; /* transaction list */ + lstcon_group_t *tes_src_grp; /* group run the test */ + lstcon_group_t *tes_dst_grp; /* target group */ - int tes_paramlen; /* test parameter length */ - char tes_param[0]; /* test parameter */ -} lstcon_test_t; /*** a single test descriptor */ + int tes_paramlen; /* test parameter length */ + char tes_param[0]; /* test parameter */ +} lstcon_test_t; /* a single test descriptor */ -#define LST_GLOBAL_HASHSIZE 503 /* global nodes hash table size */ -#define LST_NODE_HASHSIZE 239 /* node hash table (for batch or group) */ +#define LST_GLOBAL_HASHSIZE 503 /* global nodes hash table size */ +#define LST_NODE_HASHSIZE 239 /* node hash table (for batch or group) */ -#define LST_SESSION_NONE 0x0 /* no session */ -#define LST_SESSION_ACTIVE 0x1 /* working session */ +#define LST_SESSION_NONE 0x0 /* no session */ +#define LST_SESSION_ACTIVE 0x1 /* working session */ -#define LST_CONSOLE_TIMEOUT 300 /* default console timeout */ +#define LST_CONSOLE_TIMEOUT 300 /* default console timeout */ typedef struct { - struct mutex ses_mutex; /* only 1 thread in session */ - lst_sid_t ses_id; /* global session id */ - int ses_key; /* local session key */ - int ses_state; /* state of session */ - int ses_timeout; /* timeout in seconds */ - time_t ses_laststamp; /* last operation stamp (seconds) */ - /** tests features of the session */ - unsigned ses_features; - /** features are synced with remote test nodes */ - unsigned ses_feats_updated:1; - /** force creating */ - unsigned ses_force:1; - /** session is shutting down */ - unsigned ses_shutdown:1; - /** console is timedout */ - unsigned ses_expired:1; - __u64 ses_id_cookie; /* batch id cookie */ - char ses_name[LST_NAME_SIZE]; /* session name */ - lstcon_rpc_trans_t *ses_ping; /* session pinger */ - stt_timer_t ses_ping_timer; /* timer for pinger */ - lstcon_trans_stat_t ses_trans_stat; /* transaction stats */ - - struct list_head ses_trans_list; /* global list of transaction */ - struct list_head ses_grp_list; /* global list of groups */ - struct list_head ses_bat_list; /* global list of batches */ - struct list_head ses_ndl_list; /* global list of nodes */ - struct list_head *ses_ndl_hash; /* hash table of nodes */ - - spinlock_t ses_rpc_lock; /* serialize */ - atomic_t ses_rpc_counter;/* # of initialized RPCs */ - struct list_head ses_rpc_freelist; /* idle console rpc */ -} lstcon_session_t; /*** session descriptor */ + struct mutex ses_mutex; /* only 1 thread in session */ + lst_sid_t ses_id; /* global session id */ + int ses_key; /* local session key */ + int ses_state; /* state of session */ + int ses_timeout; /* timeout in seconds */ + time_t ses_laststamp; /* last operation stamp (seconds) + */ + unsigned ses_features; /* tests features of the session + */ + unsigned ses_feats_updated:1; /* features are synced with + * remote test nodes */ + unsigned ses_force:1; /* force creating */ + unsigned ses_shutdown:1; /* session is shutting down */ + unsigned ses_expired:1; /* console is timedout */ + __u64 ses_id_cookie; /* batch id cookie */ + char ses_name[LST_NAME_SIZE];/* session name */ + lstcon_rpc_trans_t *ses_ping; /* session pinger */ + stt_timer_t ses_ping_timer; /* timer for pinger */ + lstcon_trans_stat_t ses_trans_stat; /* transaction stats */ + + struct list_head ses_trans_list; /* global list of transaction */ + struct list_head ses_grp_list; /* global list of groups */ + struct list_head ses_bat_list; /* global list of batches */ + struct list_head ses_ndl_list; /* global list of nodes */ + struct list_head *ses_ndl_hash; /* hash table of nodes */ + + spinlock_t ses_rpc_lock; /* serialize */ + atomic_t ses_rpc_counter; /* # of initialized RPCs */ + struct list_head ses_rpc_freelist; /* idle console rpc */ +} lstcon_session_t; /* session descriptor */ extern lstcon_session_t console_session; diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index a93a90de0f85..7c5185a2a795 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -53,20 +53,20 @@ static int rpc_timeout = 64; module_param(rpc_timeout, int, 0644); MODULE_PARM_DESC(rpc_timeout, "rpc timeout in seconds (64 by default, 0 == never)"); -#define sfw_unpack_id(id) \ -do { \ +#define sfw_unpack_id(id) \ +do { \ __swab64s(&(id).nid); \ __swab32s(&(id).pid); \ } while (0) -#define sfw_unpack_sid(sid) \ -do { \ +#define sfw_unpack_sid(sid) \ +do { \ __swab64s(&(sid).ses_nid); \ __swab64s(&(sid).ses_stamp); \ } while (0) -#define sfw_unpack_fw_counters(fc) \ -do { \ +#define sfw_unpack_fw_counters(fc) \ +do { \ __swab32s(&(fc).running_ms); \ __swab32s(&(fc).active_batches); \ __swab32s(&(fc).zombie_sessions); \ @@ -75,7 +75,7 @@ do { \ } while (0) #define sfw_unpack_rpc_counters(rc) \ -do { \ +do { \ __swab32s(&(rc).errors); \ __swab32s(&(rc).rpcs_sent); \ __swab32s(&(rc).rpcs_rcvd); \ @@ -86,7 +86,7 @@ do { \ } while (0) #define sfw_unpack_lnet_counters(lc) \ -do { \ +do { \ __swab32s(&(lc).errors); \ __swab32s(&(lc).msgs_max); \ __swab32s(&(lc).msgs_alloc); \ @@ -104,14 +104,14 @@ do { \ #define sfw_batch_active(b) (atomic_read(&(b)->bat_nactive) != 0) static struct smoketest_framework { - struct list_head fw_zombie_rpcs; /* RPCs to be recycled */ - struct list_head fw_zombie_sessions; /* stopping sessions */ - struct list_head fw_tests; /* registered test cases */ - atomic_t fw_nzombies; /* # zombie sessions */ - spinlock_t fw_lock; /* serialise */ - sfw_session_t *fw_session; /* _the_ session */ - int fw_shuttingdown; /* shutdown in progress */ - srpc_server_rpc_t *fw_active_srpc; /* running RPC */ + struct list_head fw_zombie_rpcs; /* RPCs to be recycled */ + struct list_head fw_zombie_sessions; /* stopping sessions */ + struct list_head fw_tests; /* registered test cases */ + atomic_t fw_nzombies; /* # zombie sessions */ + spinlock_t fw_lock; /* serialise */ + sfw_session_t *fw_session; /* _the_ session */ + int fw_shuttingdown; /* shutdown in progress */ + srpc_server_rpc_t *fw_active_srpc; /* running RPC */ } sfw_data; /* forward ref's */ @@ -160,7 +160,7 @@ static void sfw_add_session_timer(void) { sfw_session_t *sn = sfw_data.fw_session; - stt_timer_t *timer = &sn->sn_timer; + stt_timer_t *timer = &sn->sn_timer; LASSERT(!sfw_data.fw_shuttingdown); @@ -199,8 +199,8 @@ sfw_deactivate_session(void) __must_hold(&sfw_data.fw_lock) { sfw_session_t *sn = sfw_data.fw_session; - int nactive = 0; - sfw_batch_t *tsb; + int nactive = 0; + sfw_batch_t *tsb; sfw_test_case_t *tsc; if (sn == NULL) return; @@ -273,7 +273,7 @@ sfw_init_session(sfw_session_t *sn, lst_sid_t sid, strlcpy(&sn->sn_name[0], name, sizeof(sn->sn_name)); sn->sn_timer_active = 0; - sn->sn_id = sid; + sn->sn_id = sid; sn->sn_features = features; sn->sn_timeout = session_timeout; sn->sn_started = cfs_time_current(); @@ -287,8 +287,8 @@ sfw_init_session(sfw_session_t *sn, lst_sid_t sid, static void sfw_server_rpc_done(struct srpc_server_rpc *rpc) { - struct srpc_service *sv = rpc->srpc_scd->scd_svc; - int status = rpc->srpc_status; + struct srpc_service *sv = rpc->srpc_scd->scd_svc; + int status = rpc->srpc_status; CDEBUG(D_NET, "Incoming framework RPC done: service %s, peer %s, status %s:%d\n", @@ -327,7 +327,7 @@ static sfw_batch_t * sfw_find_batch(lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; - sfw_batch_t *bat; + sfw_batch_t *bat; LASSERT(sn != NULL); @@ -343,7 +343,7 @@ static sfw_batch_t * sfw_bid2batch(lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; - sfw_batch_t *bat; + sfw_batch_t *bat; LASSERT(sn != NULL); @@ -368,10 +368,10 @@ sfw_bid2batch(lst_bid_t bid) static int sfw_get_stats(srpc_stat_reqst_t *request, srpc_stat_reply_t *reply) { - sfw_session_t *sn = sfw_data.fw_session; + sfw_session_t *sn = sfw_data.fw_session; sfw_counters_t *cnt = &reply->str_fw; - sfw_batch_t *bat; - struct timeval tv; + sfw_batch_t *bat; + struct timeval tv; reply->str_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id; @@ -412,9 +412,9 @@ int sfw_make_session(srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; - srpc_msg_t *msg = container_of(request, srpc_msg_t, + srpc_msg_t *msg = container_of(request, srpc_msg_t, msg_body.mksn_reqst); - int cplen = 0; + int cplen = 0; if (request->mksn_sid.ses_nid == LNET_NID_ANY) { reply->mksn_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id; @@ -533,7 +533,7 @@ sfw_debug_session(srpc_debug_reqst_t *request, srpc_debug_reply_t *reply) static void sfw_test_rpc_fini(srpc_client_rpc_t *rpc) { - sfw_test_unit_t *tsu = rpc->crpc_priv; + sfw_test_unit_t *tsu = rpc->crpc_priv; sfw_test_instance_t *tsi = tsu->tsu_instance; /* Called with hold of tsi->tsi_lock */ @@ -544,9 +544,9 @@ sfw_test_rpc_fini(srpc_client_rpc_t *rpc) static inline int sfw_test_buffers(sfw_test_instance_t *tsi) { - struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service); - struct srpc_service *svc = tsc->tsc_srv_service; - int nbuf; + struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service); + struct srpc_service *svc = tsc->tsc_srv_service; + int nbuf; nbuf = min(svc->sv_wi_total, tsi->tsi_loop) / svc->sv_ncpts; return max(SFW_TEST_WI_MIN, nbuf + SFW_TEST_WI_EXTRA); @@ -555,10 +555,10 @@ sfw_test_buffers(sfw_test_instance_t *tsi) static int sfw_load_test(struct sfw_test_instance *tsi) { - struct sfw_test_case *tsc; - struct srpc_service *svc; - int nbuf; - int rc; + struct sfw_test_case *tsc; + struct srpc_service *svc; + int nbuf; + int rc; LASSERT(tsi != NULL); tsc = sfw_find_test_case(tsi->tsi_service); @@ -611,7 +611,7 @@ static void sfw_destroy_test_instance(sfw_test_instance_t *tsi) { srpc_client_rpc_t *rpc; - sfw_test_unit_t *tsu; + sfw_test_unit_t *tsu; if (!tsi->tsi_is_client) goto clean; @@ -728,14 +728,14 @@ sfw_unpack_addtest_req(srpc_msg_t *msg) static int sfw_add_test_instance(sfw_batch_t *tsb, srpc_server_rpc_t *rpc) { - srpc_msg_t *msg = &rpc->srpc_reqstbuf->buf_msg; - srpc_test_reqst_t *req = &msg->msg_body.tes_reqst; - srpc_bulk_t *bk = rpc->srpc_bulk; - int ndest = req->tsr_ndest; - sfw_test_unit_t *tsu; + srpc_msg_t *msg = &rpc->srpc_reqstbuf->buf_msg; + srpc_test_reqst_t *req = &msg->msg_body.tes_reqst; + srpc_bulk_t *bk = rpc->srpc_bulk; + int ndest = req->tsr_ndest; + sfw_test_unit_t *tsu; sfw_test_instance_t *tsi; - int i; - int rc; + int i; + int rc; LIBCFS_ALLOC(tsi, sizeof(*tsi)); if (tsi == NULL) { @@ -751,9 +751,9 @@ sfw_add_test_instance(sfw_batch_t *tsb, srpc_server_rpc_t *rpc) INIT_LIST_HEAD(&tsi->tsi_active_rpcs); tsi->tsi_stopping = 0; - tsi->tsi_batch = tsb; - tsi->tsi_loop = req->tsr_loop; - tsi->tsi_concur = req->tsr_concur; + tsi->tsi_batch = tsb; + tsi->tsi_loop = req->tsr_loop; + tsi->tsi_concur = req->tsr_concur; tsi->tsi_service = req->tsr_service; tsi->tsi_is_client = !!(req->tsr_is_client); tsi->tsi_stoptsu_onerr = !!(req->tsr_stop_onerr); @@ -782,8 +782,8 @@ sfw_add_test_instance(sfw_batch_t *tsb, srpc_server_rpc_t *rpc) for (i = 0; i < ndest; i++) { lnet_process_id_packed_t *dests; - lnet_process_id_packed_t id; - int j; + lnet_process_id_packed_t id; + int j; dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].kiov_page); LASSERT(dests != NULL); /* my pages are within KVM always */ @@ -824,8 +824,8 @@ static void sfw_test_unit_done(sfw_test_unit_t *tsu) { sfw_test_instance_t *tsi = tsu->tsu_instance; - sfw_batch_t *tsb = tsi->tsi_batch; - sfw_session_t *sn = tsb->bat_session; + sfw_batch_t *tsb = tsi->tsi_batch; + sfw_session_t *sn = tsb->bat_session; LASSERT(sfw_test_active(tsi)); @@ -866,9 +866,9 @@ sfw_test_unit_done(sfw_test_unit_t *tsu) static void sfw_test_rpc_done(srpc_client_rpc_t *rpc) { - sfw_test_unit_t *tsu = rpc->crpc_priv; + sfw_test_unit_t *tsu = rpc->crpc_priv; sfw_test_instance_t *tsi = tsu->tsu_instance; - int done = 0; + int done = 0; tsi->tsi_ops->tso_done_rpc(tsu, rpc); @@ -904,7 +904,7 @@ sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer, unsigned features, int nblk, int blklen, srpc_client_rpc_t **rpcpp) { - srpc_client_rpc_t *rpc = NULL; + srpc_client_rpc_t *rpc = NULL; sfw_test_instance_t *tsi = tsu->tsu_instance; spin_lock(&tsi->tsi_lock); @@ -945,9 +945,9 @@ sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer, static int sfw_run_test(swi_workitem_t *wi) { - sfw_test_unit_t *tsu = wi->swi_workitem.wi_data; + sfw_test_unit_t *tsu = wi->swi_workitem.wi_data; sfw_test_instance_t *tsi = tsu->tsu_instance; - srpc_client_rpc_t *rpc = NULL; + srpc_client_rpc_t *rpc = NULL; LASSERT(wi == &tsu->tsu_worker); @@ -995,8 +995,8 @@ test_done: static int sfw_run_batch(sfw_batch_t *tsb) { - swi_workitem_t *wi; - sfw_test_unit_t *tsu; + swi_workitem_t *wi; + sfw_test_unit_t *tsu; sfw_test_instance_t *tsi; if (sfw_batch_active(tsb)) { @@ -1032,7 +1032,7 @@ int sfw_stop_batch(sfw_batch_t *tsb, int force) { sfw_test_instance_t *tsi; - srpc_client_rpc_t *rpc; + srpc_client_rpc_t *rpc; if (!sfw_batch_active(tsb)) { CDEBUG(D_NET, "Batch %llu inactive\n", tsb->bat_id.bat_id); @@ -1118,11 +1118,11 @@ sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len, static int sfw_add_test(srpc_server_rpc_t *rpc) { - sfw_session_t *sn = sfw_data.fw_session; + sfw_session_t *sn = sfw_data.fw_session; srpc_test_reply_t *reply = &rpc->srpc_replymsg.msg_body.tes_reply; srpc_test_reqst_t *request; - int rc; - sfw_batch_t *bat; + int rc; + sfw_batch_t *bat; request = &rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst; reply->tsr_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id; @@ -1160,8 +1160,8 @@ sfw_add_test(srpc_server_rpc_t *rpc) if (request->tsr_is_client && rpc->srpc_bulk == NULL) { /* rpc will be resumed later in sfw_bulk_ready */ - int npg = sfw_id_pages(request->tsr_ndest); - int len; + int npg = sfw_id_pages(request->tsr_ndest); + int len; if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) { len = npg * PAGE_CACHE_SIZE; @@ -1189,8 +1189,8 @@ static int sfw_control_batch(srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; - int rc = 0; - sfw_batch_t *bat; + int rc = 0; + sfw_batch_t *bat; reply->bar_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id; @@ -1229,11 +1229,11 @@ sfw_control_batch(srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) static int sfw_handle_server_rpc(struct srpc_server_rpc *rpc) { - struct srpc_service *sv = rpc->srpc_scd->scd_svc; - srpc_msg_t *reply = &rpc->srpc_replymsg; - srpc_msg_t *request = &rpc->srpc_reqstbuf->buf_msg; - unsigned features = LST_FEATS_MASK; - int rc = 0; + struct srpc_service *sv = rpc->srpc_scd->scd_svc; + srpc_msg_t *reply = &rpc->srpc_replymsg; + srpc_msg_t *request = &rpc->srpc_reqstbuf->buf_msg; + unsigned features = LST_FEATS_MASK; + int rc = 0; LASSERT(sfw_data.fw_active_srpc == NULL); LASSERT(sv->sv_id <= SRPC_FRAMEWORK_SERVICE_MAX_ID); @@ -1334,8 +1334,8 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) static int sfw_bulk_ready(struct srpc_server_rpc *rpc, int status) { - struct srpc_service *sv = rpc->srpc_scd->scd_svc; - int rc; + struct srpc_service *sv = rpc->srpc_scd->scd_svc; + int rc; LASSERT(rpc->srpc_bulk != NULL); LASSERT(sv->sv_id == SRPC_SERVICE_TEST); @@ -1640,10 +1640,10 @@ extern void brw_init_test_service(void); int sfw_startup(void) { - int i; - int rc; - int error; - srpc_service_t *sv; + int i; + int rc; + int error; + srpc_service_t *sv; sfw_test_case_t *tsc; @@ -1735,9 +1735,9 @@ sfw_startup(void) void sfw_shutdown(void) { - srpc_service_t *sv; + srpc_service_t *sv; sfw_test_case_t *tsc; - int i; + int i; spin_lock(&sfw_data.fw_lock); diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 7ad62f167cea..09b8f4649796 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -39,7 +39,7 @@ #include "selftest.h" enum { - LST_INIT_NONE = 0, + LST_INIT_NONE = 0, LST_INIT_WI_SERIAL, LST_INIT_WI_TEST, LST_INIT_RPC, @@ -58,7 +58,7 @@ struct cfs_wi_sched **lst_sched_test; static void lnet_selftest_fini(void) { - int i; + int i; switch (lst_init_step) { case LST_INIT_CONSOLE: @@ -92,9 +92,9 @@ lnet_selftest_fini(void) static int lnet_selftest_init(void) { - int nscheds; - int rc; - int i; + int nscheds; + int rc; + int i; rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY, 1, &lst_sched_serial); diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index 644069a9fe4e..1dab9984c58e 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -73,7 +73,7 @@ static void ping_client_fini(sfw_test_instance_t *tsi) { sfw_session_t *sn = tsi->tsi_batch->bat_session; - int errors; + int errors; LASSERT(sn != NULL); LASSERT(tsi->tsi_is_client); @@ -89,11 +89,11 @@ static int ping_client_prep_rpc(sfw_test_unit_t *tsu, lnet_process_id_t dest, srpc_client_rpc_t **rpc) { - srpc_ping_reqst_t *req; + srpc_ping_reqst_t *req; sfw_test_instance_t *tsi = tsu->tsu_instance; - sfw_session_t *sn = tsi->tsi_batch->bat_session; - struct timeval tv; - int rc; + sfw_session_t *sn = tsi->tsi_batch->bat_session; + struct timeval tv; + int rc; LASSERT(sn != NULL); LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0); @@ -121,10 +121,10 @@ static void ping_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) { sfw_test_instance_t *tsi = tsu->tsu_instance; - sfw_session_t *sn = tsi->tsi_batch->bat_session; - srpc_ping_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.ping_reqst; - srpc_ping_reply_t *reply = &rpc->crpc_replymsg.msg_body.ping_reply; - struct timeval tv; + sfw_session_t *sn = tsi->tsi_batch->bat_session; + srpc_ping_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.ping_reqst; + srpc_ping_reply_t *reply = &rpc->crpc_replymsg.msg_body.ping_reply; + struct timeval tv; LASSERT(sn != NULL); @@ -171,9 +171,9 @@ ping_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) static int ping_server_handle(struct srpc_server_rpc *rpc) { - struct srpc_service *sv = rpc->srpc_scd->scd_svc; - srpc_msg_t *reqstmsg = &rpc->srpc_reqstbuf->buf_msg; - srpc_msg_t *replymsg = &rpc->srpc_replymsg; + struct srpc_service *sv = rpc->srpc_scd->scd_svc; + srpc_msg_t *reqstmsg = &rpc->srpc_reqstbuf->buf_msg; + srpc_msg_t *replymsg = &rpc->srpc_replymsg; srpc_ping_reqst_t *req = &reqstmsg->msg_body.ping_reqst; srpc_ping_reply_t *rep = &rpc->srpc_replymsg.msg_body.ping_reply; diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 080788ab749e..59cf01ff4334 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -104,7 +104,7 @@ srpc_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i, int nob) void srpc_free_bulk(srpc_bulk_t *bk) { - int i; + int i; struct page *pg; LASSERT(bk != NULL); @@ -124,8 +124,8 @@ srpc_free_bulk(srpc_bulk_t *bk) srpc_bulk_t * srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink) { - srpc_bulk_t *bk; - int i; + srpc_bulk_t *bk; + int i; LASSERT(bulk_npg > 0 && bulk_npg <= LNET_MAX_IOV); @@ -143,7 +143,7 @@ srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink) for (i = 0; i < bulk_npg; i++) { struct page *pg; - int nob; + int nob; pg = alloc_pages_node(cfs_cpt_spread_node(lnet_cpt_table(), cpt), GFP_IOFS, 0); @@ -193,11 +193,11 @@ srpc_init_server_rpc(struct srpc_server_rpc *rpc, static void srpc_service_fini(struct srpc_service *svc) { - struct srpc_service_cd *scd; - struct srpc_server_rpc *rpc; - struct srpc_buffer *buf; - struct list_head *q; - int i; + struct srpc_service_cd *scd; + struct srpc_server_rpc *rpc; + struct srpc_buffer *buf; + struct list_head *q; + int i; if (svc->sv_cpt_data == NULL) return; @@ -249,11 +249,11 @@ int srpc_add_buffer(struct swi_workitem *wi); static int srpc_service_init(struct srpc_service *svc) { - struct srpc_service_cd *scd; - struct srpc_server_rpc *rpc; - int nrpcs; - int i; - int j; + struct srpc_service_cd *scd; + struct srpc_server_rpc *rpc; + int nrpcs; + int i; + int j; svc->sv_shuttingdown = 0; @@ -357,8 +357,8 @@ srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_handle_md_t *mdh, srpc_event_t *ev) { - int rc; - lnet_md_t md; + int rc; + lnet_md_t md; lnet_handle_me_t meh; rc = LNetMEAttach(portal, peer, matchbits, 0, LNET_UNLINK, @@ -397,7 +397,7 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_nid_t self, lnet_handle_md_t *mdh, srpc_event_t *ev) { - int rc; + int rc; lnet_md_t md; md.user_ptr = ev; @@ -471,9 +471,9 @@ static int srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf) __must_hold(&scd->scd_lock) { - struct srpc_service *sv = scd->scd_svc; - struct srpc_msg *msg = &buf->buf_msg; - int rc; + struct srpc_service *sv = scd->scd_svc; + struct srpc_msg *msg = &buf->buf_msg; + int rc; LNetInvalidateHandle(&buf->buf_mdh); list_add(&buf->buf_list, &scd->scd_buf_posted); @@ -519,9 +519,9 @@ srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf) int srpc_add_buffer(struct swi_workitem *wi) { - struct srpc_service_cd *scd = wi->swi_workitem.wi_data; - struct srpc_buffer *buf; - int rc = 0; + struct srpc_service_cd *scd = wi->swi_workitem.wi_data; + struct srpc_buffer *buf; + int rc = 0; /* it's called by workitem scheduler threads, these threads * should have been set CPT affinity, so buffers will be posted @@ -579,9 +579,9 @@ srpc_add_buffer(struct swi_workitem *wi) int srpc_service_add_buffers(struct srpc_service *sv, int nbuffer) { - struct srpc_service_cd *scd; - int rc = 0; - int i; + struct srpc_service_cd *scd; + int rc = 0; + int i; LASSERTF(nbuffer > 0, "nbuffer must be positive: %d\n", nbuffer); @@ -633,9 +633,9 @@ srpc_service_add_buffers(struct srpc_service *sv, int nbuffer) void srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer) { - struct srpc_service_cd *scd; - int num; - int i; + struct srpc_service_cd *scd; + int num; + int i; LASSERT(!sv->sv_shuttingdown); @@ -653,9 +653,9 @@ srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer) int srpc_finish_service(struct srpc_service *sv) { - struct srpc_service_cd *scd; - struct srpc_server_rpc *rpc; - int i; + struct srpc_service_cd *scd; + struct srpc_server_rpc *rpc; + int i; LASSERT(sv->sv_shuttingdown); /* srpc_shutdown_service called */ @@ -731,9 +731,9 @@ srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf) void srpc_abort_service(struct srpc_service *sv) { - struct srpc_service_cd *scd; - struct srpc_server_rpc *rpc; - int i; + struct srpc_service_cd *scd; + struct srpc_server_rpc *rpc; + int i; CDEBUG(D_NET, "Aborting service: id %d, name %s\n", sv->sv_id, sv->sv_name); @@ -756,10 +756,10 @@ srpc_abort_service(struct srpc_service *sv) void srpc_shutdown_service(srpc_service_t *sv) { - struct srpc_service_cd *scd; - struct srpc_server_rpc *rpc; - srpc_buffer_t *buf; - int i; + struct srpc_service_cd *scd; + struct srpc_server_rpc *rpc; + srpc_buffer_t *buf; + int i; CDEBUG(D_NET, "Shutting down service: id %d, name %s\n", sv->sv_id, sv->sv_name); @@ -792,7 +792,7 @@ static int srpc_send_request(srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_reqstev; - int rc; + int rc; ev->ev_fired = 0; ev->ev_data = rpc; @@ -812,8 +812,8 @@ static int srpc_prepare_reply(srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_replyev; - __u64 *id = &rpc->crpc_reqstmsg.msg_body.reqst.rpyid; - int rc; + __u64 *id = &rpc->crpc_reqstmsg.msg_body.reqst.rpyid; + int rc; ev->ev_fired = 0; ev->ev_data = rpc; @@ -835,11 +835,11 @@ srpc_prepare_reply(srpc_client_rpc_t *rpc) static int srpc_prepare_bulk(srpc_client_rpc_t *rpc) { - srpc_bulk_t *bk = &rpc->crpc_bulk; + srpc_bulk_t *bk = &rpc->crpc_bulk; srpc_event_t *ev = &rpc->crpc_bulkev; __u64 *id = &rpc->crpc_reqstmsg.msg_body.reqst.bulkid; - int rc; - int opt; + int rc; + int opt; LASSERT(bk->bk_niov <= LNET_MAX_IOV); @@ -868,11 +868,11 @@ srpc_prepare_bulk(srpc_client_rpc_t *rpc) static int srpc_do_bulk(srpc_server_rpc_t *rpc) { - srpc_event_t *ev = &rpc->srpc_ev; - srpc_bulk_t *bk = rpc->srpc_bulk; - __u64 id = rpc->srpc_reqstbuf->buf_msg.msg_body.reqst.bulkid; - int rc; - int opt; + srpc_event_t *ev = &rpc->srpc_ev; + srpc_bulk_t *bk = rpc->srpc_bulk; + __u64 id = rpc->srpc_reqstbuf->buf_msg.msg_body.reqst.bulkid; + int rc; + int opt; LASSERT(bk != NULL); @@ -896,9 +896,9 @@ srpc_do_bulk(srpc_server_rpc_t *rpc) static void srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status) { - struct srpc_service_cd *scd = rpc->srpc_scd; - struct srpc_service *sv = scd->scd_svc; - srpc_buffer_t *buffer; + struct srpc_service_cd *scd = rpc->srpc_scd; + struct srpc_service *sv = scd->scd_svc; + srpc_buffer_t *buffer; LASSERT(status != 0 || rpc->srpc_wi.swi_state == SWI_STATE_DONE); @@ -959,11 +959,11 @@ srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status) int srpc_handle_rpc(swi_workitem_t *wi) { - struct srpc_server_rpc *rpc = wi->swi_workitem.wi_data; - struct srpc_service_cd *scd = rpc->srpc_scd; - struct srpc_service *sv = scd->scd_svc; - srpc_event_t *ev = &rpc->srpc_ev; - int rc = 0; + struct srpc_server_rpc *rpc = wi->swi_workitem.wi_data; + struct srpc_service_cd *scd = rpc->srpc_scd; + struct srpc_service *sv = scd->scd_svc; + srpc_event_t *ev = &rpc->srpc_ev; + int rc = 0; LASSERT(wi == &rpc->srpc_wi); @@ -989,7 +989,7 @@ srpc_handle_rpc(swi_workitem_t *wi) default: LBUG(); case SWI_STATE_NEWBORN: { - srpc_msg_t *msg; + srpc_msg_t *msg; srpc_generic_reply_t *reply; msg = &rpc->srpc_reqstbuf->buf_msg; @@ -1173,10 +1173,10 @@ srpc_client_rpc_done(srpc_client_rpc_t *rpc, int status) int srpc_send_rpc(swi_workitem_t *wi) { - int rc = 0; + int rc = 0; srpc_client_rpc_t *rpc; - srpc_msg_t *reply; - int do_bulk; + srpc_msg_t *reply; + int do_bulk; LASSERT(wi != NULL); @@ -1359,13 +1359,13 @@ srpc_post_rpc(srpc_client_rpc_t *rpc) int srpc_send_reply(struct srpc_server_rpc *rpc) { - srpc_event_t *ev = &rpc->srpc_ev; - struct srpc_msg *msg = &rpc->srpc_replymsg; - struct srpc_buffer *buffer = rpc->srpc_reqstbuf; - struct srpc_service_cd *scd = rpc->srpc_scd; - struct srpc_service *sv = scd->scd_svc; - __u64 rpyid; - int rc; + srpc_event_t *ev = &rpc->srpc_ev; + struct srpc_msg *msg = &rpc->srpc_replymsg; + struct srpc_buffer *buffer = rpc->srpc_reqstbuf; + struct srpc_service_cd *scd = rpc->srpc_scd; + struct srpc_service *sv = scd->scd_svc; + __u64 rpyid; + int rc; LASSERT(buffer != NULL); rpyid = buffer->buf_msg.msg_body.reqst.rpyid; @@ -1403,14 +1403,14 @@ srpc_send_reply(struct srpc_server_rpc *rpc) static void srpc_lnet_ev_handler(lnet_event_t *ev) { - struct srpc_service_cd *scd; - srpc_event_t *rpcev = ev->md.user_ptr; + struct srpc_service_cd *scd; + srpc_event_t *rpcev = ev->md.user_ptr; srpc_client_rpc_t *crpc; srpc_server_rpc_t *srpc; - srpc_buffer_t *buffer; - srpc_service_t *sv; - srpc_msg_t *msg; - srpc_msg_type_t type; + srpc_buffer_t *buffer; + srpc_service_t *sv; + srpc_msg_t *msg; + srpc_msg_type_t type; LASSERT(!in_interrupt()); diff --git a/drivers/staging/lustre/lnet/selftest/rpc.h b/drivers/staging/lustre/lnet/selftest/rpc.h index fbeb75fe5922..b7b00c6b1004 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.h +++ b/drivers/staging/lustre/lnet/selftest/rpc.h @@ -79,60 +79,61 @@ typedef struct { } WIRE_ATTR srpc_generic_reqst_t; typedef struct { - __u32 status; - lst_sid_t sid; + __u32 status; + lst_sid_t sid; } WIRE_ATTR srpc_generic_reply_t; /* FRAMEWORK RPCs */ typedef struct { - __u64 mksn_rpyid; /* reply buffer matchbits */ - lst_sid_t mksn_sid; /* session id */ - __u32 mksn_force; /* use brute force */ + __u64 mksn_rpyid; /* reply buffer matchbits */ + lst_sid_t mksn_sid; /* session id */ + __u32 mksn_force; /* use brute force */ char mksn_name[LST_NAME_SIZE]; -} WIRE_ATTR srpc_mksn_reqst_t; /* make session request */ +} WIRE_ATTR srpc_mksn_reqst_t; /* make session request */ typedef struct { - __u32 mksn_status; /* session status */ - lst_sid_t mksn_sid; /* session id */ - __u32 mksn_timeout; /* session timeout */ - char mksn_name[LST_NAME_SIZE]; + __u32 mksn_status; /* session status */ + lst_sid_t mksn_sid; /* session id */ + __u32 mksn_timeout; /* session timeout */ + char mksn_name[LST_NAME_SIZE]; } WIRE_ATTR srpc_mksn_reply_t; /* make session reply */ typedef struct { - __u64 rmsn_rpyid; /* reply buffer matchbits */ - lst_sid_t rmsn_sid; /* session id */ + __u64 rmsn_rpyid; /* reply buffer matchbits */ + lst_sid_t rmsn_sid; /* session id */ } WIRE_ATTR srpc_rmsn_reqst_t; /* remove session request */ typedef struct { - __u32 rmsn_status; - lst_sid_t rmsn_sid; /* session id */ + __u32 rmsn_status; + lst_sid_t rmsn_sid; /* session id */ } WIRE_ATTR srpc_rmsn_reply_t; /* remove session reply */ typedef struct { - __u64 join_rpyid; /* reply buffer matchbits */ - lst_sid_t join_sid; /* session id to join */ - char join_group[LST_NAME_SIZE]; /* group name */ + __u64 join_rpyid; /* reply buffer matchbits */ + lst_sid_t join_sid; /* session id to join */ + char join_group[LST_NAME_SIZE]; /* group name */ } WIRE_ATTR srpc_join_reqst_t; typedef struct { - __u32 join_status; /* returned status */ - lst_sid_t join_sid; /* session id */ - __u32 join_timeout; /* # seconds' inactivity to expire */ - char join_session[LST_NAME_SIZE]; /* session name */ + __u32 join_status; /* returned status */ + lst_sid_t join_sid; /* session id */ + __u32 join_timeout; /* # seconds' inactivity to + * expire */ + char join_session[LST_NAME_SIZE]; /* session name */ } WIRE_ATTR srpc_join_reply_t; typedef struct { - __u64 dbg_rpyid; /* reply buffer matchbits */ - lst_sid_t dbg_sid; /* session id */ - __u32 dbg_flags; /* bitmap of debug */ + __u64 dbg_rpyid; /* reply buffer matchbits */ + lst_sid_t dbg_sid; /* session id */ + __u32 dbg_flags; /* bitmap of debug */ } WIRE_ATTR srpc_debug_reqst_t; typedef struct { - __u32 dbg_status; /* returned code */ - lst_sid_t dbg_sid; /* session id */ - __u32 dbg_timeout; /* session timeout */ - __u32 dbg_nbatch; /* # of batches in the node */ - char dbg_name[LST_NAME_SIZE]; /* session name */ + __u32 dbg_status; /* returned code */ + lst_sid_t dbg_sid; /* session id */ + __u32 dbg_timeout; /* session timeout */ + __u32 dbg_nbatch; /* # of batches in the node */ + char dbg_name[LST_NAME_SIZE]; /* session name */ } WIRE_ATTR srpc_debug_reply_t; #define SRPC_BATCH_OPC_RUN 1 @@ -140,55 +141,51 @@ typedef struct { #define SRPC_BATCH_OPC_QUERY 3 typedef struct { - __u64 bar_rpyid; /* reply buffer matchbits */ - lst_sid_t bar_sid; /* session id */ - lst_bid_t bar_bid; /* batch id */ - __u32 bar_opc; /* create/start/stop batch */ - __u32 bar_testidx; /* index of test */ - __u32 bar_arg; /* parameters */ + __u64 bar_rpyid; /* reply buffer matchbits */ + lst_sid_t bar_sid; /* session id */ + lst_bid_t bar_bid; /* batch id */ + __u32 bar_opc; /* create/start/stop batch */ + __u32 bar_testidx; /* index of test */ + __u32 bar_arg; /* parameters */ } WIRE_ATTR srpc_batch_reqst_t; typedef struct { - __u32 bar_status; /* status of request */ - lst_sid_t bar_sid; /* session id */ - __u32 bar_active; /* # of active tests in batch/test */ - __u32 bar_time; /* remained time */ + __u32 bar_status; /* status of request */ + lst_sid_t bar_sid; /* session id */ + __u32 bar_active; /* # of active tests in batch/test */ + __u32 bar_time; /* remained time */ } WIRE_ATTR srpc_batch_reply_t; typedef struct { - __u64 str_rpyid; /* reply buffer matchbits */ - lst_sid_t str_sid; /* session id */ - __u32 str_type; /* type of stat */ + __u64 str_rpyid; /* reply buffer matchbits */ + lst_sid_t str_sid; /* session id */ + __u32 str_type; /* type of stat */ } WIRE_ATTR srpc_stat_reqst_t; typedef struct { - __u32 str_status; - lst_sid_t str_sid; - sfw_counters_t str_fw; - srpc_counters_t str_rpc; - lnet_counters_t str_lnet; + __u32 str_status; + lst_sid_t str_sid; + sfw_counters_t str_fw; + srpc_counters_t str_rpc; + lnet_counters_t str_lnet; } WIRE_ATTR srpc_stat_reply_t; typedef struct { - __u32 blk_opc; /* bulk operation code */ - __u32 blk_npg; /* # of pages */ - __u32 blk_flags; /* reserved flags */ + __u32 blk_opc; /* bulk operation code */ + __u32 blk_npg; /* # of pages */ + __u32 blk_flags; /* reserved flags */ } WIRE_ATTR test_bulk_req_t; typedef struct { - /** bulk operation code */ - __u16 blk_opc; - /** data check flags */ - __u16 blk_flags; - /** data length */ - __u32 blk_len; - /** reserved: offset */ - __u32 blk_offset; + __u16 blk_opc; /* bulk operation code */ + __u16 blk_flags; /* data check flags */ + __u32 blk_len; /* data length */ + __u32 blk_offset; /* reserved: offset */ } WIRE_ATTR test_bulk_req_v1_t; typedef struct { - __u32 png_size; /* size of ping message */ - __u32 png_flags; /* reserved flags */ + __u32 png_size; /* size of ping message */ + __u32 png_flags; /* reserved flags */ } WIRE_ATTR test_ping_req_t; typedef struct { @@ -197,8 +194,8 @@ typedef struct { lst_sid_t tsr_sid; /* session id */ lst_bid_t tsr_bid; /* batch id */ __u32 tsr_service; /* test type: bulk|ping|... */ - /* test client loop count or # server buffers needed */ - __u32 tsr_loop; + __u32 tsr_loop; /* test client loop count or + * # server buffers needed */ __u32 tsr_concur; /* concurrency of test */ __u8 tsr_is_client; /* is test client or not */ __u8 tsr_stop_onerr; /* stop on error */ @@ -234,8 +231,8 @@ typedef struct { typedef struct { __u64 brw_rpyid; /* reply buffer matchbits */ __u64 brw_bulkid; /* bulk buffer matchbits */ - __u32 brw_rw; /* read or write */ - __u32 brw_len; /* bulk data len */ + __u32 brw_rw; /* read or write */ + __u32 brw_len; /* bulk data len */ __u32 brw_flags; /* bulk data patterns */ } WIRE_ATTR srpc_brw_reqst_t; /* bulk r/w request */ @@ -243,20 +240,16 @@ typedef struct { __u32 brw_status; } WIRE_ATTR srpc_brw_reply_t; /* bulk r/w reply */ -#define SRPC_MSG_MAGIC 0xeeb0f00d -#define SRPC_MSG_VERSION 1 +#define SRPC_MSG_MAGIC 0xeeb0f00d +#define SRPC_MSG_VERSION 1 typedef struct srpc_msg { - /** magic number */ - __u32 msg_magic; - /** message version number */ - __u32 msg_version; - /** type of message body: srpc_msg_type_t */ - __u32 msg_type; + __u32 msg_magic; /* magic number */ + __u32 msg_version; /* message version number */ + __u32 msg_type; /* type of message body: srpc_msg_type_t */ __u32 msg_reserved0; __u32 msg_reserved1; - /** test session features */ - __u32 msg_ses_feats; + __u32 msg_ses_feats; /* test session features */ union { srpc_generic_reqst_t reqst; srpc_generic_reply_t reply; diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index d48701834b18..7939e4e04d90 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -57,14 +57,14 @@ #endif -#define SWI_STATE_NEWBORN 0 -#define SWI_STATE_REPLY_SUBMITTED 1 -#define SWI_STATE_REPLY_SENT 2 -#define SWI_STATE_REQUEST_SUBMITTED 3 -#define SWI_STATE_REQUEST_SENT 4 -#define SWI_STATE_REPLY_RECEIVED 5 -#define SWI_STATE_BULK_STARTED 6 -#define SWI_STATE_DONE 10 +#define SWI_STATE_NEWBORN 0 +#define SWI_STATE_REPLY_SUBMITTED 1 +#define SWI_STATE_REPLY_SENT 2 +#define SWI_STATE_REQUEST_SUBMITTED 3 +#define SWI_STATE_REQUEST_SENT 4 +#define SWI_STATE_REPLY_RECEIVED 5 +#define SWI_STATE_BULK_STARTED 6 +#define SWI_STATE_DONE 10 /* forward refs */ struct srpc_service; @@ -75,24 +75,24 @@ struct sfw_test_instance; /* services below SRPC_FRAMEWORK_SERVICE_MAX_ID are framework * services, e.g. create/modify session. */ -#define SRPC_SERVICE_DEBUG 0 -#define SRPC_SERVICE_MAKE_SESSION 1 -#define SRPC_SERVICE_REMOVE_SESSION 2 -#define SRPC_SERVICE_BATCH 3 -#define SRPC_SERVICE_TEST 4 -#define SRPC_SERVICE_QUERY_STAT 5 -#define SRPC_SERVICE_JOIN 6 -#define SRPC_FRAMEWORK_SERVICE_MAX_ID 10 +#define SRPC_SERVICE_DEBUG 0 +#define SRPC_SERVICE_MAKE_SESSION 1 +#define SRPC_SERVICE_REMOVE_SESSION 2 +#define SRPC_SERVICE_BATCH 3 +#define SRPC_SERVICE_TEST 4 +#define SRPC_SERVICE_QUERY_STAT 5 +#define SRPC_SERVICE_JOIN 6 +#define SRPC_FRAMEWORK_SERVICE_MAX_ID 10 /* other services start from SRPC_FRAMEWORK_SERVICE_MAX_ID+1 */ -#define SRPC_SERVICE_BRW 11 -#define SRPC_SERVICE_PING 12 -#define SRPC_SERVICE_MAX_ID 12 +#define SRPC_SERVICE_BRW 11 +#define SRPC_SERVICE_PING 12 +#define SRPC_SERVICE_MAX_ID 12 -#define SRPC_REQUEST_PORTAL 50 +#define SRPC_REQUEST_PORTAL 50 /* a lazy portal for framework RPC requests */ -#define SRPC_FRAMEWORK_REQUEST_PORTAL 51 +#define SRPC_FRAMEWORK_REQUEST_PORTAL 51 /* all reply/bulk RDMAs go to this portal */ -#define SRPC_RDMA_PORTAL 52 +#define SRPC_RDMA_PORTAL 52 static inline srpc_msg_type_t srpc_service2request (int service) @@ -136,7 +136,8 @@ srpc_service2reply (int service) } typedef enum { - SRPC_BULK_REQ_RCVD = 1, /* passive bulk request(PUT sink/GET source) received */ + SRPC_BULK_REQ_RCVD = 1, /* passive bulk request(PUT sink/GET source) + * received */ SRPC_BULK_PUT_SENT = 2, /* active bulk PUT sent (source) */ SRPC_BULK_GET_RPLD = 3, /* active bulk GET replied (sink) */ SRPC_REPLY_RCVD = 4, /* incoming reply received */ @@ -149,114 +150,114 @@ typedef enum { typedef struct { srpc_event_type_t ev_type; /* what's up */ lnet_event_kind_t ev_lnet; /* LNet event type */ - int ev_fired; /* LNet event fired? */ - int ev_status; /* LNet event status */ - void *ev_data; /* owning server/client RPC */ + int ev_fired; /* LNet event fired? */ + int ev_status; /* LNet event status */ + void *ev_data; /* owning server/client RPC */ } srpc_event_t; typedef struct { - int bk_len; /* len of bulk data */ + int bk_len; /* len of bulk data */ lnet_handle_md_t bk_mdh; - int bk_sink; /* sink/source */ - int bk_niov; /* # iov in bk_iovs */ + int bk_sink; /* sink/source */ + int bk_niov; /* # iov in bk_iovs */ lnet_kiov_t bk_iovs[0]; } srpc_bulk_t; /* bulk descriptor */ /* message buffer descriptor */ typedef struct srpc_buffer { - struct list_head buf_list; /* chain on srpc_service::*_msgq */ - srpc_msg_t buf_msg; - lnet_handle_md_t buf_mdh; - lnet_nid_t buf_self; - lnet_process_id_t buf_peer; + struct list_head buf_list; /* chain on srpc_service::*_msgq */ + srpc_msg_t buf_msg; + lnet_handle_md_t buf_mdh; + lnet_nid_t buf_self; + lnet_process_id_t buf_peer; } srpc_buffer_t; struct swi_workitem; typedef int (*swi_action_t) (struct swi_workitem *); typedef struct swi_workitem { - struct cfs_wi_sched *swi_sched; - cfs_workitem_t swi_workitem; - swi_action_t swi_action; - int swi_state; + struct cfs_wi_sched *swi_sched; + cfs_workitem_t swi_workitem; + swi_action_t swi_action; + int swi_state; } swi_workitem_t; /* server-side state of a RPC */ typedef struct srpc_server_rpc { /* chain on srpc_service::*_rpcq */ - struct list_head srpc_list; + struct list_head srpc_list; struct srpc_service_cd *srpc_scd; - swi_workitem_t srpc_wi; - srpc_event_t srpc_ev; /* bulk/reply event */ - lnet_nid_t srpc_self; - lnet_process_id_t srpc_peer; - srpc_msg_t srpc_replymsg; - lnet_handle_md_t srpc_replymdh; - srpc_buffer_t *srpc_reqstbuf; - srpc_bulk_t *srpc_bulk; - - unsigned int srpc_aborted; /* being given up */ - int srpc_status; - void (*srpc_done)(struct srpc_server_rpc *); + swi_workitem_t srpc_wi; + srpc_event_t srpc_ev; /* bulk/reply event */ + lnet_nid_t srpc_self; + lnet_process_id_t srpc_peer; + srpc_msg_t srpc_replymsg; + lnet_handle_md_t srpc_replymdh; + srpc_buffer_t *srpc_reqstbuf; + srpc_bulk_t *srpc_bulk; + + unsigned int srpc_aborted; /* being given up */ + int srpc_status; + void (*srpc_done)(struct srpc_server_rpc *); } srpc_server_rpc_t; /* client-side state of a RPC */ typedef struct srpc_client_rpc { - struct list_head crpc_list; /* chain on user's lists */ - spinlock_t crpc_lock; /* serialize */ - int crpc_service; - atomic_t crpc_refcount; - int crpc_timeout; /* # seconds to wait for reply */ - stt_timer_t crpc_timer; - swi_workitem_t crpc_wi; - lnet_process_id_t crpc_dest; - - void (*crpc_done)(struct srpc_client_rpc *); - void (*crpc_fini)(struct srpc_client_rpc *); - int crpc_status; /* completion status */ - void *crpc_priv; /* caller data */ + struct list_head crpc_list; /* chain on user's lists */ + spinlock_t crpc_lock; /* serialize */ + int crpc_service; + atomic_t crpc_refcount; + int crpc_timeout; /* # seconds to wait for reply */ + stt_timer_t crpc_timer; + swi_workitem_t crpc_wi; + lnet_process_id_t crpc_dest; + + void (*crpc_done)(struct srpc_client_rpc *); + void (*crpc_fini)(struct srpc_client_rpc *); + int crpc_status; /* completion status */ + void *crpc_priv; /* caller data */ /* state flags */ - unsigned int crpc_aborted:1; /* being given up */ - unsigned int crpc_closed:1; /* completed */ + unsigned int crpc_aborted:1; /* being given up */ + unsigned int crpc_closed:1; /* completed */ /* RPC events */ - srpc_event_t crpc_bulkev; /* bulk event */ - srpc_event_t crpc_reqstev; /* request event */ - srpc_event_t crpc_replyev; /* reply event */ + srpc_event_t crpc_bulkev; /* bulk event */ + srpc_event_t crpc_reqstev; /* request event */ + srpc_event_t crpc_replyev; /* reply event */ /* bulk, request(reqst), and reply exchanged on wire */ - srpc_msg_t crpc_reqstmsg; - srpc_msg_t crpc_replymsg; - lnet_handle_md_t crpc_reqstmdh; - lnet_handle_md_t crpc_replymdh; - srpc_bulk_t crpc_bulk; + srpc_msg_t crpc_reqstmsg; + srpc_msg_t crpc_replymsg; + lnet_handle_md_t crpc_reqstmdh; + lnet_handle_md_t crpc_replymdh; + srpc_bulk_t crpc_bulk; } srpc_client_rpc_t; -#define srpc_client_rpc_size(rpc) \ +#define srpc_client_rpc_size(rpc) \ offsetof(srpc_client_rpc_t, crpc_bulk.bk_iovs[(rpc)->crpc_bulk.bk_niov]) -#define srpc_client_rpc_addref(rpc) \ -do { \ - CDEBUG(D_NET, "RPC[%p] -> %s (%d)++\n", \ - (rpc), libcfs_id2str((rpc)->crpc_dest), \ - atomic_read(&(rpc)->crpc_refcount)); \ - LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0); \ - atomic_inc(&(rpc)->crpc_refcount); \ +#define srpc_client_rpc_addref(rpc) \ +do { \ + CDEBUG(D_NET, "RPC[%p] -> %s (%d)++\n", \ + (rpc), libcfs_id2str((rpc)->crpc_dest), \ + atomic_read(&(rpc)->crpc_refcount)); \ + LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0); \ + atomic_inc(&(rpc)->crpc_refcount); \ } while (0) -#define srpc_client_rpc_decref(rpc) \ -do { \ - CDEBUG(D_NET, "RPC[%p] -> %s (%d)--\n", \ - (rpc), libcfs_id2str((rpc)->crpc_dest), \ - atomic_read(&(rpc)->crpc_refcount)); \ - LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0); \ - if (atomic_dec_and_test(&(rpc)->crpc_refcount)) \ - srpc_destroy_client_rpc(rpc); \ +#define srpc_client_rpc_decref(rpc) \ +do { \ + CDEBUG(D_NET, "RPC[%p] -> %s (%d)--\n", \ + (rpc), libcfs_id2str((rpc)->crpc_dest), \ + atomic_read(&(rpc)->crpc_refcount)); \ + LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0); \ + if (atomic_dec_and_test(&(rpc)->crpc_refcount)) \ + srpc_destroy_client_rpc(rpc); \ } while (0) -#define srpc_event_pending(rpc) ((rpc)->crpc_bulkev.ev_fired == 0 || \ - (rpc)->crpc_reqstev.ev_fired == 0 || \ +#define srpc_event_pending(rpc) ((rpc)->crpc_bulkev.ev_fired == 0 || \ + (rpc)->crpc_reqstev.ev_fired == 0 || \ (rpc)->crpc_replyev.ev_fired == 0) /* CPU partition data of srpc service */ @@ -268,9 +269,9 @@ struct srpc_service_cd { /** event buffer */ srpc_event_t scd_ev; /** free RPC descriptors */ - struct list_head scd_rpc_free; + struct list_head scd_rpc_free; /** in-flight RPCs */ - struct list_head scd_rpc_active; + struct list_head scd_rpc_active; /** workitem for posting buffer */ swi_workitem_t scd_buf_wi; /** CPT id */ @@ -278,7 +279,7 @@ struct srpc_service_cd { /** error code for scd_buf_wi */ int scd_buf_err; /** timestamp for scd_buf_err */ - unsigned long scd_buf_err_stamp; + unsigned long scd_buf_err_stamp; /** total # request buffers */ int scd_buf_total; /** # posted request buffers */ @@ -290,9 +291,9 @@ struct srpc_service_cd { /** increase/decrease some buffers */ int scd_buf_adjust; /** posted message buffers */ - struct list_head scd_buf_posted; + struct list_head scd_buf_posted; /** blocked for RPC descriptor */ - struct list_head scd_buf_blocked; + struct list_head scd_buf_blocked; }; /* number of server workitems (mini-thread) for testing service */ @@ -318,40 +319,42 @@ typedef struct srpc_service { * - sv_handler: process incoming RPC request * - sv_bulk_ready: notify bulk data */ - int (*sv_handler) (srpc_server_rpc_t *); - int (*sv_bulk_ready) (srpc_server_rpc_t *, int); + int (*sv_handler) (srpc_server_rpc_t *); + int (*sv_bulk_ready) (srpc_server_rpc_t *, int); } srpc_service_t; typedef struct { - struct list_head sn_list; /* chain on fw_zombie_sessions */ - lst_sid_t sn_id; /* unique identifier */ - unsigned int sn_timeout; /* # seconds' inactivity to expire */ - int sn_timer_active; - unsigned int sn_features; - stt_timer_t sn_timer; - struct list_head sn_batches; /* list of batches */ - char sn_name[LST_NAME_SIZE]; - atomic_t sn_refcount; - atomic_t sn_brw_errors; - atomic_t sn_ping_errors; - unsigned long sn_started; + struct list_head sn_list; /* chain on fw_zombie_sessions */ + lst_sid_t sn_id; /* unique identifier */ + unsigned int sn_timeout; /* # seconds' inactivity to expire */ + int sn_timer_active; + unsigned int sn_features; + stt_timer_t sn_timer; + struct list_head sn_batches; /* list of batches */ + char sn_name[LST_NAME_SIZE]; + atomic_t sn_refcount; + atomic_t sn_brw_errors; + atomic_t sn_ping_errors; + unsigned long sn_started; } sfw_session_t; #define sfw_sid_equal(sid0, sid1) ((sid0).ses_nid == (sid1).ses_nid && \ (sid0).ses_stamp == (sid1).ses_stamp) typedef struct { - struct list_head bat_list; /* chain on sn_batches */ - lst_bid_t bat_id; /* batch id */ - int bat_error; /* error code of batch */ - sfw_session_t *bat_session; /* batch's session */ - atomic_t bat_nactive; /* # of active tests */ - struct list_head bat_tests; /* test instances */ + struct list_head bat_list; /* chain on sn_batches */ + lst_bid_t bat_id; /* batch id */ + int bat_error; /* error code of batch */ + sfw_session_t *bat_session; /* batch's session */ + atomic_t bat_nactive; /* # of active tests */ + struct list_head bat_tests; /* test instances */ } sfw_batch_t; typedef struct { - int (*tso_init)(struct sfw_test_instance *tsi); /* initialize test client */ - void (*tso_fini)(struct sfw_test_instance *tsi); /* finalize test client */ + int (*tso_init)(struct sfw_test_instance *tsi); /* initialize test + * client */ + void (*tso_fini)(struct sfw_test_instance *tsi); /* finalize test + * client */ int (*tso_prep_rpc)(struct sfw_test_unit *tsu, lnet_process_id_t dest, srpc_client_rpc_t **rpc); /* prep a tests rpc */ @@ -360,29 +363,31 @@ typedef struct { } sfw_test_client_ops_t; typedef struct sfw_test_instance { - struct list_head tsi_list; /* chain on batch */ - int tsi_service; /* test type */ - sfw_batch_t *tsi_batch; /* batch */ - sfw_test_client_ops_t *tsi_ops; /* test client operations */ + struct list_head tsi_list; /* chain on batch */ + int tsi_service; /* test type */ + sfw_batch_t *tsi_batch; /* batch */ + sfw_test_client_ops_t *tsi_ops; /* test client operation + */ /* public parameter for all test units */ - unsigned int tsi_is_client:1; /* is test client */ - unsigned int tsi_stoptsu_onerr:1; /* stop tsu on error */ - int tsi_concur; /* concurrency */ - int tsi_loop; /* loop count */ + unsigned int tsi_is_client:1; /* is test client */ + unsigned int tsi_stoptsu_onerr:1; /* stop tsu on error */ + int tsi_concur; /* concurrency */ + int tsi_loop; /* loop count */ /* status of test instance */ - spinlock_t tsi_lock; /* serialize */ - unsigned int tsi_stopping:1; /* test is stopping */ - atomic_t tsi_nactive; /* # of active test unit */ - struct list_head tsi_units; /* test units */ - struct list_head tsi_free_rpcs; /* free rpcs */ - struct list_head tsi_active_rpcs; /* active rpcs */ + spinlock_t tsi_lock; /* serialize */ + unsigned int tsi_stopping:1; /* test is stopping */ + atomic_t tsi_nactive; /* # of active test + * unit */ + struct list_head tsi_units; /* test units */ + struct list_head tsi_free_rpcs; /* free rpcs */ + struct list_head tsi_active_rpcs; /* active rpcs */ union { - test_ping_req_t ping; /* ping parameter */ - test_bulk_req_t bulk_v0; /* bulk parameter */ - test_bulk_req_v1_t bulk_v1; /* bulk v1 parameter */ + test_ping_req_t ping; /* ping parameter */ + test_bulk_req_t bulk_v0; /* bulk parameter */ + test_bulk_req_v1_t bulk_v1; /* bulk v1 parameter */ } tsi_u; } sfw_test_instance_t; @@ -394,18 +399,18 @@ typedef struct sfw_test_instance { #define sfw_id_pages(n) (((n) + SFW_ID_PER_PAGE - 1) / SFW_ID_PER_PAGE) typedef struct sfw_test_unit { - struct list_head tsu_list; /* chain on lst_test_instance */ - lnet_process_id_t tsu_dest; /* id of dest node */ - int tsu_loop; /* loop count of the test */ - sfw_test_instance_t *tsu_instance; /* pointer to test instance */ - void *tsu_private; /* private data */ - swi_workitem_t tsu_worker; /* workitem of the test unit */ + struct list_head tsu_list; /* chain on lst_test_instance */ + lnet_process_id_t tsu_dest; /* id of dest node */ + int tsu_loop; /* loop count of the test */ + sfw_test_instance_t *tsu_instance; /* pointer to test instance */ + void *tsu_private; /* private data */ + swi_workitem_t tsu_worker; /* workitem of the test unit */ } sfw_test_unit_t; typedef struct sfw_test_case { - struct list_head tsc_list; /* chain on fw_tests */ - srpc_service_t *tsc_srv_service; /* test service */ - sfw_test_client_ops_t *tsc_cli_ops; /* ops of test client */ + struct list_head tsc_list; /* chain on fw_tests */ + srpc_service_t *tsc_srv_service; /* test service */ + sfw_test_client_ops_t *tsc_cli_ops; /* ops of test client */ } sfw_test_case_t; srpc_client_rpc_t * @@ -501,9 +506,9 @@ void srpc_shutdown(void); static inline void srpc_destroy_client_rpc (srpc_client_rpc_t *rpc) { - LASSERT (rpc != NULL); - LASSERT (!srpc_event_pending(rpc)); - LASSERT (atomic_read(&rpc->crpc_refcount) == 0); + LASSERT(rpc != NULL); + LASSERT(!srpc_event_pending(rpc)); + LASSERT(atomic_read(&rpc->crpc_refcount) == 0); if (rpc->crpc_fini == NULL) { LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc)); @@ -520,7 +525,7 @@ srpc_init_client_rpc (srpc_client_rpc_t *rpc, lnet_process_id_t peer, void (*rpc_done)(srpc_client_rpc_t *), void (*rpc_fini)(srpc_client_rpc_t *), void *priv) { - LASSERT (nbulkiov <= LNET_MAX_IOV); + LASSERT(nbulkiov <= LNET_MAX_IOV); memset(rpc, 0, offsetof(srpc_client_rpc_t, crpc_bulk.bk_iovs[nbulkiov])); @@ -531,13 +536,13 @@ srpc_init_client_rpc (srpc_client_rpc_t *rpc, lnet_process_id_t peer, spin_lock_init(&rpc->crpc_lock); atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */ - rpc->crpc_dest = peer; - rpc->crpc_priv = priv; + rpc->crpc_dest = peer; + rpc->crpc_priv = priv; rpc->crpc_service = service; rpc->crpc_bulk.bk_len = bulklen; rpc->crpc_bulk.bk_niov = nbulkiov; - rpc->crpc_done = rpc_done; - rpc->crpc_fini = rpc_fini; + rpc->crpc_done = rpc_done; + rpc->crpc_fini = rpc_fini; LNetInvalidateHandle(&rpc->crpc_reqstmdh); LNetInvalidateHandle(&rpc->crpc_replymdh); LNetInvalidateHandle(&rpc->crpc_bulk.bk_mdh); diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index 441f9472a834..6133b54f4a82 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -50,7 +50,7 @@ * sorted by increasing expiry time. The number of slots is 2**7 (128), * to cover a time period of 1024 seconds into the future before wrapping. */ -#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ +#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ #define STTIMER_SLOTTIME (1 << STTIMER_MINPOLL) #define STTIMER_SLOTTIMEMASK (~(STTIMER_SLOTTIME - 1)) #define STTIMER_NSLOTS (1 << 7) @@ -58,13 +58,13 @@ (STTIMER_NSLOTS - 1))]) static struct st_timer_data { - spinlock_t stt_lock; - /* start time of the slot processed previously */ - unsigned long stt_prev_slot; - struct list_head stt_hash[STTIMER_NSLOTS]; - int stt_shuttingdown; - wait_queue_head_t stt_waitq; - int stt_nthreads; + spinlock_t stt_lock; + unsigned long stt_prev_slot; /* start time of the slot processed + * previously */ + struct list_head stt_hash[STTIMER_NSLOTS]; + int stt_shuttingdown; + wait_queue_head_t stt_waitq; + int stt_nthreads; } stt_data; void @@ -124,7 +124,7 @@ stt_del_timer(stt_timer_t *timer) static int stt_expire_list(struct list_head *slot, unsigned long now) { - int expired = 0; + int expired = 0; stt_timer_t *timer; while (!list_empty(slot)) { @@ -148,7 +148,7 @@ stt_expire_list(struct list_head *slot, unsigned long now) static int stt_check_timers(unsigned long *last) { - int expired = 0; + int expired = 0; unsigned long now; unsigned long this_slot; diff --git a/drivers/staging/lustre/lnet/selftest/timer.h b/drivers/staging/lustre/lnet/selftest/timer.h index d727c1e2b0ce..2a8803d89de4 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.h +++ b/drivers/staging/lustre/lnet/selftest/timer.h @@ -39,15 +39,15 @@ #define __SELFTEST_TIMER_H__ typedef struct { - struct list_head stt_list; - unsigned long stt_expires; - void (*stt_func) (void *); - void *stt_data; + struct list_head stt_list; + unsigned long stt_expires; + void (*stt_func) (void *); + void *stt_data; } stt_timer_t; -void stt_add_timer (stt_timer_t *timer); -int stt_del_timer (stt_timer_t *timer); -int stt_startup (void); -void stt_shutdown (void); +void stt_add_timer(stt_timer_t *timer); +int stt_del_timer(stt_timer_t *timer); +int stt_startup(void); +void stt_shutdown(void); #endif /* __SELFTEST_TIMER_H__ */ diff --git a/drivers/staging/lustre/lustre/fid/Makefile b/drivers/staging/lustre/lustre/fid/Makefile index 5513ce416a35..b7ef314b4b84 100644 --- a/drivers/staging/lustre/lustre/fid/Makefile +++ b/drivers/staging/lustre/lustre/fid/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += fid.o -fid-y := fid_request.o fid_lib.o -fid-$(CONFIG_PROC_FS) += lproc_fid.o +fid-y := fid_request.o fid_lib.o lproc_fid.o diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h index b5e8da8956f2..84daee1154dc 100644 --- a/drivers/staging/lustre/lustre/fid/fid_internal.h +++ b/drivers/staging/lustre/lustre/fid/fid_internal.h @@ -47,10 +47,6 @@ int seq_client_alloc_super(struct lu_client_seq *seq, const struct lu_env *env); -#if defined(CONFIG_PROC_FS) -extern struct lprocfs_vars seq_client_proc_list[]; -#endif - -extern struct proc_dir_entry *seq_type_proc_dir; +extern struct lprocfs_vars seq_client_debugfs_list[]; #endif /* __FID_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c index 7aee3935d31c..1362783b7eab 100644 --- a/drivers/staging/lustre/lustre/fid/fid_request.c +++ b/drivers/staging/lustre/lustre/fid/fid_request.c @@ -53,6 +53,8 @@ #include "../include/lustre_mdc.h" #include "fid_internal.h" +static struct dentry *seq_debugfs_dir; + static int seq_client_rpc(struct lu_client_seq *seq, struct lu_seq_range *output, __u32 opc, const char *opcname) @@ -201,10 +203,9 @@ static int seq_client_alloc_seq(const struct lu_env *env, CERROR("%s: Can't allocate new meta-sequence, rc %d\n", seq->lcs_name, rc); return rc; - } else { - CDEBUG(D_INFO, "%s: New range - "DRANGE"\n", - seq->lcs_name, PRANGE(&seq->lcs_space)); } + CDEBUG(D_INFO, "%s: New range - "DRANGE"\n", + seq->lcs_name, PRANGE(&seq->lcs_space)); } else { rc = 0; } @@ -400,37 +401,32 @@ void seq_client_flush(struct lu_client_seq *seq) } EXPORT_SYMBOL(seq_client_flush); -static void seq_client_proc_fini(struct lu_client_seq *seq) +static void seq_client_debugfs_fini(struct lu_client_seq *seq) { -#if defined(CONFIG_PROC_FS) - if (seq->lcs_proc_dir) { - if (!IS_ERR(seq->lcs_proc_dir)) - lprocfs_remove(&seq->lcs_proc_dir); - seq->lcs_proc_dir = NULL; - } -#endif /* CONFIG_PROC_FS */ + if (!IS_ERR_OR_NULL(seq->lcs_debugfs_entry)) + ldebugfs_remove(&seq->lcs_debugfs_entry); } -static int seq_client_proc_init(struct lu_client_seq *seq) +static int seq_client_debugfs_init(struct lu_client_seq *seq) { -#if defined(CONFIG_PROC_FS) int rc; - seq->lcs_proc_dir = lprocfs_register(seq->lcs_name, - seq_type_proc_dir, - NULL, NULL); + seq->lcs_debugfs_entry = ldebugfs_register(seq->lcs_name, + seq_debugfs_dir, + NULL, NULL); - if (IS_ERR(seq->lcs_proc_dir)) { - CERROR("%s: LProcFS failed in seq-init\n", - seq->lcs_name); - rc = PTR_ERR(seq->lcs_proc_dir); + if (IS_ERR_OR_NULL(seq->lcs_debugfs_entry)) { + CERROR("%s: LdebugFS failed in seq-init\n", seq->lcs_name); + rc = seq->lcs_debugfs_entry ? PTR_ERR(seq->lcs_debugfs_entry) + : -ENOMEM; + seq->lcs_debugfs_entry = NULL; return rc; } - rc = lprocfs_add_vars(seq->lcs_proc_dir, - seq_client_proc_list, seq); + rc = ldebugfs_add_vars(seq->lcs_debugfs_entry, + seq_client_debugfs_list, seq); if (rc) { - CERROR("%s: Can't init sequence manager proc, rc %d\n", + CERROR("%s: Can't init sequence manager debugfs, rc %d\n", seq->lcs_name, rc); goto out_cleanup; } @@ -438,12 +434,8 @@ static int seq_client_proc_init(struct lu_client_seq *seq) return 0; out_cleanup: - seq_client_proc_fini(seq); + seq_client_debugfs_fini(seq); return rc; - -#else /* CONFIG_PROC_FS */ - return 0; -#endif } int seq_client_init(struct lu_client_seq *seq, @@ -478,7 +470,7 @@ int seq_client_init(struct lu_client_seq *seq, snprintf(seq->lcs_name, sizeof(seq->lcs_name), "cli-%s", prefix); - rc = seq_client_proc_init(seq); + rc = seq_client_debugfs_init(seq); if (rc) seq_client_fini(seq); return rc; @@ -487,7 +479,7 @@ EXPORT_SYMBOL(seq_client_init); void seq_client_fini(struct lu_client_seq *seq) { - seq_client_proc_fini(seq); + seq_client_debugfs_fini(seq); if (seq->lcs_exp != NULL) { class_export_put(seq->lcs_exp); @@ -545,22 +537,18 @@ int client_fid_fini(struct obd_device *obd) } EXPORT_SYMBOL(client_fid_fini); -struct proc_dir_entry *seq_type_proc_dir; - static int __init fid_mod_init(void) { - seq_type_proc_dir = lprocfs_register(LUSTRE_SEQ_NAME, - proc_lustre_root, - NULL, NULL); - return PTR_ERR_OR_ZERO(seq_type_proc_dir); + seq_debugfs_dir = ldebugfs_register(LUSTRE_SEQ_NAME, + debugfs_lustre_root, + NULL, NULL); + return PTR_ERR_OR_ZERO(seq_debugfs_dir); } static void __exit fid_mod_exit(void) { - if (seq_type_proc_dir != NULL && !IS_ERR(seq_type_proc_dir)) { - lprocfs_remove(&seq_type_proc_dir); - seq_type_proc_dir = NULL; - } + if (!IS_ERR_OR_NULL(seq_debugfs_dir)) + ldebugfs_remove(&seq_debugfs_dir); } MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>"); diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c index 783939dbd4db..cc2201c25339 100644 --- a/drivers/staging/lustre/lustre/fid/lproc_fid.c +++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c @@ -59,8 +59,9 @@ * Note: this function is only used for testing, it is no safe for production * use. */ -static int lprocfs_fid_write_common(const char __user *buffer, size_t count, - struct lu_seq_range *range) +static int +ldebugfs_fid_write_common(const char __user *buffer, size_t count, + struct lu_seq_range *range) { struct lu_seq_range tmp; int rc; @@ -92,10 +93,11 @@ static int lprocfs_fid_write_common(const char __user *buffer, size_t count, return count; } -/* Client side procfs stuff */ -static ssize_t lprocfs_fid_space_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +/* Client side debugfs stuff */ +static ssize_t +ldebugfs_fid_space_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct lu_client_seq *seq; int rc; @@ -104,7 +106,7 @@ static ssize_t lprocfs_fid_space_seq_write(struct file *file, LASSERT(seq != NULL); mutex_lock(&seq->lcs_mutex); - rc = lprocfs_fid_write_common(buffer, count, &seq->lcs_space); + rc = ldebugfs_fid_write_common(buffer, count, &seq->lcs_space); if (rc == 0) { CDEBUG(D_INFO, "%s: Space: "DRANGE"\n", @@ -117,7 +119,7 @@ static ssize_t lprocfs_fid_space_seq_write(struct file *file, } static int -lprocfs_fid_space_seq_show(struct seq_file *m, void *unused) +ldebugfs_fid_space_seq_show(struct seq_file *m, void *unused) { struct lu_client_seq *seq = (struct lu_client_seq *)m->private; @@ -130,9 +132,10 @@ lprocfs_fid_space_seq_show(struct seq_file *m, void *unused) return 0; } -static ssize_t lprocfs_fid_width_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t +ldebugfs_fid_width_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct lu_client_seq *seq; __u64 max; @@ -154,10 +157,8 @@ static ssize_t lprocfs_fid_width_seq_write(struct file *file, if (val <= max && val > 0) { seq->lcs_width = val; - if (rc == 0) { - CDEBUG(D_INFO, "%s: Sequence size: %llu\n", - seq->lcs_name, seq->lcs_width); - } + CDEBUG(D_INFO, "%s: Sequence size: %llu\n", seq->lcs_name, + seq->lcs_width); } mutex_unlock(&seq->lcs_mutex); @@ -166,7 +167,7 @@ static ssize_t lprocfs_fid_width_seq_write(struct file *file, } static int -lprocfs_fid_width_seq_show(struct seq_file *m, void *unused) +ldebugfs_fid_width_seq_show(struct seq_file *m, void *unused) { struct lu_client_seq *seq = (struct lu_client_seq *)m->private; @@ -180,7 +181,7 @@ lprocfs_fid_width_seq_show(struct seq_file *m, void *unused) } static int -lprocfs_fid_fid_seq_show(struct seq_file *m, void *unused) +ldebugfs_fid_fid_seq_show(struct seq_file *m, void *unused) { struct lu_client_seq *seq = (struct lu_client_seq *)m->private; @@ -194,7 +195,7 @@ lprocfs_fid_fid_seq_show(struct seq_file *m, void *unused) } static int -lprocfs_fid_server_seq_show(struct seq_file *m, void *unused) +ldebugfs_fid_server_seq_show(struct seq_file *m, void *unused) { struct lu_client_seq *seq = (struct lu_client_seq *)m->private; struct client_obd *cli; @@ -211,15 +212,15 @@ lprocfs_fid_server_seq_show(struct seq_file *m, void *unused) return 0; } -LPROC_SEQ_FOPS(lprocfs_fid_space); -LPROC_SEQ_FOPS(lprocfs_fid_width); -LPROC_SEQ_FOPS_RO(lprocfs_fid_server); -LPROC_SEQ_FOPS_RO(lprocfs_fid_fid); +LPROC_SEQ_FOPS(ldebugfs_fid_space); +LPROC_SEQ_FOPS(ldebugfs_fid_width); +LPROC_SEQ_FOPS_RO(ldebugfs_fid_server); +LPROC_SEQ_FOPS_RO(ldebugfs_fid_fid); -struct lprocfs_vars seq_client_proc_list[] = { - { "space", &lprocfs_fid_space_fops }, - { "width", &lprocfs_fid_width_fops }, - { "server", &lprocfs_fid_server_fops }, - { "fid", &lprocfs_fid_fid_fops }, +struct lprocfs_vars seq_client_debugfs_list[] = { + { "space", &ldebugfs_fid_space_fops }, + { "width", &ldebugfs_fid_width_fops }, + { "server", &ldebugfs_fid_server_fops }, + { "fid", &ldebugfs_fid_fid_fops }, { NULL } }; diff --git a/drivers/staging/lustre/lustre/fld/Makefile b/drivers/staging/lustre/lustre/fld/Makefile index 2bbf08433dca..646e315d1aa8 100644 --- a/drivers/staging/lustre/lustre/fld/Makefile +++ b/drivers/staging/lustre/lustre/fld/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += fld.o -fld-y := fld_request.o fld_cache.o -fld-$(CONFIG_PROC_FS) += lproc_fld.o +fld-y := fld_request.o fld_cache.o lproc_fld.o diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index 68bec7658463..844576b9bc6f 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -142,10 +142,7 @@ extern struct lu_fld_hash fld_hash[]; int fld_client_rpc(struct obd_export *exp, struct lu_seq_range *range, __u32 fld_op); -#if defined(CONFIG_PROC_FS) -extern struct lprocfs_vars fld_client_proc_list[]; -#endif - +extern struct lprocfs_vars fld_client_debugfs_list[]; struct fld_cache *fld_cache_init(const char *name, int cache_size, int cache_threshold); diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index 075eb5ceedb6..c3b47f2346df 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -277,58 +277,44 @@ int fld_client_del_target(struct lu_client_fld *fld, __u64 idx) } EXPORT_SYMBOL(fld_client_del_target); -static struct proc_dir_entry *fld_type_proc_dir; +static struct dentry *fld_debugfs_dir; -#if defined(CONFIG_PROC_FS) -static int fld_client_proc_init(struct lu_client_fld *fld) +static int fld_client_debugfs_init(struct lu_client_fld *fld) { int rc; - fld->lcf_proc_dir = lprocfs_register(fld->lcf_name, - fld_type_proc_dir, - NULL, NULL); + fld->lcf_debugfs_entry = ldebugfs_register(fld->lcf_name, + fld_debugfs_dir, + NULL, NULL); - if (IS_ERR(fld->lcf_proc_dir)) { - CERROR("%s: LProcFS failed in fld-init\n", - fld->lcf_name); - rc = PTR_ERR(fld->lcf_proc_dir); + if (IS_ERR_OR_NULL(fld->lcf_debugfs_entry)) { + CERROR("%s: LdebugFS failed in fld-init\n", fld->lcf_name); + rc = fld->lcf_debugfs_entry ? PTR_ERR(fld->lcf_debugfs_entry) + : -ENOMEM; + fld->lcf_debugfs_entry = NULL; return rc; } - rc = lprocfs_add_vars(fld->lcf_proc_dir, - fld_client_proc_list, fld); + rc = ldebugfs_add_vars(fld->lcf_debugfs_entry, + fld_client_debugfs_list, fld); if (rc) { - CERROR("%s: Can't init FLD proc, rc %d\n", - fld->lcf_name, rc); + CERROR("%s: Can't init FLD debufs, rc %d\n", fld->lcf_name, rc); goto out_cleanup; } return 0; out_cleanup: - fld_client_proc_fini(fld); + fld_client_debugfs_fini(fld); return rc; } -void fld_client_proc_fini(struct lu_client_fld *fld) +void fld_client_debugfs_fini(struct lu_client_fld *fld) { - if (fld->lcf_proc_dir) { - if (!IS_ERR(fld->lcf_proc_dir)) - lprocfs_remove(&fld->lcf_proc_dir); - fld->lcf_proc_dir = NULL; - } -} -#else -static int fld_client_proc_init(struct lu_client_fld *fld) -{ - return 0; + if (!IS_ERR_OR_NULL(fld->lcf_debugfs_entry)) + ldebugfs_remove(&fld->lcf_debugfs_entry); } - -void fld_client_proc_fini(struct lu_client_fld *fld) -{ -} -#endif -EXPORT_SYMBOL(fld_client_proc_fini); +EXPORT_SYMBOL(fld_client_debugfs_fini); static inline int hash_is_sane(int hash) { @@ -372,7 +358,7 @@ int fld_client_init(struct lu_client_fld *fld, goto out; } - rc = fld_client_proc_init(fld); + rc = fld_client_debugfs_init(fld); if (rc) goto out; out: @@ -504,18 +490,16 @@ EXPORT_SYMBOL(fld_client_flush); static int __init fld_mod_init(void) { - fld_type_proc_dir = lprocfs_register(LUSTRE_FLD_NAME, - proc_lustre_root, - NULL, NULL); - return PTR_ERR_OR_ZERO(fld_type_proc_dir); + fld_debugfs_dir = ldebugfs_register(LUSTRE_FLD_NAME, + debugfs_lustre_root, + NULL, NULL); + return PTR_ERR_OR_ZERO(fld_debugfs_dir); } static void __exit fld_mod_exit(void) { - if (fld_type_proc_dir != NULL && !IS_ERR(fld_type_proc_dir)) { - lprocfs_remove(&fld_type_proc_dir); - fld_type_proc_dir = NULL; - } + if (!IS_ERR_OR_NULL(fld_debugfs_dir)) + ldebugfs_remove(&fld_debugfs_dir); } MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>"); diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c index f53fdcfae34e..b35ff288dbd5 100644 --- a/drivers/staging/lustre/lustre/fld/lproc_fld.c +++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c @@ -56,7 +56,7 @@ #include "fld_internal.h" static int -fld_proc_targets_seq_show(struct seq_file *m, void *unused) +fld_debugfs_targets_seq_show(struct seq_file *m, void *unused) { struct lu_client_fld *fld = (struct lu_client_fld *)m->private; struct lu_fld_target *target; @@ -73,7 +73,7 @@ fld_proc_targets_seq_show(struct seq_file *m, void *unused) } static int -fld_proc_hash_seq_show(struct seq_file *m, void *unused) +fld_debugfs_hash_seq_show(struct seq_file *m, void *unused) { struct lu_client_fld *fld = (struct lu_client_fld *)m->private; @@ -87,9 +87,9 @@ fld_proc_hash_seq_show(struct seq_file *m, void *unused) } static ssize_t -fld_proc_hash_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +fld_debugfs_hash_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct lu_client_fld *fld; struct lu_fld_hash *hash = NULL; @@ -128,8 +128,8 @@ fld_proc_hash_seq_write(struct file *file, } static ssize_t -fld_proc_cache_flush_write(struct file *file, const char __user *buffer, - size_t count, loff_t *pos) +fld_debugfs_cache_flush_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { struct lu_client_fld *fld = file->private_data; @@ -142,31 +142,33 @@ fld_proc_cache_flush_write(struct file *file, const char __user *buffer, return count; } -static int fld_proc_cache_flush_open(struct inode *inode, struct file *file) +static int +fld_debugfs_cache_flush_open(struct inode *inode, struct file *file) { - file->private_data = PDE_DATA(inode); + file->private_data = inode->i_private; return 0; } -static int fld_proc_cache_flush_release(struct inode *inode, struct file *file) +static int +fld_debugfs_cache_flush_release(struct inode *inode, struct file *file) { file->private_data = NULL; return 0; } -static struct file_operations fld_proc_cache_flush_fops = { +static struct file_operations fld_debugfs_cache_flush_fops = { .owner = THIS_MODULE, - .open = fld_proc_cache_flush_open, - .write = fld_proc_cache_flush_write, - .release = fld_proc_cache_flush_release, + .open = fld_debugfs_cache_flush_open, + .write = fld_debugfs_cache_flush_write, + .release = fld_debugfs_cache_flush_release, }; -LPROC_SEQ_FOPS_RO(fld_proc_targets); -LPROC_SEQ_FOPS(fld_proc_hash); +LPROC_SEQ_FOPS_RO(fld_debugfs_targets); +LPROC_SEQ_FOPS(fld_debugfs_hash); -struct lprocfs_vars fld_client_proc_list[] = { - { "targets", &fld_proc_targets_fops }, - { "hash", &fld_proc_hash_fops }, - { "cache_flush", &fld_proc_cache_flush_fops }, +struct lprocfs_vars fld_client_debugfs_list[] = { + { "targets", &fld_debugfs_targets_fops }, + { "hash", &fld_debugfs_hash_fops }, + { "cache_flush", &fld_debugfs_cache_flush_fops }, { NULL } }; diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h index be4c7d95e788..abae31b41e74 100644 --- a/drivers/staging/lustre/lustre/include/dt_object.h +++ b/drivers/staging/lustre/lustre/include/dt_object.h @@ -58,7 +58,6 @@ #include "../../include/linux/libcfs/libcfs.h" struct seq_file; -struct proc_dir_entry; struct lustre_cfg; struct thandle; @@ -1481,7 +1480,6 @@ static inline struct dt_thread_info *dt_info(const struct lu_env *env) int dt_global_init(void); void dt_global_fini(void); -#if defined (CONFIG_PROC_FS) int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off, @@ -1494,6 +1492,5 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, int count, int *eof, void *data); -#endif /* CONFIG_PROC_FS */ #endif /* __LUSTRE_DT_OBJECT_H */ diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h index 3925db160650..513c81f43d6e 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h @@ -189,22 +189,7 @@ static inline int ll_quota_off(struct super_block *sb, int off, int remount) #endif - -/* - * After 3.1, kernel's nameidata.intent.open.flags is different - * with lustre's lookup_intent.it_flags, as lustre's it_flags' - * lower bits equal to FMODE_xxx while kernel doesn't transliterate - * lower bits of nameidata.intent.open.flags to FMODE_xxx. - * */ #include <linux/version.h> -static inline int ll_namei_to_lookup_intent_flag(int flag) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) - flag = (flag & ~O_ACCMODE) | OPEN_FMODE(flag); -#endif - return flag; -} - #include <linux/fs.h> # define ll_umode_t umode_t diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h index a7658a99a08d..45651caf42cc 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h @@ -44,7 +44,6 @@ #include <linux/fs.h> #include <linux/dcache.h> -#include <linux/proc_fs.h> #include "../obd_class.h" #include "../lustre_net.h" diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h index 9cd8683573ce..2817e88e014a 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ b/drivers/staging/lustre/lustre/include/linux/obd.h @@ -43,11 +43,11 @@ #include "../obd_support.h" -# include <linux/fs.h> -# include <linux/list.h> -# include <linux/sched.h> /* for struct task_struct, for current.h */ -# include <linux/proc_fs.h> -# include <linux/mount.h> +#include <linux/fs.h> +#include <linux/list.h> +#include <linux/sched.h> /* for struct task_struct, for current.h */ +#include <linux/mount.h> + #include "../lustre_intent.h" struct ll_iattr { diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index d030847e51ba..8ede2a00ca4f 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -42,7 +42,7 @@ #ifndef _LPROCFS_SNMP_H #define _LPROCFS_SNMP_H -#include <linux/proc_fs.h> +#include <linux/debugfs.h> #include <linux/seq_file.h> #include <linux/spinlock.h> #include <linux/types.h> @@ -60,8 +60,8 @@ struct lprocfs_vars { }; struct lprocfs_static_vars { - struct lprocfs_vars *module_vars; struct lprocfs_vars *obd_vars; + struct attribute_group *sysfs_vars; }; /* if we find more consumers this could be generalized */ @@ -348,7 +348,8 @@ enum { #define EXTRA_FIRST_OPC LDLM_GLIMPSE_ENQUEUE /* class_obd.c */ -extern struct proc_dir_entry *proc_lustre_root; +extern struct dentry *debugfs_lustre_root; +extern struct kobject *lustre_kobj; struct obd_device; struct obd_histogram; @@ -378,8 +379,6 @@ extern int lprocfs_write_frac_helper(const char __user *buffer, unsigned long count, int *val, int mult); extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, int mult); -#if defined (CONFIG_PROC_FS) - extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid); /* @@ -422,9 +421,8 @@ static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc, else spin_lock(&stats->ls_lock); return 1; - } else { - return stats->ls_biggest_alloc_num; } + return stats->ls_biggest_alloc_num; } } @@ -556,53 +554,45 @@ extern void lprocfs_counter_init(struct lprocfs_stats *stats, int index, extern void lprocfs_free_obd_stats(struct obd_device *obddev); extern void lprocfs_free_md_stats(struct obd_device *obddev); struct obd_export; -struct nid_stat; -extern int lprocfs_add_clear_entry(struct obd_device *obd, - struct proc_dir_entry *entry); -extern int lprocfs_exp_setup(struct obd_export *exp, - lnet_nid_t *peer_nid, int *newnid); extern int lprocfs_exp_cleanup(struct obd_export *exp); -extern struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root, - char *name, - void *data, - struct file_operations *fops); -extern struct proc_dir_entry * -lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, +extern struct dentry *ldebugfs_add_simple(struct dentry *root, + char *name, + void *data, + struct file_operations *fops); +extern struct dentry * +ldebugfs_add_symlink(const char *name, struct dentry *parent, const char *format, ...); -extern void lprocfs_free_per_client_stats(struct obd_device *obd); -extern int -lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, - unsigned long count, void *data); -extern int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data); -extern int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, - struct lprocfs_stats *stats); +extern int ldebugfs_register_stats(struct dentry *parent, + const char *name, + struct lprocfs_stats *stats); /* lprocfs_status.c */ -extern int lprocfs_add_vars(struct proc_dir_entry *root, - struct lprocfs_vars *var, - void *data); +extern int ldebugfs_add_vars(struct dentry *parent, + struct lprocfs_vars *var, + void *data); -extern struct proc_dir_entry *lprocfs_register(const char *name, - struct proc_dir_entry *parent, - struct lprocfs_vars *list, - void *data); +extern struct dentry *ldebugfs_register(const char *name, + struct dentry *parent, + struct lprocfs_vars *list, + void *data); -extern void lprocfs_remove(struct proc_dir_entry **root); -extern void lprocfs_remove_proc_entry(const char *name, - struct proc_dir_entry *parent); +extern void ldebugfs_remove(struct dentry **entryp); -extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list); +extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list, + struct attribute_group *attrs); extern int lprocfs_obd_cleanup(struct obd_device *obd); -extern int lprocfs_seq_create(struct proc_dir_entry *parent, const char *name, - umode_t mode, - const struct file_operations *seq_fops, - void *data); -extern int lprocfs_obd_seq_create(struct obd_device *dev, const char *name, - umode_t mode, - const struct file_operations *seq_fops, - void *data); +extern int ldebugfs_seq_create(struct dentry *parent, + const char *name, + umode_t mode, + const struct file_operations *seq_fops, + void *data); +extern int ldebugfs_obd_seq_create(struct obd_device *dev, + const char *name, + umode_t mode, + const struct file_operations *seq_fops, + void *data); /* Generic callbacks */ @@ -613,15 +603,12 @@ extern int lprocfs_wr_atomic(struct file *file, const char __user *buffer, extern int lprocfs_rd_uint(struct seq_file *m, void *data); extern int lprocfs_wr_uint(struct file *file, const char __user *buffer, unsigned long count, void *data); -extern int lprocfs_rd_uuid(struct seq_file *m, void *data); extern int lprocfs_rd_name(struct seq_file *m, void *data); extern int lprocfs_rd_server_uuid(struct seq_file *m, void *data); extern int lprocfs_rd_conn_uuid(struct seq_file *m, void *data); extern int lprocfs_rd_import(struct seq_file *m, void *data); extern int lprocfs_rd_state(struct seq_file *m, void *data); extern int lprocfs_rd_connect_flags(struct seq_file *m, void *data); -extern int lprocfs_rd_num_exports(struct seq_file *m, void *data); -extern int lprocfs_rd_numrefs(struct seq_file *m, void *data); struct adaptive_timeout; extern int lprocfs_at_hist_helper(struct seq_file *m, @@ -640,12 +627,6 @@ extern int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer, size_t count, loff_t *off); /* Statfs helpers */ -extern int lprocfs_rd_blksize(struct seq_file *m, void *data); -extern int lprocfs_rd_kbytestotal(struct seq_file *m, void *data); -extern int lprocfs_rd_kbytesfree(struct seq_file *m, void *data); -extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data); -extern int lprocfs_rd_filestotal(struct seq_file *m, void *data); -extern int lprocfs_rd_filesfree(struct seq_file *m, void *data); extern int lprocfs_write_helper(const char __user *buffer, unsigned long count, int *val); @@ -685,11 +666,11 @@ extern int lprocfs_seq_release(struct inode *, struct file *); /* write the name##_seq_show function, call LPROC_SEQ_FOPS_RO for read-only proc entries; otherwise, you will define name##_seq_write function also for a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally, - call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */ + call ldebugfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */ #define __LPROC_SEQ_FOPS(name, custom_seq_write) \ static int name##_single_open(struct inode *inode, struct file *file) \ { \ - return single_open(file, name##_seq_show, PDE_DATA(inode)); \ + return single_open(file, name##_seq_show, inode->i_private); \ } \ static struct file_operations name##_fops = { \ .owner = THIS_MODULE, \ @@ -734,7 +715,7 @@ static struct file_operations name##_fops = { \ } \ static int name##_##type##_open(struct inode *inode, struct file *file) \ { \ - return single_open(file, NULL, PDE_DATA(inode)); \ + return single_open(file, NULL, inode->i_private); \ } \ static struct file_operations name##_##type##_fops = { \ .open = name##_##type##_open, \ @@ -742,6 +723,27 @@ static struct file_operations name##_fops = { \ .release = lprocfs_single_release, \ } +struct lustre_attr { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len); +}; + +#define LUSTRE_ATTR(name, mode, show, store) \ +static struct lustre_attr lustre_attr_##name = __ATTR(name, mode, show, store) + +#define LUSTRE_RO_ATTR(name) LUSTRE_ATTR(name, 0444, name##_show, NULL) +#define LUSTRE_RW_ATTR(name) LUSTRE_ATTR(name, 0644, name##_show, name##_store) + +ssize_t lustre_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf); +ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len); + +extern const struct sysfs_ops lustre_sysfs_ops; + /* lproc_ptlrpc.c */ struct ptlrpc_request; extern void target_print_req(void *seq_file, struct ptlrpc_request *req); @@ -810,206 +812,4 @@ extern int lprocfs_quota_rd_qs_factor(char *page, char **start, loff_t off, extern int lprocfs_quota_wr_qs_factor(struct file *file, const char *buffer, unsigned long count, void *data); -#else -/* CONFIG_PROC_FS is not defined */ - -#define proc_lustre_root NULL - -static inline void lprocfs_counter_add(struct lprocfs_stats *stats, - int index, long amount) -{ return; } -static inline void lprocfs_counter_incr(struct lprocfs_stats *stats, - int index) -{ return; } -static inline void lprocfs_counter_sub(struct lprocfs_stats *stats, - int index, long amount) -{ return; } -static inline void lprocfs_counter_decr(struct lprocfs_stats *stats, - int index) -{ return; } -static inline void lprocfs_counter_init(struct lprocfs_stats *stats, - int index, unsigned conf, - const char *name, const char *units) -{ return; } - -static inline __u64 lc_read_helper(struct lprocfs_counter *lc, - enum lprocfs_fields_flags field) -{ return 0; } - -/* NB: we return !NULL to satisfy error checker */ -static inline struct lprocfs_stats * -lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags) -{ return (struct lprocfs_stats *)1; } -static inline void lprocfs_clear_stats(struct lprocfs_stats *stats) -{ return; } -static inline void lprocfs_free_stats(struct lprocfs_stats **stats) -{ return; } -static inline int lprocfs_register_stats(struct proc_dir_entry *root, - const char *name, - struct lprocfs_stats *stats) -{ return 0; } -static inline void lprocfs_init_ops_stats(int num_private_stats, - struct lprocfs_stats *stats) -{ return; } -static inline void lprocfs_init_mps_stats(int num_private_stats, - struct lprocfs_stats *stats) -{ return; } -static inline void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) -{ return; } -static inline int lprocfs_alloc_obd_stats(struct obd_device *obddev, - unsigned int num_private_stats) -{ return 0; } -static inline int lprocfs_alloc_md_stats(struct obd_device *obddev, - unsigned int num_private_stats) -{ return 0; } -static inline void lprocfs_free_obd_stats(struct obd_device *obddev) -{ return; } -static inline void lprocfs_free_md_stats(struct obd_device *obddev) -{ return; } - -struct obd_export; -static inline int lprocfs_add_clear_entry(struct obd_export *exp) -{ return 0; } -static inline int lprocfs_exp_setup(struct obd_export *exp, - lnet_nid_t *peer_nid, - int *newnid) -{ return 0; } -static inline int lprocfs_exp_cleanup(struct obd_export *exp) -{ return 0; } -static inline struct proc_dir_entry * -lprocfs_add_simple(struct proc_dir_entry *root, char *name, - void *data, struct file_operations *fops) -{return 0; } -static inline struct proc_dir_entry * -lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, - const char *format, ...) -{return NULL; } -static inline void lprocfs_free_per_client_stats(struct obd_device *obd) -{ return; } -static inline -int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{return count;} -static inline -int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data) -{ return 0; } - -static inline struct proc_dir_entry * -lprocfs_register(const char *name, struct proc_dir_entry *parent, - struct lprocfs_vars *list, void *data) -{ return NULL; } -static inline int lprocfs_add_vars(struct proc_dir_entry *root, - struct lprocfs_vars *var, - void *data) -{ return 0; } -static inline void lprocfs_remove(struct proc_dir_entry **root) -{ return; } -static inline void lprocfs_remove_proc_entry(const char *name, - struct proc_dir_entry *parent) -{ return; } -static inline int lprocfs_obd_setup(struct obd_device *dev, - struct lprocfs_vars *list) -{ return 0; } -static inline int lprocfs_obd_cleanup(struct obd_device *dev) -{ return 0; } -static inline int lprocfs_rd_u64(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_uuid(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_name(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_server_uuid(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_conn_uuid(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_import(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_pinger_recov(struct seq_file *m, void *n) -{ return 0; } -static inline int lprocfs_rd_state(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_connect_flags(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_rd_num_exports(struct seq_file *m, void *data) -{ return 0; } -extern inline int lprocfs_rd_numrefs(struct seq_file *m, void *data) -{ return 0; } -struct adaptive_timeout; -static inline int lprocfs_at_hist_helper(struct seq_file *m, - struct adaptive_timeout *at) -{ return 0; } -static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data) -{ return 0; } -static inline int lprocfs_wr_timeouts(struct file *file, - const char __user *buffer, - unsigned long count, void *data) -{ return 0; } -static inline int lprocfs_wr_evict_client(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ return 0; } -static inline int lprocfs_wr_ping(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ return 0; } -static inline int lprocfs_wr_import(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ return 0; } -static inline int lprocfs_wr_pinger_recov(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ return 0; } - -/* Statfs helpers */ -static inline -int lprocfs_rd_blksize(struct seq_file *m, void *data) -{ return 0; } -static inline -int lprocfs_rd_kbytestotal(struct seq_file *m, void *data) -{ return 0; } -static inline -int lprocfs_rd_kbytesfree(struct seq_file *m, void *data) -{ return 0; } -static inline -int lprocfs_rd_kbytesavail(struct seq_file *m, void *data) -{ return 0; } -static inline -int lprocfs_rd_filestotal(struct seq_file *m, void *data) -{ return 0; } -static inline -int lprocfs_rd_filesfree(struct seq_file *m, void *data) -{ return 0; } -static inline -void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value) -{ return; } -static inline -void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value) -{ return; } -static inline -void lprocfs_oh_clear(struct obd_histogram *oh) -{ return; } -static inline -unsigned long lprocfs_oh_sum(struct obd_histogram *oh) -{ return 0; } -static inline -void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, - struct lprocfs_counter *cnt) -{ return; } -static inline -__u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx, - enum lprocfs_fields_flags field) -{ return (__u64)0; } - -#define LPROC_SEQ_FOPS_RO(name) -#define LPROC_SEQ_FOPS(name) -#define LPROC_SEQ_FOPS_RO_TYPE(name, type) -#define LPROC_SEQ_FOPS_RW_TYPE(name, type) -#define LPROC_SEQ_FOPS_WR_ONLY(name, type) - -/* lproc_ptlrpc.c */ -#define target_print_req NULL - -#endif /* CONFIG_PROC_FS */ - #endif /* LPROCFS_SNMP_H */ diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index c8cc48f00026..e1d72a7a5c2d 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -43,7 +43,6 @@ #include "lu_ref.h" struct seq_file; -struct proc_dir_entry; struct lustre_cfg; struct lprocfs_stats; @@ -277,7 +276,6 @@ struct lu_device { * Stack this device belongs to. */ struct lu_site *ld_site; - struct proc_dir_entry *ld_proc_entry; /** \todo XXX: temporary back pointer into obd. */ struct obd_device *ld_obd; diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index bac9902b56bb..f6f4c037fb30 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -60,11 +60,13 @@ struct obd_ops; struct obd_device; +extern struct kset *ldlm_ns_kset; +extern struct kset *ldlm_svc_kset; + #define OBD_LDLM_DEVICENAME "ldlm" #define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus()) #define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(36000)) -#define LDLM_CTIME_AGE_LIMIT (10) #define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024 /** @@ -232,8 +234,8 @@ struct ldlm_pool_ops { * This feature is commonly referred to as lru_resize. */ struct ldlm_pool { - /** Pool proc directory. */ - struct proc_dir_entry *pl_proc_dir; + /** Pool debugfs directory. */ + struct dentry *pl_debugfs_entry; /** Pool name, must be long enough to hold compound proc entry name. */ char pl_name[100]; /** Lock for protecting SLV/CLV updates. */ @@ -263,6 +265,10 @@ struct ldlm_pool { int pl_grant_plan; /** Pool statistics. */ struct lprocfs_stats *pl_stats; + + /* sysfs object */ + struct kobject pl_kobj; + struct completion pl_kobj_unregister; }; typedef int (*ldlm_res_policy)(struct ldlm_namespace *, struct ldlm_lock **, @@ -302,14 +308,6 @@ typedef enum { LDLM_NAMESPACE_MODEST = 1 << 1 } ldlm_appetite_t; -/** - * Default values for the "max_nolock_size", "contention_time" and - * "contended_locks" namespace tunables. - */ -#define NS_DEFAULT_MAX_NOLOCK_BYTES 0 -#define NS_DEFAULT_CONTENTION_SECONDS 2 -#define NS_DEFAULT_CONTENDED_LOCKS 32 - struct ldlm_ns_bucket { /** back pointer to namespace */ struct ldlm_namespace *nsb_namespace; @@ -390,8 +388,8 @@ struct ldlm_namespace { /** Client side original connect flags supported by server. */ __u64 ns_orig_connect_flags; - /* namespace proc dir entry */ - struct proc_dir_entry *ns_proc_dir_entry; + /* namespace debugfs dir entry */ + struct dentry *ns_debugfs_entry; /** * Position in global namespace list linking all namespaces on @@ -421,18 +419,6 @@ struct ldlm_namespace { unsigned int ns_max_unused; /** Maximum allowed age (last used time) for locks in the LRU */ unsigned int ns_max_age; - /** - * Server only: number of times we evicted clients due to lack of reply - * to ASTs. - */ - unsigned int ns_timeouts; - /** - * Number of seconds since the file change time after which the - * MDT will return an UPDATE lock along with a LOOKUP lock. - * This allows the client to start caching negative dentries - * for a directory and may save an RPC for a later stat. - */ - unsigned int ns_ctime_age_limit; /** * Used to rate-limit ldlm_namespace_dump calls. @@ -466,27 +452,6 @@ struct ldlm_namespace { /** Definition of how eagerly unused locks will be released from LRU */ ldlm_appetite_t ns_appetite; - /** - * If more than \a ns_contended_locks are found, the resource is - * considered to be contended. Lock enqueues might specify that no - * contended locks should be granted - */ - unsigned ns_contended_locks; - - /** - * The resources in this namespace remember contended state during - * \a ns_contention_time, in seconds. - */ - unsigned ns_contention_time; - - /** - * Limit size of contended extent locks, in bytes. - * If extended lock is requested for more then this many bytes and - * caller instructs us not to grant contended locks, we would disregard - * such a request. - */ - unsigned ns_max_nolock_size; - /** Limit of parallel AST RPC count. */ unsigned ns_max_parallel_ast; @@ -501,6 +466,9 @@ struct ldlm_namespace { * recalculation of LDLM pool statistics should be skipped. */ unsigned ns_stopping:1; + + struct kobject ns_kobj; /* sysfs object */ + struct completion ns_kobj_unregister; }; /** @@ -1283,13 +1251,8 @@ void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client); void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client); void ldlm_namespace_get(struct ldlm_namespace *ns); void ldlm_namespace_put(struct ldlm_namespace *ns); -#if defined (CONFIG_PROC_FS) -int ldlm_proc_setup(void); -void ldlm_proc_cleanup(void); -#else -static inline int ldlm_proc_setup(void) { return 0; } -static inline void ldlm_proc_cleanup(void) {} -#endif +int ldlm_debugfs_setup(void); +void ldlm_debugfs_cleanup(void); /* resource.c - internal */ struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h index 16dcdbfae689..d4cc09635271 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h @@ -1,17 +1,10 @@ /* -*- buffer-read-only: t -*- vi: set ro: * - * DO NOT EDIT THIS FILE (lustre_dlm_flags.h) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * It has been AutoGen-ed - * From the definitions lustre_dlm_flags.def - * and the template file lustre_dlm_flags.tpl - * - * lustre is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * lustre is distributed in the hope that it will be useful, but + * Lustre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. @@ -22,8 +15,6 @@ /** * \file lustre_dlm_flags.h * The flags and collections of flags (masks) for \see struct ldlm_lock. - * This file is derived from flag definitions in lustre_dlm_flags.def. - * The format is defined in the lustre_dlm_flags.tpl template file. * * \addtogroup LDLM Lustre Distributed Lock Manager * @{ diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h index 9c06a49f12a4..3b992b42fd91 100644 --- a/drivers/staging/lustre/lustre/include/lustre_export.h +++ b/drivers/staging/lustre/lustre/include/lustre_export.h @@ -106,34 +106,6 @@ struct mgs_export_data { spinlock_t med_lock; /* protect med_clients */ }; -/** - * per-NID statistics structure. - * It tracks access patterns to this export on a per-client-NID basis - */ -struct nid_stat { - lnet_nid_t nid; - struct hlist_node nid_hash; - struct list_head nid_list; - struct obd_device *nid_obd; - struct proc_dir_entry *nid_proc; - struct lprocfs_stats *nid_stats; - struct lprocfs_stats *nid_ldlm_stats; - atomic_t nid_exp_ref_count; /* for obd_nid_stats_hash - exp_nid_stats */ -}; - -#define nidstat_getref(nidstat) \ -do { \ - atomic_inc(&(nidstat)->nid_exp_ref_count); \ -} while (0) - -#define nidstat_putref(nidstat) \ -do { \ - atomic_dec(&(nidstat)->nid_exp_ref_count); \ - LASSERTF(atomic_read(&(nidstat)->nid_exp_ref_count) >= 0, \ - "stat %p nid_exp_ref_count < 0\n", nidstat); \ -} while (0) - enum obd_option { OBD_OPT_FORCE = 0x0001, OBD_OPT_FAILOVER = 0x0002, @@ -190,7 +162,6 @@ struct obd_export { * exp_lock protect its change */ struct obd_import *exp_imp_reverse; - struct nid_stat *exp_nid_stats; struct lprocfs_stats *exp_md_stats; /** Active connection */ struct ptlrpc_connection *exp_connection; diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h index 0a0929fd9023..c7c8fe4cdbcc 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fid.h +++ b/drivers/staging/lustre/lustre/include/lustre_fid.h @@ -346,7 +346,7 @@ struct lu_client_seq { struct lu_seq_range lcs_space; /* Seq related proc */ - struct proc_dir_entry *lcs_proc_dir; + struct dentry *lcs_debugfs_entry; /* This holds last allocated fid in last obtained seq */ struct lu_fid lcs_fid; @@ -392,9 +392,6 @@ struct lu_server_seq { /* /seq file object device */ struct dt_object *lss_obj; - /* Seq related proc */ - struct proc_dir_entry *lss_proc_dir; - /* LUSTRE_SEQ_SERVER or LUSTRE_SEQ_CONTROLLER */ enum lu_mgr_type lss_type; diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h index 5ee4b1ed0995..c1f08dee3bd6 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fld.h +++ b/drivers/staging/lustre/lustre/include/lustre_fld.h @@ -71,10 +71,6 @@ struct lu_fld_target { struct lu_server_fld { /** - * Fld dir proc entry. */ - struct proc_dir_entry *lsf_proc_dir; - - /** * /fld file object device */ struct dt_object *lsf_obj; @@ -99,8 +95,8 @@ struct lu_server_fld { struct lu_client_fld { /** - * Client side proc entry. */ - struct proc_dir_entry *lcf_proc_dir; + * Client side debugfs entry. */ + struct dentry *lcf_debugfs_entry; /** * List of exports client FLD knows about. */ @@ -123,10 +119,10 @@ struct lu_client_fld { struct fld_cache *lcf_cache; /** - * Client fld proc entry name. */ - char lcf_name[LUSTRE_MDT_MAXNAMELEN]; + * Client fld debugfs entry name. */ + char lcf_name[LUSTRE_MDT_MAXNAMELEN]; - int lcf_flags; + int lcf_flags; }; /* Client methods */ @@ -153,7 +149,7 @@ int fld_client_add_target(struct lu_client_fld *fld, int fld_client_del_target(struct lu_client_fld *fld, __u64 idx); -void fld_client_proc_fini(struct lu_client_fld *fld); +void fld_client_debugfs_fini(struct lu_client_fld *fld); /** @} fld */ diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index bf135630c39a..43ee9f0eb4d4 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -549,19 +549,13 @@ do { \ __blocked = cfs_block_sigsinv(0); \ \ for (;;) { \ - unsigned __wstate; \ - \ - __wstate = info->lwi_on_signal != NULL && \ - (__timeout == 0 || __allow_intr) ? \ - TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; \ - \ - set_current_state(TASK_INTERRUPTIBLE); \ - \ if (condition) \ break; \ \ + set_current_state(TASK_INTERRUPTIBLE); \ + \ if (__timeout == 0) { \ - schedule(); \ + schedule(); \ } else { \ long interval = info->lwi_interval? \ min_t(long, \ @@ -582,6 +576,8 @@ do { \ } \ } \ \ + set_current_state(TASK_RUNNING); \ + \ if (condition) \ break; \ if (cfs_signal_pending()) { \ @@ -605,7 +601,6 @@ do { \ \ cfs_restore_sigs(__blocked); \ \ - set_current_state(TASK_RUNNING); \ remove_wait_queue(&wq, &__wait); \ } while (0) diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index e2805bd1acf1..998dcd94c1b2 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -1978,8 +1978,8 @@ struct ptlrpc_service { int srv_nthrs_cpt_init; /** limit of threads number for each partition */ int srv_nthrs_cpt_limit; - /** Root of /proc dir tree for this service */ - struct proc_dir_entry *srv_procroot; + /** Root of debugfs dir tree for this service */ + struct dentry *srv_debugfs_entry; /** Pointer to statistic data for this service */ struct lprocfs_stats *srv_stats; /** # hp per lp reqs to handle */ @@ -2016,6 +2016,10 @@ struct ptlrpc_service { int srv_cpt_bits; /** CPT table this service is running over */ struct cfs_cpt_table *srv_cptable; + + /* sysfs object */ + struct kobject srv_kobj; + struct completion srv_kobj_unregister; /** * partition data for ptlrpc service */ @@ -2525,7 +2529,8 @@ void ptlrpc_schedule_difficult_reply(struct ptlrpc_reply_state *rs); int ptlrpc_hpreq_handler(struct ptlrpc_request *req); struct ptlrpc_service *ptlrpc_register_service( struct ptlrpc_service_conf *conf, - struct proc_dir_entry *proc_entry); + struct kset *parent, + struct dentry *debugfs_entry); void ptlrpc_stop_all_threads(struct ptlrpc_service *svc); int ptlrpc_start_threads(struct ptlrpc_service *svc); @@ -2947,15 +2952,9 @@ void ptlrpcd_decref(void); * @{ */ const char *ll_opcode2str(__u32 opcode); -#if defined (CONFIG_PROC_FS) void ptlrpc_lprocfs_register_obd(struct obd_device *obd); void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd); void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes); -#else -static inline void ptlrpc_lprocfs_register_obd(struct obd_device *obd) {} -static inline void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd) {} -static inline void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes) {} -#endif /** @} */ /* ptlrpc/llog_client.c */ diff --git a/drivers/staging/lustre/lustre/include/lustre_quota.h b/drivers/staging/lustre/lustre/include/lustre_quota.h deleted file mode 100644 index 2643f28070a2..000000000000 --- a/drivers/staging/lustre/lustre/include/lustre_quota.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA - * - * GPL HEADER END - */ -/* - * Copyright (c) 2011, 2012, Intel Corporation. - * Use is subject to license terms. - */ - -#ifndef _LUSTRE_QUOTA_H -#define _LUSTRE_QUOTA_H - -/** \defgroup quota quota - * - */ - -#include <linux/fs.h> -#include <linux/quota.h> -#include <linux/quotaops.h> - -#include "dt_object.h" -#include "lustre_fid.h" -#include "lustre_dlm.h" - -#ifndef MAX_IQ_TIME -#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ -#endif - -#ifndef MAX_DQ_TIME -#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ -#endif - -struct lquota_id_info; -struct lquota_trans; - -/* Gather all quota record type in an union that can be used to read any records - * from disk. All fields of these records must be 64-bit aligned, otherwise the - * OSD layer may swab them incorrectly. */ -union lquota_rec { - struct lquota_glb_rec lqr_glb_rec; - struct lquota_slv_rec lqr_slv_rec; - struct lquota_acct_rec lqr_acct_rec; -}; - -/* Index features supported by the global index objects - * Only used for migration purpose and should be removed once on-disk migration - * is no longer needed */ -extern struct dt_index_features dt_quota_iusr_features; -extern struct dt_index_features dt_quota_busr_features; -extern struct dt_index_features dt_quota_igrp_features; -extern struct dt_index_features dt_quota_bgrp_features; - -/* Name used in the configuration logs to identify the default metadata pool - * (composed of all the MDTs, with pool ID 0) and the default data pool (all - * the OSTs, with pool ID 0 too). */ -#define QUOTA_METAPOOL_NAME "mdt=" -#define QUOTA_DATAPOOL_NAME "ost=" - -/* - * Quota Master Target support - */ - -/* Request handlers for quota master operations. - * This is used by the MDT to pass quota/lock requests to the quota master - * target. This won't be needed any more once the QMT is a real target and - * does not rely any more on the MDT service threads and namespace. */ -struct qmt_handlers { - /* Handle quotactl request from client. */ - int (*qmth_quotactl)(const struct lu_env *, struct lu_device *, - struct obd_quotactl *); - - /* Handle dqacq/dqrel request from slave. */ - int (*qmth_dqacq)(const struct lu_env *, struct lu_device *, - struct ptlrpc_request *); - - /* LDLM intent policy associated with quota locks */ - int (*qmth_intent_policy)(const struct lu_env *, struct lu_device *, - struct ptlrpc_request *, struct ldlm_lock **, - int); - - /* Initialize LVB of ldlm resource associated with quota objects */ - int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *); - - /* Update LVB of ldlm resource associated with quota objects */ - int (*qmth_lvbo_update)(struct lu_device *, struct ldlm_resource *, - struct ptlrpc_request *, int); - - /* Return size of LVB to be packed in ldlm message */ - int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *); - - /* Fill request buffer with lvb */ - int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *, - int); - - /* Free lvb associated with ldlm resource */ - int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *); -}; - -/* actual handlers are defined in lustre/quota/qmt_handler.c */ -extern struct qmt_handlers qmt_hdls; - -/* - * Quota enforcement support on slaves - */ - -struct qsd_instance; - -/* The quota slave feature is implemented under the form of a library. - * The API is the following: - * - * - qsd_init(): the user (mostly the OSD layer) should first allocate a qsd - * instance via qsd_init(). This creates all required structures - * to manage quota enforcement for this target and performs all - * low-level initialization which does not involve any lustre - * object. qsd_init() should typically be called when the OSD - * is being set up. - * - * - qsd_prepare(): This sets up on-disk objects associated with the quota slave - * feature and initiates the quota reintegration procedure if - * needed. qsd_prepare() should typically be called when - * ->ldo_prepare is invoked. - * - * - qsd_start(): a qsd instance should be started once recovery is completed - * (i.e. when ->ldo_recovery_complete is called). This is used - * to notify the qsd layer that quota should now be enforced - * again via the qsd_op_begin/end functions. The last step of the - * reintegration procedure (namely usage reconciliation) will be - * completed during start. - * - * - qsd_fini(): is used to release a qsd_instance structure allocated with - * qsd_init(). This releases all quota slave objects and frees the - * structures associated with the qsd_instance. - * - * - qsd_op_begin(): is used to enforce quota, it must be called in the - * declaration of each operation. qsd_op_end() should then be - * invoked later once all operations have been completed in - * order to release/adjust the quota space. - * Running qsd_op_begin() before qsd_start() isn't fatal and - * will return success. - * Once qsd_start() has been run, qsd_op_begin() will block - * until the reintegration procedure is completed. - * - * - qsd_op_end(): performs the post operation quota processing. This must be - * called after the operation transaction stopped. - * While qsd_op_begin() must be invoked each time a new - * operation is declared, qsd_op_end() should be called only - * once for the whole transaction. - * - * - qsd_op_adjust(): triggers pre-acquire/release if necessary. - * - * Below are the function prototypes to be used by OSD layer to manage quota - * enforcement. Arguments are documented where each function is defined. */ - -struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *, - struct proc_dir_entry *); -int qsd_prepare(const struct lu_env *, struct qsd_instance *); -int qsd_start(const struct lu_env *, struct qsd_instance *); -void qsd_fini(const struct lu_env *, struct qsd_instance *); -int qsd_op_begin(const struct lu_env *, struct qsd_instance *, - struct lquota_trans *, struct lquota_id_info *, int *); -void qsd_op_end(const struct lu_env *, struct qsd_instance *, - struct lquota_trans *); -void qsd_op_adjust(const struct lu_env *, struct qsd_instance *, - union lquota_id *, int); -/* This is exported for the ldiskfs quota migration only, - * see convert_quota_file() */ -int lquota_disk_write_glb(const struct lu_env *, struct dt_object *, - __u64, struct lquota_glb_rec *); - -/* - * Quota information attached to a transaction - */ - -struct lquota_entry; - -struct lquota_id_info { - /* quota identifier */ - union lquota_id lqi_id; - - /* USRQUOTA or GRPQUOTA for now, could be expanded for - * directory quota or other types later. */ - int lqi_type; - - /* inodes or kbytes to be consumed or released, it could - * be negative when releasing space. */ - long long lqi_space; - - /* quota slave entry structure associated with this ID */ - struct lquota_entry *lqi_qentry; - - /* whether we are reporting blocks or inodes */ - bool lqi_is_blk; -}; - -/* Since we enforce only inode quota in meta pool (MDTs), and block quota in - * data pool (OSTs), there are at most 4 quota ids being enforced in a single - * transaction, which is chown transaction: - * original uid and gid, new uid and gid. - * - * This value might need to be revised when directory quota is added. */ -#define QUOTA_MAX_TRANSIDS 4 - -/* all qids involved in a single transaction */ -struct lquota_trans { - unsigned short lqt_id_cnt; - struct lquota_id_info lqt_ids[QUOTA_MAX_TRANSIDS]; -}; - -/* flags for quota local enforcement */ -#define QUOTA_FL_OVER_USRQUOTA 0x01 -#define QUOTA_FL_OVER_GRPQUOTA 0x02 -#define QUOTA_FL_SYNC 0x04 - -#define IS_LQUOTA_RES(res) \ - (res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA || \ - res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB) - -/* helper function used by MDT & OFD to retrieve quota accounting information - * on slave */ -int lquotactl_slv(const struct lu_env *, struct dt_device *, - struct obd_quotactl *); -/** @} quota */ -#endif /* _LUSTRE_QUOTA_H */ diff --git a/drivers/staging/lustre/lustre/include/lustre_sec.h b/drivers/staging/lustre/lustre/include/lustre_sec.h index dff70a5b9bc4..707ff69717c6 100644 --- a/drivers/staging/lustre/lustre/include/lustre_sec.h +++ b/drivers/staging/lustre/lustre/include/lustre_sec.h @@ -1061,15 +1061,7 @@ const char *sec2target_str(struct ptlrpc_sec *sec); /* * lprocfs */ -#if defined (CONFIG_PROC_FS) -struct proc_dir_entry; -extern struct proc_dir_entry *sptlrpc_proc_root; int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev); -#else -#define sptlrpc_proc_root NULL -static inline int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev) -{ return 0; } -#endif /* * server side diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 2a88b806fca5..55452e562bd4 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -244,11 +244,12 @@ struct obd_type { struct list_head typ_chain; struct obd_ops *typ_dt_ops; struct md_ops *typ_md_ops; - struct proc_dir_entry *typ_procroot; + struct dentry *typ_debugfs_entry; char *typ_name; int typ_refcnt; struct lu_device_type *typ_lu; spinlock_t obd_type_lock; + struct kobject *typ_kobj; }; struct brw_page { @@ -544,7 +545,7 @@ struct pool_desc { struct lov_qos_rr pool_rr; /* round robin qos */ struct hlist_node pool_hash; /* access by poolname */ struct list_head pool_list; /* serial access */ - struct proc_dir_entry *pool_proc_entry; /* file in /proc */ + struct dentry *pool_debugfs_entry; /* file in /proc */ struct obd_device *pool_lobd; /* obd of the lov/lod to which * this pool belongs */ }; @@ -565,13 +566,15 @@ struct lov_obd { int lov_pool_count; struct cfs_hash *lov_pools_hash_body; /* used for key access */ struct list_head lov_pool_list; /* used for sequential access */ - struct proc_dir_entry *lov_pool_proc_entry; + struct dentry *lov_pool_debugfs_entry; enum lustre_sec_part lov_sp_me; /* Cached LRU pages from upper layer */ void *lov_cache; struct rw_semaphore lov_notify_lock; + + struct kobject *lov_tgts_kobj; }; struct lmv_tgt_desc { @@ -610,6 +613,7 @@ struct lmv_obd { struct lmv_tgt_desc **tgts; struct obd_connect_data conn_data; + struct kobject *lmv_tgts_kobj; }; struct niobuf_local { @@ -841,9 +845,6 @@ struct obd_device { struct cfs_hash *obd_uuid_hash; /* nid-export hash body */ struct cfs_hash *obd_nid_hash; - /* nid stats body */ - struct cfs_hash *obd_nid_stats_hash; - struct list_head obd_nid_stats; atomic_t obd_refcount; wait_queue_head_t obd_refcount_waitq; struct list_head obd_exports; @@ -913,10 +914,8 @@ struct obd_device { unsigned int md_cntr_base; struct lprocfs_stats *md_stats; - struct proc_dir_entry *obd_proc_entry; - void *obd_proc_private; /* type private PDEs */ - struct proc_dir_entry *obd_proc_exports_entry; - struct proc_dir_entry *obd_svc_procroot; + struct dentry *obd_debugfs_entry; + struct dentry *obd_svc_debugfs_entry; struct lprocfs_stats *obd_svc_stats; atomic_t obd_evict_inprogress; wait_queue_head_t obd_evict_inprogress_waitq; @@ -936,6 +935,9 @@ struct obd_device { struct lu_ref obd_reference; int obd_conn_inprogress; + + struct kobject obd_kobj; /* sysfs object */ + struct completion obd_kobj_unregister; }; #define OBD_LLOG_FL_SENDNOW 0x0001 diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 34b5fa3f081c..36ed78127830 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -75,8 +75,7 @@ struct lu_device_type; extern struct list_head obd_types; struct obd_export *class_conn2export(struct lustre_handle *); int class_register_type(struct obd_ops *, struct md_ops *, - struct lprocfs_vars *, const char *nm, - struct lu_device_type *ldt); + const char *nm, struct lu_device_type *ldt); int class_unregister_type(const char *nm); struct obd_device *class_newdev(const char *type_name, const char *name); @@ -140,14 +139,7 @@ int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg); int class_add_uuid(const char *uuid, __u64 nid); /*obdecho*/ -#if defined (CONFIG_PROC_FS) extern void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars); -#else -static inline void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -#endif #define CFG_F_START 0x01 /* Set when we start updating from a log */ #define CFG_F_MARKER 0x02 /* We are within a maker */ @@ -357,7 +349,6 @@ static inline int obd_check_dev_active(struct obd_device *obd) return rc; } -#if defined (CONFIG_PROC_FS) #define OBD_COUNTER_OFFSET(op) \ ((offsetof(struct obd_ops, o_ ## op) - \ offsetof(struct obd_ops, o_iocontrol)) \ @@ -379,10 +370,6 @@ static inline int obd_check_dev_active(struct obd_device *obd) OBD_COUNTER_OFFSET(op); \ LASSERT(coffset < (export)->exp_obd->obd_stats->ls_num); \ lprocfs_counter_incr((export)->exp_obd->obd_stats, coffset); \ - if ((export)->exp_nid_stats != NULL && \ - (export)->exp_nid_stats->nid_stats != NULL) \ - lprocfs_counter_incr( \ - (export)->exp_nid_stats->nid_stats, coffset);\ } #define MD_COUNTER_OFFSET(op) \ @@ -411,27 +398,6 @@ static inline int obd_check_dev_active(struct obd_device *obd) (export)->exp_md_stats, coffset); \ } -#else -#define OBD_COUNTER_OFFSET(op) -#define OBD_COUNTER_INCREMENT(obd, op) -#define EXP_COUNTER_INCREMENT(exp, op) -#define MD_COUNTER_INCREMENT(obd, op) -#define EXP_MD_COUNTER_INCREMENT(exp, op) -#endif - -static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat *tmp) -{ - /* Always add in ldlm_stats */ - tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC - ,LPROCFS_STATS_FLAG_NOPERCPU); - if (tmp->nid_ldlm_stats == NULL) - return -ENOMEM; - - lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats); - - return lprocfs_register_stats(tmp->nid_proc, "ldlm_stats", - tmp->nid_ldlm_stats); -} #define OBD_CHECK_MD_OP(obd, op, err) \ do { \ diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h index 2991d2ee780b..73e2d4880b9b 100644 --- a/drivers/staging/lustre/lustre/include/obd_support.h +++ b/drivers/staging/lustre/lustre/include/obd_support.h @@ -509,7 +509,6 @@ extern atomic_t libcfs_kmemory; extern void obd_update_maxusage(void); -#if defined (CONFIG_PROC_FS) #define obd_memory_add(size) \ lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size)) #define obd_memory_sub(size) \ @@ -530,46 +529,6 @@ extern void obd_update_maxusage(void); extern __u64 obd_memory_max(void); extern __u64 obd_pages_max(void); -#else - -extern __u64 obd_alloc; -extern __u64 obd_pages; - -extern __u64 obd_max_alloc; -extern __u64 obd_max_pages; - -static inline void obd_memory_add(long size) -{ - obd_alloc += size; - if (obd_alloc > obd_max_alloc) - obd_max_alloc = obd_alloc; -} - -static inline void obd_memory_sub(long size) -{ - obd_alloc -= size; -} - -static inline void obd_pages_add(int order) -{ - obd_pages += 1<< order; - if (obd_pages > obd_max_pages) - obd_max_pages = obd_pages; -} - -static inline void obd_pages_sub(int order) -{ - obd_pages -= 1<< order; -} - -#define obd_memory_sum() (obd_alloc) -#define obd_pages_sum() (obd_pages) - -#define obd_memory_max() (obd_max_alloc) -#define obd_pages_max() (obd_max_pages) - -#endif - #define OBD_DEBUG_MEMUSAGE (1) #if OBD_DEBUG_MEMUSAGE @@ -676,37 +635,20 @@ do { \ __OBD_VMALLOC_VEROBSE(ptr, cptab, cpt, size) -/* Allocations above this size are considered too big and could not be done - * atomically. - * - * Be very careful when changing this value, especially when decreasing it, - * since vmalloc in Linux doesn't perform well on multi-cores system, calling - * vmalloc in critical path would hurt performance badly. See LU-66. - */ -#define OBD_ALLOC_BIG (4 * PAGE_CACHE_SIZE) - #define OBD_ALLOC_LARGE(ptr, size) \ do { \ - if (size > OBD_ALLOC_BIG) \ - OBD_VMALLOC(ptr, size); \ - else \ - OBD_ALLOC(ptr, size); \ + ptr = libcfs_kvzalloc(size, GFP_NOFS); \ } while (0) #define OBD_CPT_ALLOC_LARGE(ptr, cptab, cpt, size) \ do { \ - if (size > OBD_ALLOC_BIG) \ - OBD_CPT_VMALLOC(ptr, cptab, cpt, size); \ - else \ - OBD_CPT_ALLOC(ptr, cptab, cpt, size); \ + ptr = libcfs_kvzalloc_cpt(cptab, cpt, size, GFP_NOFS); \ } while (0) #define OBD_FREE_LARGE(ptr, size) \ do { \ - if (size > OBD_ALLOC_BIG) \ - OBD_VFREE(ptr, size); \ - else \ - OBD_FREE(ptr, size); \ + (void)(size); \ + kvfree(ptr); \ } while (0) diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index 19448fe52cfd..e0c1ccafbd63 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -836,25 +836,24 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, *exceed = 1; } return result; - } else { - /* - * region is within kms and, hence, within real file - * size (A). We need to increase i_size to cover the - * read region so that generic_file_read() will do its - * job, but that doesn't mean the kms size is - * _correct_, it is only the _minimum_ size. If - * someone does a stat they will get the correct size - * which will always be >= the kms value here. - * b=11081 - */ - if (cl_isize_read(inode) < kms) { - cl_isize_write_nolock(inode, kms); - CDEBUG(D_VFSTRACE, - DFID" updating i_size %llu\n", - PFID(lu_object_fid(&obj->co_lu)), - (__u64)cl_isize_read(inode)); + } + /* + * region is within kms and, hence, within real file + * size (A). We need to increase i_size to cover the + * read region so that generic_file_read() will do its + * job, but that doesn't mean the kms size is + * _correct_, it is only the _minimum_ size. If + * someone does a stat they will get the correct size + * which will always be >= the kms value here. + * b=11081 + */ + if (cl_isize_read(inode) < kms) { + cl_isize_write_nolock(inode, kms); + CDEBUG(D_VFSTRACE, + DFID" updating i_size %llu\n", + PFID(lu_object_fid(&obj->co_lu)), + (__u64)cl_isize_read(inode)); - } } } ccc_object_size_unlock(obj); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index 70b909f55861..6601e6b12c32 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -197,8 +197,7 @@ void ldlm_destroy_flock_export(struct obd_export *exp); void l_check_ns_lock(struct ldlm_namespace *ns); void l_check_no_ns_lock(struct ldlm_namespace *ns); -extern struct proc_dir_entry *ldlm_svc_proc_dir; -extern struct proc_dir_entry *ldlm_type_proc_dir; +extern struct dentry *ldlm_svc_debugfs_dir; struct ldlm_state { struct ptlrpc_service *ldlm_cb_service; @@ -238,40 +237,85 @@ enum ldlm_policy_res { typedef enum ldlm_policy_res ldlm_policy_res_t; -#define LDLM_POOL_PROC_READER_SEQ_SHOW(var, type) \ - static int lprocfs_##var##_seq_show(struct seq_file *m, void *v) \ +#define LDLM_POOL_SYSFS_PRINT_int(v) sprintf(buf, "%d\n", v) +#define LDLM_POOL_SYSFS_SET_int(a, b) { a = b; } +#define LDLM_POOL_SYSFS_PRINT_u64(v) sprintf(buf, "%lld\n", v) +#define LDLM_POOL_SYSFS_SET_u64(a, b) { a = b; } +#define LDLM_POOL_SYSFS_PRINT_atomic(v) sprintf(buf, "%d\n", atomic_read(&v)) +#define LDLM_POOL_SYSFS_SET_atomic(a, b) atomic_set(&a, b) + +#define LDLM_POOL_SYSFS_READER_SHOW(var, type) \ + static ssize_t var##_show(struct kobject *kobj, \ + struct attribute *attr, \ + char *buf) \ { \ - struct ldlm_pool *pl = m->private; \ + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, \ + pl_kobj); \ type tmp; \ \ spin_lock(&pl->pl_lock); \ tmp = pl->pl_##var; \ spin_unlock(&pl->pl_lock); \ \ - return lprocfs_rd_uint(m, &tmp); \ + return LDLM_POOL_SYSFS_PRINT_##type(tmp); \ } \ struct __##var##__dummy_read {; } /* semicolon catcher */ -#define LDLM_POOL_PROC_WRITER(var, type) \ - static int lprocfs_wr_##var(struct file *file, \ - const char __user *buffer, \ - unsigned long count, void *data) \ +#define LDLM_POOL_SYSFS_WRITER_STORE(var, type) \ + static ssize_t var##_store(struct kobject *kobj, \ + struct attribute *attr, \ + const char *buffer, \ + size_t count) \ { \ - struct ldlm_pool *pl = data; \ - type tmp; \ + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, \ + pl_kobj); \ + unsigned long tmp; \ int rc; \ \ - rc = lprocfs_wr_uint(file, buffer, count, &tmp); \ + rc = kstrtoul(buffer, 10, &tmp); \ if (rc < 0) { \ - CERROR("Can't parse user input, rc = %d\n", rc); \ return rc; \ } \ \ spin_lock(&pl->pl_lock); \ - pl->pl_##var = tmp; \ + LDLM_POOL_SYSFS_SET_##type(pl->pl_##var, tmp); \ spin_unlock(&pl->pl_lock); \ \ - return rc; \ + return count; \ + } \ + struct __##var##__dummy_write {; } /* semicolon catcher */ + +#define LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(var, type) \ + static ssize_t var##_show(struct kobject *kobj, \ + struct attribute *attr, \ + char *buf) \ + { \ + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, \ + pl_kobj); \ + \ + return LDLM_POOL_SYSFS_PRINT_##type(pl->pl_##var); \ + } \ + struct __##var##__dummy_read {; } /* semicolon catcher */ + +#define LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(var, type) \ + static ssize_t var##_store(struct kobject *kobj, \ + struct attribute *attr, \ + const char *buffer, \ + size_t count) \ + { \ + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, \ + pl_kobj); \ + unsigned long tmp; \ + int rc; \ + \ + rc = kstrtoul(buffer, 10, &tmp); \ + if (rc < 0) { \ + return rc; \ + } \ + \ + LDLM_POOL_SYSFS_SET_##type(pl->pl_##var, tmp); \ + \ + return count; \ } \ struct __##var##__dummy_write {; } /* semicolon catcher */ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index 0a0b435f11fc..764f98684d74 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -667,10 +667,9 @@ int target_send_reply_msg(struct ptlrpc_request *req, int rc, int fail_id) DEBUG_REQ(D_NET, req, "processing error (%d)", rc); req->rq_status = rc; return ptlrpc_send_error(req, 1); - } else { - DEBUG_REQ(D_NET, req, "sending reply"); } + DEBUG_REQ(D_NET, req, "sending reply"); return ptlrpc_send_reply(req, PTLRPC_REPLY_MAYBE_DIFFICULT); } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 6a22f4183b30..bb2246d3b22b 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -931,7 +931,9 @@ static void search_granted_lock(struct list_head *queue, prev->mode_link = &mode_end->l_sl_mode; prev->policy_link = &req->l_sl_policy; return; - } else if (lock->l_resource->lr_type == LDLM_IBITS) { + } + + if (lock->l_resource->lr_type == LDLM_IBITS) { for (;;) { policy_end = list_entry(lock->l_sl_policy.prev, @@ -967,11 +969,10 @@ static void search_granted_lock(struct list_head *queue, prev->mode_link = &mode_end->l_sl_mode; prev->policy_link = &req->l_sl_policy; return; - } else { - LDLM_ERROR(lock, - "is not LDLM_PLAIN or LDLM_IBITS lock"); - LBUG(); } + + LDLM_ERROR(lock, "is not LDLM_PLAIN or LDLM_IBITS lock"); + LBUG(); } /* insert point is last lock on the queue, diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index 6d731d3eda0a..b7b6ca1196b7 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -58,6 +58,10 @@ MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on"); static struct mutex ldlm_ref_mutex; static int ldlm_refcount; +struct kobject *ldlm_kobj; +struct kset *ldlm_ns_kset; +struct kset *ldlm_svc_kset; + struct ldlm_cb_async_args { struct ldlm_cb_set_arg *ca_set_arg; struct ldlm_lock *ca_lock; @@ -1002,6 +1006,42 @@ void ldlm_destroy_export(struct obd_export *exp) } EXPORT_SYMBOL(ldlm_destroy_export); +extern unsigned int ldlm_cancel_unused_locks_before_replay; + +static ssize_t cancel_unused_locks_before_replay_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", ldlm_cancel_unused_locks_before_replay); +} +static ssize_t cancel_unused_locks_before_replay_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) +{ + int rc; + unsigned long val; + + rc = kstrtoul(buffer, 10, &val); + if (rc) + return rc; + + ldlm_cancel_unused_locks_before_replay = val; + + return count; +} +LUSTRE_RW_ATTR(cancel_unused_locks_before_replay); + +/* These are for root of /sys/fs/lustre/ldlm */ +static struct attribute *ldlm_attrs[] = { + &lustre_attr_cancel_unused_locks_before_replay.attr, + NULL, +}; + +static struct attribute_group ldlm_attr_group = { + .attrs = ldlm_attrs, +}; + static int ldlm_setup(void) { static struct ptlrpc_service_conf conf; @@ -1016,7 +1056,29 @@ static int ldlm_setup(void) if (ldlm_state == NULL) return -ENOMEM; - rc = ldlm_proc_setup(); + ldlm_kobj = kobject_create_and_add("ldlm", lustre_kobj); + if (!ldlm_kobj) { + rc = -ENOMEM; + goto out; + } + + rc = sysfs_create_group(ldlm_kobj, &ldlm_attr_group); + if (rc) + goto out; + + ldlm_ns_kset = kset_create_and_add("namespaces", NULL, ldlm_kobj); + if (!ldlm_ns_kset) { + rc = -ENOMEM; + goto out; + } + + ldlm_svc_kset = kset_create_and_add("services", NULL, ldlm_kobj); + if (!ldlm_svc_kset) { + rc = -ENOMEM; + goto out; + } + + rc = ldlm_debugfs_setup(); if (rc != 0) goto out; @@ -1050,7 +1112,8 @@ static int ldlm_setup(void) }, }; ldlm_state->ldlm_cb_service = - ptlrpc_register_service(&conf, ldlm_svc_proc_dir); + ptlrpc_register_service(&conf, ldlm_svc_kset, + ldlm_svc_debugfs_dir); if (IS_ERR(ldlm_state->ldlm_cb_service)) { CERROR("failed to start service\n"); rc = PTR_ERR(ldlm_state->ldlm_cb_service); @@ -1088,7 +1151,6 @@ static int ldlm_setup(void) goto out; } - rc = ldlm_pools_init(); if (rc) { CERROR("Failed to initialize LDLM pools: %d\n", rc); @@ -1135,8 +1197,14 @@ static int ldlm_cleanup(void) if (ldlm_state->ldlm_cb_service != NULL) ptlrpc_unregister_service(ldlm_state->ldlm_cb_service); - ldlm_proc_cleanup(); + if (ldlm_ns_kset) + kset_unregister(ldlm_ns_kset); + if (ldlm_svc_kset) + kset_unregister(ldlm_svc_kset); + if (ldlm_kobj) + kobject_put(ldlm_kobj); + ldlm_debugfs_cleanup(); kfree(ldlm_state); ldlm_state = NULL; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 53e1377873cd..1605b9c69271 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -90,10 +90,10 @@ * pl_server_lock_volume - Current server lock volume (calculated); * * As it may be seen from list above, we have few possible tunables which may - * affect behavior much. They all may be modified via proc. However, they also + * affect behavior much. They all may be modified via sysfs. However, they also * give a possibility for constructing few pre-defined behavior policies. If * none of predefines is suitable for a working pattern being used, new one may - * be "constructed" via proc tunables. + * be "constructed" via sysfs tunables. */ #define DEBUG_SUBSYSTEM S_LDLM @@ -654,7 +654,6 @@ int ldlm_pool_setup(struct ldlm_pool *pl, int limit) } EXPORT_SYMBOL(ldlm_pool_setup); -#if defined(CONFIG_PROC_FS) static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused) { int granted, grant_rate, cancel_rate, grant_step; @@ -696,9 +695,12 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused) } LPROC_SEQ_FOPS_RO(lprocfs_pool_state); -static int lprocfs_grant_speed_seq_show(struct seq_file *m, void *unused) +static ssize_t grant_speed_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_pool *pl = m->private; + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, + pl_kobj); + int grant_speed; spin_lock(&pl->pl_lock); @@ -706,42 +708,88 @@ static int lprocfs_grant_speed_seq_show(struct seq_file *m, void *unused) grant_speed = atomic_read(&pl->pl_grant_rate) - atomic_read(&pl->pl_cancel_rate); spin_unlock(&pl->pl_lock); - return lprocfs_rd_uint(m, &grant_speed); + return sprintf(buf, "%d\n", grant_speed); } +LUSTRE_RO_ATTR(grant_speed); -LDLM_POOL_PROC_READER_SEQ_SHOW(grant_plan, int); -LPROC_SEQ_FOPS_RO(lprocfs_grant_plan); +LDLM_POOL_SYSFS_READER_SHOW(grant_plan, int); +LUSTRE_RO_ATTR(grant_plan); -LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int); -LDLM_POOL_PROC_WRITER(recalc_period, int); -static ssize_t lprocfs_recalc_period_seq_write(struct file *file, - const char __user *buf, - size_t len, loff_t *off) -{ - struct seq_file *seq = file->private_data; +LDLM_POOL_SYSFS_READER_SHOW(recalc_period, int); +LDLM_POOL_SYSFS_WRITER_STORE(recalc_period, int); +LUSTRE_RW_ATTR(recalc_period); - return lprocfs_wr_recalc_period(file, buf, len, seq->private); -} -LPROC_SEQ_FOPS(lprocfs_recalc_period); +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(server_lock_volume, u64); +LUSTRE_RO_ATTR(server_lock_volume); -LPROC_SEQ_FOPS_RO_TYPE(ldlm_pool, u64); -LPROC_SEQ_FOPS_RO_TYPE(ldlm_pool, atomic); -LPROC_SEQ_FOPS_RW_TYPE(ldlm_pool_rw, atomic); +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(limit, atomic); +LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(limit, atomic); +LUSTRE_RW_ATTR(limit); -LPROC_SEQ_FOPS_RO(lprocfs_grant_speed); +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(granted, atomic); +LUSTRE_RO_ATTR(granted); + +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(cancel_rate, atomic); +LUSTRE_RO_ATTR(cancel_rate); + +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(grant_rate, atomic); +LUSTRE_RO_ATTR(grant_rate); + +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(lock_volume_factor, atomic); +LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(lock_volume_factor, atomic); +LUSTRE_RW_ATTR(lock_volume_factor); #define LDLM_POOL_ADD_VAR(name, var, ops) \ do { \ snprintf(var_name, MAX_STRING_SIZE, #name); \ pool_vars[0].data = var; \ pool_vars[0].fops = ops; \ - lprocfs_add_vars(pl->pl_proc_dir, pool_vars, NULL);\ + ldebugfs_add_vars(pl->pl_debugfs_entry, pool_vars, NULL);\ } while (0) -static int ldlm_pool_proc_init(struct ldlm_pool *pl) +/* These are for pools in /sys/fs/lustre/ldlm/namespaces/.../pool */ +static struct attribute *ldlm_pl_attrs[] = { + &lustre_attr_grant_speed.attr, + &lustre_attr_grant_plan.attr, + &lustre_attr_recalc_period.attr, + &lustre_attr_server_lock_volume.attr, + &lustre_attr_limit.attr, + &lustre_attr_granted.attr, + &lustre_attr_cancel_rate.attr, + &lustre_attr_grant_rate.attr, + &lustre_attr_lock_volume_factor.attr, + NULL, +}; + +static void ldlm_pl_release(struct kobject *kobj) +{ + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, + pl_kobj); + complete(&pl->pl_kobj_unregister); +} + +static struct kobj_type ldlm_pl_ktype = { + .default_attrs = ldlm_pl_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = ldlm_pl_release, +}; + +static int ldlm_pool_sysfs_init(struct ldlm_pool *pl) +{ + struct ldlm_namespace *ns = ldlm_pl2ns(pl); + int err; + + init_completion(&pl->pl_kobj_unregister); + err = kobject_init_and_add(&pl->pl_kobj, &ldlm_pl_ktype, &ns->ns_kobj, + "pool"); + + return err; +} + +static int ldlm_pool_debugfs_init(struct ldlm_pool *pl) { struct ldlm_namespace *ns = ldlm_pl2ns(pl); - struct proc_dir_entry *parent_ns_proc; + struct dentry *debugfs_ns_parent; struct lprocfs_vars pool_vars[2]; char *var_name = NULL; int rc = 0; @@ -750,19 +798,19 @@ static int ldlm_pool_proc_init(struct ldlm_pool *pl) if (!var_name) return -ENOMEM; - parent_ns_proc = ns->ns_proc_dir_entry; - if (parent_ns_proc == NULL) { - CERROR("%s: proc entry is not initialized\n", + debugfs_ns_parent = ns->ns_debugfs_entry; + if (IS_ERR_OR_NULL(debugfs_ns_parent)) { + CERROR("%s: debugfs entry is not initialized\n", ldlm_ns_name(ns)); rc = -EINVAL; goto out_free_name; } - pl->pl_proc_dir = lprocfs_register("pool", parent_ns_proc, - NULL, NULL); - if (IS_ERR(pl->pl_proc_dir)) { - CERROR("LProcFS failed in ldlm-pool-init\n"); - rc = PTR_ERR(pl->pl_proc_dir); - pl->pl_proc_dir = NULL; + pl->pl_debugfs_entry = ldebugfs_register("pool", debugfs_ns_parent, + NULL, NULL); + if (IS_ERR(pl->pl_debugfs_entry)) { + CERROR("LdebugFS failed in ldlm-pool-init\n"); + rc = PTR_ERR(pl->pl_debugfs_entry); + pl->pl_debugfs_entry = NULL; goto out_free_name; } @@ -770,20 +818,7 @@ static int ldlm_pool_proc_init(struct ldlm_pool *pl) memset(pool_vars, 0, sizeof(pool_vars)); pool_vars[0].name = var_name; - LDLM_POOL_ADD_VAR("server_lock_volume", &pl->pl_server_lock_volume, - &ldlm_pool_u64_fops); - LDLM_POOL_ADD_VAR("limit", &pl->pl_limit, &ldlm_pool_rw_atomic_fops); - LDLM_POOL_ADD_VAR("granted", &pl->pl_granted, &ldlm_pool_atomic_fops); - LDLM_POOL_ADD_VAR("grant_speed", pl, &lprocfs_grant_speed_fops); - LDLM_POOL_ADD_VAR("cancel_rate", &pl->pl_cancel_rate, - &ldlm_pool_atomic_fops); - LDLM_POOL_ADD_VAR("grant_rate", &pl->pl_grant_rate, - &ldlm_pool_atomic_fops); - LDLM_POOL_ADD_VAR("grant_plan", pl, &lprocfs_grant_plan_fops); - LDLM_POOL_ADD_VAR("recalc_period", pl, &lprocfs_recalc_period_fops); - LDLM_POOL_ADD_VAR("lock_volume_factor", &pl->pl_lock_volume_factor, - &ldlm_pool_rw_atomic_fops); - LDLM_POOL_ADD_VAR("state", pl, &lprocfs_pool_state_fops); + LDLM_POOL_ADD_VAR(state, pl, &lprocfs_pool_state_fops); pl->pl_stats = lprocfs_alloc_stats(LDLM_POOL_LAST_STAT - LDLM_POOL_FIRST_STAT, 0); @@ -825,32 +860,31 @@ static int ldlm_pool_proc_init(struct ldlm_pool *pl) lprocfs_counter_init(pl->pl_stats, LDLM_POOL_TIMING_STAT, LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV, "recalc_timing", "sec"); - rc = lprocfs_register_stats(pl->pl_proc_dir, "stats", pl->pl_stats); + rc = ldebugfs_register_stats(pl->pl_debugfs_entry, "stats", + pl->pl_stats); out_free_name: kfree(var_name); return rc; } -static void ldlm_pool_proc_fini(struct ldlm_pool *pl) +static void ldlm_pool_sysfs_fini(struct ldlm_pool *pl) +{ + kobject_put(&pl->pl_kobj); + wait_for_completion(&pl->pl_kobj_unregister); +} + +static void ldlm_pool_debugfs_fini(struct ldlm_pool *pl) { if (pl->pl_stats != NULL) { lprocfs_free_stats(&pl->pl_stats); pl->pl_stats = NULL; } - if (pl->pl_proc_dir != NULL) { - lprocfs_remove(&pl->pl_proc_dir); - pl->pl_proc_dir = NULL; + if (pl->pl_debugfs_entry != NULL) { + ldebugfs_remove(&pl->pl_debugfs_entry); + pl->pl_debugfs_entry = NULL; } } -#else /* !CONFIG_PROC_FS */ -static int ldlm_pool_proc_init(struct ldlm_pool *pl) -{ - return 0; -} - -static void ldlm_pool_proc_fini(struct ldlm_pool *pl) {} -#endif /* CONFIG_PROC_FS */ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns, int idx, ldlm_side_t client) @@ -881,7 +915,11 @@ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns, pl->pl_recalc_period = LDLM_POOL_CLI_DEF_RECALC_PERIOD; } pl->pl_client_lock_volume = 0; - rc = ldlm_pool_proc_init(pl); + rc = ldlm_pool_debugfs_init(pl); + if (rc) + return rc; + + rc = ldlm_pool_sysfs_init(pl); if (rc) return rc; @@ -893,7 +931,8 @@ EXPORT_SYMBOL(ldlm_pool_init); void ldlm_pool_fini(struct ldlm_pool *pl) { - ldlm_pool_proc_fini(pl); + ldlm_pool_sysfs_fini(pl); + ldlm_pool_debugfs_fini(pl); /* * Pool should not be used after this point. We can't free it here as @@ -1362,8 +1401,7 @@ static int ldlm_pools_thread_main(void *arg) if (thread_test_and_clear_flags(thread, SVC_STOPPING)) break; - else - thread_test_and_clear_flags(thread, SVC_EVENT); + thread_test_and_clear_flags(thread, SVC_EVENT); } thread_set_flags(thread, SVC_STOPPED); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 4f713183145b..6245a2c36a0f 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1462,7 +1462,7 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, lock->l_last_used)); lv = lvf * la * unused; - /* Inform pool about current CLV to see it via proc. */ + /* Inform pool about current CLV to see it via debugfs. */ ldlm_pool_set_clv(pl, lv); /* Stop when SLV is not yet come from server or lv is smaller than @@ -1472,7 +1472,7 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, } /** - * Callback function for proc used policy. Makes decision whether to keep + * Callback function for debugfs used policy. Makes decision whether to keep * \a lock in LRU for current \a LRU size \a unused, added in current scan \a * added and number of locks to be preferably canceled \a count. * diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 7149edab44f4..cdb63665a113 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -61,19 +61,17 @@ LIST_HEAD(ldlm_cli_active_namespace_list); /* Client namespaces that don't have any locks in them */ LIST_HEAD(ldlm_cli_inactive_namespace_list); -struct proc_dir_entry *ldlm_type_proc_dir = NULL; -static struct proc_dir_entry *ldlm_ns_proc_dir = NULL; -struct proc_dir_entry *ldlm_svc_proc_dir = NULL; - -extern unsigned int ldlm_cancel_unused_locks_before_replay; +static struct dentry *ldlm_debugfs_dir; +static struct dentry *ldlm_ns_debugfs_dir; +struct dentry *ldlm_svc_debugfs_dir; /* during debug dump certain amount of granted locks for one resource to avoid * DDOS. */ unsigned int ldlm_dump_granted_max = 256; -#if defined(CONFIG_PROC_FS) -static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, - size_t count, loff_t *off) +static ssize_t +lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, + size_t count, loff_t *off) { ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE); ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE); @@ -82,81 +80,82 @@ static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, LPROC_SEQ_FOPS_WR_ONLY(ldlm, dump_ns); LPROC_SEQ_FOPS_RW_TYPE(ldlm_rw, uint); -LPROC_SEQ_FOPS_RO_TYPE(ldlm, uint); -int ldlm_proc_setup(void) +static struct lprocfs_vars ldlm_debugfs_list[] = { + { "dump_namespaces", &ldlm_dump_ns_fops, NULL, 0222 }, + { "dump_granted_max", &ldlm_rw_uint_fops, &ldlm_dump_granted_max }, + { NULL } +}; + +int ldlm_debugfs_setup(void) { int rc; - struct lprocfs_vars list[] = { - { "dump_namespaces", &ldlm_dump_ns_fops, NULL, 0222 }, - { "dump_granted_max", &ldlm_rw_uint_fops, - &ldlm_dump_granted_max }, - { "cancel_unused_locks_before_replay", &ldlm_rw_uint_fops, - &ldlm_cancel_unused_locks_before_replay }, - { NULL } }; - LASSERT(ldlm_ns_proc_dir == NULL); - - ldlm_type_proc_dir = lprocfs_register(OBD_LDLM_DEVICENAME, - proc_lustre_root, - NULL, NULL); - if (IS_ERR(ldlm_type_proc_dir)) { + + ldlm_debugfs_dir = ldebugfs_register(OBD_LDLM_DEVICENAME, + debugfs_lustre_root, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_type_proc_dir); + rc = ldlm_debugfs_dir ? PTR_ERR(ldlm_debugfs_dir) : -ENOMEM; goto err; } - ldlm_ns_proc_dir = lprocfs_register("namespaces", - ldlm_type_proc_dir, - NULL, NULL); - if (IS_ERR(ldlm_ns_proc_dir)) { + ldlm_ns_debugfs_dir = ldebugfs_register("namespaces", + ldlm_debugfs_dir, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_ns_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_ns_proc_dir); + rc = ldlm_ns_debugfs_dir ? PTR_ERR(ldlm_ns_debugfs_dir) + : -ENOMEM; goto err_type; } - ldlm_svc_proc_dir = lprocfs_register("services", - ldlm_type_proc_dir, - NULL, NULL); - if (IS_ERR(ldlm_svc_proc_dir)) { + ldlm_svc_debugfs_dir = ldebugfs_register("services", + ldlm_debugfs_dir, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_svc_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_svc_proc_dir); + rc = ldlm_svc_debugfs_dir ? PTR_ERR(ldlm_svc_debugfs_dir) + : -ENOMEM; goto err_ns; } - rc = lprocfs_add_vars(ldlm_type_proc_dir, list, NULL); + rc = ldebugfs_add_vars(ldlm_debugfs_dir, ldlm_debugfs_list, NULL); return 0; err_ns: - lprocfs_remove(&ldlm_ns_proc_dir); + ldebugfs_remove(&ldlm_ns_debugfs_dir); err_type: - lprocfs_remove(&ldlm_type_proc_dir); + ldebugfs_remove(&ldlm_debugfs_dir); err: - ldlm_svc_proc_dir = NULL; - ldlm_type_proc_dir = NULL; - ldlm_ns_proc_dir = NULL; + ldlm_svc_debugfs_dir = NULL; + ldlm_ns_debugfs_dir = NULL; + ldlm_debugfs_dir = NULL; return rc; } -void ldlm_proc_cleanup(void) +void ldlm_debugfs_cleanup(void) { - if (ldlm_svc_proc_dir) - lprocfs_remove(&ldlm_svc_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_svc_debugfs_dir)) + ldebugfs_remove(&ldlm_svc_debugfs_dir); - if (ldlm_ns_proc_dir) - lprocfs_remove(&ldlm_ns_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_ns_debugfs_dir)) + ldebugfs_remove(&ldlm_ns_debugfs_dir); - if (ldlm_type_proc_dir) - lprocfs_remove(&ldlm_type_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_debugfs_dir)) + ldebugfs_remove(&ldlm_debugfs_dir); - ldlm_svc_proc_dir = NULL; - ldlm_type_proc_dir = NULL; - ldlm_ns_proc_dir = NULL; + ldlm_svc_debugfs_dir = NULL; + ldlm_ns_debugfs_dir = NULL; + ldlm_debugfs_dir = NULL; } -static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v) +static ssize_t resource_count_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u64 res = 0; struct cfs_hash_bd bd; int i; @@ -164,46 +163,56 @@ static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v) /* result is not strictly consistent */ cfs_hash_for_each_bucket(ns->ns_rs_hash, &bd, i) res += cfs_hash_bd_count_get(&bd); - return lprocfs_rd_u64(m, &res); + return sprintf(buf, "%lld\n", res); } -LPROC_SEQ_FOPS_RO(lprocfs_ns_resources); +LUSTRE_RO_ATTR(resource_count); -static int lprocfs_ns_locks_seq_show(struct seq_file *m, void *v) +static ssize_t lock_count_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u64 locks; locks = lprocfs_stats_collector(ns->ns_stats, LDLM_NSS_LOCKS, LPROCFS_FIELDS_FLAGS_SUM); - return lprocfs_rd_u64(m, &locks); + return sprintf(buf, "%lld\n", locks); +} +LUSTRE_RO_ATTR(lock_count); + +static ssize_t lock_unused_count_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + + return sprintf(buf, "%d\n", ns->ns_nr_unused); } -LPROC_SEQ_FOPS_RO(lprocfs_ns_locks); +LUSTRE_RO_ATTR(lock_unused_count); -static int lprocfs_lru_size_seq_show(struct seq_file *m, void *v) +static ssize_t lru_size_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u32 *nr = &ns->ns_max_unused; if (ns_connect_lru_resize(ns)) nr = &ns->ns_nr_unused; - return lprocfs_rd_uint(m, nr); + return sprintf(buf, "%u", *nr); } -static ssize_t lprocfs_lru_size_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lru_size_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private; - char dummy[MAX_STRING_SIZE + 1]; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); unsigned long tmp; int lru_resize; int err; - dummy[MAX_STRING_SIZE] = '\0'; - if (copy_from_user(dummy, buffer, MAX_STRING_SIZE)) - return -EFAULT; - - if (strncmp(dummy, "clear", 5) == 0) { + if (strncmp(buffer, "clear", 5) == 0) { CDEBUG(D_DLMTRACE, "dropping all unused locks from namespace %s\n", ldlm_ns_name(ns)); @@ -229,9 +238,9 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, return count; } - err = kstrtoul(dummy, 10, &tmp); + err = kstrtoul(buffer, 10, &tmp); if (err != 0) { - CERROR("invalid value written\n"); + CERROR("lru_size: invalid value written\n"); return -EINVAL; } lru_resize = (tmp == 0); @@ -277,25 +286,56 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(lprocfs_lru_size); +LUSTRE_RW_ATTR(lru_size); -static int lprocfs_elc_seq_show(struct seq_file *m, void *v) +static ssize_t lru_max_age_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; - unsigned int supp = ns_connect_cancelset(ns); + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); - return lprocfs_rd_uint(m, &supp); + return sprintf(buf, "%u", ns->ns_max_age); } -static ssize_t lprocfs_elc_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lru_max_age_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private; - unsigned int supp = -1; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + unsigned long tmp; + int err; + + err = kstrtoul(buffer, 10, &tmp); + if (err != 0) + return -EINVAL; + + ns->ns_max_age = tmp; + + return count; +} +LUSTRE_RW_ATTR(lru_max_age); + +static ssize_t early_lock_cancel_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + + return sprintf(buf, "%d\n", ns_connect_cancelset(ns)); +} + +static ssize_t early_lock_cancel_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + unsigned long supp = -1; int rc; - rc = lprocfs_wr_uint(file, buffer, count, &supp); + rc = kstrtoul(buffer, 10, &supp); if (rc < 0) return rc; @@ -305,91 +345,88 @@ static ssize_t lprocfs_elc_seq_write(struct file *file, ns->ns_connect_flags |= OBD_CONNECT_CANCELSET; return count; } -LPROC_SEQ_FOPS(lprocfs_elc); +LUSTRE_RW_ATTR(early_lock_cancel); + +/* These are for namespaces in /sys/fs/lustre/ldlm/namespaces/ */ +static struct attribute *ldlm_ns_attrs[] = { + &lustre_attr_resource_count.attr, + &lustre_attr_lock_count.attr, + &lustre_attr_lock_unused_count.attr, + &lustre_attr_lru_size.attr, + &lustre_attr_lru_max_age.attr, + &lustre_attr_early_lock_cancel.attr, + NULL, +}; -void ldlm_namespace_proc_unregister(struct ldlm_namespace *ns) +static void ldlm_ns_release(struct kobject *kobj) { - if (ns->ns_proc_dir_entry == NULL) + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + complete(&ns->ns_kobj_unregister); +} + +static struct kobj_type ldlm_ns_ktype = { + .default_attrs = ldlm_ns_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = ldlm_ns_release, +}; + +static void ldlm_namespace_debugfs_unregister(struct ldlm_namespace *ns) +{ + if (IS_ERR_OR_NULL(ns->ns_debugfs_entry)) CERROR("dlm namespace %s has no procfs dir?\n", ldlm_ns_name(ns)); else - lprocfs_remove(&ns->ns_proc_dir_entry); + ldebugfs_remove(&ns->ns_debugfs_entry); if (ns->ns_stats != NULL) lprocfs_free_stats(&ns->ns_stats); } -#define LDLM_NS_ADD_VAR(name, var, ops) \ - do { \ - snprintf(lock_name, MAX_STRING_SIZE, name); \ - lock_vars[0].data = var; \ - lock_vars[0].fops = ops; \ - lprocfs_add_vars(ns_pde, lock_vars, NULL); \ - } while (0) - -int ldlm_namespace_proc_register(struct ldlm_namespace *ns) +void ldlm_namespace_sysfs_unregister(struct ldlm_namespace *ns) { - struct lprocfs_vars lock_vars[2]; - char lock_name[MAX_STRING_SIZE + 1]; - struct proc_dir_entry *ns_pde; + kobject_put(&ns->ns_kobj); + wait_for_completion(&ns->ns_kobj_unregister); +} - LASSERT(ns != NULL); - LASSERT(ns->ns_rs_hash != NULL); +int ldlm_namespace_sysfs_register(struct ldlm_namespace *ns) +{ + int err; - if (ns->ns_proc_dir_entry != NULL) { - ns_pde = ns->ns_proc_dir_entry; - } else { - ns_pde = proc_mkdir(ldlm_ns_name(ns), ldlm_ns_proc_dir); - if (ns_pde == NULL) - return -ENOMEM; - ns->ns_proc_dir_entry = ns_pde; - } + ns->ns_kobj.kset = ldlm_ns_kset; + init_completion(&ns->ns_kobj_unregister); + err = kobject_init_and_add(&ns->ns_kobj, &ldlm_ns_ktype, NULL, + "%s", ldlm_ns_name(ns)); ns->ns_stats = lprocfs_alloc_stats(LDLM_NSS_LAST, 0); - if (ns->ns_stats == NULL) + if (ns->ns_stats == NULL) { + kobject_put(&ns->ns_kobj); return -ENOMEM; + } lprocfs_counter_init(ns->ns_stats, LDLM_NSS_LOCKS, LPROCFS_CNTR_AVGMINMAX, "locks", "locks"); - lock_name[MAX_STRING_SIZE] = '\0'; - - memset(lock_vars, 0, sizeof(lock_vars)); - lock_vars[0].name = lock_name; + return err; +} - LDLM_NS_ADD_VAR("resource_count", ns, &lprocfs_ns_resources_fops); - LDLM_NS_ADD_VAR("lock_count", ns, &lprocfs_ns_locks_fops); +static int ldlm_namespace_debugfs_register(struct ldlm_namespace *ns) +{ + struct dentry *ns_entry; - if (ns_is_client(ns)) { - LDLM_NS_ADD_VAR("lock_unused_count", &ns->ns_nr_unused, - &ldlm_uint_fops); - LDLM_NS_ADD_VAR("lru_size", ns, &lprocfs_lru_size_fops); - LDLM_NS_ADD_VAR("lru_max_age", &ns->ns_max_age, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("early_lock_cancel", ns, &lprocfs_elc_fops); + if (!IS_ERR_OR_NULL(ns->ns_debugfs_entry)) { + ns_entry = ns->ns_debugfs_entry; } else { - LDLM_NS_ADD_VAR("ctime_age_limit", &ns->ns_ctime_age_limit, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("lock_timeouts", &ns->ns_timeouts, - &ldlm_uint_fops); - LDLM_NS_ADD_VAR("max_nolock_bytes", &ns->ns_max_nolock_size, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("contention_seconds", &ns->ns_contention_time, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("contended_locks", &ns->ns_contended_locks, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("max_parallel_ast", &ns->ns_max_parallel_ast, - &ldlm_rw_uint_fops); + ns_entry = debugfs_create_dir(ldlm_ns_name(ns), + ldlm_ns_debugfs_dir); + if (ns_entry == NULL) + return -ENOMEM; + ns->ns_debugfs_entry = ns_entry; } + return 0; } #undef MAX_STRING_SIZE -#else /* CONFIG_PROC_FS */ - -#define ldlm_namespace_proc_unregister(ns) ({; }) -#define ldlm_namespace_proc_register(ns) ({0; }) - -#endif /* CONFIG_PROC_FS */ static unsigned ldlm_res_hop_hash(struct cfs_hash *hs, const void *key, unsigned mask) @@ -623,25 +660,26 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, atomic_set(&ns->ns_bref, 0); init_waitqueue_head(&ns->ns_waitq); - ns->ns_max_nolock_size = NS_DEFAULT_MAX_NOLOCK_BYTES; - ns->ns_contention_time = NS_DEFAULT_CONTENTION_SECONDS; - ns->ns_contended_locks = NS_DEFAULT_CONTENDED_LOCKS; - ns->ns_max_parallel_ast = LDLM_DEFAULT_PARALLEL_AST_LIMIT; ns->ns_nr_unused = 0; ns->ns_max_unused = LDLM_DEFAULT_LRU_SIZE; ns->ns_max_age = LDLM_DEFAULT_MAX_ALIVE; - ns->ns_ctime_age_limit = LDLM_CTIME_AGE_LIMIT; - ns->ns_timeouts = 0; ns->ns_orig_connect_flags = 0; ns->ns_connect_flags = 0; ns->ns_stopping = 0; - rc = ldlm_namespace_proc_register(ns); + + rc = ldlm_namespace_sysfs_register(ns); if (rc != 0) { - CERROR("Can't initialize ns proc, rc %d\n", rc); + CERROR("Can't initialize ns sysfs, rc %d\n", rc); goto out_hash; } + rc = ldlm_namespace_debugfs_register(ns); + if (rc != 0) { + CERROR("Can't initialize ns proc, rc %d\n", rc); + goto out_sysfs; + } + idx = ldlm_namespace_nr_read(client); rc = ldlm_pool_init(&ns->ns_pool, ns, idx, client); if (rc) { @@ -652,7 +690,9 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, ldlm_namespace_register(ns, client); return ns; out_proc: - ldlm_namespace_proc_unregister(ns); + ldlm_namespace_debugfs_unregister(ns); +out_sysfs: + ldlm_namespace_sysfs_unregister(ns); ldlm_namespace_cleanup(ns, 0); out_hash: cfs_hash_putref(ns->ns_rs_hash); @@ -898,7 +938,7 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns) * Removing it after @dir may cause oops. */ ldlm_pool_fini(&ns->ns_pool); - ldlm_namespace_proc_unregister(ns); + ldlm_namespace_debugfs_unregister(ns); cfs_hash_putref(ns->ns_rs_hash); /* Namespace \a ns should be not on list at this time, otherwise * this will cause issues related to using freed \a ns in poold @@ -915,7 +955,7 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns) * proc1: destroy import * class_disconnect_export(grab cl_sem) -> * -> ldlm_namespace_free -> - * -> lprocfs_remove(grab _lprocfs_lock). + * -> ldebugfs_remove(grab _lprocfs_lock). * proc2: read proc info * lprocfs_fops_read(grab _lprocfs_lock) -> * -> osc_rd_active, etc(grab cl_sem). diff --git a/drivers/staging/lustre/lustre/libcfs/Makefile b/drivers/staging/lustre/lustre/libcfs/Makefile index 2996a48a31fb..ec98f44a10dd 100644 --- a/drivers/staging/lustre/lustre/libcfs/Makefile +++ b/drivers/staging/lustre/lustre/libcfs/Makefile @@ -2,11 +2,11 @@ obj-$(CONFIG_LUSTRE_FS) += libcfs.o libcfs-linux-objs := linux-tracefile.o linux-debug.o libcfs-linux-objs += linux-prim.o linux-cpu.o -libcfs-linux-objs += linux-tcpip.o libcfs-linux-objs += linux-curproc.o libcfs-linux-objs += linux-module.o libcfs-linux-objs += linux-crypto.o libcfs-linux-objs += linux-crypto-adler.o +libcfs-linux-objs += linux-mem.o libcfs-linux-objs := $(addprefix linux/,$(libcfs-linux-objs)) diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c index 92444b0fe2a3..7b7fc215e633 100644 --- a/drivers/staging/lustre/lustre/libcfs/fail.c +++ b/drivers/staging/lustre/lustre/libcfs/fail.c @@ -41,7 +41,7 @@ EXPORT_SYMBOL(cfs_fail_loc); unsigned int cfs_fail_val = 0; EXPORT_SYMBOL(cfs_fail_val); -wait_queue_head_t cfs_race_waitq; +DECLARE_WAIT_QUEUE_HEAD(cfs_race_waitq); EXPORT_SYMBOL(cfs_race_waitq); int cfs_race_state; diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-mem.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-mem.c new file mode 100644 index 000000000000..025e2f0028ab --- /dev/null +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-mem.c @@ -0,0 +1,59 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + */ +/* + * This file creates a memory allocation primitive for Lustre, that + * allows to fallback to vmalloc allocations should regular kernel allocations + * fail due to size or system memory fragmentation. + * + * Author: Oleg Drokin <green@linuxhacker.ru> + * + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Seagate Technology. + */ +#include <linux/slab.h> +#include <linux/vmalloc.h> + +#include "../../../include/linux/libcfs/libcfs.h" + +void *libcfs_kvzalloc(size_t size, gfp_t flags) +{ + void *ret; + + ret = kzalloc(size, flags | __GFP_NOWARN); + if (!ret) + ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL); + return ret; +} +EXPORT_SYMBOL(libcfs_kvzalloc); + +void *libcfs_kvzalloc_cpt(struct cfs_cpt_table *cptab, int cpt, size_t size, + gfp_t flags) +{ + void *ret; + + ret = kzalloc_node(size, flags | __GFP_NOWARN, + cfs_cpt_spread_node(cptab, cpt)); + if (!ret) { + WARN_ON(!(flags & (__GFP_FS|__GFP_HIGH))); + ret = vmalloc_node(size, cfs_cpt_spread_node(cptab, cpt)); + } + + return ret; +} +EXPORT_SYMBOL(libcfs_kvzalloc_cpt); diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c index 483cbc82e538..eb10e3b478aa 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c @@ -49,7 +49,7 @@ static unsigned int pages_factor[CFS_TCD_TYPE_MAX] = { char *cfs_trace_console_buffers[NR_CPUS][CFS_TCD_TYPE_MAX]; -struct rw_semaphore cfs_tracefile_sem; +static DECLARE_RWSEM(cfs_tracefile_sem); int cfs_tracefile_init_arch(void) { @@ -57,8 +57,6 @@ int cfs_tracefile_init_arch(void) int j; struct cfs_trace_cpu_data *tcd; - init_rwsem(&cfs_tracefile_sem); - /* initialize trace_data */ memset(cfs_trace_data, 0, sizeof(cfs_trace_data)); for (i = 0; i < CFS_TCD_TYPE_MAX; i++) { diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index f0ee76abfd5a..e60b2e9b9194 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -49,7 +49,6 @@ #include <linux/file.h> #include <linux/list.h> -#include <linux/proc_fs.h> #include <linux/sysctl.h> # define DEBUG_SUBSYSTEM S_LNET @@ -67,8 +66,6 @@ MODULE_DESCRIPTION("Portals v3.1"); MODULE_LICENSE("GPL"); extern struct miscdevice libcfs_dev; -extern struct rw_semaphore cfs_tracefile_sem; -extern struct mutex cfs_trace_thread_mutex; extern struct cfs_wi_sched *cfs_sched_rehash; extern void libcfs_init_nidstrings(void); @@ -249,8 +246,8 @@ static int libcfs_psdev_release(unsigned long flags, void *args) return 0; } -static struct rw_semaphore ioctl_list_sem; -static struct list_head ioctl_list; +static DECLARE_RWSEM(ioctl_list_sem); +static LIST_HEAD(ioctl_list); int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand) { @@ -393,11 +390,6 @@ static int init_libcfs_module(void) libcfs_arch_init(); libcfs_init_nidstrings(); - init_rwsem(&cfs_tracefile_sem); - mutex_init(&cfs_trace_thread_mutex); - init_rwsem(&ioctl_list_sem); - INIT_LIST_HEAD(&ioctl_list); - init_waitqueue_head(&cfs_race_waitq); rc = libcfs_debug_init(5 * 1024 * 1024); if (rc < 0) { diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index c86394f7f4d9..6ee2adcf8890 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -52,7 +52,7 @@ union cfs_trace_data_union (*cfs_trace_data[TCD_MAX_TYPES])[NR_CPUS] __cacheline char cfs_tracefile[TRACEFILE_NAME_SIZE]; long long cfs_tracefile_size = CFS_TRACEFILE_SIZE; static struct tracefiled_ctl trace_tctl; -struct mutex cfs_trace_thread_mutex; +static DEFINE_MUTEX(cfs_trace_thread_mutex); static int thread_running; static atomic_t cfs_tage_allocated = ATOMIC_INIT(0); diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile index 7d70115d5bc7..2cbc46838fdd 100644 --- a/drivers/staging/lustre/lustre/llite/Makefile +++ b/drivers/staging/lustre/lustre/llite/Makefile @@ -5,7 +5,6 @@ lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \ xattr.o xattr_cache.o remote_perm.o llite_rmtacl.o llite_capa.o \ rw26.o super25.o statahead.o \ ../lclient/glimpse.o ../lclient/lcommon_cl.o ../lclient/lcommon_misc.o \ - vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o + vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o lproc_llite.o -lustre-$(CONFIG_PROC_FS) += lproc_llite.o llite_lloop-y := lloop.o diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 702f62d44430..5c05f41d3575 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -3239,8 +3239,6 @@ void ll_iocontrol_unregister(void *magic) down_write(&llioc.ioc_sem); list_for_each_entry(tmp, &llioc.ioc_head, iocd_list) { if (tmp == magic) { - unsigned int size = tmp->iocd_size; - list_del(&tmp->iocd_list); up_write(&llioc.ioc_sem); diff --git a/drivers/staging/lustre/lustre/llite/llite_capa.c b/drivers/staging/lustre/lustre/llite/llite_capa.c index aec9a44120c0..a6268718b76e 100644 --- a/drivers/staging/lustre/lustre/llite/llite_capa.c +++ b/drivers/staging/lustre/lustre/llite/llite_capa.c @@ -140,6 +140,7 @@ static void sort_add_capa(struct obd_capa *ocapa, struct list_head *head) static inline int obd_capa_open_count(struct obd_capa *oc) { struct ll_inode_info *lli = ll_i2info(oc->u.cli.inode); + return atomic_read(&lli->lli_open_count); } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 1253b3cf50a8..f097d4d167d5 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -57,12 +57,6 @@ #define VM_FAULT_RETRY 0 #endif -/* Kernel 3.1 kills LOOKUP_CONTINUE, LOOKUP_PARENT is equivalent to it. - * seem kernel commit 49084c3bb2055c401f3493c13edae14d49128ca0 */ -#ifndef LOOKUP_CONTINUE -#define LOOKUP_CONTINUE LOOKUP_PARENT -#endif - /** Only used on client-side for indicating the tail of dir hash/offset. */ #define LL_DIR_END_OFF 0x7fffffffffffffffULL #define LL_DIR_END_OFF_32BIT 0x7fffffffUL @@ -471,7 +465,7 @@ struct ll_sb_info { struct obd_uuid ll_sb_uuid; struct obd_export *ll_md_exp; struct obd_export *ll_dt_exp; - struct proc_dir_entry* ll_proc_root; + struct dentry *ll_debugfs_entry; struct lu_fid ll_root_fid; /* root object fid */ int ll_flags; @@ -493,9 +487,6 @@ struct ll_sb_info { unsigned int ll_namelen; struct file_operations *ll_fop; - /* =0 - hold lock over whole read/write - * >0 - max. chunk to be read/written w/o lock re-acquiring */ - unsigned long ll_max_rw_chunk; unsigned int ll_md_brw_size; /* used by readdir */ struct lu_site *ll_site; @@ -524,10 +515,11 @@ struct ll_sb_info { struct rmtacl_ctl_table ll_rct; struct eacl_table ll_et; __kernel_fsid_t ll_fsid; + struct kobject ll_kobj; /* sysfs object */ + struct super_block *ll_sb; /* struct super_block (for sysfs code)*/ + struct completion ll_kobj_unregister; }; -#define LL_DEFAULT_MAX_RW_CHUNK (32 * 1024 * 1024) - struct ll_ra_read { pgoff_t lrr_start; pgoff_t lrr_count; @@ -644,7 +636,8 @@ struct lov_stripe_md; extern spinlock_t inode_lock; -extern struct proc_dir_entry *proc_lustre_fs_root; +extern struct dentry *llite_root; +extern struct kset *llite_kset; static inline struct inode *ll_info2i(struct ll_inode_info *lli) { @@ -670,30 +663,14 @@ void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar); struct ll_ra_read *ll_ra_read_get(struct file *f); /* llite/lproc_llite.c */ -#if defined (CONFIG_PROC_FS) -int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, char *osc, char *mdc); -void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi); +int ldebugfs_register_mountpoint(struct dentry *parent, + struct super_block *sb, char *osc, char *mdc); +void ldebugfs_unregister_mountpoint(struct ll_sb_info *sbi); void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count); void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars); void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, struct ll_file_data *file, loff_t pos, size_t count, int rw); -#else -static inline int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, char *osc, char *mdc){return 0;} -static inline void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi) {} -static inline -void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) {} -static inline void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -static inline void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, - struct ll_file_data *file, loff_t pos, - size_t count, int rw) {} -#endif - /* llite/dir.c */ void ll_release_page(struct page *page, int remove); diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index c6611b11779c..25139885b5a7 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -57,7 +57,8 @@ #include "llite_internal.h" struct kmem_cache *ll_file_data_slab; -struct proc_dir_entry *proc_lustre_fs_root; +struct dentry *llite_root; +struct kset *llite_kset; static LIST_HEAD(ll_super_blocks); static DEFINE_SPINLOCK(ll_sb_lock); @@ -66,7 +67,7 @@ static DEFINE_SPINLOCK(ll_sb_lock); #define log2(n) ffz(~(n)) #endif -static struct ll_sb_info *ll_init_sbi(void) +static struct ll_sb_info *ll_init_sbi(struct super_block *sb) { struct ll_sb_info *sbi = NULL; unsigned long pages; @@ -134,6 +135,8 @@ static struct ll_sb_info *ll_init_sbi(void) atomic_set(&sbi->ll_agl_total, 0); sbi->ll_flags |= LL_SBI_AGL_ENABLED; + sbi->ll_sb = sb; + return sbi; } @@ -181,11 +184,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, return -ENOMEM; } - if (proc_lustre_fs_root) { - err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb, - dt, md); + if (llite_root != NULL) { + err = ldebugfs_register_mountpoint(llite_root, sb, dt, md); if (err < 0) - CERROR("could not register mount in /proc/fs/lustre\n"); + CERROR("could not register mount in <debugfs>/lustre/llite\n"); } /* indicate the features supported by this client */ @@ -284,6 +286,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, char *buf; buf = kzalloc(PAGE_CACHE_SIZE, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out_md_fid; + } obd_connect_flags2str(buf, PAGE_CACHE_SIZE, valid ^ CLIENT_CONNECT_MDT_REQD, ","); LCONSOLE_ERROR_MSG(0x170, "Server %s does not support feature(s) needed for correct operation of this client (%s). Please upgrade server or downgrade client.\n", @@ -308,7 +314,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, sb->s_magic = LL_SUPER_MAGIC; sb->s_maxbytes = MAX_LFS_FILESIZE; sbi->ll_namelen = osfs->os_namelen; - sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK; if ((sbi->ll_flags & LL_SBI_USER_XATTR) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { @@ -400,7 +405,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if (!OBD_FAIL_CHECK(OBD_FAIL_OSC_CONNECT_CKSUM)) { /* OBD_CONNECT_CKSUM should always be set, even if checksums are * disabled by default, because it can still be enabled on the - * fly via /proc. As a consequence, we still need to come to an + * fly via /sys. As a consequence, we still need to come to an * agreement on the supported algorithms at connect time */ data->ocd_connect_flags |= OBD_CONNECT_CKSUM; @@ -595,7 +600,7 @@ out_md: out: kfree(data); kfree(osfs); - lprocfs_unregister_mountpoint(sbi); + ldebugfs_unregister_mountpoint(sbi); return err; } @@ -676,7 +681,7 @@ static void client_common_put_super(struct super_block *sb) * see LU-2543. */ obd_zombie_barrier(); - lprocfs_unregister_mountpoint(sbi); + ldebugfs_unregister_mountpoint(sbi); obd_fid_fini(sbi->ll_md_exp->exp_obd); obd_disconnect(sbi->ll_md_exp); @@ -904,8 +909,6 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) char *dt = NULL, *md = NULL; char *profilenm = get_profile_name(sb); struct config_llog_instance *cfg; - /* %p for void* in printf needs 16+2 characters: 0xffffffffffffffff */ - const int instlen = sizeof(cfg->cfg_instance) * 2 + 2; int err; CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb); @@ -917,7 +920,7 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) try_module_get(THIS_MODULE); /* client additional sb info */ - lsi->lsi_llsbi = sbi = ll_init_sbi(); + lsi->lsi_llsbi = sbi = ll_init_sbi(sb); if (!sbi) { module_put(THIS_MODULE); kfree(cfg); diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 83a9b85474e1..486dca6077de 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -48,31 +48,33 @@ static struct file_operations ll_rw_extents_stats_fops; static struct file_operations ll_rw_extents_stats_pp_fops; static struct file_operations ll_rw_offset_stats_fops; -static int ll_blksize_seq_show(struct seq_file *m, void *v) +static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%u\n", osfs.os_bsize); + return sprintf(buf, "%u\n", osfs.os_bsize); return rc; } -LPROC_SEQ_FOPS_RO(ll_blksize); +LUSTRE_RO_ATTR(blocksize); -static int ll_kbytestotal_seq_show(struct seq_file *m, void *v) +static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) { @@ -82,21 +84,22 @@ static int ll_kbytestotal_seq_show(struct seq_file *m, void *v) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + rc = sprintf(buf, "%llu\n", result); } return rc; } -LPROC_SEQ_FOPS_RO(ll_kbytestotal); +LUSTRE_RO_ATTR(kbytestotal); -static int ll_kbytesfree_seq_show(struct seq_file *m, void *v) +static ssize_t kbytesfree_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) { @@ -106,21 +109,22 @@ static int ll_kbytesfree_seq_show(struct seq_file *m, void *v) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + rc = sprintf(buf, "%llu\n", result); } return rc; } -LPROC_SEQ_FOPS_RO(ll_kbytesfree); +LUSTRE_RO_ATTR(kbytesfree); -static int ll_kbytesavail_seq_show(struct seq_file *m, void *v) +static ssize_t kbytesavail_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) { @@ -130,81 +134,79 @@ static int ll_kbytesavail_seq_show(struct seq_file *m, void *v) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + rc = sprintf(buf, "%llu\n", result); } return rc; } -LPROC_SEQ_FOPS_RO(ll_kbytesavail); +LUSTRE_RO_ATTR(kbytesavail); -static int ll_filestotal_seq_show(struct seq_file *m, void *v) +static ssize_t filestotal_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%llu\n", osfs.os_files); + return sprintf(buf, "%llu\n", osfs.os_files); return rc; } -LPROC_SEQ_FOPS_RO(ll_filestotal); +LUSTRE_RO_ATTR(filestotal); -static int ll_filesfree_seq_show(struct seq_file *m, void *v) +static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); struct obd_statfs osfs; int rc; - LASSERT(sb != NULL); - rc = ll_statfs_internal(sb, &osfs, + rc = ll_statfs_internal(sbi->ll_sb, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%llu\n", osfs.os_ffree); + return sprintf(buf, "%llu\n", osfs.os_ffree); return rc; } -LPROC_SEQ_FOPS_RO(ll_filesfree); +LUSTRE_RO_ATTR(filesfree); -static int ll_client_type_seq_show(struct seq_file *m, void *v) +static ssize_t client_type_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - LASSERT(sbi != NULL); - - if (sbi->ll_flags & LL_SBI_RMT_CLIENT) - seq_puts(m, "remote client\n"); - else - seq_puts(m, "local client\n"); - - return 0; + return sprintf(buf, "%s client\n", + sbi->ll_flags & LL_SBI_RMT_CLIENT ? "remote" : "local"); } -LPROC_SEQ_FOPS_RO(ll_client_type); +LUSTRE_RO_ATTR(client_type); -static int ll_fstype_seq_show(struct seq_file *m, void *v) +static ssize_t fstype_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - LASSERT(sb != NULL); - seq_printf(m, "%s\n", sb->s_type->name); - return 0; + return sprintf(buf, "%s\n", sbi->ll_sb->s_type->name); } -LPROC_SEQ_FOPS_RO(ll_fstype); +LUSTRE_RO_ATTR(fstype); -static int ll_sb_uuid_seq_show(struct seq_file *m, void *v) +static ssize_t uuid_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = (struct super_block *)m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - LASSERT(sb != NULL); - seq_printf(m, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid); - return 0; + return sprintf(buf, "%s\n", sbi->ll_sb_uuid.uuid); } -LPROC_SEQ_FOPS_RO(ll_sb_uuid); +LUSTRE_RO_ATTR(uuid); static int ll_site_stats_seq_show(struct seq_file *m, void *v) { @@ -218,10 +220,11 @@ static int ll_site_stats_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(ll_site_stats); -static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v) +static ssize_t max_read_ahead_mb_show(struct kobject *kobj, + struct attribute *attr, char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); long pages_number; int mult; @@ -230,23 +233,27 @@ static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v) spin_unlock(&sbi->ll_lock); mult = 1 << (20 - PAGE_CACHE_SHIFT); - return lprocfs_seq_read_frac_helper(m, pages_number, mult); + return lprocfs_read_frac_helper(buf, PAGE_SIZE, pages_number, mult); } -static ssize_t ll_max_readahead_mb_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_read_ahead_mb_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int mult, rc, pages_number; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long pages_number; - mult = 1 << (20 - PAGE_CACHE_SHIFT); - rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult); + rc = kstrtoul(buffer, 10, &pages_number); if (rc) return rc; - if (pages_number < 0 || pages_number > totalram_pages / 2) { + pages_number *= 1 << (20 - PAGE_CACHE_SHIFT); /* MB -> pages */ + + if (pages_number > totalram_pages / 2) { + CERROR("can't set file readahead more than %lu MB\n", totalram_pages >> (20 - PAGE_CACHE_SHIFT + 1)); /*1/2 of RAM*/ return -ERANGE; @@ -258,12 +265,14 @@ static ssize_t ll_max_readahead_mb_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_max_readahead_mb); +LUSTRE_RW_ATTR(max_read_ahead_mb); -static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v) +static ssize_t max_read_ahead_per_file_mb_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); long pages_number; int mult; @@ -272,24 +281,24 @@ static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v) spin_unlock(&sbi->ll_lock); mult = 1 << (20 - PAGE_CACHE_SHIFT); - return lprocfs_seq_read_frac_helper(m, pages_number, mult); + return lprocfs_read_frac_helper(buf, PAGE_SIZE, pages_number, mult); } -static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_read_ahead_per_file_mb_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int mult, rc, pages_number; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long pages_number; - mult = 1 << (20 - PAGE_CACHE_SHIFT); - rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult); + rc = kstrtoul(buffer, 10, &pages_number); if (rc) return rc; - if (pages_number < 0 || - pages_number > sbi->ll_ra_info.ra_max_pages) { + if (pages_number > sbi->ll_ra_info.ra_max_pages) { CERROR("can't set file readahead more than max_read_ahead_mb %lu MB\n", sbi->ll_ra_info.ra_max_pages); return -ERANGE; @@ -301,12 +310,14 @@ static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_max_readahead_per_file_mb); +LUSTRE_RW_ATTR(max_read_ahead_per_file_mb); -static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *unused) +static ssize_t max_read_ahead_whole_mb_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); long pages_number; int mult; @@ -315,26 +326,26 @@ static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *unused) spin_unlock(&sbi->ll_lock); mult = 1 << (20 - PAGE_CACHE_SHIFT); - return lprocfs_seq_read_frac_helper(m, pages_number, mult); + return lprocfs_read_frac_helper(buf, PAGE_SIZE, pages_number, mult); } -static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_read_ahead_whole_mb_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int mult, rc, pages_number; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long pages_number; - mult = 1 << (20 - PAGE_CACHE_SHIFT); - rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult); + rc = kstrtoul(buffer, 10, &pages_number); if (rc) return rc; /* Cap this at the current max readahead window size, the readahead * algorithm does this anyway so it's pointless to set it larger. */ - if (pages_number < 0 || - pages_number > sbi->ll_ra_info.ra_max_pages_per_file) { + if (pages_number > sbi->ll_ra_info.ra_max_pages_per_file) { CERROR("can't set max_read_ahead_whole_mb more than max_read_ahead_per_file_mb: %lu\n", sbi->ll_ra_info.ra_max_pages_per_file >> (20 - PAGE_CACHE_SHIFT)); return -ERANGE; @@ -346,7 +357,7 @@ static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_max_read_ahead_whole_mb); +LUSTRE_RW_ATTR(max_read_ahead_whole_mb); static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v) { @@ -469,28 +480,30 @@ out: } LPROC_SEQ_FOPS(ll_max_cached_mb); -static int ll_checksum_seq_show(struct seq_file *m, void *v) +static ssize_t checksum_pages_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - seq_printf(m, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0); - return 0; + return sprintf(buf, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0); } -static ssize_t ll_checksum_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t checksum_pages_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int val, rc; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long val; if (!sbi->ll_dt_exp) /* Not set up yet */ return -EAGAIN; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; if (val) @@ -505,154 +518,146 @@ static ssize_t ll_checksum_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_checksum); - -static int ll_max_rw_chunk_seq_show(struct seq_file *m, void *v) -{ - struct super_block *sb = m->private; - - seq_printf(m, "%lu\n", ll_s2sbi(sb)->ll_max_rw_chunk); - return 0; -} - -static ssize_t ll_max_rw_chunk_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - int rc, val; - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - ll_s2sbi(sb)->ll_max_rw_chunk = val; - return count; -} -LPROC_SEQ_FOPS(ll_max_rw_chunk); +LUSTRE_RW_ATTR(checksum_pages); -static int ll_rd_track_id(struct seq_file *m, enum stats_track_type type) +static ssize_t ll_rd_track_id(struct kobject *kobj, char *buf, + enum stats_track_type type) { - struct super_block *sb = m->private; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - if (ll_s2sbi(sb)->ll_stats_track_type == type) - seq_printf(m, "%d\n", ll_s2sbi(sb)->ll_stats_track_id); - else if (ll_s2sbi(sb)->ll_stats_track_type == STATS_TRACK_ALL) - seq_puts(m, "0 (all)\n"); + if (sbi->ll_stats_track_type == type) + return sprintf(buf, "%d\n", sbi->ll_stats_track_id); + else if (sbi->ll_stats_track_type == STATS_TRACK_ALL) + return sprintf(buf, "0 (all)\n"); else - seq_puts(m, "untracked\n"); - - return 0; + return sprintf(buf, "untracked\n"); } -static int ll_wr_track_id(const char __user *buffer, unsigned long count, - void *data, enum stats_track_type type) +static ssize_t ll_wr_track_id(struct kobject *kobj, const char *buffer, + size_t count, + enum stats_track_type type) { - struct super_block *sb = data; - int rc, pid; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long pid; - rc = lprocfs_write_helper(buffer, count, &pid); + rc = kstrtoul(buffer, 10, &pid); if (rc) return rc; - ll_s2sbi(sb)->ll_stats_track_id = pid; + sbi->ll_stats_track_id = pid; if (pid == 0) - ll_s2sbi(sb)->ll_stats_track_type = STATS_TRACK_ALL; + sbi->ll_stats_track_type = STATS_TRACK_ALL; else - ll_s2sbi(sb)->ll_stats_track_type = type; - lprocfs_clear_stats(ll_s2sbi(sb)->ll_stats); + sbi->ll_stats_track_type = type; + lprocfs_clear_stats(sbi->ll_stats); return count; } -static int ll_track_pid_seq_show(struct seq_file *m, void *v) +static ssize_t stats_track_pid_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - return ll_rd_track_id(m, STATS_TRACK_PID); + return ll_rd_track_id(kobj, buf, STATS_TRACK_PID); } -static ssize_t ll_track_pid_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t stats_track_pid_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct seq_file *seq = file->private_data; - return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PID); + return ll_wr_track_id(kobj, buffer, count, STATS_TRACK_PID); } -LPROC_SEQ_FOPS(ll_track_pid); +LUSTRE_RW_ATTR(stats_track_pid); -static int ll_track_ppid_seq_show(struct seq_file *m, void *v) +static ssize_t stats_track_ppid_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - return ll_rd_track_id(m, STATS_TRACK_PPID); + return ll_rd_track_id(kobj, buf, STATS_TRACK_PPID); } -static ssize_t ll_track_ppid_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t stats_track_ppid_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct seq_file *seq = file->private_data; - return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PPID); + return ll_wr_track_id(kobj, buffer, count, STATS_TRACK_PPID); } -LPROC_SEQ_FOPS(ll_track_ppid); +LUSTRE_RW_ATTR(stats_track_ppid); -static int ll_track_gid_seq_show(struct seq_file *m, void *v) +static ssize_t stats_track_gid_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - return ll_rd_track_id(m, STATS_TRACK_GID); + return ll_rd_track_id(kobj, buf, STATS_TRACK_GID); } -static ssize_t ll_track_gid_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t stats_track_gid_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct seq_file *seq = file->private_data; - return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_GID); + return ll_wr_track_id(kobj, buffer, count, STATS_TRACK_GID); } -LPROC_SEQ_FOPS(ll_track_gid); +LUSTRE_RW_ATTR(stats_track_gid); -static int ll_statahead_max_seq_show(struct seq_file *m, void *v) +static ssize_t statahead_max_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - seq_printf(m, "%u\n", sbi->ll_sa_max); - return 0; + return sprintf(buf, "%u\n", sbi->ll_sa_max); } -static ssize_t ll_statahead_max_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t statahead_max_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int val, rc; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; - if (val >= 0 && val <= LL_SA_RPC_MAX) + if (val <= LL_SA_RPC_MAX) sbi->ll_sa_max = val; else - CERROR("Bad statahead_max value %d. Valid values are in the range [0, %d]\n", + CERROR("Bad statahead_max value %lu. Valid values are in the range [0, %d]\n", val, LL_SA_RPC_MAX); return count; } -LPROC_SEQ_FOPS(ll_statahead_max); +LUSTRE_RW_ATTR(statahead_max); -static int ll_statahead_agl_seq_show(struct seq_file *m, void *v) +static ssize_t statahead_agl_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - seq_printf(m, "%u\n", sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0); - return 0; + return sprintf(buf, "%u\n", sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0); } -static ssize_t ll_statahead_agl_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t statahead_agl_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int val, rc; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -663,7 +668,7 @@ static ssize_t ll_statahead_agl_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_statahead_agl); +LUSTRE_RW_ATTR(statahead_agl); static int ll_statahead_stats_seq_show(struct seq_file *m, void *v) { @@ -681,24 +686,27 @@ static int ll_statahead_stats_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(ll_statahead_stats); -static int ll_lazystatfs_seq_show(struct seq_file *m, void *v) +static ssize_t lazystatfs_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - seq_printf(m, "%u\n", sbi->ll_flags & LL_SBI_LAZYSTATFS ? 1 : 0); - return 0; + return sprintf(buf, "%u\n", sbi->ll_flags & LL_SBI_LAZYSTATFS ? 1 : 0); } -static ssize_t ll_lazystatfs_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lazystatfs_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int val, rc; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -709,12 +717,14 @@ static ssize_t ll_lazystatfs_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_lazystatfs); +LUSTRE_RW_ATTR(lazystatfs); -static int ll_max_easize_seq_show(struct seq_file *m, void *v) +static ssize_t max_easize_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); unsigned int ealen; int rc; @@ -722,15 +732,16 @@ static int ll_max_easize_seq_show(struct seq_file *m, void *v) if (rc) return rc; - seq_printf(m, "%u\n", ealen); - return 0; + return sprintf(buf, "%u\n", ealen); } -LPROC_SEQ_FOPS_RO(ll_max_easize); +LUSTRE_RO_ATTR(max_easize); -static int ll_default_easize_seq_show(struct seq_file *m, void *v) +static ssize_t default_easize_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); unsigned int ealen; int rc; @@ -738,42 +749,9 @@ static int ll_default_easize_seq_show(struct seq_file *m, void *v) if (rc) return rc; - seq_printf(m, "%u\n", ealen); - return 0; -} -LPROC_SEQ_FOPS_RO(ll_default_easize); - -static int ll_max_cookiesize_seq_show(struct seq_file *m, void *v) -{ - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - unsigned int cookielen; - int rc; - - rc = ll_get_max_cookiesize(sbi, &cookielen); - if (rc) - return rc; - - seq_printf(m, "%u\n", cookielen); - return 0; -} -LPROC_SEQ_FOPS_RO(ll_max_cookiesize); - -static int ll_default_cookiesize_seq_show(struct seq_file *m, void *v) -{ - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - unsigned int cookielen; - int rc; - - rc = ll_get_default_cookiesize(sbi, &cookielen); - if (rc) - return rc; - - seq_printf(m, "%u\n", cookielen); - return 0; + return sprintf(buf, "%u\n", ealen); } -LPROC_SEQ_FOPS_RO(ll_default_cookiesize); +LUSTRE_RO_ATTR(default_easize); static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) { @@ -799,26 +777,27 @@ static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(ll_sbi_flags); -static int ll_xattr_cache_seq_show(struct seq_file *m, void *v) +static ssize_t xattr_cache_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct super_block *sb = m->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); - seq_printf(m, "%u\n", sbi->ll_xattr_cache_enabled); - - return 0; + return sprintf(buf, "%u\n", sbi->ll_xattr_cache_enabled); } -static ssize_t ll_xattr_cache_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t xattr_cache_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct seq_file *seq = file->private_data; - struct super_block *sb = seq->private; - struct ll_sb_info *sbi = ll_s2sbi(sb); - int val, rc; + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -832,46 +811,59 @@ static ssize_t ll_xattr_cache_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ll_xattr_cache); +LUSTRE_RW_ATTR(xattr_cache); static struct lprocfs_vars lprocfs_llite_obd_vars[] = { - { "uuid", &ll_sb_uuid_fops, NULL, 0 }, /* { "mntpt_path", ll_rd_path, 0, 0 }, */ - { "fstype", &ll_fstype_fops, NULL, 0 }, { "site", &ll_site_stats_fops, NULL, 0 }, - { "blocksize", &ll_blksize_fops, NULL, 0 }, - { "kbytestotal", &ll_kbytestotal_fops, NULL, 0 }, - { "kbytesfree", &ll_kbytesfree_fops, NULL, 0 }, - { "kbytesavail", &ll_kbytesavail_fops, NULL, 0 }, - { "filestotal", &ll_filestotal_fops, NULL, 0 }, - { "filesfree", &ll_filesfree_fops, NULL, 0 }, - { "client_type", &ll_client_type_fops, NULL, 0 }, /* { "filegroups", lprocfs_rd_filegroups, 0, 0 }, */ - { "max_read_ahead_mb", &ll_max_readahead_mb_fops, NULL }, - { "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops, - NULL }, - { "max_read_ahead_whole_mb", &ll_max_read_ahead_whole_mb_fops, NULL }, { "max_cached_mb", &ll_max_cached_mb_fops, NULL }, - { "checksum_pages", &ll_checksum_fops, NULL }, - { "max_rw_chunk", &ll_max_rw_chunk_fops, NULL }, - { "stats_track_pid", &ll_track_pid_fops, NULL }, - { "stats_track_ppid", &ll_track_ppid_fops, NULL }, - { "stats_track_gid", &ll_track_gid_fops, NULL }, - { "statahead_max", &ll_statahead_max_fops, NULL }, - { "statahead_agl", &ll_statahead_agl_fops, NULL }, { "statahead_stats", &ll_statahead_stats_fops, NULL, 0 }, - { "lazystatfs", &ll_lazystatfs_fops, NULL }, - { "max_easize", &ll_max_easize_fops, NULL, 0 }, - { "default_easize", &ll_default_easize_fops, NULL, 0 }, - { "max_cookiesize", &ll_max_cookiesize_fops, NULL, 0 }, - { "default_cookiesize", &ll_default_cookiesize_fops, NULL, 0 }, { "sbi_flags", &ll_sbi_flags_fops, NULL, 0 }, - { "xattr_cache", &ll_xattr_cache_fops, NULL, 0 }, { NULL } }; #define MAX_STRING_SIZE 128 +static struct attribute *llite_attrs[] = { + &lustre_attr_blocksize.attr, + &lustre_attr_kbytestotal.attr, + &lustre_attr_kbytesfree.attr, + &lustre_attr_kbytesavail.attr, + &lustre_attr_filestotal.attr, + &lustre_attr_filesfree.attr, + &lustre_attr_client_type.attr, + &lustre_attr_fstype.attr, + &lustre_attr_uuid.attr, + &lustre_attr_max_read_ahead_mb.attr, + &lustre_attr_max_read_ahead_per_file_mb.attr, + &lustre_attr_max_read_ahead_whole_mb.attr, + &lustre_attr_checksum_pages.attr, + &lustre_attr_stats_track_pid.attr, + &lustre_attr_stats_track_ppid.attr, + &lustre_attr_stats_track_gid.attr, + &lustre_attr_statahead_max.attr, + &lustre_attr_statahead_agl.attr, + &lustre_attr_lazystatfs.attr, + &lustre_attr_max_easize.attr, + &lustre_attr_default_easize.attr, + &lustre_attr_xattr_cache.attr, + NULL, +}; + +static void llite_sb_release(struct kobject *kobj) +{ + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kobj); + complete(&sbi->ll_kobj_unregister); +} + +static struct kobj_type llite_ktype = { + .default_attrs = llite_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = llite_sb_release, +}; + static const struct llite_file_opcode { __u32 opcode; __u32 type; @@ -958,24 +950,18 @@ static const char *ra_stat_string[] = { [RA_STAT_WRONG_GRAB_PAGE] = "wrong page from grab_cache_page", }; -LPROC_SEQ_FOPS_RO_TYPE(llite, name); -LPROC_SEQ_FOPS_RO_TYPE(llite, uuid); - -int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, char *osc, char *mdc) +int ldebugfs_register_mountpoint(struct dentry *parent, + struct super_block *sb, char *osc, char *mdc) { - struct lprocfs_vars lvars[2]; struct lustre_sb_info *lsi = s2lsi(sb); struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_device *obd; - struct proc_dir_entry *dir; + struct dentry *dir; char name[MAX_STRING_SIZE + 1], *ptr; int err, id, len, rc; - memset(lvars, 0, sizeof(lvars)); name[MAX_STRING_SIZE] = '\0'; - lvars[0].name = name; LASSERT(sbi != NULL); LASSERT(mdc != NULL); @@ -991,30 +977,32 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent, snprintf(name, MAX_STRING_SIZE, "%.*s-%p", len, lsi->lsi_lmd->lmd_profile, sb); - sbi->ll_proc_root = lprocfs_register(name, parent, NULL, NULL); - if (IS_ERR(sbi->ll_proc_root)) { - err = PTR_ERR(sbi->ll_proc_root); - sbi->ll_proc_root = NULL; + dir = ldebugfs_register(name, parent, NULL, NULL); + if (IS_ERR_OR_NULL(dir)) { + err = dir ? PTR_ERR(dir) : -ENOMEM; + sbi->ll_debugfs_entry = NULL; return err; } + sbi->ll_debugfs_entry = dir; - rc = lprocfs_seq_create(sbi->ll_proc_root, "dump_page_cache", 0444, - &vvp_dump_pgcache_file_ops, sbi); + rc = ldebugfs_seq_create(sbi->ll_debugfs_entry, "dump_page_cache", 0444, + &vvp_dump_pgcache_file_ops, sbi); if (rc) CWARN("Error adding the dump_page_cache file\n"); - rc = lprocfs_seq_create(sbi->ll_proc_root, "extents_stats", 0644, - &ll_rw_extents_stats_fops, sbi); + rc = ldebugfs_seq_create(sbi->ll_debugfs_entry, "extents_stats", 0644, + &ll_rw_extents_stats_fops, sbi); if (rc) CWARN("Error adding the extent_stats file\n"); - rc = lprocfs_seq_create(sbi->ll_proc_root, "extents_stats_per_process", - 0644, &ll_rw_extents_stats_pp_fops, sbi); + rc = ldebugfs_seq_create(sbi->ll_debugfs_entry, + "extents_stats_per_process", + 0644, &ll_rw_extents_stats_pp_fops, sbi); if (rc) CWARN("Error adding the extents_stats_per_process file\n"); - rc = lprocfs_seq_create(sbi->ll_proc_root, "offset_stats", 0644, - &ll_rw_offset_stats_fops, sbi); + rc = ldebugfs_seq_create(sbi->ll_debugfs_entry, "offset_stats", 0644, + &ll_rw_offset_stats_fops, sbi); if (rc) CWARN("Error adding the offset_stats file\n"); @@ -1040,7 +1028,8 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent, (type & LPROCFS_CNTR_AVGMINMAX), llite_opcode_table[id].opname, ptr); } - err = lprocfs_register_stats(sbi->ll_proc_root, "stats", sbi->ll_stats); + err = ldebugfs_register_stats(sbi->ll_debugfs_entry, "stats", + sbi->ll_stats); if (err) goto out; @@ -1054,76 +1043,53 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent, for (id = 0; id < ARRAY_SIZE(ra_stat_string); id++) lprocfs_counter_init(sbi->ll_ra_stats, id, 0, ra_stat_string[id], "pages"); - err = lprocfs_register_stats(sbi->ll_proc_root, "read_ahead_stats", + + err = ldebugfs_register_stats(sbi->ll_debugfs_entry, "read_ahead_stats", sbi->ll_ra_stats); if (err) goto out; - err = lprocfs_add_vars(sbi->ll_proc_root, lprocfs_llite_obd_vars, sb); + err = ldebugfs_add_vars(sbi->ll_debugfs_entry, + lprocfs_llite_obd_vars, sb); if (err) goto out; - /* MDC info */ - obd = class_name2obd(mdc); - - LASSERT(obd != NULL); - LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); - LASSERT(obd->obd_type->typ_name != NULL); - - dir = proc_mkdir(obd->obd_type->typ_name, sbi->ll_proc_root); - if (dir == NULL) { - err = -ENOMEM; - goto out; - } - - snprintf(name, MAX_STRING_SIZE, "common_name"); - lvars[0].fops = &llite_name_fops; - err = lprocfs_add_vars(dir, lvars, obd); + sbi->ll_kobj.kset = llite_kset; + init_completion(&sbi->ll_kobj_unregister); + err = kobject_init_and_add(&sbi->ll_kobj, &llite_ktype, NULL, + "%s", name); if (err) goto out; - snprintf(name, MAX_STRING_SIZE, "uuid"); - lvars[0].fops = &llite_uuid_fops; - err = lprocfs_add_vars(dir, lvars, obd); + /* MDC info */ + obd = class_name2obd(mdc); + + err = sysfs_create_link(&sbi->ll_kobj, &obd->obd_kobj, + obd->obd_type->typ_name); if (err) goto out; /* OSC */ obd = class_name2obd(osc); - LASSERT(obd != NULL); - LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); - LASSERT(obd->obd_type->typ_name != NULL); - - dir = proc_mkdir(obd->obd_type->typ_name, sbi->ll_proc_root); - if (dir == NULL) { - err = -ENOMEM; - goto out; - } - - snprintf(name, MAX_STRING_SIZE, "common_name"); - lvars[0].fops = &llite_name_fops; - err = lprocfs_add_vars(dir, lvars, obd); - if (err) - goto out; - - snprintf(name, MAX_STRING_SIZE, "uuid"); - lvars[0].fops = &llite_uuid_fops; - err = lprocfs_add_vars(dir, lvars, obd); + err = sysfs_create_link(&sbi->ll_kobj, &obd->obd_kobj, + obd->obd_type->typ_name); out: if (err) { - lprocfs_remove(&sbi->ll_proc_root); + ldebugfs_remove(&sbi->ll_debugfs_entry); lprocfs_free_stats(&sbi->ll_ra_stats); lprocfs_free_stats(&sbi->ll_stats); } return err; } -void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi) +void ldebugfs_unregister_mountpoint(struct ll_sb_info *sbi) { - if (sbi->ll_proc_root) { - lprocfs_remove(&sbi->ll_proc_root); + if (sbi->ll_debugfs_entry) { + ldebugfs_remove(&sbi->ll_debugfs_entry); + kobject_put(&sbi->ll_kobj); + wait_for_completion(&sbi->ll_kobj_unregister); lprocfs_free_stats(&sbi->ll_ra_stats); lprocfs_free_stats(&sbi->ll_stats); } @@ -1531,6 +1497,5 @@ LPROC_SEQ_FOPS(ll_rw_offset_stats); void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = NULL; lvars->obd_vars = lprocfs_llite_obd_vars; } diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index a494f6271fa0..e4020ce8cb7b 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -89,7 +89,6 @@ void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg)); static int __init init_lustre_lite(void) { - struct proc_dir_entry *entry; lnet_process_id_t lnet_id; struct timeval tv; int i, rc, seed[2]; @@ -128,15 +127,18 @@ static int __init init_lustre_lite(void) if (ll_rmtperm_hash_cachep == NULL) goto out_cache; - entry = lprocfs_register("llite", proc_lustre_root, NULL, NULL); - if (IS_ERR(entry)) { - rc = PTR_ERR(entry); - CERROR("cannot register '/proc/fs/lustre/llite': rc = %d\n", - rc); + llite_root = debugfs_create_dir("llite", debugfs_lustre_root); + if (IS_ERR_OR_NULL(llite_root)) { + rc = llite_root ? PTR_ERR(llite_root) : -ENOMEM; + llite_root = NULL; goto out_cache; } - proc_lustre_fs_root = entry; + llite_kset = kset_create_and_add("llite", NULL, lustre_kobj); + if (!llite_kset) { + rc = -ENOMEM; + goto out_debugfs; + } cfs_get_random_bytes(seed, sizeof(seed)); @@ -155,7 +157,7 @@ static int __init init_lustre_lite(void) setup_timer(&ll_capa_timer, ll_capa_timer_callback, 0); rc = ll_capa_thread_start(); if (rc != 0) - goto out_proc; + goto out_sysfs; rc = vvp_global_init(); if (rc != 0) @@ -176,8 +178,10 @@ out_vvp: out_capa: del_timer(&ll_capa_timer); ll_capa_thread_stop(); -out_proc: - lprocfs_remove(&proc_lustre_fs_root); +out_sysfs: + kset_unregister(llite_kset); +out_debugfs: + debugfs_remove(llite_root); out_cache: if (ll_inode_cachep != NULL) kmem_cache_destroy(ll_inode_cachep); @@ -200,7 +204,8 @@ static void __exit exit_lustre_lite(void) lustre_register_kill_super_cb(NULL); lustre_register_client_process_config(NULL); - lprocfs_remove(&proc_lustre_fs_root); + debugfs_remove(llite_root); + kset_unregister(llite_kset); ll_xattr_fini(); vvp_global_fini(); diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index fde41d7c5e3d..b8f6a8779fd3 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -253,7 +253,7 @@ int cl_sb_fini(struct super_block *sb) /**************************************************************************** * - * /proc/fs/lustre/llite/$MNT/dump_page_cache + * debugfs/lustre/llite/$MNT/dump_page_cache * ****************************************************************************/ @@ -517,7 +517,7 @@ static void vvp_pgcache_stop(struct seq_file *f, void *v) /* Nothing to do */ } -static struct seq_operations vvp_pgcache_ops = { +static const struct seq_operations vvp_pgcache_ops = { .start = vvp_pgcache_start, .next = vvp_pgcache_next, .stop = vvp_pgcache_stop, @@ -526,16 +526,17 @@ static struct seq_operations vvp_pgcache_ops = { static int vvp_dump_pgcache_seq_open(struct inode *inode, struct file *filp) { - struct ll_sb_info *sbi = PDE_DATA(inode); - struct seq_file *seq; - int result; + struct seq_file *seq; + int rc; - result = seq_open(filp, &vvp_pgcache_ops); - if (result == 0) { - seq = filp->private_data; - seq->private = sbi; - } - return result; + rc = seq_open(filp, &vvp_pgcache_ops); + if (rc) + return rc; + + seq = filp->private_data; + seq->private = inode->i_private; + + return 0; } const struct file_operations vvp_dump_pgcache_file_ops = { diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index e0fcbe1395fd..362a87d0d0d3 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -188,11 +188,11 @@ int ll_setxattr_common(struct inode *inode, const char *name, valid |= rce_ops2valid(rce->rce_ops); } #endif - oc = ll_mdscapa_get(inode); - rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid, name, pv, size, 0, flags, - ll_i2suppgid(inode), &req); - capa_put(oc); + oc = ll_mdscapa_get(inode); + rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, + valid, name, pv, size, 0, flags, + ll_i2suppgid(inode), &req); + capa_put(oc); #ifdef CONFIG_FS_POSIX_ACL if (new_value != NULL) lustre_posix_acl_xattr_free(new_value, size); diff --git a/drivers/staging/lustre/lustre/lmv/Makefile b/drivers/staging/lustre/lustre/lmv/Makefile index a7a15369af15..1a24299791d7 100644 --- a/drivers/staging/lustre/lustre/lmv/Makefile +++ b/drivers/staging/lustre/lustre/lmv/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += lmv.o -lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o -lmv-$(CONFIG_PROC_FS) += lproc_lmv.o +lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o lproc_lmv.o diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index 852d78721ca9..b808728daee7 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -144,14 +144,8 @@ struct lmv_tgt_desc *lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data, struct lu_fid *fid); /* lproc_lmv.c */ -#if defined(CONFIG_PROC_FS) void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars); -#else -static inline void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -#endif + extern struct file_operations lmv_proc_target_fops; #endif diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 8e05852ea712..aca686a2ca10 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -199,7 +199,6 @@ static int lmv_connect(const struct lu_env *env, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { - struct proc_dir_entry *lmv_proc_dir; struct lmv_obd *lmv = &obd->u.lmv; struct lustre_handle conn = { 0 }; int rc = 0; @@ -230,19 +229,8 @@ static int lmv_connect(const struct lu_env *env, if (data) lmv->conn_data = *data; - if (obd->obd_proc_private != NULL) { - lmv_proc_dir = obd->obd_proc_private; - } else { - lmv_proc_dir = lprocfs_register("target_obds", obd->obd_proc_entry, - NULL, NULL); - if (IS_ERR(lmv_proc_dir)) { - CERROR("could not register /proc/fs/lustre/%s/%s/target_obds.", - obd->obd_type->typ_name, obd->obd_name); - lmv_proc_dir = NULL; - } - obd->obd_proc_private = lmv_proc_dir; - } - + lmv->lmv_tgts_kobj = kobject_create_and_add("target_obds", + &obd->obd_kobj); /* * All real clients should perform actual connection right away, because * it is possible, that LMV will not have opportunity to connect targets @@ -252,10 +240,8 @@ static int lmv_connect(const struct lu_env *env, if (data->ocd_connect_flags & OBD_CONNECT_REAL) rc = lmv_check_connect(obd); - if (rc && lmv_proc_dir) { - lprocfs_remove(&lmv_proc_dir); - obd->obd_proc_private = NULL; - } + if (rc && lmv->lmv_tgts_kobj) + kobject_put(lmv->lmv_tgts_kobj); return rc; } @@ -337,7 +323,6 @@ static int lmv_init_ea_size(struct obd_export *exp, int easize, static int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) { - struct proc_dir_entry *lmv_proc_dir; struct lmv_obd *lmv = &obd->u.lmv; struct obd_uuid *cluuid = &lmv->cluuid; struct obd_uuid lmv_mdc_uuid = { "LMV_MDC_UUID" }; @@ -415,25 +400,10 @@ static int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) mdc_obd->obd_name, mdc_obd->obd_uuid.uuid, atomic_read(&obd->obd_refcount)); - lmv_proc_dir = obd->obd_proc_private; - if (lmv_proc_dir) { - struct proc_dir_entry *mdc_symlink; - - LASSERT(mdc_obd->obd_type != NULL); - LASSERT(mdc_obd->obd_type->typ_name != NULL); - mdc_symlink = lprocfs_add_symlink(mdc_obd->obd_name, - lmv_proc_dir, - "../../../%s/%s", - mdc_obd->obd_type->typ_name, - mdc_obd->obd_name); - if (mdc_symlink == NULL) { - CERROR("Could not register LMV target /proc/fs/lustre/%s/%s/target_obds/%s.", - obd->obd_type->typ_name, obd->obd_name, - mdc_obd->obd_name); - lprocfs_remove(&lmv_proc_dir); - obd->obd_proc_private = NULL; - } - } + if (lmv->lmv_tgts_kobj) + /* Even if we failed to create the link, that's fine */ + rc = sysfs_create_link(lmv->lmv_tgts_kobj, &mdc_obd->obd_kobj, + mdc_obd->obd_name); return 0; } @@ -610,7 +580,6 @@ int lmv_check_connect(struct obd_device *obd) static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) { - struct proc_dir_entry *lmv_proc_dir; struct lmv_obd *lmv = &obd->u.lmv; struct obd_device *mdc_obd; int rc; @@ -626,9 +595,9 @@ static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) mdc_obd->obd_no_recov = obd->obd_no_recov; } - lmv_proc_dir = obd->obd_proc_private; - if (lmv_proc_dir) - lprocfs_remove_proc_entry(mdc_obd->obd_name, lmv_proc_dir); + if (lmv->lmv_tgts_kobj) + sysfs_remove_link(lmv->lmv_tgts_kobj, + mdc_obd->obd_name); rc = obd_fid_fini(tgt->ltd_exp->exp_obd); if (rc) @@ -676,11 +645,8 @@ static int lmv_disconnect(struct obd_export *exp) lmv_disconnect_mdc(obd, lmv->tgts[i]); } - if (obd->obd_proc_private) - lprocfs_remove((struct proc_dir_entry **)&obd->obd_proc_private); - else - CERROR("/proc/fs/lustre/%s/%s/target_obds missing\n", - obd->obd_type->typ_name, obd->obd_name); + if (lmv->lmv_tgts_kobj) + kobject_put(lmv->lmv_tgts_kobj); out_local: /* @@ -1309,7 +1275,7 @@ int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { struct lmv_obd *lmv = &obd->u.lmv; - struct lprocfs_static_vars lvars; + struct lprocfs_static_vars lvars = { NULL }; struct lmv_desc *desc; int rc; @@ -1343,16 +1309,12 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg) lprocfs_lmv_init_vars(&lvars); - lprocfs_obd_setup(obd, lvars.obd_vars); -#if defined (CONFIG_PROC_FS) - { - rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", - 0444, &lmv_proc_target_fops, obd); - if (rc) - CWARN("%s: error adding LMV target_obd file: rc = %d\n", - obd->obd_name, rc); - } -#endif + lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars); + rc = ldebugfs_seq_create(obd->obd_debugfs_entry, "target_obd", + 0444, &lmv_proc_target_fops, obd); + if (rc) + CWARN("%s: error adding LMV target_obd file: rc = %d\n", + obd->obd_name, rc); rc = fld_client_init(&lmv->lmv_fld, obd->obd_name, LUSTRE_CLI_FLD_HASH_DHT); if (rc) { @@ -2311,7 +2273,7 @@ static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) * stack. */ break; case OBD_CLEANUP_EXPORTS: - fld_client_proc_fini(&lmv->lmv_fld); + fld_client_debugfs_fini(&lmv->lmv_fld); lprocfs_obd_cleanup(obd); break; default: @@ -2873,7 +2835,7 @@ static int __init lmv_init(void) lprocfs_lmv_init_vars(&lvars); rc = class_register_type(&lmv_obd_ops, &lmv_md_ops, - lvars.module_vars, LUSTRE_LMV_NAME, NULL); + LUSTRE_LMV_NAME, NULL); return rc; } diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c index 22e5c315faa4..311fc1b70c4d 100644 --- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c +++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c @@ -42,17 +42,17 @@ #include "../include/obd_class.h" #include "lmv_internal.h" -static int lmv_numobd_seq_show(struct seq_file *m, void *v) +static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = (struct obd_device *)m->private; - struct lmv_desc *desc; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + struct lmv_desc *desc; - LASSERT(dev != NULL); desc = &dev->u.lmv.desc; - seq_printf(m, "%u\n", desc->ld_tgt_count); - return 0; + return sprintf(buf, "%u\n", desc->ld_tgt_count); } -LPROC_SEQ_FOPS_RO(lmv_numobd); +LUSTRE_RO_ATTR(numobd); static const char *placement_name[] = { [PLACEMENT_CHAR_POLICY] = "CHAR", @@ -77,66 +77,61 @@ static const char *placement_policy2name(enum placement_policy placement) return placement_name[placement]; } -static int lmv_placement_seq_show(struct seq_file *m, void *v) +static ssize_t placement_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = (struct obd_device *)m->private; - struct lmv_obd *lmv; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + struct lmv_obd *lmv; - LASSERT(dev != NULL); lmv = &dev->u.lmv; - seq_printf(m, "%s\n", placement_policy2name(lmv->lmv_placement)); - return 0; + return sprintf(buf, "%s\n", placement_policy2name(lmv->lmv_placement)); } #define MAX_POLICY_STRING_SIZE 64 -static ssize_t lmv_placement_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t placement_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; - char dummy[MAX_POLICY_STRING_SIZE + 1]; - int len = count; - enum placement_policy policy; - struct lmv_obd *lmv; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + char dummy[MAX_POLICY_STRING_SIZE + 1]; + enum placement_policy policy; + struct lmv_obd *lmv = &dev->u.lmv; - if (copy_from_user(dummy, buffer, MAX_POLICY_STRING_SIZE)) - return -EFAULT; + memcpy(dummy, buffer, MAX_POLICY_STRING_SIZE); - LASSERT(dev != NULL); - lmv = &dev->u.lmv; + if (count > MAX_POLICY_STRING_SIZE) + count = MAX_POLICY_STRING_SIZE; - if (len > MAX_POLICY_STRING_SIZE) - len = MAX_POLICY_STRING_SIZE; + if (dummy[count - 1] == '\n') + count--; + dummy[count] = '\0'; - if (dummy[len - 1] == '\n') - len--; - dummy[len] = '\0'; - - policy = placement_name2policy(dummy, len); + policy = placement_name2policy(dummy, count); if (policy != PLACEMENT_INVAL_POLICY) { spin_lock(&lmv->lmv_lock); lmv->lmv_placement = policy; spin_unlock(&lmv->lmv_lock); } else { - CERROR("Invalid placement policy \"%s\"!\n", dummy); return -EINVAL; } return count; } -LPROC_SEQ_FOPS(lmv_placement); +LUSTRE_RW_ATTR(placement); -static int lmv_activeobd_seq_show(struct seq_file *m, void *v) +static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = (struct obd_device *)m->private; - struct lmv_desc *desc; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + struct lmv_desc *desc; - LASSERT(dev != NULL); desc = &dev->u.lmv.desc; - seq_printf(m, "%u\n", desc->ld_active_tgt_count); - return 0; + return sprintf(buf, "%u\n", desc->ld_active_tgt_count); } -LPROC_SEQ_FOPS_RO(lmv_activeobd); +LUSTRE_RO_ATTR(activeobd); static int lmv_desc_uuid_seq_show(struct seq_file *m, void *v) { @@ -182,7 +177,7 @@ static int lmv_tgt_seq_show(struct seq_file *p, void *v) return 0; } -static struct seq_operations lmv_tgt_sops = { +static const struct seq_operations lmv_tgt_sops = { .start = lmv_tgt_seq_start, .stop = lmv_tgt_seq_stop, .next = lmv_tgt_seq_next, @@ -199,29 +194,16 @@ static int lmv_target_seq_open(struct inode *inode, struct file *file) return rc; seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private; return 0; } -LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid); - static struct lprocfs_vars lprocfs_lmv_obd_vars[] = { - { "numobd", &lmv_numobd_fops, NULL, 0 }, - { "placement", &lmv_placement_fops, NULL, 0 }, - { "activeobd", &lmv_activeobd_fops, NULL, 0 }, - { "uuid", &lmv_uuid_fops, NULL, 0 }, { "desc_uuid", &lmv_desc_uuid_fops, NULL, 0 }, { NULL } }; -LPROC_SEQ_FOPS_RO_TYPE(lmv, numrefs); - -static struct lprocfs_vars lprocfs_lmv_module_vars[] = { - { "num_refs", &lmv_numrefs_fops, NULL, 0 }, - { NULL } -}; - struct file_operations lmv_proc_target_fops = { .owner = THIS_MODULE, .open = lmv_target_seq_open, @@ -230,8 +212,19 @@ struct file_operations lmv_proc_target_fops = { .release = seq_release, }; +static struct attribute *lmv_attrs[] = { + &lustre_attr_activeobd.attr, + &lustre_attr_numobd.attr, + &lustre_attr_placement.attr, + NULL, +}; + +static struct attribute_group lmv_attr_group = { + .attrs = lmv_attrs, +}; + void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_lmv_module_vars; + lvars->sysfs_vars = &lmv_attr_group; lvars->obd_vars = lprocfs_lmv_obd_vars; } diff --git a/drivers/staging/lustre/lustre/lov/Makefile b/drivers/staging/lustre/lustre/lov/Makefile index 6fe56a24b165..e4cc0db21014 100644 --- a/drivers/staging/lustre/lustre/lov/Makefile +++ b/drivers/staging/lustre/lustre/lov/Makefile @@ -2,5 +2,4 @@ obj-$(CONFIG_LUSTRE_FS) += lov.o lov-y := lov_obd.o lov_pack.o lov_offset.o lov_merge.o \ lov_request.o lov_ea.o lov_dev.o lov_object.o lov_page.o \ lov_lock.o lov_io.o lovsub_dev.o lovsub_object.o lovsub_page.o \ - lovsub_lock.o lovsub_io.o lov_pool.o -lov-$(CONFIG_PROC_FS) += lproc_lov.o + lovsub_lock.o lovsub_io.o lov_pool.o lproc_lov.o diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index b644acc9b034..dde9656d4dd6 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -71,13 +71,6 @@ }) #endif -struct lov_lock_handles { - struct portals_handle llh_handle; - atomic_t llh_refcount; - int llh_stripe_count; - struct lustre_handle llh_handles[0]; -}; - struct lov_request { struct obd_info rq_oi; struct lov_request_set *rq_rqset; @@ -88,7 +81,6 @@ struct lov_request { int rq_stripe; /* stripe number */ int rq_complete; int rq_rc; - int rq_buflen; /* length of sub_md */ u32 rq_oabufs; u32 rq_pgaidx; @@ -109,9 +101,6 @@ struct lov_request_set { struct llog_cookie *set_cookies; int set_cookie_sent; struct obd_trans_info *set_oti; - u32 set_oabufs; - struct brw_page *set_pga; - struct lov_lock_handles *set_lockh; struct list_head set_list; wait_queue_head_t set_waitq; spinlock_t set_lock; @@ -136,32 +125,6 @@ static inline void lov_put_reqset(struct lov_request_set *set) lov_finish_set(set); } -static inline struct lov_lock_handles * -lov_handle2llh(struct lustre_handle *handle) -{ - LASSERT(handle != NULL); - return class_handle2object(handle->cookie); -} - -static inline void lov_llh_put(struct lov_lock_handles *llh) -{ - CDEBUG(D_INFO, "PUTting llh %p : new refcount %d\n", llh, - atomic_read(&llh->llh_refcount) - 1); - LASSERT(atomic_read(&llh->llh_refcount) > 0 && - atomic_read(&llh->llh_refcount) < 0x5a5a); - if (atomic_dec_and_test(&llh->llh_refcount)) { - class_handle_unhash(&llh->llh_handle); - /* The structure may be held by other threads because RCU. - * -jxiong */ - if (atomic_read(&llh->llh_refcount)) - return; - - OBD_FREE_RCU(llh, sizeof(*llh) + - sizeof(*llh->llh_handles) * llh->llh_stripe_count, - &llh->llh_handle); - } -} - #define lov_uuid2str(lv, index) \ (char *)((lv)->lov_tgts[index]->ltd_uuid.uuid) @@ -265,15 +228,8 @@ void lsm_free_plain(struct lov_stripe_md *lsm); void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm); /* lproc_lov.c */ -#if defined (CONFIG_PROC_FS) extern const struct file_operations lov_proc_target_fops; void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars); -#else -static inline void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -#endif /* lov_cl.c */ extern struct lu_device_type lov_device_type; diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 054ca32099c8..ca1caaea2701 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -127,7 +127,6 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, struct obd_device *tgt_obd; static struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" }; struct obd_import *imp; - struct proc_dir_entry *lov_proc_dir; int rc; if (!lov->lov_tgts[index]) @@ -186,28 +185,10 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, CDEBUG(D_CONFIG, "Connected tgt idx %d %s (%s) %sactive\n", index, obd_uuid2str(tgt_uuid), tgt_obd->obd_name, activate ? "":"in"); - lov_proc_dir = obd->obd_proc_private; - if (lov_proc_dir) { - struct obd_device *osc_obd = lov->lov_tgts[index]->ltd_exp->exp_obd; - struct proc_dir_entry *osc_symlink; - - LASSERT(osc_obd != NULL); - LASSERT(osc_obd->obd_magic == OBD_DEVICE_MAGIC); - LASSERT(osc_obd->obd_type->typ_name != NULL); - - osc_symlink = lprocfs_add_symlink(osc_obd->obd_name, - lov_proc_dir, - "../../../%s/%s", - osc_obd->obd_type->typ_name, - osc_obd->obd_name); - if (osc_symlink == NULL) { - CERROR("could not register LOV target /proc/fs/lustre/%s/%s/target_obds/%s.", - obd->obd_type->typ_name, obd->obd_name, - osc_obd->obd_name); - lprocfs_remove(&lov_proc_dir); - obd->obd_proc_private = NULL; - } - } + if (lov->lov_tgts_kobj) + /* Even if we failed, that's ok */ + rc = sysfs_create_link(lov->lov_tgts_kobj, &tgt_obd->obd_kobj, + tgt_obd->obd_name); return 0; } @@ -239,6 +220,10 @@ static int lov_connect(const struct lu_env *env, lov->lov_ocd = *data; obd_getref(obd); + + lov->lov_tgts_kobj = kobject_create_and_add("target_obds", + &obd->obd_kobj); + for (i = 0; i < lov->desc.ld_tgt_count; i++) { tgt = lov->lov_tgts[i]; if (!tgt || obd_uuid_empty(&tgt->ltd_uuid)) @@ -268,7 +253,6 @@ static int lov_connect(const struct lu_env *env, static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt) { - struct proc_dir_entry *lov_proc_dir; struct lov_obd *lov = &obd->u.lov; struct obd_device *osc_obd; int rc; @@ -284,10 +268,10 @@ static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt) } if (osc_obd) { - lov_proc_dir = obd->obd_proc_private; - if (lov_proc_dir) { - lprocfs_remove_proc_entry(osc_obd->obd_name, lov_proc_dir); - } + if (lov->lov_tgts_kobj) + sysfs_remove_link(lov->lov_tgts_kobj, + osc_obd->obd_name); + /* Pass it on to our clients. * XXX This should be an argument to disconnect, * XXX not a back-door flag on the OBD. Ah well. @@ -337,6 +321,10 @@ static int lov_disconnect(struct obd_export *exp) lov_del_target(obd, i, NULL, lov->lov_tgts[i]->ltd_gen); } } + + if (lov->lov_tgts_kobj) + kobject_put(lov->lov_tgts_kobj); + obd_putref(obd); out: @@ -821,21 +809,16 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg) goto out; lprocfs_lov_init_vars(&lvars); - lprocfs_obd_setup(obd, lvars.obd_vars); -#if defined (CONFIG_PROC_FS) - { - int rc1; + lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars); - rc1 = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", - 0444, &lov_proc_target_fops, obd); - if (rc1) - CWARN("Error adding the target_obd file\n"); - } -#endif - lov->lov_pool_proc_entry = lprocfs_register("pools", - obd->obd_proc_entry, - NULL, NULL); + rc = ldebugfs_seq_create(obd->obd_debugfs_entry, "target_obd", + 0444, &lov_proc_target_fops, obd); + if (rc) + CWARN("Error adding the target_obd file\n"); + lov->lov_pool_debugfs_entry = ldebugfs_register("pools", + obd->obd_debugfs_entry, + NULL, NULL); return 0; out: @@ -1417,7 +1400,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, __u32 flags; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - if ((index >= count)) + if (index >= count) return -ENODEV; if (!lov->lov_tgts[index]) @@ -2365,7 +2348,7 @@ static int __init lov_init(void) } lprocfs_lov_init_vars(&lvars); - rc = class_register_type(&lov_obd_ops, NULL, lvars.module_vars, + rc = class_register_type(&lov_obd_ops, NULL, LUSTRE_LOV_NAME, &lov_device_type); if (rc) { diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 5356d5324176..92b9ffece4a0 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -367,9 +367,11 @@ int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, if (rc) return rc; magic = le32_to_cpu(lmm->lmm_magic); + pattern = le32_to_cpu(lmm->lmm_pattern); } else { magic = LOV_MAGIC; stripe_count = lov_get_stripecnt(lov, magic, 0); + pattern = LOV_PATTERN_RAID0; } /* If we aren't passed an lsmp struct, we just want the size */ @@ -384,7 +386,6 @@ int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, return 0; } - pattern = le32_to_cpu(lmm->lmm_pattern); lsm_size = lov_alloc_memmd(lsmp, stripe_count, pattern, magic); if (lsm_size < 0) return lsm_size; diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c index 75301fa066a0..1e4d3fbee323 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pool.c +++ b/drivers/staging/lustre/lustre/lov/lov_pool.c @@ -64,7 +64,7 @@ void lov_pool_putref(struct pool_desc *pool) if (atomic_dec_and_test(&pool->pool_refcount)) { LASSERT(hlist_unhashed(&pool->pool_hash)); LASSERT(list_empty(&pool->pool_list)); - LASSERT(pool->pool_proc_entry == NULL); + LASSERT(pool->pool_debugfs_entry == NULL); lov_ost_pool_free(&(pool->pool_rr.lqr_pool)); lov_ost_pool_free(&(pool->pool_obds)); kfree(pool); @@ -152,7 +152,6 @@ cfs_hash_ops_t pool_hash_operations = { }; -#if defined (CONFIG_PROC_FS) /* ifdef needed for liblustre support */ /* * pool /proc seq_file methods @@ -269,7 +268,7 @@ static int pool_proc_show(struct seq_file *s, void *v) return 0; } -static struct seq_operations pool_proc_ops = { +static const struct seq_operations pool_proc_ops = { .start = pool_proc_start, .next = pool_proc_next, .stop = pool_proc_stop, @@ -283,7 +282,7 @@ static int pool_proc_open(struct inode *inode, struct file *file) rc = seq_open(file, &pool_proc_ops); if (!rc) { struct seq_file *s = file->private_data; - s->private = PDE_DATA(inode); + s->private = inode->i_private; } return rc; } @@ -294,7 +293,6 @@ static struct file_operations pool_proc_operations = { .llseek = seq_lseek, .release = seq_release, }; -#endif /* CONFIG_PROC_FS */ void lov_dump_pool(int level, struct pool_desc *pool) { @@ -454,20 +452,21 @@ int lov_pool_new(struct obd_device *obd, char *poolname) INIT_HLIST_NODE(&new_pool->pool_hash); -#if defined (CONFIG_PROC_FS) /* we need this assert seq_file is not implemented for liblustre */ /* get ref for /proc file */ lov_pool_getref(new_pool); - new_pool->pool_proc_entry = lprocfs_add_simple(lov->lov_pool_proc_entry, - poolname, new_pool, - &pool_proc_operations); - if (IS_ERR(new_pool->pool_proc_entry)) { - CWARN("Cannot add proc pool entry "LOV_POOLNAMEF"\n", poolname); - new_pool->pool_proc_entry = NULL; + new_pool->pool_debugfs_entry = ldebugfs_add_simple( + lov->lov_pool_debugfs_entry, + poolname, new_pool, + &pool_proc_operations); + if (IS_ERR_OR_NULL(new_pool->pool_debugfs_entry)) { + CWARN("Cannot add debugfs pool entry "LOV_POOLNAMEF"\n", + poolname); + new_pool->pool_debugfs_entry = NULL; lov_pool_putref(new_pool); } - CDEBUG(D_INFO, "pool %p - proc %p\n", new_pool, new_pool->pool_proc_entry); -#endif + CDEBUG(D_INFO, "pool %p - proc %p\n", + new_pool, new_pool->pool_debugfs_entry); spin_lock(&obd->obd_dev_lock); list_add_tail(&new_pool->pool_list, &lov->lov_pool_list); @@ -493,7 +492,7 @@ out_err: lov->lov_pool_count--; spin_unlock(&obd->obd_dev_lock); - lprocfs_remove(&new_pool->pool_proc_entry); + ldebugfs_remove(&new_pool->pool_debugfs_entry); lov_ost_pool_free(&new_pool->pool_rr.lqr_pool); out_free_pool_obds: @@ -514,9 +513,9 @@ int lov_pool_del(struct obd_device *obd, char *poolname) if (pool == NULL) return -ENOENT; - if (pool->pool_proc_entry != NULL) { - CDEBUG(D_INFO, "proc entry %p\n", pool->pool_proc_entry); - lprocfs_remove(&pool->pool_proc_entry); + if (!IS_ERR_OR_NULL(pool->pool_debugfs_entry)) { + CDEBUG(D_INFO, "proc entry %p\n", pool->pool_debugfs_entry); + ldebugfs_remove(&pool->pool_debugfs_entry); lov_pool_putref(pool); } diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index f6e13149d2ad..f4de8b84c5c2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -68,19 +68,9 @@ void lov_finish_set(struct lov_request_set *set) if (req->rq_oi.oi_oa) OBDO_FREE(req->rq_oi.oi_oa); - if (req->rq_oi.oi_md) - OBD_FREE_LARGE(req->rq_oi.oi_md, req->rq_buflen); kfree(req->rq_oi.oi_osfs); kfree(req); } - - if (set->set_pga) { - int len = set->set_oabufs * sizeof(*set->set_pga); - OBD_FREE_LARGE(set->set_pga, len); - } - if (set->set_lockh) - lov_llh_put(set->set_lockh); - kfree(set); } @@ -617,8 +607,7 @@ void lov_update_statfs(struct obd_statfs *osfs, struct obd_statfs *lov_sfs, if (tmp & 1) { if (quit) break; - else - quit = 1; + quit = 1; shift = 0; } tmp >>= 1; diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c index 174cbf5c138f..380b8271bf24 100644 --- a/drivers/staging/lustre/lustre/lov/lproc_lov.c +++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c @@ -166,29 +166,29 @@ static ssize_t lov_stripecount_seq_write(struct file *file, } LPROC_SEQ_FOPS(lov_stripecount); -static int lov_numobd_seq_show(struct seq_file *m, void *v) +static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = (struct obd_device *)m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct lov_desc *desc; - LASSERT(dev != NULL); desc = &dev->u.lov.desc; - seq_printf(m, "%u\n", desc->ld_tgt_count); - return 0; + return sprintf(buf, "%u\n", desc->ld_tgt_count); } -LPROC_SEQ_FOPS_RO(lov_numobd); +LUSTRE_RO_ATTR(numobd); -static int lov_activeobd_seq_show(struct seq_file *m, void *v) +static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = (struct obd_device *)m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct lov_desc *desc; - LASSERT(dev != NULL); desc = &dev->u.lov.desc; - seq_printf(m, "%u\n", desc->ld_active_tgt_count); - return 0; + return sprintf(buf, "%u\n", desc->ld_active_tgt_count); } -LPROC_SEQ_FOPS_RO(lov_activeobd); +LUSTRE_RO_ATTR(activeobd); static int lov_desc_uuid_seq_show(struct seq_file *m, void *v) { @@ -258,48 +258,34 @@ static int lov_target_seq_open(struct inode *inode, struct file *file) return rc; seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private; return 0; } -LPROC_SEQ_FOPS_RO_TYPE(lov, uuid); -LPROC_SEQ_FOPS_RO_TYPE(lov, filestotal); -LPROC_SEQ_FOPS_RO_TYPE(lov, filesfree); -LPROC_SEQ_FOPS_RO_TYPE(lov, blksize); -LPROC_SEQ_FOPS_RO_TYPE(lov, kbytestotal); -LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesfree); -LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesavail); - static struct lprocfs_vars lprocfs_lov_obd_vars[] = { - { "uuid", &lov_uuid_fops, NULL, 0 }, { "stripesize", &lov_stripesize_fops, NULL }, { "stripeoffset", &lov_stripeoffset_fops, NULL }, { "stripecount", &lov_stripecount_fops, NULL }, { "stripetype", &lov_stripetype_fops, NULL }, - { "numobd", &lov_numobd_fops, NULL, 0 }, - { "activeobd", &lov_activeobd_fops, NULL, 0 }, - { "filestotal", &lov_filestotal_fops, NULL, 0 }, - { "filesfree", &lov_filesfree_fops, NULL, 0 }, /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/ - { "blocksize", &lov_blksize_fops, NULL, 0 }, - { "kbytestotal", &lov_kbytestotal_fops, NULL, 0 }, - { "kbytesfree", &lov_kbytesfree_fops, NULL, 0 }, - { "kbytesavail", &lov_kbytesavail_fops, NULL, 0 }, { "desc_uuid", &lov_desc_uuid_fops, NULL, 0 }, { NULL } }; -LPROC_SEQ_FOPS_RO_TYPE(lov, numrefs); +static struct attribute *lov_attrs[] = { + &lustre_attr_activeobd.attr, + &lustre_attr_numobd.attr, + NULL, +}; -static struct lprocfs_vars lprocfs_lov_module_vars[] = { - { "num_refs", &lov_numrefs_fops, NULL, 0 }, - { NULL } +static struct attribute_group lov_attr_group = { + .attrs = lov_attrs, }; void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_lov_module_vars; - lvars->obd_vars = lprocfs_lov_obd_vars; + lvars->sysfs_vars = &lov_attr_group; + lvars->obd_vars = lprocfs_lov_obd_vars; } const struct file_operations lov_proc_target_fops = { diff --git a/drivers/staging/lustre/lustre/mdc/Makefile b/drivers/staging/lustre/lustre/mdc/Makefile index 2516551a6dc3..99ba9ff0d83a 100644 --- a/drivers/staging/lustre/lustre/mdc/Makefile +++ b/drivers/staging/lustre/lustre/mdc/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += mdc.o -mdc-y := mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o -mdc-$(CONFIG_PROC_FS) += lproc_mdc.o +mdc-y := mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o lproc_mdc.o diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index 23d22a4a606e..1c95f87a0e2a 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -40,29 +40,34 @@ #include "../include/lprocfs_status.h" #include "mdc_internal.h" -static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v) +static ssize_t max_rpcs_in_flight_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + int len; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; client_obd_list_lock(&cli->cl_loi_list_lock); - seq_printf(m, "%u\n", cli->cl_max_rpcs_in_flight); + len = sprintf(buf, "%u\n", cli->cl_max_rpcs_in_flight); client_obd_list_unlock(&cli->cl_loi_list_lock); - return 0; + return len; } -static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file, - const char __user *buffer, - size_t count, - loff_t *off) +static ssize_t max_rpcs_in_flight_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = - ((struct seq_file *)file->private_data)->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; - int val, rc; + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -75,11 +80,11 @@ static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(mdc_max_rpcs_in_flight); +LUSTRE_RW_ATTR(max_rpcs_in_flight); static int mdc_kuc_open(struct inode *inode, struct file *file) { - return single_open(file, NULL, PDE_DATA(inode)); + return single_open(file, NULL, inode->i_private); } /* temporary for testing */ @@ -155,49 +160,39 @@ static struct file_operations mdc_kuc_fops = { LPROC_SEQ_FOPS_WR_ONLY(mdc, ping); -LPROC_SEQ_FOPS_RO_TYPE(mdc, uuid); LPROC_SEQ_FOPS_RO_TYPE(mdc, connect_flags); -LPROC_SEQ_FOPS_RO_TYPE(mdc, blksize); -LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytestotal); -LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytesfree); -LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytesavail); -LPROC_SEQ_FOPS_RO_TYPE(mdc, filestotal); -LPROC_SEQ_FOPS_RO_TYPE(mdc, filesfree); LPROC_SEQ_FOPS_RO_TYPE(mdc, server_uuid); LPROC_SEQ_FOPS_RO_TYPE(mdc, conn_uuid); LPROC_SEQ_FOPS_RO_TYPE(mdc, timeouts); LPROC_SEQ_FOPS_RO_TYPE(mdc, state); -static int mdc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v) +/* + * Note: below sysfs entry is provided, but not currently in use, instead + * sbi->sb_md_brw_size is used, the per obd variable should be used + * when DNE is enabled, and dir pages are managed in MDC layer. + * Don't forget to enable sysfs store function then. + */ +static ssize_t max_pages_per_rpc_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - return lprocfs_obd_rd_max_pages_per_rpc(m, m->private); + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + struct client_obd *cli = &dev->u.cli; + + return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); } -LPROC_SEQ_FOPS_RO(mdc_obd_max_pages_per_rpc); +LUSTRE_RO_ATTR(max_pages_per_rpc); LPROC_SEQ_FOPS_RW_TYPE(mdc, import); LPROC_SEQ_FOPS_RW_TYPE(mdc, pinger_recov); static struct lprocfs_vars lprocfs_mdc_obd_vars[] = { - { "uuid", &mdc_uuid_fops, NULL, 0 }, { "ping", &mdc_ping_fops, NULL, 0222 }, { "connect_flags", &mdc_connect_flags_fops, NULL, 0 }, - { "blocksize", &mdc_blksize_fops, NULL, 0 }, - { "kbytestotal", &mdc_kbytestotal_fops, NULL, 0 }, - { "kbytesfree", &mdc_kbytesfree_fops, NULL, 0 }, - { "kbytesavail", &mdc_kbytesavail_fops, NULL, 0 }, - { "filestotal", &mdc_filestotal_fops, NULL, 0 }, - { "filesfree", &mdc_filesfree_fops, NULL, 0 }, /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/ { "mds_server_uuid", &mdc_server_uuid_fops, NULL, 0 }, { "mds_conn_uuid", &mdc_conn_uuid_fops, NULL, 0 }, - /* - * FIXME: below proc entry is provided, but not in used, instead - * sbi->sb_md_brw_size is used, the per obd variable should be used - * when CMD is enabled, and dir pages are managed in MDC layer. - * Remember to enable proc write function. - */ - { "max_pages_per_rpc", &mdc_obd_max_pages_per_rpc_fops, NULL, 0 }, - { "max_rpcs_in_flight", &mdc_max_rpcs_in_flight_fops, NULL, 0 }, { "timeouts", &mdc_timeouts_fops, NULL, 0 }, { "import", &mdc_import_fops, NULL, 0 }, { "state", &mdc_state_fops, NULL, 0 }, @@ -206,15 +201,18 @@ static struct lprocfs_vars lprocfs_mdc_obd_vars[] = { { NULL } }; -LPROC_SEQ_FOPS_RO_TYPE(mdc, numrefs); +static struct attribute *mdc_attrs[] = { + &lustre_attr_max_rpcs_in_flight.attr, + &lustre_attr_max_pages_per_rpc.attr, + NULL, +}; -static struct lprocfs_vars lprocfs_mdc_module_vars[] = { - { "num_refs", &mdc_numrefs_fops, NULL, 0 }, - { NULL } +static struct attribute_group mdc_attr_group = { + .attrs = mdc_attrs, }; void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_mdc_module_vars; + lvars->sysfs_vars = &mdc_attr_group; lvars->obd_vars = lprocfs_mdc_obd_vars; } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index 81780c943a08..4d149435e949 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -40,14 +40,7 @@ #include "../include/lustre_mdc.h" #include "../include/lustre_mds.h" -#if defined CONFIG_PROC_FS void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars); -#else -static inline void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -#endif void mdc_pack_body(struct ptlrpc_request *req, const struct lu_fid *fid, struct obd_capa *oc, __u64 valid, int ea_size, diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index cbbdfceb9b2a..c23511f7c142 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -75,11 +75,11 @@ static int mdc_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req, if (IS_ERR(c)) { CDEBUG(D_INFO, "alloc capa failed!\n"); return PTR_ERR(c); - } else { - c->c_capa = *capa; - *oc = c; - return 0; } + + c->c_capa = *capa; + *oc = c; + return 0; } static inline int mdc_queue_wait(struct ptlrpc_request *req) @@ -1818,10 +1818,7 @@ static int mdc_ioc_swap_layouts(struct obd_export *exp, ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); - if (rc) - goto out; -out: ptlrpc_req_finished(req); return rc; } @@ -2447,7 +2444,7 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) if (rc) goto err_close_lock; lprocfs_mdc_init_vars(&lvars); - lprocfs_obd_setup(obd, lvars.obd_vars); + lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars); sptlrpc_lprocfs_cliobd_attach(obd); ptlrpc_lprocfs_register_obd(obd); @@ -2713,7 +2710,7 @@ static int __init mdc_init(void) lprocfs_mdc_init_vars(&lvars); - return class_register_type(&mdc_obd_ops, &mdc_md_ops, lvars.module_vars, + return class_register_type(&mdc_obd_ops, &mdc_md_ops, LUSTRE_MDC_NAME, NULL); } diff --git a/drivers/staging/lustre/lustre/mgc/Makefile b/drivers/staging/lustre/lustre/mgc/Makefile index cc6e9f51a8e8..8ea29a89cf50 100644 --- a/drivers/staging/lustre/lustre/mgc/Makefile +++ b/drivers/staging/lustre/lustre/mgc/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += mgc.o -mgc-y := mgc_request.o -mgc-$(CONFIG_PROC_FS) += lproc_mgc.o +mgc-y := mgc_request.o lproc_mgc.o diff --git a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c index c4ea38e5f077..34a9317d6d63 100644 --- a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c +++ b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c @@ -40,7 +40,6 @@ #include "../include/lprocfs_status.h" #include "mgc_internal.h" -LPROC_SEQ_FOPS_RO_TYPE(mgc, uuid); LPROC_SEQ_FOPS_RO_TYPE(mgc, connect_flags); LPROC_SEQ_FOPS_RO_TYPE(mgc, server_uuid); LPROC_SEQ_FOPS_RO_TYPE(mgc, conn_uuid); @@ -56,7 +55,6 @@ static int mgc_ir_state_seq_show(struct seq_file *m, void *v) LPROC_SEQ_FOPS_RO(mgc_ir_state); static struct lprocfs_vars lprocfs_mgc_obd_vars[] = { - { "uuid", &mgc_uuid_fops, NULL, 0 }, { "ping", &mgc_ping_fops, NULL, 0222 }, { "connect_flags", &mgc_connect_flags_fops, NULL, 0 }, { "mgs_server_uuid", &mgc_server_uuid_fops, NULL, 0 }, @@ -67,14 +65,7 @@ static struct lprocfs_vars lprocfs_mgc_obd_vars[] = { { NULL } }; -LPROC_SEQ_FOPS_RO_TYPE(mgc, numrefs); -static struct lprocfs_vars lprocfs_mgc_module_vars[] = { - { "num_refs", &mgc_numrefs_fops, NULL, 0 }, - { NULL } -}; - void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_mgc_module_vars; lvars->obd_vars = lprocfs_mgc_obd_vars; } diff --git a/drivers/staging/lustre/lustre/mgc/mgc_internal.h b/drivers/staging/lustre/lustre/mgc/mgc_internal.h index a6f8b3ced2e7..82fb8f46e037 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_internal.h +++ b/drivers/staging/lustre/lustre/mgc/mgc_internal.h @@ -44,19 +44,8 @@ #include "../include/lustre_log.h" #include "../include/lustre_export.h" -#if defined (CONFIG_PROC_FS) void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars); int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data); -#else -static inline void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -static inline int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) -{ - return 0; -} -#endif /* CONFIG_PROC_FS */ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld); diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index f152e5ceb941..174dfc32876b 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -448,7 +448,6 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) return rc; } -#if defined (CONFIG_PROC_FS) int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) { struct obd_device *obd = data; @@ -477,7 +476,6 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) LPROCFS_CLIMP_EXIT(obd); return 0; } -#endif /* reenqueue any lost locks */ #define RQ_RUNNING 0x1 @@ -722,7 +720,7 @@ static int mgc_cleanup(struct obd_device *obd) static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { - struct lprocfs_static_vars lvars; + struct lprocfs_static_vars lvars = { NULL }; int rc; ptlrpcd_addref(); @@ -738,7 +736,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) } lprocfs_mgc_init_vars(&lvars); - lprocfs_obd_setup(obd, lvars.obd_vars); + lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars); sptlrpc_lprocfs_cliobd_attach(obd); if (atomic_inc_return(&mgc_count) == 1) { @@ -1745,7 +1743,7 @@ struct obd_ops mgc_obd_ops = { static int __init mgc_init(void) { - return class_register_type(&mgc_obd_ops, NULL, NULL, + return class_register_type(&mgc_obd_ops, NULL, LUSTRE_MGC_NAME, NULL); } diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile index e894681797c2..d0f70b41acf6 100644 --- a/drivers/staging/lustre/lustre/obdclass/Makefile +++ b/drivers/staging/lustre/lustre/obdclass/Makefile @@ -6,6 +6,4 @@ obdclass-y := linux/linux-module.o linux/linux-obdo.o linux/linux-sysctl.o \ lustre_handles.o lustre_peer.o \ statfs_pack.o obdo.o obd_config.o obd_mount.o \ lu_object.o dt_object.o capa.o cl_object.o \ - cl_page.o cl_lock.o cl_io.o lu_ref.o acl.o - -obdclass-$(CONFIG_PROC_FS) += lprocfs_counters.o + cl_page.o cl_lock.o cl_io.o lu_ref.o acl.o lprocfs_counters.o diff --git a/drivers/staging/lustre/lustre/obdclass/acl.c b/drivers/staging/lustre/lustre/obdclass/acl.c index 194c48a29205..bc3fc4780cb9 100644 --- a/drivers/staging/lustre/lustre/obdclass/acl.c +++ b/drivers/staging/lustre/lustre/obdclass/acl.c @@ -120,7 +120,6 @@ static int lustre_ext_acl_xattr_reduce_space(ext_acl_xattr_header **header, { int ext_count = le32_to_cpu((*header)->a_count); int ext_size = CFS_ACL_XATTR_SIZE(ext_count, ext_acl_xattr); - int old_size = CFS_ACL_XATTR_SIZE(old_count, ext_acl_xattr); ext_acl_xattr_header *new; if (unlikely(old_count <= ext_count)) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index f13d1fbffd9d..163fe0cd7f9a 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -906,10 +906,8 @@ struct lu_env *cl_env_nested_get(struct cl_env_nest *nest) if (env != NULL) { if (!cl_io_is_going(env)) return env; - else { - cl_env_put(env, &nest->cen_refcheck); - nest->cen_cookie = cl_env_reenter(); - } + cl_env_put(env, &nest->cen_refcheck); + nest->cen_cookie = cl_env_reenter(); } env = cl_env_get(&nest->cen_refcheck); if (IS_ERR(env)) { diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 88735530f91b..a7f3032f34dd 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -62,12 +62,6 @@ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg, # define PINVRNT(env, page, exp) \ ((void)sizeof(env), (void)sizeof(page), (void)sizeof !!(exp)) -/* Disable page statistic by default due to huge performance penalty. */ -#define CS_PAGE_INC(o, item) -#define CS_PAGE_DEC(o, item) -#define CS_PAGESTATE_INC(o, state) -#define CS_PAGESTATE_DEC(o, state) - /** * Internal version of cl_page_top, it should be called if the page is * known to be not freed, says with page referenced, or radix tree lock held, @@ -248,7 +242,6 @@ EXPORT_SYMBOL(cl_page_gang_lookup); static void cl_page_free(const struct lu_env *env, struct cl_page *page) { struct cl_object *obj = page->cp_obj; - int pagesize = cl_object_header(obj)->coh_page_bufsize; PASSERT(env, page, list_empty(&page->cp_batch)); PASSERT(env, page, page->cp_owner == NULL); @@ -265,8 +258,6 @@ static void cl_page_free(const struct lu_env *env, struct cl_page *page) list_del_init(page->cp_layers.next); slice->cpl_ops->cpo_fini(env, slice); } - CS_PAGE_DEC(obj, total); - CS_PAGESTATE_DEC(obj, page->cp_state); lu_object_ref_del_at(&obj->co_lu, &page->cp_obj_ref, "cl_page", page); cl_object_put(env, obj); lu_ref_fini(&page->cp_reference); @@ -324,11 +315,6 @@ static struct cl_page *cl_page_alloc(const struct lu_env *env, } } } - if (result == 0) { - CS_PAGE_INC(o, total); - CS_PAGE_INC(o, create); - CS_PAGESTATE_DEC(o, CPS_CACHED); - } } else { page = ERR_PTR(-ENOMEM); } @@ -361,7 +347,6 @@ static struct cl_page *cl_page_find0(const struct lu_env *env, might_sleep(); hdr = cl_object_header(o); - CS_PAGE_INC(o, lookup); CDEBUG(D_PAGE, "%lu@"DFID" %p %lx %d\n", idx, PFID(&hdr->coh_lu.loh_fid), vmpage, vmpage->private, type); @@ -388,7 +373,6 @@ static struct cl_page *cl_page_find0(const struct lu_env *env, } if (page != NULL) { - CS_PAGE_INC(o, hit); return page; } @@ -555,8 +539,6 @@ static void cl_page_state_set0(const struct lu_env *env, PASSERT(env, page, equi(state == CPS_OWNED, page->cp_owner != NULL)); - CS_PAGESTATE_DEC(page->cp_obj, page->cp_state); - CS_PAGESTATE_INC(page->cp_obj, state); cl_page_state_set_trust(page, state); } } diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 6e967af2f6b4..1bc37566b3a5 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -506,15 +506,8 @@ int obd_init_checks(void) return ret; } -#if defined (CONFIG_PROC_FS) extern int class_procfs_init(void); extern int class_procfs_clean(void); -#else -static inline int class_procfs_init(void) -{ return 0; } -static inline int class_procfs_clean(void) -{ return 0; } -#endif static int __init init_obdclass(void) { @@ -529,24 +522,22 @@ static int __init init_obdclass(void) spin_lock_init(&obd_types_lock); obd_zombie_impexp_init(); - if (IS_ENABLED(CONFIG_PROC_FS)) { - obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM, - LPROCFS_STATS_FLAG_NONE | - LPROCFS_STATS_FLAG_IRQ_SAFE); + obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM, + LPROCFS_STATS_FLAG_NONE | + LPROCFS_STATS_FLAG_IRQ_SAFE); - if (obd_memory == NULL) { - CERROR("kmalloc of 'obd_memory' failed\n"); - return -ENOMEM; - } - - lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT, - LPROCFS_CNTR_AVGMINMAX, - "memused", "bytes"); - lprocfs_counter_init(obd_memory, OBD_MEMORY_PAGES_STAT, - LPROCFS_CNTR_AVGMINMAX, - "pagesused", "pages"); + if (obd_memory == NULL) { + CERROR("kmalloc of 'obd_memory' failed\n"); + return -ENOMEM; } + lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT, + LPROCFS_CNTR_AVGMINMAX, + "memused", "bytes"); + lprocfs_counter_init(obd_memory, OBD_MEMORY_PAGES_STAT, + LPROCFS_CNTR_AVGMINMAX, + "pagesused", "pages"); + err = obd_init_checks(); if (err == -EOVERFLOW) return err; @@ -620,7 +611,6 @@ void obd_update_maxusage(void) } EXPORT_SYMBOL(obd_update_maxusage); -#if defined (CONFIG_PROC_FS) __u64 obd_memory_max(void) { __u64 ret; @@ -644,7 +634,6 @@ __u64 obd_pages_max(void) return ret; } EXPORT_SYMBOL(obd_pages_max); -#endif /* liblustre doesn't call cleanup_obdclass, apparently. we carry on in this * ifdef to the end of the file to cover module and versioning goo.*/ diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c index b1eee0a6dc9a..b67b0feb03e0 100644 --- a/drivers/staging/lustre/lustre/obdclass/dt_object.c +++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c @@ -49,8 +49,6 @@ /* fid_be_to_cpu() */ #include "../include/lustre_fid.h" -#include "../include/lustre_quota.h" - /* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */ LU_KEY_INIT(dt_global, struct dt_thread_info); LU_KEY_FINI(dt_global, struct dt_thread_info); @@ -237,7 +235,8 @@ EXPORT_SYMBOL(dt_locate_at); /** * find a object named \a entry in given \a dfh->dfh_o directory. */ -static int dt_find_entry(const struct lu_env *env, const char *entry, void *data) +static int dt_find_entry(const struct lu_env *env, + const char *entry, void *data) { struct dt_find_hint *dfh = data; struct dt_device *dt = dfh->dfh_dt; @@ -330,9 +329,9 @@ static struct dt_object *dt_reg_open(const struct lu_env *env, int result; result = dt_lookup_dir(env, p, name, fid); - if (result == 0){ + if (result == 0) o = dt_locate(env, dt, fid); - } else + else o = ERR_PTR(result); return o; @@ -923,7 +922,7 @@ int dt_index_read(const struct lu_env *env, struct dt_device *dev, ii->ii_version = dt_version_get(env, obj); /* walk the index and fill lu_idxpages with key/record pairs */ - rc = dt_index_walk(env, obj, rdpg, dt_index_page_build ,ii); + rc = dt_index_walk(env, obj, rdpg, dt_index_page_build, ii); dt_read_unlock(env, obj); if (rc == 0) { @@ -939,8 +938,6 @@ out: } EXPORT_SYMBOL(dt_index_read); -#if defined (CONFIG_PROC_FS) - int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1055,5 +1052,3 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, return rc; } EXPORT_SYMBOL(lprocfs_dt_rd_filesfree); - -#endif /* CONFIG_PROC_FS */ diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 37d6aefde534..978c3c5c460a 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -156,7 +156,7 @@ EXPORT_SYMBOL(class_put_type); #define CLASS_MAX_NAME 1024 int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, - struct lprocfs_vars *vars, const char *name, + const char *name, struct lu_device_type *ldt) { struct obd_type *type; @@ -191,11 +191,19 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, strcpy(type->typ_name, name); spin_lock_init(&type->obd_type_lock); - type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root, - vars, type); - if (IS_ERR(type->typ_procroot)) { - rc = PTR_ERR(type->typ_procroot); - type->typ_procroot = NULL; + type->typ_debugfs_entry = ldebugfs_register(type->typ_name, + debugfs_lustre_root, + NULL, type); + if (IS_ERR_OR_NULL(type->typ_debugfs_entry)) { + rc = type->typ_debugfs_entry ? PTR_ERR(type->typ_debugfs_entry) + : -ENOMEM; + type->typ_debugfs_entry = NULL; + goto failed; + } + + type->typ_kobj = kobject_create_and_add(type->typ_name, lustre_kobj); + if (!type->typ_kobj) { + rc = -ENOMEM; goto failed; } @@ -213,6 +221,8 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, return 0; failed: + if (type->typ_kobj) + kobject_put(type->typ_kobj); kfree(type->typ_name); kfree(type->typ_md_ops); kfree(type->typ_dt_ops); @@ -239,9 +249,11 @@ int class_unregister_type(const char *name) return -EBUSY; } - if (type->typ_procroot) { - lprocfs_remove(&type->typ_procroot); - } + if (type->typ_kobj) + kobject_put(type->typ_kobj); + + if (!IS_ERR_OR_NULL(type->typ_debugfs_entry)) + ldebugfs_remove(&type->typ_debugfs_entry); if (type->typ_lu) lu_device_type_fini(type->typ_lu); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index 06944b863d16..e3c6dcb42cff 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -53,7 +53,6 @@ #include <linux/fcntl.h> #include <linux/delay.h> #include <linux/skbuff.h> -#include <linux/proc_fs.h> #include <linux/fs.h> #include <linux/poll.h> #include <linux/list.h> @@ -64,6 +63,7 @@ #include <linux/uaccess.h> #include <linux/miscdevice.h> #include <linux/seq_file.h> +#include <linux/kobject.h> #include "../../../include/linux/libcfs/libcfs.h" #include "../../../include/linux/lnet/lnetctl.h" @@ -216,29 +216,27 @@ struct miscdevice obd_psdev = { }; -#if defined (CONFIG_PROC_FS) -static int obd_proc_version_seq_show(struct seq_file *m, void *v) +static ssize_t version_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - seq_printf(m, "lustre: %s\nkernel: %s\nbuild: %s\n", - LUSTRE_VERSION_STRING, "patchless_client", BUILD_VERSION); - return 0; + return sprintf(buf, "%s\n", LUSTRE_VERSION_STRING); } -LPROC_SEQ_FOPS_RO(obd_proc_version); -int obd_proc_pinger_seq_show(struct seq_file *m, void *v) +static ssize_t pinger_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - seq_printf(m, "%s\n", "on"); - return 0; + return sprintf(buf, "%s\n", "on"); } -LPROC_SEQ_FOPS_RO(obd_proc_pinger); -static int obd_proc_health_seq_show(struct seq_file *m, void *v) +static ssize_t health_show(struct kobject *kobj, struct attribute *attr, + char *buf) { bool healthy = true; int i; + size_t len = 0; if (libcfs_catastrophe) - seq_printf(m, "LBUG\n"); + return sprintf(buf, "LBUG\n"); read_lock(&obd_dev_lock); for (i = 0; i < class_devno_max(); i++) { @@ -256,8 +254,6 @@ static int obd_proc_health_seq_show(struct seq_file *m, void *v) read_unlock(&obd_dev_lock); if (obd_health_check(NULL, obd)) { - seq_printf(m, "device %s reported unhealthy\n", - obd->obd_name); healthy = false; } class_decref(obd, __func__, current); @@ -266,32 +262,29 @@ static int obd_proc_health_seq_show(struct seq_file *m, void *v) read_unlock(&obd_dev_lock); if (healthy) - seq_puts(m, "healthy\n"); + len = sprintf(buf, "healthy\n"); else - seq_puts(m, "NOT HEALTHY\n"); + len = sprintf(buf, "NOT HEALTHY\n"); - return 0; + return len; } -LPROC_SEQ_FOPS_RO(obd_proc_health); -static int obd_proc_jobid_var_seq_show(struct seq_file *m, void *v) +static ssize_t jobid_var_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - seq_printf(m, "%s\n", obd_jobid_var); - return 0; + return snprintf(buf, PAGE_SIZE, "%s\n", obd_jobid_var); } -static ssize_t obd_proc_jobid_var_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t jobid_var_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, + size_t count) { if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN) return -EINVAL; memset(obd_jobid_var, 0, JOBSTATS_JOBID_VAR_MAX_LEN + 1); - /* This might leave the var invalid on error, which is probably fine.*/ - if (copy_from_user(obd_jobid_var, buffer, count)) - return -EFAULT; + memcpy(obd_jobid_var, buffer, count); /* Trim the trailing '\n' if any */ if (obd_jobid_var[count - 1] == '\n') @@ -299,23 +292,21 @@ static ssize_t obd_proc_jobid_var_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(obd_proc_jobid_var); -static int obd_proc_jobid_name_seq_show(struct seq_file *m, void *v) +static ssize_t jobid_name_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - seq_printf(m, "%s\n", obd_jobid_var); - return 0; + return snprintf(buf, PAGE_SIZE, "%s\n", obd_jobid_node); } -static ssize_t obd_proc_jobid_name_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, + size_t count) { if (!count || count > JOBSTATS_JOBID_SIZE) return -EINVAL; - if (copy_from_user(obd_jobid_node, buffer, count)) - return -EFAULT; + memcpy(obd_jobid_node, buffer, count); obd_jobid_node[count] = 0; @@ -325,20 +316,24 @@ static ssize_t obd_proc_jobid_name_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(obd_proc_jobid_name); - -/* Root for /proc/fs/lustre */ -struct proc_dir_entry *proc_lustre_root = NULL; -EXPORT_SYMBOL(proc_lustre_root); - -struct lprocfs_vars lprocfs_base[] = { - { "version", &obd_proc_version_fops }, - { "pinger", &obd_proc_pinger_fops }, - { "health_check", &obd_proc_health_fops }, - { "jobid_var", &obd_proc_jobid_var_fops }, - { .name = "jobid_name", - .fops = &obd_proc_jobid_name_fops}, - { NULL } + +/* Root for /sys/kernel/debug/lustre */ +struct dentry *debugfs_lustre_root; +EXPORT_SYMBOL_GPL(debugfs_lustre_root); + +LUSTRE_RO_ATTR(version); +LUSTRE_RO_ATTR(pinger); +LUSTRE_RO_ATTR(health); +LUSTRE_RW_ATTR(jobid_var); +LUSTRE_RW_ATTR(jobid_name); + +static struct attribute *lustre_attrs[] = { + &lustre_attr_version.attr, + &lustre_attr_pinger.attr, + &lustre_attr_health.attr, + &lustre_attr_jobid_name.attr, + &lustre_attr_jobid_var.attr, + NULL, }; static void *obd_device_list_seq_start(struct seq_file *p, loff_t *pos) @@ -406,7 +401,7 @@ static int obd_device_list_open(struct inode *inode, struct file *file) return rc; seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private; return 0; } @@ -419,31 +414,57 @@ struct file_operations obd_device_list_fops = { .release = seq_release, }; +struct kobject *lustre_kobj; +EXPORT_SYMBOL_GPL(lustre_kobj); + +static struct attribute_group lustre_attr_group = { + .attrs = lustre_attrs, +}; + int class_procfs_init(void) { int rc = 0; + struct dentry *file; + + lustre_kobj = kobject_create_and_add("lustre", fs_kobj); + if (lustre_kobj == NULL) + goto out; + + /* Create the files associated with this kobject */ + rc = sysfs_create_group(lustre_kobj, &lustre_attr_group); + if (rc) { + kobject_put(lustre_kobj); + goto out; + } - proc_lustre_root = lprocfs_register("fs/lustre", NULL, - lprocfs_base, NULL); - if (IS_ERR(proc_lustre_root)) { - rc = PTR_ERR(proc_lustre_root); - proc_lustre_root = NULL; + debugfs_lustre_root = debugfs_create_dir("lustre", NULL); + if (IS_ERR_OR_NULL(debugfs_lustre_root)) { + rc = debugfs_lustre_root ? PTR_ERR(debugfs_lustre_root) + : -ENOMEM; + debugfs_lustre_root = NULL; + kobject_put(lustre_kobj); goto out; } - rc = lprocfs_seq_create(proc_lustre_root, "devices", 0444, - &obd_device_list_fops, NULL); + file = debugfs_create_file("devices", 0444, debugfs_lustre_root, NULL, + &obd_device_list_fops); + if (IS_ERR_OR_NULL(file)) { + rc = file ? PTR_ERR(file) : -ENOMEM; + kobject_put(lustre_kobj); + goto out; + } out: - if (rc) - CERROR("error adding /proc/fs/lustre/devices file\n"); - return 0; + return rc; } int class_procfs_clean(void) { - if (proc_lustre_root) { - lprocfs_remove(&proc_lustre_root); - } + if (debugfs_lustre_root != NULL) + debugfs_remove_recursive(debugfs_lustre_root); + + debugfs_lustre_root = NULL; + + kobject_put(lustre_kobj); + return 0; } -#endif /* CONFIG_PROC_FS */ diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c index 4b62d25764ad..54f0a81f7b51 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c @@ -38,7 +38,6 @@ #include <linux/sysctl.h> #include <linux/sched.h> #include <linux/mm.h> -#include <linux/proc_fs.h> #include <linux/slab.h> #include <linux/stat.h> #include <linux/ctype.h> @@ -55,30 +54,6 @@ static struct ctl_table_header *obd_table_header; #endif - -#define OBD_SYSCTL 300 - -enum { - OBD_TIMEOUT = 3, /* RPC timeout before recovery/intr */ - OBD_DUMP_ON_TIMEOUT, /* dump kernel debug log upon eviction */ - OBD_MEMUSED, /* bytes currently OBD_ALLOCated */ - OBD_PAGESUSED, /* pages currently OBD_PAGE_ALLOCated */ - OBD_MAXMEMUSED, /* maximum bytes OBD_ALLOCated concurrently */ - OBD_MAXPAGESUSED, /* maximum pages OBD_PAGE_ALLOCated concurrently */ - OBD_SYNCFILTER, /* XXX temporary, as we play with sync osts.. */ - OBD_LDLM_TIMEOUT, /* LDLM timeout for ASTs before client eviction */ - OBD_DUMP_ON_EVICTION, /* dump kernel debug log upon eviction */ - OBD_DEBUG_PEER_ON_TIMEOUT, /* dump peer debug when RPC times out */ - OBD_ALLOC_FAIL_RATE, /* memory allocation random failure rate */ - OBD_MAX_DIRTY_PAGES, /* maximum dirty pages */ - OBD_AT_MIN, /* Adaptive timeouts params */ - OBD_AT_MAX, - OBD_AT_EXTRA, - OBD_AT_EARLY_MARGIN, - OBD_AT_HISTORY, -}; - - #ifdef CONFIG_SYSCTL static int proc_set_timeout(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c index c8f6ab006124..48dbbcf97702 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c @@ -279,9 +279,8 @@ static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle, loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) { up_read(&cathandle->lgh_lock); return loghandle; - } else { - up_write(&loghandle->lgh_lock); } + up_write(&loghandle->lgh_lock); } up_read(&cathandle->lgh_lock); @@ -299,9 +298,8 @@ static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle, if (loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) { up_write(&cathandle->lgh_lock); return loghandle; - } else { - up_write(&loghandle->lgh_lock); } + up_write(&loghandle->lgh_lock); } CDEBUG(D_INODE, "use next log\n"); diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 57c6ddd95f3e..17e7c1807863 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -221,8 +221,6 @@ int lprocfs_write_frac_helper(const char __user *buffer, unsigned long count, } EXPORT_SYMBOL(lprocfs_write_frac_helper); -#if defined (CONFIG_PROC_FS) - static int lprocfs_no_percpu_stats; module_param(lprocfs_no_percpu_stats, int, 0644); MODULE_PARM_DESC(lprocfs_no_percpu_stats, "Do not alloc percpu data for lprocfs stats"); @@ -243,11 +241,11 @@ EXPORT_SYMBOL(lprocfs_seq_release); /* lprocfs API calls */ -struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root, - char *name, void *data, - struct file_operations *fops) +struct dentry *ldebugfs_add_simple(struct dentry *root, + char *name, void *data, + struct file_operations *fops) { - struct proc_dir_entry *proc; + struct dentry *entry; umode_t mode = 0; if (root == NULL || name == NULL || fops == NULL) @@ -257,19 +255,19 @@ struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root, mode = 0444; if (fops->write) mode |= 0200; - proc = proc_create_data(name, mode, root, fops, data); - if (!proc) { - CERROR("LprocFS: No memory to create /proc entry %s", name); - return ERR_PTR(-ENOMEM); + entry = debugfs_create_file(name, mode, root, data, fops); + if (IS_ERR_OR_NULL(entry)) { + CERROR("LprocFS: No memory to create <debugfs> entry %s", name); + return entry ?: ERR_PTR(-ENOMEM); } - return proc; + return entry; } -EXPORT_SYMBOL(lprocfs_add_simple); +EXPORT_SYMBOL(ldebugfs_add_simple); -struct proc_dir_entry *lprocfs_add_symlink(const char *name, - struct proc_dir_entry *parent, const char *format, ...) +struct dentry *ldebugfs_add_symlink(const char *name, struct dentry *parent, + const char *format, ...) { - struct proc_dir_entry *entry; + struct dentry *entry; char *dest; va_list ap; @@ -284,37 +282,29 @@ struct proc_dir_entry *lprocfs_add_symlink(const char *name, vsnprintf(dest, MAX_STRING_SIZE, format, ap); va_end(ap); - entry = proc_symlink(name, parent, dest); - if (entry == NULL) - CERROR("LprocFS: Could not create symbolic link from %s to %s", + entry = debugfs_create_symlink(name, parent, dest); + if (IS_ERR_OR_NULL(entry)) { + CERROR("LdebugFS: Could not create symbolic link from %s to %s", name, dest); + entry = NULL; + } kfree(dest); return entry; } -EXPORT_SYMBOL(lprocfs_add_symlink); +EXPORT_SYMBOL(ldebugfs_add_symlink); static struct file_operations lprocfs_generic_fops = { }; -/** - * Add /proc entries. - * - * \param root [in] The parent proc entry on which new entry will be added. - * \param list [in] Array of proc entries to be added. - * \param data [in] The argument to be passed when entries read/write routines - * are called through /proc file. - * - * \retval 0 on success - * < 0 on error - */ -int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, - void *data) +int ldebugfs_add_vars(struct dentry *parent, + struct lprocfs_vars *list, + void *data) { - if (root == NULL || list == NULL) + if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(list)) return -EINVAL; while (list->name != NULL) { - struct proc_dir_entry *proc; + struct dentry *entry; umode_t mode = 0; if (list->proc_mode != 0000) { @@ -325,54 +315,50 @@ int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, if (list->fops->write) mode |= 0200; } - proc = proc_create_data(list->name, mode, root, - list->fops ?: &lprocfs_generic_fops, - list->data ?: data); - if (proc == NULL) - return -ENOMEM; + entry = debugfs_create_file(list->name, mode, parent, + list->data ?: data, + list->fops ?: &lprocfs_generic_fops + ); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; list++; } return 0; } -EXPORT_SYMBOL(lprocfs_add_vars); - -void lprocfs_remove(struct proc_dir_entry **rooth) -{ - proc_remove(*rooth); - *rooth = NULL; -} -EXPORT_SYMBOL(lprocfs_remove); +EXPORT_SYMBOL(ldebugfs_add_vars); -void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent) +void ldebugfs_remove(struct dentry **entryp) { - LASSERT(parent != NULL); - remove_proc_entry(name, parent); + debugfs_remove(*entryp); + *entryp = NULL; } -EXPORT_SYMBOL(lprocfs_remove_proc_entry); +EXPORT_SYMBOL(ldebugfs_remove); -struct proc_dir_entry *lprocfs_register(const char *name, - struct proc_dir_entry *parent, - struct lprocfs_vars *list, void *data) +struct dentry *ldebugfs_register(const char *name, + struct dentry *parent, + struct lprocfs_vars *list, void *data) { - struct proc_dir_entry *entry; + struct dentry *entry; - entry = proc_mkdir(name, parent); - if (entry == NULL) { - entry = ERR_PTR(-ENOMEM); + entry = debugfs_create_dir(name, parent); + if (IS_ERR_OR_NULL(entry)) { + entry = entry ?: ERR_PTR(-ENOMEM); goto out; } - if (list != NULL) { - int rc = lprocfs_add_vars(entry, list, data); + if (!IS_ERR_OR_NULL(list)) { + int rc; + + rc = ldebugfs_add_vars(entry, list, data); if (rc != 0) { - lprocfs_remove(&entry); + debugfs_remove(entry); entry = ERR_PTR(rc); } } out: return entry; } -EXPORT_SYMBOL(lprocfs_register); +EXPORT_SYMBOL(ldebugfs_register); /* Generic callbacks */ int lprocfs_rd_uint(struct seq_file *m, void *data) @@ -437,15 +423,15 @@ int lprocfs_wr_atomic(struct file *file, const char __user *buffer, } EXPORT_SYMBOL(lprocfs_wr_atomic); -int lprocfs_rd_uuid(struct seq_file *m, void *data) +static ssize_t uuid_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - LASSERT(obd != NULL); - seq_printf(m, "%s\n", obd->obd_uuid.uuid); - return 0; + return sprintf(buf, "%s\n", obd->obd_uuid.uuid); } -EXPORT_SYMBOL(lprocfs_rd_uuid); +LUSTRE_RO_ATTR(uuid); int lprocfs_rd_name(struct seq_file *m, void *data) { @@ -457,23 +443,27 @@ int lprocfs_rd_name(struct seq_file *m, void *data) } EXPORT_SYMBOL(lprocfs_rd_name); -int lprocfs_rd_blksize(struct seq_file *m, void *data) +static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%u\n", osfs.os_bsize); + return sprintf(buf, "%u\n", osfs.os_bsize); return rc; } -EXPORT_SYMBOL(lprocfs_rd_blksize); +LUSTRE_RO_ATTR(blocksize); -int lprocfs_rd_kbytestotal(struct seq_file *m, void *data) +static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), @@ -485,16 +475,18 @@ int lprocfs_rd_kbytestotal(struct seq_file *m, void *data) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + return sprintf(buf, "%llu\n", result); } return rc; } -EXPORT_SYMBOL(lprocfs_rd_kbytestotal); +LUSTRE_RO_ATTR(kbytestotal); -int lprocfs_rd_kbytesfree(struct seq_file *m, void *data) +static ssize_t kbytesfree_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), @@ -506,16 +498,18 @@ int lprocfs_rd_kbytesfree(struct seq_file *m, void *data) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + return sprintf(buf, "%llu\n", result); } return rc; } -EXPORT_SYMBOL(lprocfs_rd_kbytesfree); +LUSTRE_RO_ATTR(kbytesfree); -int lprocfs_rd_kbytesavail(struct seq_file *m, void *data) +static ssize_t kbytesavail_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), @@ -527,40 +521,44 @@ int lprocfs_rd_kbytesavail(struct seq_file *m, void *data) while (blk_size >>= 1) result <<= 1; - seq_printf(m, "%llu\n", result); + return sprintf(buf, "%llu\n", result); } return rc; } -EXPORT_SYMBOL(lprocfs_rd_kbytesavail); +LUSTRE_RO_ATTR(kbytesavail); -int lprocfs_rd_filestotal(struct seq_file *m, void *data) +static ssize_t filestotal_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%llu\n", osfs.os_files); + return sprintf(buf, "%llu\n", osfs.os_files); return rc; } -EXPORT_SYMBOL(lprocfs_rd_filestotal); +LUSTRE_RO_ATTR(filestotal); -int lprocfs_rd_filesfree(struct seq_file *m, void *data) +static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *obd = data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct obd_statfs osfs; int rc = obd_statfs(NULL, obd->obd_self_export, &osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), OBD_STATFS_NODELAY); if (!rc) - seq_printf(m, "%llu\n", osfs.os_ffree); + return sprintf(buf, "%llu\n", osfs.os_ffree); return rc; } -EXPORT_SYMBOL(lprocfs_rd_filesfree); +LUSTRE_RO_ATTR(filesfree); int lprocfs_rd_server_uuid(struct seq_file *m, void *data) { @@ -930,43 +928,62 @@ int lprocfs_rd_connect_flags(struct seq_file *m, void *data) } EXPORT_SYMBOL(lprocfs_rd_connect_flags); -int lprocfs_rd_num_exports(struct seq_file *m, void *data) -{ - struct obd_device *obd = data; - - LASSERT(obd != NULL); - seq_printf(m, "%u\n", obd->obd_num_exports); - return 0; -} -EXPORT_SYMBOL(lprocfs_rd_num_exports); +static struct attribute *obd_def_attrs[] = { + &lustre_attr_blocksize.attr, + &lustre_attr_kbytestotal.attr, + &lustre_attr_kbytesfree.attr, + &lustre_attr_kbytesavail.attr, + &lustre_attr_filestotal.attr, + &lustre_attr_filesfree.attr, + &lustre_attr_uuid.attr, + NULL, +}; -int lprocfs_rd_numrefs(struct seq_file *m, void *data) +static void obd_sysfs_release(struct kobject *kobj) { - struct obd_type *class = (struct obd_type *) data; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - LASSERT(class != NULL); - seq_printf(m, "%d\n", class->typ_refcnt); - return 0; + complete(&obd->obd_kobj_unregister); } -EXPORT_SYMBOL(lprocfs_rd_numrefs); -int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list) +static struct kobj_type obd_ktype = { + .default_attrs = obd_def_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = obd_sysfs_release, +}; + +int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list, + struct attribute_group *attrs) { int rc = 0; - LASSERT(obd != NULL); - LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); - LASSERT(obd->obd_type->typ_procroot != NULL); - - obd->obd_proc_entry = lprocfs_register(obd->obd_name, - obd->obd_type->typ_procroot, - list, obd); - if (IS_ERR(obd->obd_proc_entry)) { - rc = PTR_ERR(obd->obd_proc_entry); + init_completion(&obd->obd_kobj_unregister); + rc = kobject_init_and_add(&obd->obd_kobj, &obd_ktype, + obd->obd_type->typ_kobj, + "%s", obd->obd_name); + if (rc) + return rc; + + if (attrs) { + rc = sysfs_create_group(&obd->obd_kobj, attrs); + if (rc) { + kobject_put(&obd->obd_kobj); + return rc; + } + } + + obd->obd_debugfs_entry = ldebugfs_register(obd->obd_name, + obd->obd_type->typ_debugfs_entry, + list, obd); + if (IS_ERR_OR_NULL(obd->obd_debugfs_entry)) { + rc = obd->obd_debugfs_entry ? PTR_ERR(obd->obd_debugfs_entry) + : -ENOMEM; CERROR("error %d setting up lprocfs for %s\n", rc, obd->obd_name); - obd->obd_proc_entry = NULL; + obd->obd_debugfs_entry = NULL; } + return rc; } EXPORT_SYMBOL(lprocfs_obd_setup); @@ -975,58 +992,16 @@ int lprocfs_obd_cleanup(struct obd_device *obd) { if (!obd) return -EINVAL; - if (obd->obd_proc_exports_entry) { - /* Should be no exports left */ - lprocfs_remove(&obd->obd_proc_exports_entry); - obd->obd_proc_exports_entry = NULL; - } - if (obd->obd_proc_entry) { - lprocfs_remove(&obd->obd_proc_entry); - obd->obd_proc_entry = NULL; - } - return 0; -} -EXPORT_SYMBOL(lprocfs_obd_cleanup); - -static void lprocfs_free_client_stats(struct nid_stat *client_stat) -{ - CDEBUG(D_CONFIG, "stat %p - data %p/%p\n", client_stat, - client_stat->nid_proc, client_stat->nid_stats); - - LASSERTF(atomic_read(&client_stat->nid_exp_ref_count) == 0, - "nid %s:count %d\n", libcfs_nid2str(client_stat->nid), - atomic_read(&client_stat->nid_exp_ref_count)); - - if (client_stat->nid_proc) - lprocfs_remove(&client_stat->nid_proc); - if (client_stat->nid_stats) - lprocfs_free_stats(&client_stat->nid_stats); + if (!IS_ERR_OR_NULL(obd->obd_debugfs_entry)) + ldebugfs_remove(&obd->obd_debugfs_entry); - if (client_stat->nid_ldlm_stats) - lprocfs_free_stats(&client_stat->nid_ldlm_stats); + kobject_put(&obd->obd_kobj); + wait_for_completion(&obd->obd_kobj_unregister); - kfree(client_stat); - return; - -} - -void lprocfs_free_per_client_stats(struct obd_device *obd) -{ - struct cfs_hash *hash = obd->obd_nid_stats_hash; - struct nid_stat *stat; - - /* we need extra list - because hash_exit called to early */ - /* not need locking because all clients is died */ - while (!list_empty(&obd->obd_nid_stats)) { - stat = list_entry(obd->obd_nid_stats.next, - struct nid_stat, nid_list); - list_del_init(&stat->nid_list); - cfs_hash_del(hash, &stat->nid, &stat->nid_hash); - lprocfs_free_client_stats(stat); - } + return 0; } -EXPORT_SYMBOL(lprocfs_free_per_client_stats); +EXPORT_SYMBOL(lprocfs_obd_cleanup); int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid) { @@ -1257,8 +1232,10 @@ static int lprocfs_stats_seq_open(struct inode *inode, struct file *file) rc = seq_open(file, &lprocfs_stats_seq_sops); if (rc) return rc; + seq = file->private_data; - seq->private = PDE_DATA(inode); + seq->private = inode->i_private; + return 0; } @@ -1271,20 +1248,21 @@ struct file_operations lprocfs_stats_seq_fops = { .release = lprocfs_seq_release, }; -int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, +int ldebugfs_register_stats(struct dentry *parent, const char *name, struct lprocfs_stats *stats) { - struct proc_dir_entry *entry; - LASSERT(root != NULL); + struct dentry *entry; - entry = proc_create_data(name, 0644, root, - &lprocfs_stats_seq_fops, stats); - if (entry == NULL) - return -ENOMEM; + LASSERT(!IS_ERR_OR_NULL(parent)); + + entry = debugfs_create_file(name, 0644, parent, stats, + &lprocfs_stats_seq_fops); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; return 0; } -EXPORT_SYMBOL(lprocfs_register_stats); +EXPORT_SYMBOL(ldebugfs_register_stats); void lprocfs_counter_init(struct lprocfs_stats *stats, int index, unsigned conf, const char *name, const char *units) @@ -1388,7 +1366,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats) int rc, i; LASSERT(obd->obd_stats == NULL); - LASSERT(obd->obd_proc_entry != NULL); + LASSERT(obd->obd_debugfs_entry != NULL); LASSERT(obd->obd_cntr_base == 0); num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) + @@ -1409,7 +1387,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats) "Missing obd_stat initializer obd_op operation at offset %d.\n", i - num_private_stats); } - rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats); + rc = ldebugfs_register_stats(obd->obd_debugfs_entry, "stats", stats); if (rc < 0) { lprocfs_free_stats(&stats); } else { @@ -1479,7 +1457,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, int rc, i; LASSERT(obd->md_stats == NULL); - LASSERT(obd->obd_proc_entry != NULL); + LASSERT(obd->obd_debugfs_entry != NULL); LASSERT(obd->md_cntr_base == 0); num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) + @@ -1497,7 +1475,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, LBUG(); } } - rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats); + rc = ldebugfs_register_stats(obd->obd_debugfs_entry, "md_stats", stats); if (rc < 0) { lprocfs_free_stats(&stats); } else { @@ -1543,241 +1521,8 @@ void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) } EXPORT_SYMBOL(lprocfs_init_ldlm_stats); -int lprocfs_exp_print_uuid(struct cfs_hash *hs, struct cfs_hash_bd *bd, - struct hlist_node *hnode, void *data) - -{ - struct obd_export *exp = cfs_hash_object(hs, hnode); - struct seq_file *m = (struct seq_file *)data; - - if (exp->exp_nid_stats) - seq_printf(m, "%s\n", obd_uuid2str(&exp->exp_client_uuid)); - - return 0; -} - -static int -lproc_exp_uuid_seq_show(struct seq_file *m, void *unused) -{ - struct nid_stat *stats = (struct nid_stat *)m->private; - struct obd_device *obd = stats->nid_obd; - - cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid, - lprocfs_exp_print_uuid, m); - return 0; -} - -LPROC_SEQ_FOPS_RO(lproc_exp_uuid); - -struct exp_hash_cb_data { - struct seq_file *m; - bool first; -}; - -int lprocfs_exp_print_hash(struct cfs_hash *hs, struct cfs_hash_bd *bd, - struct hlist_node *hnode, void *cb_data) - -{ - struct exp_hash_cb_data *data = (struct exp_hash_cb_data *)cb_data; - struct obd_export *exp = cfs_hash_object(hs, hnode); - - if (exp->exp_lock_hash != NULL) { - if (data->first) { - cfs_hash_debug_header(data->m); - data->first = false; - } - cfs_hash_debug_str(hs, data->m); - } - - return 0; -} - -static int -lproc_exp_hash_seq_show(struct seq_file *m, void *unused) -{ - struct nid_stat *stats = (struct nid_stat *)m->private; - struct obd_device *obd = stats->nid_obd; - struct exp_hash_cb_data cb_data = { - .m = m, - .first = true - }; - - cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid, - lprocfs_exp_print_hash, &cb_data); - return 0; -} - -LPROC_SEQ_FOPS_RO(lproc_exp_hash); - -int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data) -{ - seq_printf(m, "%s\n", - "Write into this file to clear all nid stats and stale nid entries"); - return 0; -} -EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); - -static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data) -{ - struct nid_stat *stat = obj; - - CDEBUG(D_INFO, "refcnt %d\n", atomic_read(&stat->nid_exp_ref_count)); - if (atomic_read(&stat->nid_exp_ref_count) == 1) { - /* object has only hash references. */ - spin_lock(&stat->nid_obd->obd_nid_lock); - list_move(&stat->nid_list, data); - spin_unlock(&stat->nid_obd->obd_nid_lock); - return 1; - } - /* we has reference to object - only clear data*/ - if (stat->nid_stats) - lprocfs_clear_stats(stat->nid_stats); - - return 0; -} - -int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - struct nid_stat *client_stat; - LIST_HEAD(free_list); - - cfs_hash_cond_del(obd->obd_nid_stats_hash, - lprocfs_nid_stats_clear_write_cb, &free_list); - - while (!list_empty(&free_list)) { - client_stat = list_entry(free_list.next, struct nid_stat, - nid_list); - list_del_init(&client_stat->nid_list); - lprocfs_free_client_stats(client_stat); - } - - return count; -} -EXPORT_SYMBOL(lprocfs_nid_stats_clear_write); - -int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) -{ - struct nid_stat *new_stat, *old_stat; - struct obd_device *obd = NULL; - struct proc_dir_entry *entry; - char *buffer = NULL; - int rc = 0; - - *newnid = 0; - - if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry || - !exp->exp_obd->obd_nid_stats_hash) - return -EINVAL; - - /* not test against zero because eric say: - * You may only test nid against another nid, or LNET_NID_ANY. - * Anything else is nonsense.*/ - if (!nid || *nid == LNET_NID_ANY) - return 0; - - obd = exp->exp_obd; - - CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash); - - new_stat = kzalloc(sizeof(*new_stat), GFP_NOFS); - if (new_stat == NULL) - return -ENOMEM; - - new_stat->nid = *nid; - new_stat->nid_obd = exp->exp_obd; - /* we need set default refcount to 1 to balance obd_disconnect */ - atomic_set(&new_stat->nid_exp_ref_count, 1); - - old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash, - nid, &new_stat->nid_hash); - CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n", - old_stat, libcfs_nid2str(*nid), - atomic_read(&new_stat->nid_exp_ref_count)); - - /* We need to release old stats because lprocfs_exp_cleanup() hasn't - * been and will never be called. */ - if (exp->exp_nid_stats) { - nidstat_putref(exp->exp_nid_stats); - exp->exp_nid_stats = NULL; - } - - /* Return -EALREADY here so that we know that the /proc - * entry already has been created */ - if (old_stat != new_stat) { - exp->exp_nid_stats = old_stat; - rc = -EALREADY; - goto destroy_new; - } - /* not found - create */ - buffer = kzalloc(LNET_NIDSTR_SIZE, GFP_NOFS); - if (buffer == NULL) { - rc = -ENOMEM; - goto destroy_new; - } - - memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE); - new_stat->nid_proc = lprocfs_register(buffer, - obd->obd_proc_exports_entry, - NULL, NULL); - kfree(buffer); - - if (IS_ERR(new_stat->nid_proc)) { - CERROR("Error making export directory for nid %s\n", - libcfs_nid2str(*nid)); - rc = PTR_ERR(new_stat->nid_proc); - new_stat->nid_proc = NULL; - goto destroy_new_ns; - } - - entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", - new_stat, &lproc_exp_uuid_fops); - if (IS_ERR(entry)) { - CWARN("Error adding the NID stats file\n"); - rc = PTR_ERR(entry); - goto destroy_new_ns; - } - - entry = lprocfs_add_simple(new_stat->nid_proc, "hash", - new_stat, &lproc_exp_hash_fops); - if (IS_ERR(entry)) { - CWARN("Error adding the hash file\n"); - rc = PTR_ERR(entry); - goto destroy_new_ns; - } - - exp->exp_nid_stats = new_stat; - *newnid = 1; - /* protect competitive add to list, not need locking on destroy */ - spin_lock(&obd->obd_nid_lock); - list_add(&new_stat->nid_list, &obd->obd_nid_stats); - spin_unlock(&obd->obd_nid_lock); - - return rc; - -destroy_new_ns: - if (new_stat->nid_proc != NULL) - lprocfs_remove(&new_stat->nid_proc); - cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash); - -destroy_new: - nidstat_putref(new_stat); - kfree(new_stat); - return rc; -} -EXPORT_SYMBOL(lprocfs_exp_setup); - int lprocfs_exp_cleanup(struct obd_export *exp) { - struct nid_stat *stat = exp->exp_nid_stats; - - if (!stat || !exp->exp_obd) - return 0; - - nidstat_putref(exp->exp_nid_stats); - exp->exp_nid_stats = NULL; - return 0; } EXPORT_SYMBOL(lprocfs_exp_cleanup); @@ -1972,35 +1717,35 @@ char *lprocfs_find_named_value(const char *buffer, const char *name, } EXPORT_SYMBOL(lprocfs_find_named_value); -int lprocfs_seq_create(struct proc_dir_entry *parent, +int ldebugfs_seq_create(struct dentry *parent, const char *name, umode_t mode, const struct file_operations *seq_fops, void *data) { - struct proc_dir_entry *entry; + struct dentry *entry; /* Disallow secretly (un)writable entries. */ LASSERT((seq_fops->write == NULL) == ((mode & 0222) == 0)); - entry = proc_create_data(name, mode, parent, seq_fops, data); - if (entry == NULL) - return -ENOMEM; + entry = debugfs_create_file(name, mode, parent, data, seq_fops); + if (IS_ERR_OR_NULL(entry)) + return entry ? PTR_ERR(entry) : -ENOMEM; return 0; } -EXPORT_SYMBOL(lprocfs_seq_create); +EXPORT_SYMBOL(ldebugfs_seq_create); -int lprocfs_obd_seq_create(struct obd_device *dev, - const char *name, - umode_t mode, - const struct file_operations *seq_fops, - void *data) +int ldebugfs_obd_seq_create(struct obd_device *dev, + const char *name, + umode_t mode, + const struct file_operations *seq_fops, + void *data) { - return lprocfs_seq_create(dev->obd_proc_entry, name, - mode, seq_fops, data); + return ldebugfs_seq_create(dev->obd_debugfs_entry, name, + mode, seq_fops, data); } -EXPORT_SYMBOL(lprocfs_obd_seq_create); +EXPORT_SYMBOL(ldebugfs_obd_seq_create); void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value) { @@ -2056,4 +1801,26 @@ int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data) } EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc); -#endif +ssize_t lustre_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct lustre_attr *a = container_of(attr, struct lustre_attr, attr); + + return a->show ? a->show(kobj, attr, buf) : 0; +} +EXPORT_SYMBOL_GPL(lustre_attr_show); + +ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct lustre_attr *a = container_of(attr, struct lustre_attr, attr); + + return a->store ? a->store(kobj, attr, buf, len) : len; +} +EXPORT_SYMBOL_GPL(lustre_attr_store); + +const struct sysfs_ops lustre_sysfs_ops = { + .show = lustre_attr_show, + .store = lustre_attr_store, +}; +EXPORT_SYMBOL_GPL(lustre_sysfs_ops); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 4458faad1b1a..eae660660358 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -1989,14 +1989,10 @@ void lu_global_fini(void) static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx) { -#if defined (CONFIG_PROC_FS) struct lprocfs_counter ret; lprocfs_stats_collect(stats, idx, &ret); return (__u32)ret.lc_count; -#else - return 0; -#endif } /** diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 0bda9c56f148..fbdb748a36b9 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -49,7 +49,6 @@ static cfs_hash_ops_t uuid_hash_ops; static cfs_hash_ops_t nid_hash_ops; -static cfs_hash_ops_t nid_stat_hash_ops; /*********** string parsing utils *********/ @@ -383,7 +382,6 @@ int class_attach(struct lustre_cfg *lcfg) INIT_LIST_HEAD(&obd->obd_unlinked_exports); INIT_LIST_HEAD(&obd->obd_delayed_exports); INIT_LIST_HEAD(&obd->obd_exports_timed); - INIT_LIST_HEAD(&obd->obd_nid_stats); spin_lock_init(&obd->obd_nid_lock); spin_lock_init(&obd->obd_dev_lock); mutex_init(&obd->obd_dev_mutex); @@ -486,7 +484,6 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_starting = 1; obd->obd_uuid_hash = NULL; obd->obd_nid_hash = NULL; - obd->obd_nid_stats_hash = NULL; spin_unlock(&obd->obd_dev_lock); /* create an uuid-export lustre hash */ @@ -515,19 +512,6 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) goto err_hash; } - /* create a nid-stats lustre hash */ - obd->obd_nid_stats_hash = cfs_hash_create("NID_STATS", - HASH_NID_STATS_CUR_BITS, - HASH_NID_STATS_MAX_BITS, - HASH_NID_STATS_BKT_BITS, 0, - CFS_HASH_MIN_THETA, - CFS_HASH_MAX_THETA, - &nid_stat_hash_ops, CFS_HASH_DEFAULT); - if (!obd->obd_nid_stats_hash) { - err = -ENOMEM; - goto err_hash; - } - exp = class_new_export(obd, &obd->obd_uuid); if (IS_ERR(exp)) { err = PTR_ERR(exp); @@ -567,10 +551,6 @@ err_hash: cfs_hash_putref(obd->obd_nid_hash); obd->obd_nid_hash = NULL; } - if (obd->obd_nid_stats_hash) { - cfs_hash_putref(obd->obd_nid_stats_hash); - obd->obd_nid_stats_hash = NULL; - } obd->obd_starting = 0; CERROR("setup %s failed (%d)\n", obd->obd_name, err); return err; @@ -694,12 +674,6 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_nid_hash = NULL; } - /* destroy a nid-stats hash body */ - if (obd->obd_nid_stats_hash) { - cfs_hash_putref(obd->obd_nid_stats_hash); - obd->obd_nid_stats_hash = NULL; - } - class_decref(obd, "setup", obd); obd->obd_set_up = 0; @@ -866,29 +840,26 @@ int class_add_profile(int proflen, char *prof, int osclen, char *osc, INIT_LIST_HEAD(&lprof->lp_list); LASSERT(proflen == (strlen(prof) + 1)); - lprof->lp_profile = kzalloc(proflen, GFP_NOFS); + lprof->lp_profile = kmemdup(prof, proflen, GFP_NOFS); if (lprof->lp_profile == NULL) { err = -ENOMEM; goto free_lprof; } - memcpy(lprof->lp_profile, prof, proflen); LASSERT(osclen == (strlen(osc) + 1)); - lprof->lp_dt = kzalloc(osclen, GFP_NOFS); + lprof->lp_dt = kmemdup(osc, osclen, GFP_NOFS); if (lprof->lp_dt == NULL) { err = -ENOMEM; goto free_lp_profile; } - memcpy(lprof->lp_dt, osc, osclen); if (mdclen > 0) { LASSERT(mdclen == (strlen(mdc) + 1)); - lprof->lp_md = kzalloc(mdclen, GFP_NOFS); + lprof->lp_md = kmemdup(mdc, mdclen, GFP_NOFS); if (lprof->lp_md == NULL) { err = -ENOMEM; goto free_lp_dt; } - memcpy(lprof->lp_md, mdc, mdclen); } list_add(&lprof->lp_list, &lustre_profile_list); @@ -1893,57 +1864,3 @@ static cfs_hash_ops_t nid_hash_ops = { .hs_get = nid_export_get, .hs_put_locked = nid_export_put_locked, }; - - -/* - * nid<->nidstats hash operations - */ - -static void * -nidstats_key(struct hlist_node *hnode) -{ - struct nid_stat *ns; - - ns = hlist_entry(hnode, struct nid_stat, nid_hash); - - return &ns->nid; -} - -static int -nidstats_keycmp(const void *key, struct hlist_node *hnode) -{ - return *(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key; -} - -static void * -nidstats_object(struct hlist_node *hnode) -{ - return hlist_entry(hnode, struct nid_stat, nid_hash); -} - -static void -nidstats_get(struct cfs_hash *hs, struct hlist_node *hnode) -{ - struct nid_stat *ns; - - ns = hlist_entry(hnode, struct nid_stat, nid_hash); - nidstat_getref(ns); -} - -static void -nidstats_put_locked(struct cfs_hash *hs, struct hlist_node *hnode) -{ - struct nid_stat *ns; - - ns = hlist_entry(hnode, struct nid_stat, nid_hash); - nidstat_putref(ns); -} - -static cfs_hash_ops_t nid_stat_hash_ops = { - .hs_hash = nid_hash, - .hs_key = nidstats_key, - .hs_keycmp = nidstats_keycmp, - .hs_object = nidstats_object, - .hs_get = nidstats_get, - .hs_put_locked = nidstats_put_locked, -}; diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 1f9a5f7841ae..ce4a71f7171a 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -147,7 +147,7 @@ int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd, char *s1, char *s2, char *s3, char *s4) { struct lustre_cfg_bufs bufs; - struct lustre_cfg * lcfg = NULL; + struct lustre_cfg *lcfg = NULL; int rc; CDEBUG(D_TRACE, "lcfg %s %#x %s %s %s %s\n", cfgname, diff --git a/drivers/staging/lustre/lustre/obdecho/Makefile b/drivers/staging/lustre/lustre/obdecho/Makefile index 672028fc7f6e..a659a37a7e93 100644 --- a/drivers/staging/lustre/lustre/obdecho/Makefile +++ b/drivers/staging/lustre/lustre/obdecho/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_LUSTRE_FS) += obdecho.o -obdecho-y := echo_client.o lproc_echo.o +obdecho-y := echo_client.o diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 53761787a56f..0222fd2e4757 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -2141,15 +2141,11 @@ static struct obd_ops echo_client_obd_ops = { int echo_client_init(void) { - struct lprocfs_static_vars lvars = { NULL }; int rc; - lprocfs_echo_init_vars(&lvars); - rc = lu_kmem_init(echo_caches); if (rc == 0) { rc = class_register_type(&echo_client_obd_ops, NULL, - lvars.module_vars, LUSTRE_ECHO_CLIENT_NAME, &echo_device_type); if (rc) @@ -2166,15 +2162,10 @@ void echo_client_exit(void) static int __init obdecho_init(void) { - struct lprocfs_static_vars lvars; - LCONSOLE_INFO("Echo OBD driver; http://www.lustre.org/\n"); LASSERT(PAGE_CACHE_SIZE % OBD_ECHO_BLOCK_SIZE == 0); - lprocfs_echo_init_vars(&lvars); - - return echo_client_init(); } diff --git a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c b/drivers/staging/lustre/lustre/obdecho/lproc_echo.c deleted file mode 100644 index 0beb97db7c7d..000000000000 --- a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ -#define DEBUG_SUBSYSTEM S_ECHO - -#include "../include/lprocfs_status.h" -#include "../include/obd_class.h" - -#if defined(CONFIG_PROC_FS) -LPROC_SEQ_FOPS_RO_TYPE(echo, uuid); -static struct lprocfs_vars lprocfs_echo_obd_vars[] = { - { "uuid", &echo_uuid_fops, NULL, 0 }, - { NULL } -}; - -LPROC_SEQ_FOPS_RO_TYPE(echo, numrefs); -static struct lprocfs_vars lprocfs_echo_module_vars[] = { - { "num_refs", &echo_numrefs_fops, NULL, 0 }, - { NULL } -}; - -void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars) -{ - lvars->module_vars = lprocfs_echo_module_vars; - lvars->obd_vars = lprocfs_echo_obd_vars; -} -#endif /* CONFIG_PROC_FS */ diff --git a/drivers/staging/lustre/lustre/osc/Makefile b/drivers/staging/lustre/lustre/osc/Makefile index 54927fba4eb4..37cdeea9ac49 100644 --- a/drivers/staging/lustre/lustre/osc/Makefile +++ b/drivers/staging/lustre/lustre/osc/Makefile @@ -1,4 +1,3 @@ obj-$(CONFIG_LUSTRE_FS) += osc.o osc-y := osc_request.o osc_dev.o osc_object.o \ - osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o -osc-$(CONFIG_PROC_FS) += lproc_osc.o + osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o lproc_osc.o diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index 15a66209831c..ff6d2e2ffdab 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -42,25 +42,25 @@ #include <linux/seq_file.h> #include "osc_internal.h" -static int osc_active_seq_show(struct seq_file *m, void *v) +static ssize_t active_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; - - LPROCFS_CLIMP_CHECK(dev); - seq_printf(m, "%d\n", !dev->u.cli.cl_import->imp_deactive); - LPROCFS_CLIMP_EXIT(dev); + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); - return 0; + return sprintf(buf, "%d\n", !dev->u.cli.cl_import->imp_deactive); } -static ssize_t osc_active_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t active_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; - int val, rc; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; if (val < 0 || val > 1) @@ -70,41 +70,43 @@ static ssize_t osc_active_seq_write(struct file *file, if (dev->u.cli.cl_import->imp_deactive == val) rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val); else - CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n", val); + CDEBUG(D_CONFIG, "activate %ld: ignoring repeat request\n", + val); return count; } -LPROC_SEQ_FOPS(osc_active); +LUSTRE_RW_ATTR(active); -static int osc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v) +static ssize_t max_rpcs_in_flight_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; - client_obd_list_lock(&cli->cl_loi_list_lock); - seq_printf(m, "%u\n", cli->cl_max_rpcs_in_flight); - client_obd_list_unlock(&cli->cl_loi_list_lock); - - return 0; + return sprintf(buf, "%u\n", cli->cl_max_rpcs_in_flight); } -static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_rpcs_in_flight_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; struct ptlrpc_request_pool *pool = cli->cl_import->imp_rq_pool; - int val, rc; + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; if (val < 1 || val > OSC_MAX_RIF_MAX) return -ERANGE; - LPROCFS_CLIMP_CHECK(dev); if (pool && val > cli->cl_max_rpcs_in_flight) pool->prp_populate(pool, val-cli->cl_max_rpcs_in_flight); @@ -112,14 +114,16 @@ static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file, cli->cl_max_rpcs_in_flight = val; client_obd_list_unlock(&cli->cl_loi_list_lock); - LPROCFS_CLIMP_EXIT(dev); return count; } -LPROC_SEQ_FOPS(osc_max_rpcs_in_flight); +LUSTRE_RW_ATTR(max_rpcs_in_flight); -static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v) +static ssize_t max_dirty_mb_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; long val; int mult; @@ -129,22 +133,26 @@ static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v) client_obd_list_unlock(&cli->cl_loi_list_lock); mult = 1 << 20; - return lprocfs_seq_read_frac_helper(m, val, mult); + return lprocfs_read_frac_helper(buf, PAGE_SIZE, val, mult); } -static ssize_t osc_max_dirty_mb_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_dirty_mb_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; - int pages_number, mult, rc; + int rc; + unsigned long pages_number; - mult = 1 << (20 - PAGE_CACHE_SHIFT); - rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult); + rc = kstrtoul(buffer, 10, &pages_number); if (rc) return rc; + pages_number *= 1 << (20 - PAGE_CACHE_SHIFT); /* MB -> pages */ + if (pages_number <= 0 || pages_number > OSC_MAX_DIRTY_MB_MAX << (20 - PAGE_CACHE_SHIFT) || pages_number > totalram_pages / 4) /* 1/4 of RAM */ @@ -157,7 +165,7 @@ static ssize_t osc_max_dirty_mb_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(osc_max_dirty_mb); +LUSTRE_RW_ATTR(max_dirty_mb); static int osc_cached_mb_seq_show(struct seq_file *m, void *v) { @@ -210,44 +218,51 @@ static ssize_t osc_cached_mb_seq_write(struct file *file, } LPROC_SEQ_FOPS(osc_cached_mb); -static int osc_cur_dirty_bytes_seq_show(struct seq_file *m, void *v) +static ssize_t cur_dirty_bytes_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; + int len; client_obd_list_lock(&cli->cl_loi_list_lock); - seq_printf(m, "%lu\n", cli->cl_dirty); + len = sprintf(buf, "%lu\n", cli->cl_dirty); client_obd_list_unlock(&cli->cl_loi_list_lock); - return 0; + return len; } -LPROC_SEQ_FOPS_RO(osc_cur_dirty_bytes); +LUSTRE_RO_ATTR(cur_dirty_bytes); -static int osc_cur_grant_bytes_seq_show(struct seq_file *m, void *v) +static ssize_t cur_grant_bytes_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; + int len; client_obd_list_lock(&cli->cl_loi_list_lock); - seq_printf(m, "%lu\n", cli->cl_avail_grant); + len = sprintf(buf, "%lu\n", cli->cl_avail_grant); client_obd_list_unlock(&cli->cl_loi_list_lock); - return 0; + return len; } -static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t cur_grant_bytes_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &obd->u.cli; - int rc; - __u64 val; - - if (obd == NULL) - return 0; + int rc; + unsigned long long val; - rc = lprocfs_write_u64_helper(buffer, count, &val); + rc = kstrtoull(buffer, 10, &val); if (rc) return rc; @@ -255,54 +270,56 @@ static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, client_obd_list_lock(&cli->cl_loi_list_lock); if (val >= cli->cl_avail_grant) { client_obd_list_unlock(&cli->cl_loi_list_lock); - return 0; + return -EINVAL; } client_obd_list_unlock(&cli->cl_loi_list_lock); - LPROCFS_CLIMP_CHECK(obd); if (cli->cl_import->imp_state == LUSTRE_IMP_FULL) rc = osc_shrink_grant_to_target(cli, val); - LPROCFS_CLIMP_EXIT(obd); if (rc) return rc; return count; } -LPROC_SEQ_FOPS(osc_cur_grant_bytes); +LUSTRE_RW_ATTR(cur_grant_bytes); -static int osc_cur_lost_grant_bytes_seq_show(struct seq_file *m, void *v) +static ssize_t cur_lost_grant_bytes_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *dev = m->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; + int len; client_obd_list_lock(&cli->cl_loi_list_lock); - seq_printf(m, "%lu\n", cli->cl_lost_grant); + len = sprintf(buf, "%lu\n", cli->cl_lost_grant); client_obd_list_unlock(&cli->cl_loi_list_lock); - return 0; + return len; } -LPROC_SEQ_FOPS_RO(osc_cur_lost_grant_bytes); +LUSTRE_RO_ATTR(cur_lost_grant_bytes); -static int osc_grant_shrink_interval_seq_show(struct seq_file *m, void *v) +static ssize_t grant_shrink_interval_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - if (obd == NULL) - return 0; - seq_printf(m, "%d\n", obd->u.cli.cl_grant_shrink_interval); - return 0; + return sprintf(buf, "%d\n", obd->u.cli.cl_grant_shrink_interval); } -static ssize_t osc_grant_shrink_interval_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t grant_shrink_interval_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; - int val, rc; - - if (obd == NULL) - return 0; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -313,30 +330,29 @@ static ssize_t osc_grant_shrink_interval_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(osc_grant_shrink_interval); +LUSTRE_RW_ATTR(grant_shrink_interval); -static int osc_checksum_seq_show(struct seq_file *m, void *v) +static ssize_t checksums_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; - - if (obd == NULL) - return 0; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - seq_printf(m, "%d\n", obd->u.cli.cl_checksum ? 1 : 0); - return 0; + return sprintf(buf, "%d\n", obd->u.cli.cl_checksum ? 1 : 0); } -static ssize_t osc_checksum_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t checksums_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; - int val, rc; - - if (obd == NULL) - return 0; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -344,7 +360,7 @@ static ssize_t osc_checksum_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(osc_checksum); +LUSTRE_RW_ATTR(checksums); static int osc_checksum_type_seq_show(struct seq_file *m, void *v) { @@ -400,22 +416,27 @@ static ssize_t osc_checksum_type_seq_write(struct file *file, } LPROC_SEQ_FOPS(osc_checksum_type); -static int osc_resend_count_seq_show(struct seq_file *m, void *v) +static ssize_t resend_count_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends)); - return 0; + return sprintf(buf, "%u\n", atomic_read(&obd->u.cli.cl_resends)); } -static ssize_t osc_resend_count_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t resend_count_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; - int val, rc; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); + int rc; + unsigned long val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoul(buffer, 10, &val); if (rc) return rc; @@ -426,75 +447,94 @@ static ssize_t osc_resend_count_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(osc_resend_count); +LUSTRE_RW_ATTR(resend_count); -static int osc_contention_seconds_seq_show(struct seq_file *m, void *v) +static ssize_t contention_seconds_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct osc_device *od = obd2osc_dev(obd); - seq_printf(m, "%u\n", od->od_contention_time); - return 0; + return sprintf(buf, "%u\n", od->od_contention_time); } -static ssize_t osc_contention_seconds_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t contention_seconds_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct osc_device *od = obd2osc_dev(obd); return lprocfs_write_helper(buffer, count, &od->od_contention_time) ?: count; } -LPROC_SEQ_FOPS(osc_contention_seconds); +LUSTRE_RW_ATTR(contention_seconds); -static int osc_lockless_truncate_seq_show(struct seq_file *m, void *v) +static ssize_t lockless_truncate_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct osc_device *od = obd2osc_dev(obd); - seq_printf(m, "%u\n", od->od_lockless_truncate); - return 0; + return sprintf(buf, "%u\n", od->od_lockless_truncate); } -static ssize_t osc_lockless_truncate_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lockless_truncate_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); struct osc_device *od = obd2osc_dev(obd); return lprocfs_write_helper(buffer, count, &od->od_lockless_truncate) ?: count; } -LPROC_SEQ_FOPS(osc_lockless_truncate); +LUSTRE_RW_ATTR(lockless_truncate); -static int osc_destroys_in_flight_seq_show(struct seq_file *m, void *v) +static ssize_t destroys_in_flight_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct obd_device *obd = m->private; + struct obd_device *obd = container_of(kobj, struct obd_device, + obd_kobj); - seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_destroy_in_flight)); - return 0; + return sprintf(buf, "%u\n", + atomic_read(&obd->u.cli.cl_destroy_in_flight)); } -LPROC_SEQ_FOPS_RO(osc_destroys_in_flight); +LUSTRE_RO_ATTR(destroys_in_flight); -static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v) +static ssize_t max_pages_per_rpc_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - return lprocfs_obd_rd_max_pages_per_rpc(m, m->private); + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); + struct client_obd *cli = &dev->u.cli; + + return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); } -static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t max_pages_per_rpc_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kobj); struct client_obd *cli = &dev->u.cli; struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data; int chunk_mask, rc; - __u64 val; + unsigned long long val; - rc = lprocfs_write_u64_helper(buffer, count, &val); + rc = kstrtoull(buffer, 10, &val); if (rc) return rc; @@ -502,32 +542,21 @@ static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file, if (val >= ONE_MB_BRW_SIZE) val >>= PAGE_CACHE_SHIFT; - LPROCFS_CLIMP_CHECK(dev); - chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_CACHE_SHIFT)) - 1); /* max_pages_per_rpc must be chunk aligned */ val = (val + ~chunk_mask) & chunk_mask; if (val == 0 || val > ocd->ocd_brw_size >> PAGE_CACHE_SHIFT) { - LPROCFS_CLIMP_EXIT(dev); return -ERANGE; } client_obd_list_lock(&cli->cl_loi_list_lock); cli->cl_max_pages_per_rpc = val; client_obd_list_unlock(&cli->cl_loi_list_lock); - LPROCFS_CLIMP_EXIT(dev); return count; } -LPROC_SEQ_FOPS(osc_obd_max_pages_per_rpc); +LUSTRE_RW_ATTR(max_pages_per_rpc); -LPROC_SEQ_FOPS_RO_TYPE(osc, uuid); LPROC_SEQ_FOPS_RO_TYPE(osc, connect_flags); -LPROC_SEQ_FOPS_RO_TYPE(osc, blksize); -LPROC_SEQ_FOPS_RO_TYPE(osc, kbytestotal); -LPROC_SEQ_FOPS_RO_TYPE(osc, kbytesfree); -LPROC_SEQ_FOPS_RO_TYPE(osc, kbytesavail); -LPROC_SEQ_FOPS_RO_TYPE(osc, filestotal); -LPROC_SEQ_FOPS_RO_TYPE(osc, filesfree); LPROC_SEQ_FOPS_RO_TYPE(osc, server_uuid); LPROC_SEQ_FOPS_RO_TYPE(osc, conn_uuid); LPROC_SEQ_FOPS_RO_TYPE(osc, timeouts); @@ -539,46 +568,20 @@ LPROC_SEQ_FOPS_RW_TYPE(osc, import); LPROC_SEQ_FOPS_RW_TYPE(osc, pinger_recov); static struct lprocfs_vars lprocfs_osc_obd_vars[] = { - { "uuid", &osc_uuid_fops, NULL, 0 }, { "ping", &osc_ping_fops, NULL, 0222 }, { "connect_flags", &osc_connect_flags_fops, NULL, 0 }, - { "blocksize", &osc_blksize_fops, NULL, 0 }, - { "kbytestotal", &osc_kbytestotal_fops, NULL, 0 }, - { "kbytesfree", &osc_kbytesfree_fops, NULL, 0 }, - { "kbytesavail", &osc_kbytesavail_fops, NULL, 0 }, - { "filestotal", &osc_filestotal_fops, NULL, 0 }, - { "filesfree", &osc_filesfree_fops, NULL, 0 }, /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/ { "ost_server_uuid", &osc_server_uuid_fops, NULL, 0 }, { "ost_conn_uuid", &osc_conn_uuid_fops, NULL, 0 }, - { "active", &osc_active_fops, NULL }, - { "max_pages_per_rpc", &osc_obd_max_pages_per_rpc_fops, NULL }, - { "max_rpcs_in_flight", &osc_max_rpcs_in_flight_fops, NULL }, - { "destroys_in_flight", &osc_destroys_in_flight_fops, NULL, 0 }, - { "max_dirty_mb", &osc_max_dirty_mb_fops, NULL }, { "osc_cached_mb", &osc_cached_mb_fops, NULL }, - { "cur_dirty_bytes", &osc_cur_dirty_bytes_fops, NULL, 0 }, - { "cur_grant_bytes", &osc_cur_grant_bytes_fops, NULL }, - { "cur_lost_grant_bytes", &osc_cur_lost_grant_bytes_fops, NULL, 0}, - { "grant_shrink_interval", &osc_grant_shrink_interval_fops, NULL }, - { "checksums", &osc_checksum_fops, NULL }, { "checksum_type", &osc_checksum_type_fops, NULL }, - { "resend_count", &osc_resend_count_fops, NULL}, { "timeouts", &osc_timeouts_fops, NULL, 0 }, - { "contention_seconds", &osc_contention_seconds_fops, NULL }, - { "lockless_truncate", &osc_lockless_truncate_fops, NULL }, { "import", &osc_import_fops, NULL }, { "state", &osc_state_fops, NULL, 0 }, { "pinger_recov", &osc_pinger_recov_fops, NULL }, { NULL } }; -LPROC_SEQ_FOPS_RO_TYPE(osc, numrefs); -static struct lprocfs_vars lprocfs_osc_module_vars[] = { - { "num_refs", &osc_numrefs_fops, NULL, 0 }, - { NULL } -}; - #define pct(a, b) (b ? a * 100 / b : 0) static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v) @@ -679,8 +682,8 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v) #undef pct static ssize_t osc_rpc_stats_seq_write(struct file *file, - const char __user *buf, - size_t len, loff_t *off) + const char __user *buf, + size_t len, loff_t *off) { struct seq_file *seq = file->private_data; struct obd_device *dev = seq->private; @@ -718,8 +721,8 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v) } static ssize_t osc_stats_seq_write(struct file *file, - const char __user *buf, - size_t len, loff_t *off) + const char __user *buf, + size_t len, loff_t *off) { struct seq_file *seq = file->private_data; struct obd_device *dev = seq->private; @@ -735,17 +738,38 @@ int lproc_osc_attach_seqstat(struct obd_device *dev) { int rc; - rc = lprocfs_seq_create(dev->obd_proc_entry, "osc_stats", 0644, - &osc_stats_fops, dev); + rc = ldebugfs_seq_create(dev->obd_debugfs_entry, "osc_stats", 0644, + &osc_stats_fops, dev); if (rc == 0) - rc = lprocfs_obd_seq_create(dev, "rpc_stats", 0644, - &osc_rpc_stats_fops, dev); + rc = ldebugfs_obd_seq_create(dev, "rpc_stats", 0644, + &osc_rpc_stats_fops, dev); return rc; } +static struct attribute *osc_attrs[] = { + &lustre_attr_active.attr, + &lustre_attr_checksums.attr, + &lustre_attr_contention_seconds.attr, + &lustre_attr_cur_dirty_bytes.attr, + &lustre_attr_cur_grant_bytes.attr, + &lustre_attr_cur_lost_grant_bytes.attr, + &lustre_attr_destroys_in_flight.attr, + &lustre_attr_grant_shrink_interval.attr, + &lustre_attr_lockless_truncate.attr, + &lustre_attr_max_dirty_mb.attr, + &lustre_attr_max_pages_per_rpc.attr, + &lustre_attr_max_rpcs_in_flight.attr, + &lustre_attr_resend_count.attr, + NULL, +}; + +static struct attribute_group osc_attr_group = { + .attrs = osc_attrs, +}; + void lprocfs_osc_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_osc_module_vars; + lvars->sysfs_vars = &osc_attr_group; lvars->obd_vars = lprocfs_osc_obd_vars; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index d44b3d4ffe4d..5592d32a1a95 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -112,8 +112,8 @@ static const char *oes_strings[] = { /* ----- extent part 0 ----- */ \ __ext, EXTPARA(__ext), \ /* ----- part 1 ----- */ \ - atomic_read(&__ext->oe_refc), \ - atomic_read(&__ext->oe_users), \ + atomic_read(&__ext->oe_refc), \ + atomic_read(&__ext->oe_users), \ list_empty_marker(&__ext->oe_link), \ oes_strings[__ext->oe_state], ext_flags(__ext, __buf), \ __ext->oe_obj, \ @@ -297,12 +297,12 @@ out: #define sanity_check_nolock(ext) \ osc_extent_sanity_check0(ext, __func__, __LINE__) -#define sanity_check(ext) ({ \ - int __res; \ +#define sanity_check(ext) ({ \ + int __res; \ osc_object_lock((ext)->oe_obj); \ - __res = sanity_check_nolock(ext); \ - osc_object_unlock((ext)->oe_obj); \ - __res; \ + __res = sanity_check_nolock(ext); \ + osc_object_unlock((ext)->oe_obj); \ + __res; \ }) @@ -411,7 +411,7 @@ static void osc_extent_put_trust(struct osc_extent *ext) static struct osc_extent *osc_extent_search(struct osc_object *obj, pgoff_t index) { - struct rb_node *n = obj->oo_root.rb_node; + struct rb_node *n = obj->oo_root.rb_node; struct osc_extent *tmp, *p = NULL; LASSERT(osc_object_is_locked(obj)); @@ -447,8 +447,8 @@ static struct osc_extent *osc_extent_lookup(struct osc_object *obj, /* caller must have held object lock. */ static void osc_extent_insert(struct osc_object *obj, struct osc_extent *ext) { - struct rb_node **n = &obj->oo_root.rb_node; - struct rb_node *parent = NULL; + struct rb_node **n = &obj->oo_root.rb_node; + struct rb_node *parent = NULL; struct osc_extent *tmp; LASSERT(ext->oe_intree == 0); @@ -544,19 +544,19 @@ static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur, LASSERT(cur->oe_osclock == victim->oe_osclock); ppc_bits = osc_cli(obj)->cl_chunkbits - PAGE_CACHE_SHIFT; chunk_start = cur->oe_start >> ppc_bits; - chunk_end = cur->oe_end >> ppc_bits; - if (chunk_start != (victim->oe_end >> ppc_bits) + 1 && + chunk_end = cur->oe_end >> ppc_bits; + if (chunk_start != (victim->oe_end >> ppc_bits) + 1 && chunk_end + 1 != victim->oe_start >> ppc_bits) return -ERANGE; OSC_EXTENT_DUMP(D_CACHE, victim, "will be merged by %p.\n", cur); - cur->oe_start = min(cur->oe_start, victim->oe_start); - cur->oe_end = max(cur->oe_end, victim->oe_end); - cur->oe_grants += victim->oe_grants; + cur->oe_start = min(cur->oe_start, victim->oe_start); + cur->oe_end = max(cur->oe_end, victim->oe_end); + cur->oe_grants += victim->oe_grants; cur->oe_nr_pages += victim->oe_nr_pages; /* only the following bits are needed to merge */ - cur->oe_urgent |= victim->oe_urgent; + cur->oe_urgent |= victim->oe_urgent; cur->oe_memalloc |= victim->oe_memalloc; list_splice_init(&victim->oe_pages, &cur->oe_pages); list_del_init(&victim->oe_link); @@ -624,18 +624,18 @@ struct osc_extent *osc_extent_find(const struct lu_env *env, { struct client_obd *cli = osc_cli(obj); - struct cl_lock *lock; + struct cl_lock *lock; struct osc_extent *cur; struct osc_extent *ext; struct osc_extent *conflict = NULL; struct osc_extent *found = NULL; - pgoff_t chunk; - pgoff_t max_end; - int max_pages; /* max_pages_per_rpc */ - int chunksize; - int ppc_bits; /* pages per chunk bits */ - int chunk_mask; - int rc; + pgoff_t chunk; + pgoff_t max_end; + int max_pages; /* max_pages_per_rpc */ + int chunksize; + int ppc_bits; /* pages per chunk bits */ + int chunk_mask; + int rc; cur = osc_extent_alloc(obj); if (cur == NULL) @@ -646,10 +646,10 @@ struct osc_extent *osc_extent_find(const struct lu_env *env, LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); LASSERT(cli->cl_chunkbits >= PAGE_CACHE_SHIFT); - ppc_bits = cli->cl_chunkbits - PAGE_CACHE_SHIFT; + ppc_bits = cli->cl_chunkbits - PAGE_CACHE_SHIFT; chunk_mask = ~((1 << ppc_bits) - 1); - chunksize = 1 << cli->cl_chunkbits; - chunk = index >> ppc_bits; + chunksize = 1 << cli->cl_chunkbits; + chunk = index >> ppc_bits; /* align end to rpc edge, rpc size may not be a power 2 integer. */ max_pages = cli->cl_max_pages_per_rpc; @@ -659,15 +659,15 @@ struct osc_extent *osc_extent_find(const struct lu_env *env, /* initialize new extent by parameters so far */ cur->oe_max_end = max_end; - cur->oe_start = index & chunk_mask; - cur->oe_end = ((index + ~chunk_mask + 1) & chunk_mask) - 1; + cur->oe_start = index & chunk_mask; + cur->oe_end = ((index + ~chunk_mask + 1) & chunk_mask) - 1; if (cur->oe_start < lock->cll_descr.cld_start) cur->oe_start = lock->cll_descr.cld_start; if (cur->oe_end > max_end) cur->oe_end = max_end; cur->oe_osclock = lock; - cur->oe_grants = 0; - cur->oe_mppr = max_pages; + cur->oe_grants = 0; + cur->oe_mppr = max_pages; /* grants has been allocated by caller */ LASSERTF(*grants >= chunksize + cli->cl_extent_tax, @@ -681,7 +681,7 @@ restart: ext = first_extent(obj); while (ext != NULL) { loff_t ext_chk_start = ext->oe_start >> ppc_bits; - loff_t ext_chk_end = ext->oe_end >> ppc_bits; + loff_t ext_chk_end = ext->oe_end >> ppc_bits; LASSERT(sanity_check_nolock(ext) == 0); if (chunk > ext_chk_end + 1) @@ -755,14 +755,14 @@ restart: EASSERT((ext->oe_start & ~chunk_mask) == 0, ext); /* pull ext's start back to cover cur */ - ext->oe_start = cur->oe_start; + ext->oe_start = cur->oe_start; ext->oe_grants += chunksize; *grants -= chunksize; found = osc_extent_hold(ext); } else if (chunk == ext_chk_end + 1) { /* rear merge */ - ext->oe_end = cur->oe_end; + ext->oe_end = cur->oe_end; ext->oe_grants += chunksize; *grants -= chunksize; @@ -943,21 +943,21 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext, * @size, then partial truncate happens. */ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, - bool partial) + bool partial) { - struct cl_env_nest nest; - struct lu_env *env; - struct cl_io *io; - struct osc_object *obj = ext->oe_obj; - struct client_obd *cli = osc_cli(obj); + struct cl_env_nest nest; + struct lu_env *env; + struct cl_io *io; + struct osc_object *obj = ext->oe_obj; + struct client_obd *cli = osc_cli(obj); struct osc_async_page *oap; struct osc_async_page *tmp; - int pages_in_chunk = 0; - int ppc_bits = cli->cl_chunkbits - PAGE_CACHE_SHIFT; - __u64 trunc_chunk = trunc_index >> ppc_bits; - int grants = 0; - int nr_pages = 0; - int rc = 0; + int pages_in_chunk = 0; + int ppc_bits = cli->cl_chunkbits - PAGE_CACHE_SHIFT; + __u64 trunc_chunk = trunc_index >> ppc_bits; + int grants = 0; + int nr_pages = 0; + int rc = 0; LASSERT(sanity_check(ext) == 0); EASSERT(ext->oe_state == OES_TRUNC, ext); @@ -976,8 +976,8 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, /* discard all pages with index greater then trunc_index */ list_for_each_entry_safe(oap, tmp, &ext->oe_pages, oap_pending_item) { - struct cl_page *sub = oap2cl_page(oap); - struct cl_page *page = cl_page_top(sub); + struct cl_page *sub = oap2cl_page(oap); + struct cl_page *page = cl_page_top(sub); LASSERT(list_empty(&oap->oap_rpc_item)); @@ -1022,7 +1022,7 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, grants = ext->oe_grants; ext->oe_grants = 0; } else { /* calculate how many grants we can free */ - int chunks = (ext->oe_end >> ppc_bits) - trunc_chunk; + int chunks = (ext->oe_end >> ppc_bits) - trunc_chunk; pgoff_t last_index; @@ -1038,10 +1038,10 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, } /* this is what we can free from this extent */ - grants = chunks << cli->cl_chunkbits; + grants = chunks << cli->cl_chunkbits; ext->oe_grants -= grants; - last_index = ((trunc_chunk + 1) << ppc_bits) - 1; - ext->oe_end = min(last_index, ext->oe_max_end); + last_index = ((trunc_chunk + 1) << ppc_bits) - 1; + ext->oe_end = min(last_index, ext->oe_max_end); LASSERT(ext->oe_end >= ext->oe_start); LASSERT(ext->oe_grants > 0); } @@ -1236,8 +1236,8 @@ static inline int osc_is_ready(struct osc_object *osc) static int osc_make_ready(const struct lu_env *env, struct osc_async_page *oap, int cmd) { - struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = cl_page_top(oap2cl_page(oap)); + struct osc_page *opg = oap2osc_page(oap); + struct cl_page *page = cl_page_top(oap2cl_page(oap)); int result; LASSERT(cmd == OBD_BRW_WRITE); /* no cached reads */ @@ -1251,10 +1251,10 @@ static int osc_make_ready(const struct lu_env *env, struct osc_async_page *oap, static int osc_refresh_count(const struct lu_env *env, struct osc_async_page *oap, int cmd) { - struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = oap2cl_page(oap); + struct osc_page *opg = oap2osc_page(oap); + struct cl_page *page = oap2cl_page(oap); struct cl_object *obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; int result; loff_t kms; @@ -1283,10 +1283,10 @@ static int osc_refresh_count(const struct lu_env *env, static int osc_completion(const struct lu_env *env, struct osc_async_page *oap, int cmd, int rc) { - struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = cl_page_top(oap2cl_page(oap)); - struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); - enum cl_req_type crt; + struct osc_page *opg = oap2osc_page(oap); + struct cl_page *page = cl_page_top(oap2cl_page(oap)); + struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); + enum cl_req_type crt; int srvlock; cmd &= ~OBD_BRW_NOQUOTA; @@ -1318,7 +1318,7 @@ static int osc_completion(const struct lu_env *env, struct osc_async_page *oap, /* statistic */ if (rc == 0 && srvlock) { - struct lu_device *ld = opg->ops_cl.cpl_obj->co_lu.lo_dev; + struct lu_device *ld = opg->ops_cl.cpl_obj->co_lu.lo_dev; struct osc_stats *stats = &lu2osc_dev(ld)->od_stats; int bytes = oap->oap_count; @@ -1396,7 +1396,7 @@ static int osc_reserve_grant(struct client_obd *cli, unsigned int bytes) int rc = -EDQUOT; if (cli->cl_avail_grant >= bytes) { - cli->cl_avail_grant -= bytes; + cli->cl_avail_grant -= bytes; cli->cl_reserved_grant += bytes; rc = 0; } @@ -1527,7 +1527,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, struct osc_async_page *oap, int bytes) { struct osc_object *osc = oap->oap_obj; - struct lov_oinfo *loi = osc->oo_oinfo; + struct lov_oinfo *loi = osc->oo_oinfo; struct osc_cache_waiter ocw; struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL); int rc = -EDQUOT; @@ -1782,7 +1782,7 @@ static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli, struct osc_async_page *oap, int sent, int rc) { struct osc_object *osc = oap->oap_obj; - struct lov_oinfo *loi = osc->oo_oinfo; + struct lov_oinfo *loi = osc->oo_oinfo; __u64 xid = 0; if (oap->oap_request != NULL) { @@ -2049,7 +2049,7 @@ osc_send_read_rpc(const struct lu_env *env, struct client_obd *cli, #define list_to_obj(list, item) ({ \ struct list_head *__tmp = (list)->next; \ - list_del_init(__tmp); \ + list_del_init(__tmp); \ list_entry(__tmp, struct osc_object, oo_##item); \ }) @@ -2179,7 +2179,7 @@ static int osc_io_unplug0(const struct lu_env *env, struct client_obd *cli, } static int osc_io_unplug_async(const struct lu_env *env, - struct client_obd *cli, struct osc_object *osc) + struct client_obd *cli, struct osc_object *osc) { /* XXX: policy is no use actually. */ return osc_io_unplug0(env, cli, osc, PDL_POLICY_ROUND, 1); @@ -2194,7 +2194,7 @@ void osc_io_unplug(const struct lu_env *env, struct client_obd *cli, int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops, struct page *page, loff_t offset) { - struct obd_export *exp = osc_export(osc); + struct obd_export *exp = osc_export(osc); struct osc_async_page *oap = &ops->ops_oap; if (!page) @@ -2224,16 +2224,16 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, struct osc_page *ops) { struct osc_io *oio = osc_env_io(env); - struct osc_extent *ext = NULL; + struct osc_extent *ext = NULL; struct osc_async_page *oap = &ops->ops_oap; - struct client_obd *cli = oap->oap_cli; - struct osc_object *osc = oap->oap_obj; + struct client_obd *cli = oap->oap_cli; + struct osc_object *osc = oap->oap_obj; pgoff_t index; - int grants = 0; - int brw_flags = OBD_BRW_ASYNC; - int cmd = OBD_BRW_WRITE; - int need_release = 0; - int rc = 0; + int grants = 0; + int brw_flags = OBD_BRW_ASYNC; + int cmd = OBD_BRW_WRITE; + int need_release = 0; + int rc = 0; if (oap->oap_magic != OAP_MAGIC) return -EINVAL; @@ -2256,7 +2256,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, /* check if the file's owner/group is over quota */ if (!(cmd & OBD_BRW_NOQUOTA)) { struct cl_object *obj; - struct cl_attr *attr; + struct cl_attr *attr; unsigned int qid[MAXQUOTAS]; obj = cl_object_top(&osc->oo_cl); @@ -2386,7 +2386,7 @@ int osc_teardown_async_page(const struct lu_env *env, struct osc_object *obj, struct osc_page *ops) { struct osc_async_page *oap = &ops->ops_oap; - struct osc_extent *ext = NULL; + struct osc_extent *ext = NULL; int rc = 0; LASSERT(oap->oap_magic == OAP_MAGIC); @@ -2425,10 +2425,10 @@ int osc_teardown_async_page(const struct lu_env *env, int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, struct osc_page *ops) { - struct osc_extent *ext = NULL; - struct osc_object *obj = cl2osc(ops->ops_cl.cpl_obj); - struct cl_page *cp = ops->ops_cl.cpl_page; - pgoff_t index = cp->cp_index; + struct osc_extent *ext = NULL; + struct osc_object *obj = cl2osc(ops->ops_cl.cpl_obj); + struct cl_page *cp = ops->ops_cl.cpl_page; + pgoff_t index = cp->cp_index; struct osc_async_page *oap = &ops->ops_oap; bool unplug = false; int rc = 0; @@ -2507,14 +2507,14 @@ out: int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops) { struct osc_async_page *oap = &ops->ops_oap; - struct osc_object *obj = oap->oap_obj; - struct client_obd *cli = osc_cli(obj); - struct osc_extent *ext; - struct osc_extent *found = NULL; - struct list_head *plist; + struct osc_object *obj = oap->oap_obj; + struct client_obd *cli = osc_cli(obj); + struct osc_extent *ext; + struct osc_extent *found = NULL; + struct list_head *plist; pgoff_t index = oap2cl_page(oap)->cp_index; - int rc = -EBUSY; - int cmd; + int rc = -EBUSY; + int cmd; LASSERT(!oap->oap_interrupted); oap->oap_interrupted = 1; @@ -2523,10 +2523,10 @@ int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops) osc_object_lock(obj); if (oap->oap_cmd & OBD_BRW_WRITE) { plist = &obj->oo_urgent_exts; - cmd = OBD_BRW_WRITE; + cmd = OBD_BRW_WRITE; } else { plist = &obj->oo_reading_exts; - cmd = OBD_BRW_READ; + cmd = OBD_BRW_READ; } list_for_each_entry(ext, plist, oe_link) { if (ext->oe_start <= index && ext->oe_end >= index) { @@ -2564,13 +2564,13 @@ int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops) int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj, struct list_head *list, int cmd, int brw_flags) { - struct client_obd *cli = osc_cli(obj); - struct osc_extent *ext; + struct client_obd *cli = osc_cli(obj); + struct osc_extent *ext; struct osc_async_page *oap, *tmp; - int page_count = 0; - int mppr = cli->cl_max_pages_per_rpc; - pgoff_t start = CL_PAGE_EOF; - pgoff_t end = 0; + int page_count = 0; + int mppr = cli->cl_max_pages_per_rpc; + pgoff_t start = CL_PAGE_EOF; + pgoff_t end = 0; list_for_each_entry(oap, list, oap_pending_item) { struct cl_page *cp = oap2cl_page(oap); @@ -2785,7 +2785,7 @@ int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj, { struct osc_extent *ext; pgoff_t index = start; - int result = 0; + int result = 0; again: osc_object_lock(obj); diff --git a/drivers/staging/lustre/lustre/osc/osc_dev.c b/drivers/staging/lustre/lustre/osc/osc_dev.c index ce5c3af1237b..9222c9f4faae 100644 --- a/drivers/staging/lustre/lustre/osc/osc_dev.c +++ b/drivers/staging/lustre/lustre/osc/osc_dev.c @@ -118,7 +118,7 @@ static struct lu_device *osc2lu_dev(struct osc_device *osc) */ static void *osc_key_init(const struct lu_context *ctx, - struct lu_context_key *key) + struct lu_context_key *key) { struct osc_thread_info *info; @@ -248,14 +248,14 @@ static const struct lu_device_type_operations osc_device_type_ops = { .ldto_device_alloc = osc_device_alloc, .ldto_device_free = osc_device_free, - .ldto_device_init = osc_device_init, - .ldto_device_fini = osc_device_fini + .ldto_device_init = osc_device_init, + .ldto_device_fini = osc_device_fini }; struct lu_device_type osc_device_type = { - .ldt_tags = LU_DEVICE_CL, - .ldt_name = LUSTRE_OSC_NAME, - .ldt_ops = &osc_device_type_ops, + .ldt_tags = LU_DEVICE_CL, + .ldt_name = LUSTRE_OSC_NAME, + .ldt_ops = &osc_device_type_ops, .ldt_ctx_tags = LCT_CL_THREAD }; diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index af96c7bc7764..470698b0dd75 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -136,16 +136,8 @@ extern spinlock_t osc_ast_guard; int osc_cleanup(struct obd_device *obd); int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg); -#if defined (CONFIG_PROC_FS) int lproc_osc_attach_seqstat(struct obd_device *dev); void lprocfs_osc_init_vars(struct lprocfs_static_vars *lvars); -#else -static inline int lproc_osc_attach_seqstat(struct obd_device *dev) {return 0;} -static inline void lprocfs_osc_init_vars(struct lprocfs_static_vars *lvars) -{ - memset(lvars, 0, sizeof(*lvars)); -} -#endif extern struct lu_device_type osc_device_type; diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 3c7300b0651d..fa24e9ed1831 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -100,16 +100,16 @@ static int osc_io_submit(const struct lu_env *env, const struct cl_io_slice *ios, enum cl_req_type crt, struct cl_2queue *queue) { - struct cl_page *page; - struct cl_page *tmp; - struct client_obd *cli = NULL; - struct osc_object *osc = NULL; /* to keep gcc happy */ - struct osc_page *opg; - struct cl_io *io; + struct cl_page *page; + struct cl_page *tmp; + struct client_obd *cli = NULL; + struct osc_object *osc = NULL; /* to keep gcc happy */ + struct osc_page *opg; + struct cl_io *io; LIST_HEAD(list); - struct cl_page_list *qin = &queue->c2_qin; - struct cl_page_list *qout = &queue->c2_qout; + struct cl_page_list *qin = &queue->c2_qin; + struct cl_page_list *qout = &queue->c2_qout; int queued = 0; int result = 0; int cmd; @@ -189,8 +189,8 @@ static int osc_io_submit(const struct lu_env *env, static void osc_page_touch_at(const struct lu_env *env, struct cl_object *obj, pgoff_t idx, unsigned to) { - struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; int valid; __u64 kms; @@ -233,8 +233,8 @@ static void osc_page_touch_at(const struct lu_env *env, static void osc_page_touch(const struct lu_env *env, struct osc_page *opage, unsigned to) { - struct cl_page *page = opage->ops_cl.cpl_page; - struct cl_object *obj = opage->ops_cl.cpl_obj; + struct cl_page *page = opage->ops_cl.cpl_page; + struct cl_object *obj = opage->ops_cl.cpl_obj; osc_page_touch_at(env, obj, page->cp_index, to); } @@ -260,7 +260,7 @@ static int osc_io_prepare_write(const struct lu_env *env, { struct osc_device *dev = lu2osc_dev(slice->cpl_obj->co_lu.lo_dev); struct obd_import *imp = class_exp2cliimp(dev->od_exp); - struct osc_io *oio = cl2osc_io(env, ios); + struct osc_io *oio = cl2osc_io(env, ios); int result = 0; /* @@ -284,9 +284,9 @@ static int osc_io_commit_write(const struct lu_env *env, const struct cl_page_slice *slice, unsigned from, unsigned to) { - struct osc_io *oio = cl2osc_io(env, ios); - struct osc_page *opg = cl2osc_page(slice); - struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); + struct osc_io *oio = cl2osc_io(env, ios); + struct osc_page *opg = cl2osc_page(slice); + struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); struct osc_async_page *oap = &opg->ops_oap; LASSERT(to > 0); @@ -311,10 +311,10 @@ static int osc_io_commit_write(const struct lu_env *env, static int osc_io_fault_start(const struct lu_env *env, const struct cl_io_slice *ios) { - struct cl_io *io; + struct cl_io *io; struct cl_fault_io *fio; - io = ios->cis_io; + io = ios->cis_io; fio = &io->u.ci_fault; CDEBUG(D_INFO, "%lu %d %d\n", fio->ft_index, fio->ft_writable, fio->ft_nob); @@ -375,11 +375,11 @@ static void osc_trunc_check(const struct lu_env *env, struct cl_io *io, struct osc_io *oio, __u64 size) { struct cl_object *clob; - int partial; + int partial; pgoff_t start; - clob = oio->oi_cl.cis_obj; - start = cl_index(clob, size); + clob = oio->oi_cl.cis_obj; + start = cl_index(clob, size); partial = cl_offset(clob, start) < size; /* @@ -392,17 +392,17 @@ static void osc_trunc_check(const struct lu_env *env, struct cl_io *io, static int osc_io_setattr_start(const struct lu_env *env, const struct cl_io_slice *slice) { - struct cl_io *io = slice->cis_io; - struct osc_io *oio = cl2osc_io(env, slice); - struct cl_object *obj = slice->cis_obj; - struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; - struct obdo *oa = &oio->oi_oa; + struct cl_io *io = slice->cis_io; + struct osc_io *oio = cl2osc_io(env, slice); + struct cl_object *obj = slice->cis_obj; + struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct obdo *oa = &oio->oi_oa; struct osc_async_cbargs *cbargs = &oio->oi_cbarg; - __u64 size = io->u.ci_setattr.sa_attr.lvb_size; - unsigned int ia_valid = io->u.ci_setattr.sa_valid; - int result = 0; - struct obd_info oinfo = { { { 0 } } }; + __u64 size = io->u.ci_setattr.sa_attr.lvb_size; + unsigned int ia_valid = io->u.ci_setattr.sa_valid; + int result = 0; + struct obd_info oinfo = { { { 0 } } }; /* truncate cache dirty pages first */ if (cl_io_is_trunc(io)) @@ -477,8 +477,8 @@ static int osc_io_setattr_start(const struct lu_env *env, static void osc_io_setattr_end(const struct lu_env *env, const struct cl_io_slice *slice) { - struct cl_io *io = slice->cis_io; - struct osc_io *oio = cl2osc_io(env, slice); + struct cl_io *io = slice->cis_io; + struct osc_io *oio = cl2osc_io(env, slice); struct cl_object *obj = slice->cis_obj; struct osc_async_cbargs *cbargs = &oio->oi_cbarg; int result = 0; @@ -512,8 +512,8 @@ static void osc_io_setattr_end(const struct lu_env *env, static int osc_io_read_start(const struct lu_env *env, const struct cl_io_slice *slice) { - struct cl_object *obj = slice->cis_obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct cl_object *obj = slice->cis_obj; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; int rc = 0; if (!slice->cis_io->ci_noatime) { @@ -528,8 +528,8 @@ static int osc_io_read_start(const struct lu_env *env, static int osc_io_write_start(const struct lu_env *env, const struct cl_io_slice *slice) { - struct cl_object *obj = slice->cis_obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct cl_object *obj = slice->cis_obj; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; int rc = 0; OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_SETTIME, 1); @@ -544,10 +544,10 @@ static int osc_io_write_start(const struct lu_env *env, static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj, struct cl_fsync_io *fio) { - struct osc_io *oio = osc_env_io(env); - struct obdo *oa = &oio->oi_oa; - struct obd_info *oinfo = &oio->oi_info; - struct lov_oinfo *loi = obj->oo_oinfo; + struct osc_io *oio = osc_env_io(env); + struct obdo *oa = &oio->oi_oa; + struct obd_info *oinfo = &oio->oi_info; + struct lov_oinfo *loi = obj->oo_oinfo; struct osc_async_cbargs *cbargs = &oio->oi_cbarg; int rc = 0; @@ -575,13 +575,13 @@ static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj, static int osc_io_fsync_start(const struct lu_env *env, const struct cl_io_slice *slice) { - struct cl_io *io = slice->cis_io; + struct cl_io *io = slice->cis_io; struct cl_fsync_io *fio = &io->u.ci_fsync; - struct cl_object *obj = slice->cis_obj; - struct osc_object *osc = cl2osc(obj); - pgoff_t start = cl_index(obj, fio->fi_start); - pgoff_t end = cl_index(obj, fio->fi_end); - int result = 0; + struct cl_object *obj = slice->cis_obj; + struct osc_object *osc = cl2osc(obj); + pgoff_t start = cl_index(obj, fio->fi_start); + pgoff_t end = cl_index(obj, fio->fi_end); + int result = 0; if (fio->fi_end == OBD_OBJECT_EOF) end = CL_PAGE_EOF; @@ -615,15 +615,15 @@ static void osc_io_fsync_end(const struct lu_env *env, const struct cl_io_slice *slice) { struct cl_fsync_io *fio = &slice->cis_io->u.ci_fsync; - struct cl_object *obj = slice->cis_obj; + struct cl_object *obj = slice->cis_obj; pgoff_t start = cl_index(obj, fio->fi_start); - pgoff_t end = cl_index(obj, fio->fi_end); + pgoff_t end = cl_index(obj, fio->fi_end); int result = 0; if (fio->fi_mode == CL_FSYNC_LOCAL) { result = osc_cache_wait_range(env, cl2osc(obj), start, end); } else if (fio->fi_mode == CL_FSYNC_ALL) { - struct osc_io *oio = cl2osc_io(env, slice); + struct osc_io *oio = cl2osc_io(env, slice); struct osc_async_cbargs *cbargs = &oio->oi_cbarg; wait_for_completion(&cbargs->opc_sync); @@ -717,17 +717,17 @@ static void osc_req_attr_set(const struct lu_env *env, struct cl_req_attr *attr, u64 flags) { struct lov_oinfo *oinfo; - struct cl_req *clerq; - struct cl_page *apage; /* _some_ page in @clerq */ - struct cl_lock *lock; /* _some_ lock protecting @apage */ - struct osc_lock *olck; - struct osc_page *opg; - struct obdo *oa; - struct ost_lvb *lvb; - - oinfo = cl2osc(obj)->oo_oinfo; - lvb = &oinfo->loi_lvb; - oa = attr->cra_oa; + struct cl_req *clerq; + struct cl_page *apage; /* _some_ page in @clerq */ + struct cl_lock *lock; /* _some_ lock protecting @apage */ + struct osc_lock *olck; + struct osc_page *opg; + struct obdo *oa; + struct ost_lvb *lvb; + + oinfo = cl2osc(obj)->oo_oinfo; + lvb = &oinfo->loi_lvb; + oa = attr->cra_oa; if ((flags & OBD_MD_FLMTIME) != 0) { oa->o_mtime = lvb->lvb_mtime; @@ -759,7 +759,7 @@ static void osc_req_attr_set(const struct lu_env *env, lock = cl_lock_at_page(env, apage->cp_obj, apage, NULL, 1, 1); if (lock == NULL) { struct cl_object_header *head; - struct cl_lock *scan; + struct cl_lock *scan; head = cl_object_header(apage->cp_obj); list_for_each_entry(scan, &head->coh_locks, diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 350ad49550ab..70b1b43f692b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -89,9 +89,9 @@ static struct ldlm_lock *osc_handle_ptr(struct lustre_handle *handle) */ static int osc_lock_invariant(struct osc_lock *ols) { - struct ldlm_lock *lock = osc_handle_ptr(&ols->ols_handle); - struct ldlm_lock *olock = ols->ols_lock; - int handle_used = lustre_handle_is_used(&ols->ols_handle); + struct ldlm_lock *lock = osc_handle_ptr(&ols->ols_handle); + struct ldlm_lock *olock = ols->ols_lock; + int handle_used = lustre_handle_is_used(&ols->ols_handle); if (ergo(osc_lock_is_lockless(ols), ols->ols_locklessable && ols->ols_lock == NULL)) @@ -164,7 +164,7 @@ static void osc_lock_detach(const struct lu_env *env, struct osc_lock *olck) lock_res_and_lock(dlmlock); if (dlmlock->l_granted_mode == dlmlock->l_req_mode) { struct cl_object *obj = olck->ols_cl.cls_obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; __u64 old_kms; cl_object_attr_lock(obj); @@ -237,7 +237,7 @@ static int osc_lock_unuse(const struct lu_env *env, static void osc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) { - struct osc_lock *ols = cl2osc_lock(slice); + struct osc_lock *ols = cl2osc_lock(slice); LINVRNT(osc_lock_invariant(ols)); /* @@ -337,25 +337,25 @@ static void osc_ast_data_put(const struct lu_env *env, struct osc_lock *olck) static void osc_lock_lvb_update(const struct lu_env *env, struct osc_lock *olck, int rc) { - struct ost_lvb *lvb; - struct cl_object *obj; - struct lov_oinfo *oinfo; - struct cl_attr *attr; - unsigned valid; + struct ost_lvb *lvb; + struct cl_object *obj; + struct lov_oinfo *oinfo; + struct cl_attr *attr; + unsigned valid; if (!(olck->ols_flags & LDLM_FL_LVB_READY)) return; - lvb = &olck->ols_lvb; - obj = olck->ols_cl.cls_obj; + lvb = &olck->ols_lvb; + obj = olck->ols_cl.cls_obj; oinfo = cl2osc(obj)->oo_oinfo; - attr = &osc_env_info(env)->oti_attr; + attr = &osc_env_info(env)->oti_attr; valid = CAT_BLOCKS | CAT_ATIME | CAT_CTIME | CAT_MTIME | CAT_SIZE; cl_lvb2attr(attr, lvb); cl_object_attr_lock(obj); if (rc == 0) { - struct ldlm_lock *dlmlock; + struct ldlm_lock *dlmlock; __u64 size; dlmlock = olck->ols_lock; @@ -401,23 +401,23 @@ static void osc_lock_lvb_update(const struct lu_env *env, struct osc_lock *olck, static void osc_lock_granted(const struct lu_env *env, struct osc_lock *olck, struct ldlm_lock *dlmlock, int rc) { - struct ldlm_extent *ext; - struct cl_lock *lock; + struct ldlm_extent *ext; + struct cl_lock *lock; struct cl_lock_descr *descr; LASSERT(dlmlock->l_granted_mode == dlmlock->l_req_mode); if (olck->ols_state < OLS_GRANTED) { - lock = olck->ols_cl.cls_lock; - ext = &dlmlock->l_policy_data.l_extent; + lock = olck->ols_cl.cls_lock; + ext = &dlmlock->l_policy_data.l_extent; descr = &osc_env_info(env)->oti_descr; descr->cld_obj = lock->cll_descr.cld_obj; /* XXX check that ->l_granted_mode is valid. */ - descr->cld_mode = osc_ldlm2cl_lock(dlmlock->l_granted_mode); + descr->cld_mode = osc_ldlm2cl_lock(dlmlock->l_granted_mode); descr->cld_start = cl_index(descr->cld_obj, ext->start); - descr->cld_end = cl_index(descr->cld_obj, ext->end); - descr->cld_gid = ext->gid; + descr->cld_end = cl_index(descr->cld_obj, ext->end); + descr->cld_gid = ext->gid; /* * tell upper layers the extent of the lock that was actually * granted @@ -482,11 +482,11 @@ static void osc_lock_upcall0(const struct lu_env *env, struct osc_lock *olck) */ static int osc_lock_upcall(void *cookie, int errcode) { - struct osc_lock *olck = cookie; - struct cl_lock_slice *slice = &olck->ols_cl; - struct cl_lock *lock = slice->cls_lock; - struct lu_env *env; - struct cl_env_nest nest; + struct osc_lock *olck = cookie; + struct cl_lock_slice *slice = &olck->ols_cl; + struct cl_lock *lock = slice->cls_lock; + struct lu_env *env; + struct cl_env_nest nest; env = cl_env_nested_get(&nest); if (!IS_ERR(env)) { @@ -626,7 +626,7 @@ static int osc_dlm_blocking_ast0(const struct lu_env *env, void *data, int flag) { struct osc_lock *olck; - struct cl_lock *lock; + struct cl_lock *lock; int result; int cancel; @@ -733,9 +733,9 @@ static int osc_ldlm_blocking_ast(struct ldlm_lock *dlmlock, struct ldlm_lock_desc *new, void *data, int flag) { - struct lu_env *env; + struct lu_env *env; struct cl_env_nest nest; - int result; + int result; /* * This can be called in the context of outer IO, e.g., @@ -774,9 +774,9 @@ static int osc_ldlm_completion_ast(struct ldlm_lock *dlmlock, __u64 flags, void *data) { struct cl_env_nest nest; - struct lu_env *env; - struct osc_lock *olck; - struct cl_lock *lock; + struct lu_env *env; + struct osc_lock *olck; + struct cl_lock *lock; int result; int dlmrc; @@ -830,15 +830,15 @@ static int osc_ldlm_completion_ast(struct ldlm_lock *dlmlock, static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) { - struct ptlrpc_request *req = data; + struct ptlrpc_request *req = data; struct osc_lock *olck; - struct cl_lock *lock; - struct cl_object *obj; - struct cl_env_nest nest; - struct lu_env *env; - struct ost_lvb *lvb; - struct req_capsule *cap; - int result; + struct cl_lock *lock; + struct cl_object *obj; + struct cl_env_nest nest; + struct lu_env *env; + struct ost_lvb *lvb; + struct req_capsule *cap; + int result; LASSERT(lustre_msg_get_opc(req->rq_reqmsg) == LDLM_GL_CALLBACK); @@ -916,11 +916,11 @@ static void osc_lock_build_einfo(const struct lu_env *env, */ mode = CLM_READ; - einfo->ei_type = LDLM_EXTENT; - einfo->ei_mode = osc_cl_lock2ldlm(mode); - einfo->ei_cb_bl = osc_ldlm_blocking_ast; - einfo->ei_cb_cp = osc_ldlm_completion_ast; - einfo->ei_cb_gl = osc_ldlm_glimpse_ast; + einfo->ei_type = LDLM_EXTENT; + einfo->ei_mode = osc_cl_lock2ldlm(mode); + einfo->ei_cb_bl = osc_ldlm_blocking_ast; + einfo->ei_cb_cp = osc_ldlm_completion_ast; + einfo->ei_cb_gl = osc_ldlm_glimpse_ast; einfo->ei_cbdata = lock; /* value to be put into ->l_ast_data */ } @@ -948,9 +948,9 @@ static void osc_lock_to_lockless(const struct lu_env *env, ols->ols_locklessable = 1; slice->cls_ops = &osc_lock_lockless_ops; } else { - struct osc_io *oio = osc_env_io(env); - struct cl_io *io = oio->oi_cl.cis_io; - struct cl_object *obj = slice->cls_obj; + struct osc_io *oio = osc_env_io(env); + struct cl_io *io = oio->oi_cl.cis_io; + struct cl_object *obj = slice->cls_obj; struct osc_object *oob = cl2osc(obj); const struct osc_device *osd = lu2osc_dev(obj->co_lu.lo_dev); struct obd_connect_data *ocd; @@ -1006,13 +1006,13 @@ static int osc_lock_compatible(const struct osc_lock *qing, static int osc_lock_enqueue_wait(const struct lu_env *env, const struct osc_lock *olck) { - struct cl_lock *lock = olck->ols_cl.cls_lock; - struct cl_lock_descr *descr = &lock->cll_descr; - struct cl_object_header *hdr = cl_object_header(descr->cld_obj); - struct cl_lock *scan; - struct cl_lock *conflict = NULL; - int lockless = osc_lock_is_lockless(olck); - int rc = 0; + struct cl_lock *lock = olck->ols_cl.cls_lock; + struct cl_lock_descr *descr = &lock->cll_descr; + struct cl_object_header *hdr = cl_object_header(descr->cld_obj); + struct cl_lock *scan; + struct cl_lock *conflict = NULL; + int lockless = osc_lock_is_lockless(olck); + int rc = 0; LASSERT(cl_lock_is_mutexed(lock)); @@ -1102,8 +1102,8 @@ static int osc_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, struct cl_io *unused, __u32 enqflags) { - struct osc_lock *ols = cl2osc_lock(slice); - struct cl_lock *lock = ols->ols_cl.cls_lock; + struct osc_lock *ols = cl2osc_lock(slice); + struct cl_lock *lock = ols->ols_cl.cls_lock; int result; LASSERT(cl_lock_is_mutexed(lock)); @@ -1116,10 +1116,10 @@ static int osc_lock_enqueue(const struct lu_env *env, result = osc_lock_enqueue_wait(env, ols); if (result == 0) { if (!osc_lock_is_lockless(ols)) { - struct osc_object *obj = cl2osc(slice->cls_obj); - struct osc_thread_info *info = osc_env_info(env); - struct ldlm_res_id *resname = &info->oti_resname; - ldlm_policy_data_t *policy = &info->oti_policy; + struct osc_object *obj = cl2osc(slice->cls_obj); + struct osc_thread_info *info = osc_env_info(env); + struct ldlm_res_id *resname = &info->oti_resname; + ldlm_policy_data_t *policy = &info->oti_policy; struct ldlm_enqueue_info *einfo = &ols->ols_einfo; /* lock will be passed as upcall cookie, @@ -1164,7 +1164,7 @@ static int osc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice) { struct osc_lock *olck = cl2osc_lock(slice); - struct cl_lock *lock = olck->ols_cl.cls_lock; + struct cl_lock *lock = olck->ols_cl.cls_lock; LINVRNT(osc_lock_invariant(olck)); @@ -1176,8 +1176,7 @@ static int osc_lock_wait(const struct lu_env *env, /* It is from enqueue RPC reply upcall for * updating state. Do not re-enqueue. */ return -ENAVAIL; - else - olck->ols_state = OLS_NEW; + olck->ols_state = OLS_NEW; } else { LASSERT(lock->cll_error); return lock->cll_error; @@ -1245,14 +1244,14 @@ static int osc_lock_use(const struct lu_env *env, static int osc_lock_flush(struct osc_lock *ols, int discard) { - struct cl_lock *lock = ols->ols_cl.cls_lock; - struct cl_env_nest nest; - struct lu_env *env; + struct cl_lock *lock = ols->ols_cl.cls_lock; + struct cl_env_nest nest; + struct lu_env *env; int result = 0; env = cl_env_nested_get(&nest); if (!IS_ERR(env)) { - struct osc_object *obj = cl2osc(ols->ols_cl.cls_obj); + struct osc_object *obj = cl2osc(ols->ols_cl.cls_obj); struct cl_lock_descr *descr = &lock->cll_descr; int rc = 0; @@ -1298,11 +1297,11 @@ static int osc_lock_flush(struct osc_lock *ols, int discard) static void osc_lock_cancel(const struct lu_env *env, const struct cl_lock_slice *slice) { - struct cl_lock *lock = slice->cls_lock; - struct osc_lock *olck = cl2osc_lock(slice); + struct cl_lock *lock = slice->cls_lock; + struct osc_lock *olck = cl2osc_lock(slice); struct ldlm_lock *dlmlock = olck->ols_lock; - int result = 0; - int discard; + int result = 0; + int discard; LASSERT(cl_lock_is_mutexed(lock)); LINVRNT(osc_lock_invariant(olck)); @@ -1482,7 +1481,7 @@ static int osc_lock_lockless_unuse(const struct lu_env *env, static void osc_lock_lockless_cancel(const struct lu_env *env, const struct cl_lock_slice *slice) { - struct osc_lock *ols = cl2osc_lock(slice); + struct osc_lock *ols = cl2osc_lock(slice); int result; result = osc_lock_flush(ols, 0); @@ -1496,7 +1495,7 @@ static int osc_lock_lockless_wait(const struct lu_env *env, const struct cl_lock_slice *slice) { struct osc_lock *olck = cl2osc_lock(slice); - struct cl_lock *lock = olck->ols_cl.cls_lock; + struct cl_lock *lock = olck->ols_cl.cls_lock; LINVRNT(osc_lock_invariant(olck)); LASSERT(olck->ols_state >= OLS_UPCALL_RECEIVED); @@ -1512,7 +1511,7 @@ static void osc_lock_lockless_state(const struct lu_env *env, LINVRNT(osc_lock_invariant(lock)); if (state == CLS_HELD) { - struct osc_io *oio = osc_env_io(env); + struct osc_io *oio = osc_env_io(env); LASSERT(ergo(lock->ols_owner, lock->ols_owner == oio)); lock->ols_owner = oio; @@ -1591,7 +1590,7 @@ int osc_lock_init(const struct lu_env *env, int osc_dlm_lock_pageref(struct ldlm_lock *dlm) { struct osc_lock *olock; - int rc = 0; + int rc = 0; spin_lock(&osc_ast_guard); olock = dlm->l_ast_data; diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index 92c202f70395..c628a250ebd6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -72,7 +72,7 @@ static struct osc_object *lu2osc(const struct lu_object *obj) static int osc_object_init(const struct lu_env *env, struct lu_object *obj, const struct lu_object_conf *conf) { - struct osc_object *osc = lu2osc(obj); + struct osc_object *osc = lu2osc(obj); const struct cl_object_conf *cconf = lu2cl_conf(conf); int i; @@ -136,9 +136,9 @@ int osc_lvb_print(const struct lu_env *env, void *cookie, static int osc_object_print(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *obj) { - struct osc_object *osc = lu2osc(obj); - struct lov_oinfo *oinfo = osc->oo_oinfo; - struct osc_async_rc *ar = &oinfo->loi_ar; + struct osc_object *osc = lu2osc(obj); + struct lov_oinfo *oinfo = osc->oo_oinfo; + struct osc_async_rc *ar = &oinfo->loi_ar; (*p)(env, cookie, "id: " DOSTID " idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", POSTID(&oinfo->loi_oi), oinfo->loi_ost_idx, @@ -163,7 +163,7 @@ int osc_attr_set(const struct lu_env *env, struct cl_object *obj, const struct cl_attr *attr, unsigned valid) { struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo; - struct ost_lvb *lvb = &oinfo->loi_lvb; + struct ost_lvb *lvb = &oinfo->loi_lvb; if (valid & CAT_SIZE) lvb->lvb_size = attr->cat_size; @@ -188,7 +188,7 @@ static int osc_object_glimpse(const struct lu_env *env, { struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo; - lvb->lvb_size = oinfo->loi_kms; + lvb->lvb_size = oinfo->loi_kms; lvb->lvb_blocks = oinfo->loi_lvb.lvb_blocks; return 0; } @@ -208,9 +208,9 @@ void osc_object_clear_contended(struct osc_object *obj) int osc_object_is_contended(struct osc_object *obj) { - struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev); + struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev); int osc_contention_time = dev->od_contention_time; - unsigned long cur_time = cfs_time_current(); + unsigned long cur_time = cfs_time_current(); unsigned long retry_time; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_OBJECT_CONTENTION)) @@ -255,7 +255,7 @@ struct lu_object *osc_object_alloc(const struct lu_env *env, struct lu_device *dev) { struct osc_object *osc; - struct lu_object *obj; + struct lu_object *obj; OBD_SLAB_ALLOC_PTR_GFP(osc, osc_object_kmem, GFP_NOFS); if (osc != NULL) { diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 76ba58b09c5d..43dfa73dd3a6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -216,7 +216,7 @@ static int osc_page_cache_add(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io) { - struct osc_io *oio = osc_env_io(env); + struct osc_io *oio = osc_env_io(env); struct osc_page *opg = cl2osc_page(slice); int result; @@ -247,7 +247,7 @@ void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj, { memset(policy, 0, sizeof(*policy)); policy->l_extent.start = cl_offset(obj, start); - policy->l_extent.end = cl_offset(obj, end + 1) - 1; + policy->l_extent.end = cl_offset(obj, end + 1) - 1; } static int osc_page_addref_lock(const struct lu_env *env, @@ -255,7 +255,7 @@ static int osc_page_addref_lock(const struct lu_env *env, struct cl_lock *lock) { struct osc_lock *olock; - int rc; + int rc; LASSERT(opg->ops_lock == NULL); @@ -274,7 +274,7 @@ static int osc_page_addref_lock(const struct lu_env *env, static void osc_page_putref_lock(const struct lu_env *env, struct osc_page *opg) { - struct cl_lock *lock = opg->ops_lock; + struct cl_lock *lock = opg->ops_lock; struct osc_lock *olock; LASSERT(lock != NULL); @@ -291,7 +291,7 @@ static int osc_page_is_under_lock(const struct lu_env *env, struct cl_io *unused) { struct cl_lock *lock; - int result = -ENODATA; + int result = -ENODATA; lock = cl_lock_at_page(env, slice->cpl_obj, slice->cpl_page, NULL, 1, 0); @@ -317,7 +317,7 @@ static void osc_page_completion_read(const struct lu_env *env, const struct cl_page_slice *slice, int ioret) { - struct osc_page *opg = cl2osc_page(slice); + struct osc_page *opg = cl2osc_page(slice); struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); if (likely(opg->ops_lock)) @@ -329,7 +329,7 @@ static void osc_page_completion_write(const struct lu_env *env, const struct cl_page_slice *slice, int ioret) { - struct osc_page *opg = cl2osc_page(slice); + struct osc_page *opg = cl2osc_page(slice); struct osc_object *obj = cl2osc(slice->cpl_obj); osc_lru_add(osc_cli(obj), opg); @@ -364,10 +364,10 @@ static int osc_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) { - struct osc_page *opg = cl2osc_page(slice); + struct osc_page *opg = cl2osc_page(slice); struct osc_async_page *oap = &opg->ops_oap; - struct osc_object *obj = cl2osc(slice->cpl_obj); - struct client_obd *cli = &osc_export(obj)->exp_obd->u.cli; + struct osc_object *obj = cl2osc(slice->cpl_obj); + struct client_obd *cli = &osc_export(obj)->exp_obd->u.cli; return (*printer)(env, cookie, LUSTRE_OSC_NAME "-page@%p: 1< %#x %d %u %s %s > 2< %llu %u %u %#x %#x | %p %p %p > 3< %s %p %d %lu %d > 4< %d %d %d %lu %s | %s %s %s %s > 5< %s %s %s %s | %d %s | %d %s %s>\n", opg, @@ -408,7 +408,7 @@ static int osc_page_print(const struct lu_env *env, static void osc_page_delete(const struct lu_env *env, const struct cl_page_slice *slice) { - struct osc_page *opg = cl2osc_page(slice); + struct osc_page *opg = cl2osc_page(slice); struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); int rc; @@ -437,13 +437,13 @@ static void osc_page_delete(const struct lu_env *env, void osc_page_clip(const struct lu_env *env, const struct cl_page_slice *slice, int from, int to) { - struct osc_page *opg = cl2osc_page(slice); + struct osc_page *opg = cl2osc_page(slice); struct osc_async_page *oap = &opg->ops_oap; LINVRNT(osc_page_protected(env, opg, CLM_READ, 0)); opg->ops_from = from; - opg->ops_to = to; + opg->ops_to = to; spin_lock(&oap->oap_lock); oap->oap_async_flags |= ASYNC_COUNT_STABLE; spin_unlock(&oap->oap_lock); @@ -502,11 +502,11 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, struct page *vmpage) { struct osc_object *osc = cl2osc(obj); - struct osc_page *opg = cl_object_page_slice(obj, page); + struct osc_page *opg = cl_object_page_slice(obj, page); int result; opg->ops_from = 0; - opg->ops_to = PAGE_CACHE_SIZE; + opg->ops_to = PAGE_CACHE_SIZE; result = osc_prep_async_page(osc, opg, vmpage, cl_offset(obj, page->cp_index)); @@ -540,7 +540,7 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, enum cl_req_type crt, int brw_flags) { struct osc_async_page *oap = &opg->ops_oap; - struct osc_object *obj = oap->oap_obj; + struct osc_object *obj = oap->oap_obj; LINVRNT(osc_page_protected(env, opg, crt == CRT_WRITE ? CLM_WRITE : CLM_READ, 1)); @@ -550,9 +550,9 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, LASSERT(oap->oap_async_flags & ASYNC_READY); LASSERT(oap->oap_async_flags & ASYNC_COUNT_STABLE); - oap->oap_cmd = crt == CRT_WRITE ? OBD_BRW_WRITE : OBD_BRW_READ; - oap->oap_page_off = opg->ops_from; - oap->oap_count = opg->ops_to - opg->ops_from; + oap->oap_cmd = crt == CRT_WRITE ? OBD_BRW_WRITE : OBD_BRW_READ; + oap->oap_page_off = opg->ops_from; + oap->oap_count = opg->ops_to - opg->ops_from; oap->oap_brw_flags = OBD_BRW_SYNC | brw_flags; if (!client_is_remote(osc_export(obj)) && diff --git a/drivers/staging/lustre/lustre/osc/osc_quota.c b/drivers/staging/lustre/lustre/osc/osc_quota.c index 6690f149a04c..2ff253f458f8 100644 --- a/drivers/staging/lustre/lustre/osc/osc_quota.c +++ b/drivers/staging/lustre/lustre/osc/osc_quota.c @@ -232,7 +232,7 @@ int osc_quota_setup(struct obd_device *obd) int osc_quota_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; + struct client_obd *cli = &obd->u.cli; int type; for (type = 0; type < MAXQUOTAS; type++) @@ -245,8 +245,8 @@ int osc_quotactl(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl) { struct ptlrpc_request *req; - struct obd_quotactl *oqc; - int rc; + struct obd_quotactl *oqc; + int rc; req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), &RQF_OST_QUOTACTL, LUSTRE_OST_VERSION, @@ -285,10 +285,10 @@ int osc_quotactl(struct obd_device *unused, struct obd_export *exp, int osc_quotacheck(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl) { - struct client_obd *cli = &exp->exp_obd->u.cli; - struct ptlrpc_request *req; - struct obd_quotactl *body; - int rc; + struct client_obd *cli = &exp->exp_obd->u.cli; + struct ptlrpc_request *req; + struct obd_quotactl *body; + int rc; req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), &RQF_OST_QUOTACHECK, LUSTRE_OST_VERSION, diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index ded184edb50f..f84b4c78a8a0 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -264,7 +264,7 @@ static int osc_getattr_async(struct obd_export *exp, struct obd_info *oinfo, { struct ptlrpc_request *req; struct osc_async_args *aa; - int rc; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_GETATTR); if (req == NULL) @@ -294,8 +294,8 @@ static int osc_getattr(const struct lu_env *env, struct obd_export *exp, struct obd_info *oinfo) { struct ptlrpc_request *req; - struct ost_body *body; - int rc; + struct ost_body *body; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_GETATTR); if (req == NULL) @@ -338,8 +338,8 @@ static int osc_setattr(const struct lu_env *env, struct obd_export *exp, struct obd_info *oinfo, struct obd_trans_info *oti) { struct ptlrpc_request *req; - struct ost_body *body; - int rc; + struct ost_body *body; + int rc; LASSERT(oinfo->oi_oa->o_valid & OBD_MD_FLGROUP); @@ -403,9 +403,9 @@ int osc_setattr_async_base(struct obd_export *exp, struct obd_info *oinfo, obd_enqueue_update_f upcall, void *cookie, struct ptlrpc_request_set *rqset) { - struct ptlrpc_request *req; + struct ptlrpc_request *req; struct osc_setattr_args *sa; - int rc; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_SETATTR); if (req == NULL) @@ -460,9 +460,9 @@ int osc_real_create(struct obd_export *exp, struct obdo *oa, struct lov_stripe_md **ea, struct obd_trans_info *oti) { struct ptlrpc_request *req; - struct ost_body *body; - struct lov_stripe_md *lsm; - int rc; + struct ost_body *body; + struct lov_stripe_md *lsm; + int rc; LASSERT(oa); LASSERT(ea); @@ -548,10 +548,10 @@ int osc_punch_base(struct obd_export *exp, struct obd_info *oinfo, obd_enqueue_update_f upcall, void *cookie, struct ptlrpc_request_set *rqset) { - struct ptlrpc_request *req; + struct ptlrpc_request *req; struct osc_setattr_args *sa; - struct ost_body *body; - int rc; + struct ost_body *body; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_PUNCH); if (req == NULL) @@ -577,7 +577,7 @@ int osc_punch_base(struct obd_export *exp, struct obd_info *oinfo, req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_setattr_interpret; CLASSERT (sizeof(*sa) <= sizeof(req->rq_async_args)); sa = ptlrpc_req_async_args(req); - sa->sa_oa = oinfo->oi_oa; + sa->sa_oa = oinfo->oi_oa; sa->sa_upcall = upcall; sa->sa_cookie = cookie; if (rqset == PTLRPCD_SET) @@ -616,9 +616,9 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo, struct ptlrpc_request_set *rqset) { struct ptlrpc_request *req; - struct ost_body *body; + struct ost_body *body; struct osc_fsync_args *fa; - int rc; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_SYNC); if (req == NULL) @@ -757,9 +757,9 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp, struct obd_trans_info *oti, struct obd_export *md_export, void *capa) { - struct client_obd *cli = &exp->exp_obd->u.cli; + struct client_obd *cli = &exp->exp_obd->u.cli; struct ptlrpc_request *req; - struct ost_body *body; + struct ost_body *body; LIST_HEAD(cancels); int rc, count; @@ -947,7 +947,7 @@ static int osc_shrink_grant(struct client_obd *cli) int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes) { - int rc = 0; + int rc = 0; struct ost_body *body; client_obd_list_lock(&cli->cl_loi_list_lock); @@ -1007,8 +1007,8 @@ static int osc_should_shrink_grant(struct client_obd *client) if (client->cl_import->imp_state == LUSTRE_IMP_FULL && client->cl_avail_grant > brw_size) return 1; - else - osc_update_next_shrink(client); + + osc_update_next_shrink(client); } return 0; } @@ -1131,8 +1131,8 @@ static int check_write_rcs(struct ptlrpc_request *req, int requested_nob, int niocount, u32 page_count, struct brw_page **pga) { - int i; - __u32 *remote_rcs; + int i; + __u32 *remote_rcs; remote_rcs = req_capsule_server_sized_get(&req->rq_pill, &RMF_RCS, sizeof(*remote_rcs) * @@ -1182,15 +1182,15 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) } static u32 osc_checksum_bulk(int nob, u32 pg_count, - struct brw_page **pga, int opc, - cksum_type_t cksum_type) + struct brw_page **pga, int opc, + cksum_type_t cksum_type) { - __u32 cksum; - int i = 0; - struct cfs_crypto_hash_desc *hdesc; - unsigned int bufsize; - int err; - unsigned char cfs_alg = cksum_obd2cfs(cksum_type); + __u32 cksum; + int i = 0; + struct cfs_crypto_hash_desc *hdesc; + unsigned int bufsize; + int err; + unsigned char cfs_alg = cksum_obd2cfs(cksum_type); LASSERT(pg_count > 0); @@ -1250,14 +1250,14 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, struct obd_capa *ocapa, int reserve, int resend) { - struct ptlrpc_request *req; + struct ptlrpc_request *req; struct ptlrpc_bulk_desc *desc; - struct ost_body *body; - struct obd_ioobj *ioobj; - struct niobuf_remote *niobuf; + struct ost_body *body; + struct obd_ioobj *ioobj; + struct niobuf_remote *niobuf; int niocount, i, requested_nob, opc, rc; struct osc_brw_async_args *aa; - struct req_capsule *pill; + struct req_capsule *pill; struct brw_page *pg_prev; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_PREP_REQ)) @@ -1359,8 +1359,8 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, niobuf->len += pg->count; } else { niobuf->offset = pg->off; - niobuf->len = pg->count; - niobuf->flags = pg->flag; + niobuf->len = pg->count; + niobuf->flags = pg->flag; } pg_prev = pg; } @@ -1581,9 +1581,9 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) if (body->oa.o_valid & OBD_MD_FLCKSUM) { static int cksum_counter; - __u32 server_cksum = body->oa.o_cksum; - char *via; - char *router; + __u32 server_cksum = body->oa.o_cksum; + char *via; + char *router; cksum_type_t cksum_type; cksum_type = cksum_type_unpack(body->oa.o_valid &OBD_MD_FLFLAGS? @@ -1758,7 +1758,7 @@ static int brw_interpret(const struct lu_env *env, struct osc_brw_async_args *aa = data; struct osc_extent *ext; struct osc_extent *tmp; - struct cl_object *obj = NULL; + struct cl_object *obj = NULL; struct client_obd *cli = aa->aa_cli; rc = osc_brw_fini_request(req, rc); @@ -1862,26 +1862,25 @@ static int brw_interpret(const struct lu_env *env, int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, struct list_head *ext_list, int cmd, pdl_policy_t pol) { - struct ptlrpc_request *req = NULL; - struct osc_extent *ext; - struct brw_page **pga = NULL; - struct osc_brw_async_args *aa = NULL; - struct obdo *oa = NULL; - struct osc_async_page *oap; - struct osc_async_page *tmp; - struct cl_req *clerq = NULL; - enum cl_req_type crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE : - CRT_READ; - struct ldlm_lock *lock = NULL; - struct cl_req_attr *crattr = NULL; - u64 starting_offset = OBD_OBJECT_EOF; - u64 ending_offset = 0; - int mpflag = 0; - int mem_tight = 0; - int page_count = 0; - int i; - int rc; - struct ost_body *body; + struct ptlrpc_request *req = NULL; + struct osc_extent *ext; + struct brw_page **pga = NULL; + struct osc_brw_async_args *aa = NULL; + struct obdo *oa = NULL; + struct osc_async_page *oap; + struct osc_async_page *tmp; + struct cl_req *clerq = NULL; + enum cl_req_type crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE : CRT_READ; + struct ldlm_lock *lock = NULL; + struct cl_req_attr *crattr = NULL; + u64 starting_offset = OBD_OBJECT_EOF; + u64 ending_offset = 0; + int mpflag = 0; + int mem_tight = 0; + int page_count = 0; + int i; + int rc; + struct ost_body *body; LIST_HEAD(rpc_list); LASSERT(!list_empty(ext_list)); @@ -2300,7 +2299,9 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, ldlm_lock_decref(lockh, mode); LDLM_LOCK_PUT(matched); return -ECANCELED; - } else if (osc_set_lock_data_with_check(matched, einfo)) { + } + + if (osc_set_lock_data_with_check(matched, einfo)) { *flags |= LDLM_FL_LVB_READY; /* addref the lock only if not async requests and PW * lock is matched whereas we asked for PR. */ @@ -2325,10 +2326,10 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, ldlm_lock_decref(lockh, einfo->ei_mode); LDLM_LOCK_PUT(matched); return ELDLM_OK; - } else { - ldlm_lock_decref(lockh, mode); - LDLM_LOCK_PUT(matched); } + + ldlm_lock_decref(lockh, mode); + LDLM_LOCK_PUT(matched); } no_match: @@ -2480,10 +2481,10 @@ static int osc_statfs_async(struct obd_export *exp, struct obd_info *oinfo, __u64 max_age, struct ptlrpc_request_set *rqset) { - struct obd_device *obd = class_exp2obd(exp); + struct obd_device *obd = class_exp2obd(exp); struct ptlrpc_request *req; struct osc_async_args *aa; - int rc; + int rc; /* We could possibly pass max_age in the request (as an absolute * timestamp or a "seconds.usec ago") so the target can avoid doing @@ -2522,10 +2523,10 @@ static int osc_statfs_async(struct obd_export *exp, static int osc_statfs(const struct lu_env *env, struct obd_export *exp, struct obd_statfs *osfs, __u64 max_age, __u32 flags) { - struct obd_device *obd = class_exp2obd(exp); - struct obd_statfs *msfs; + struct obd_device *obd = class_exp2obd(exp); + struct obd_statfs *msfs; struct ptlrpc_request *req; - struct obd_import *imp = NULL; + struct obd_import *imp = NULL; int rc; /*Since the request might also come from lprocfs, so we need @@ -2749,9 +2750,9 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, return 0; } else if (KEY_IS(KEY_LAST_ID)) { struct ptlrpc_request *req; - u64 *reply; - char *tmp; - int rc; + u64 *reply; + char *tmp; + int rc; req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_GET_INFO_LAST_ID); @@ -2788,14 +2789,14 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, } else if (KEY_IS(KEY_FIEMAP)) { struct ll_fiemap_info_key *fm_key = (struct ll_fiemap_info_key *)key; - struct ldlm_res_id res_id; - ldlm_policy_data_t policy; - struct lustre_handle lockh; - ldlm_mode_t mode = 0; - struct ptlrpc_request *req; - struct ll_user_fiemap *reply; - char *tmp; - int rc; + struct ldlm_res_id res_id; + ldlm_policy_data_t policy; + struct lustre_handle lockh; + ldlm_mode_t mode = 0; + struct ptlrpc_request *req; + struct ll_user_fiemap *reply; + char *tmp; + int rc; if (!(fm_key->fiemap.fm_flags & FIEMAP_FLAG_SYNC)) goto skip_locking; @@ -2881,10 +2882,10 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, void *val, struct ptlrpc_request_set *set) { struct ptlrpc_request *req; - struct obd_device *obd = exp->exp_obd; - struct obd_import *imp = class_exp2cliimp(exp); - char *tmp; - int rc; + struct obd_device *obd = exp->exp_obd; + struct obd_import *imp = class_exp2cliimp(exp); + char *tmp; + int rc; OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_SHUTDOWN, 10); @@ -3071,8 +3072,8 @@ static int osc_import_event(struct obd_device *obd, } case IMP_EVENT_INVALIDATE: { struct ldlm_namespace *ns = obd->obd_namespace; - struct lu_env *env; - int refcheck; + struct lu_env *env; + int refcheck; env = cl_env_get(&refcheck); if (!IS_ERR(env)) { @@ -3159,9 +3160,9 @@ static int brw_queue_work(const struct lu_env *env, void *data) int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { struct lprocfs_static_vars lvars = { NULL }; - struct client_obd *cli = &obd->u.cli; - void *handler; - int rc; + struct client_obd *cli = &obd->u.cli; + void *handler; + int rc; rc = ptlrpcd_addref(); if (rc) @@ -3184,7 +3185,7 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) cli->cl_grant_shrink_interval = GRANT_SHRINK_INTERVAL; lprocfs_osc_init_vars(&lvars); - if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0) { + if (lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars) == 0) { lproc_osc_attach_seqstat(obd); sptlrpc_lprocfs_cliobd_attach(obd); ptlrpc_lprocfs_register_obd(obd); @@ -3351,7 +3352,7 @@ static int __init osc_init(void) lprocfs_osc_init_vars(&lvars); - rc = class_register_type(&osc_obd_ops, NULL, lvars.module_vars, + rc = class_register_type(&osc_obd_ops, NULL, LUSTRE_OSC_NAME, &osc_device_type); if (rc) { lu_kmem_fini(osc_caches); diff --git a/drivers/staging/lustre/lustre/ptlrpc/Makefile b/drivers/staging/lustre/lustre/ptlrpc/Makefile index fb50cd4c65b6..24bbac19ddd1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/Makefile +++ b/drivers/staging/lustre/lustre/ptlrpc/Makefile @@ -15,6 +15,5 @@ ptlrpc_objs += pers.o lproc_ptlrpc.o wiretest.o layout.o ptlrpc_objs += sec.o sec_bulk.o sec_gc.o sec_config.o ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o -ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs) -ptlrpc-$(CONFIG_PROC_FS) += sec_lproc.o +ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs) sec_lproc.o ptlrpc-$(CONFIG_LUSTRE_TRANSLATE_ERRNOS) += errno.o diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 45b7af77c37e..35ebe0f35bd1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -57,8 +57,8 @@ void ptlrpc_init_client(int req_portal, int rep_portal, char *name, struct ptlrpc_client *cl) { cl->cli_request_portal = req_portal; - cl->cli_reply_portal = rep_portal; - cl->cli_name = name; + cl->cli_reply_portal = rep_portal; + cl->cli_name = name; } EXPORT_SYMBOL(ptlrpc_init_client); @@ -68,9 +68,9 @@ EXPORT_SYMBOL(ptlrpc_init_client); struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid) { struct ptlrpc_connection *c; - lnet_nid_t self; - lnet_process_id_t peer; - int err; + lnet_nid_t self; + lnet_process_id_t peer; + int err; /* ptlrpc_uuid_to_peer() initializes its 2nd parameter * before accessing its values. */ @@ -148,7 +148,7 @@ struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_imp(struct ptlrpc_request *req, desc->bd_import = class_import_get(imp); desc->bd_req = req; - desc->bd_cbid.cbid_fn = client_bulk_callback; + desc->bd_cbid.cbid_fn = client_bulk_callback; desc->bd_cbid.cbid_arg = desc; /* This makes req own desc, and free it when she frees herself */ @@ -343,8 +343,8 @@ static int unpack_reply(struct ptlrpc_request *req) static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) { struct ptlrpc_request *early_req; - time_t olddl; - int rc; + time_t olddl; + int rc; req->rq_early = 0; spin_unlock(&req->rq_lock); @@ -390,7 +390,7 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) return rc; } -struct kmem_cache *request_cache; +static struct kmem_cache *request_cache; int ptlrpc_request_cache_init(void) { @@ -580,8 +580,8 @@ static int __ptlrpc_request_bufs_pack(struct ptlrpc_request *request, int count, __u32 *lengths, char **bufs, struct ptlrpc_cli_ctx *ctx) { - struct obd_import *imp = request->rq_import; - int rc; + struct obd_import *imp = request->rq_import; + int rc; if (unlikely(ctx)) request->rq_cli_ctx = sptlrpc_cli_ctx_get(ctx); @@ -605,10 +605,10 @@ static int __ptlrpc_request_bufs_pack(struct ptlrpc_request *request, request->rq_type = PTL_RPC_MSG_REQUEST; request->rq_export = NULL; - request->rq_req_cbid.cbid_fn = request_out_callback; + request->rq_req_cbid.cbid_fn = request_out_callback; request->rq_req_cbid.cbid_arg = request; - request->rq_reply_cbid.cbid_fn = reply_in_callback; + request->rq_reply_cbid.cbid_fn = reply_in_callback; request->rq_reply_cbid.cbid_arg = request; request->rq_reply_deadline = 0; @@ -761,8 +761,8 @@ EXPORT_SYMBOL(ptlrpc_request_alloc); * initialize its buffer structure according to capsule template \a format. */ struct ptlrpc_request *ptlrpc_request_alloc_pool(struct obd_import *imp, - struct ptlrpc_request_pool *pool, - const struct req_format *format) + struct ptlrpc_request_pool *pool, + const struct req_format *format) { return ptlrpc_request_alloc_internal(imp, pool, format); } @@ -789,11 +789,11 @@ EXPORT_SYMBOL(ptlrpc_request_free); * Returns allocated request or NULL on error. */ struct ptlrpc_request *ptlrpc_request_alloc_pack(struct obd_import *imp, - const struct req_format *format, - __u32 version, int opcode) + const struct req_format *format, + __u32 version, int opcode) { struct ptlrpc_request *req = ptlrpc_request_alloc(imp, format); - int rc; + int rc; if (req) { rc = ptlrpc_request_pack(req, version, opcode); @@ -820,7 +820,7 @@ ptlrpc_prep_req_pool(struct obd_import *imp, struct ptlrpc_request_pool *pool) { struct ptlrpc_request *request; - int rc; + int rc; request = __ptlrpc_request_alloc(imp, pool); if (!request) @@ -868,9 +868,9 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void) INIT_LIST_HEAD(&set->set_new_requests); INIT_LIST_HEAD(&set->set_cblist); set->set_max_inflight = UINT_MAX; - set->set_producer = NULL; + set->set_producer = NULL; set->set_producer_arg = NULL; - set->set_rc = 0; + set->set_rc = 0; return set; } @@ -894,9 +894,9 @@ struct ptlrpc_request_set *ptlrpc_prep_fcset(int max, set_producer_func func, if (!set) return NULL; - set->set_max_inflight = max; - set->set_producer = func; - set->set_producer_arg = arg; + set->set_max_inflight = max; + set->set_producer = func; + set->set_producer_arg = arg; return set; } @@ -912,10 +912,10 @@ EXPORT_SYMBOL(ptlrpc_prep_fcset); */ void ptlrpc_set_destroy(struct ptlrpc_request_set *set) { - struct list_head *tmp; - struct list_head *next; - int expected_phase; - int n = 0; + struct list_head *tmp; + struct list_head *next; + int expected_phase; + int n = 0; /* Requests on the set should either all be completed, or all be new */ expected_phase = (atomic_read(&set->set_remaining) == 0) ? @@ -1013,7 +1013,7 @@ EXPORT_SYMBOL(ptlrpc_set_add_req); * Currently only used for ptlrpcd. */ void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc, - struct ptlrpc_request *req) + struct ptlrpc_request *req) { struct ptlrpc_request_set *set = pc->pc_set; int count, i; @@ -1400,7 +1400,7 @@ static int after_reply(struct ptlrpc_request *req) */ static int ptlrpc_send_new_req(struct ptlrpc_request *req) { - struct obd_import *imp = req->rq_import; + struct obd_import *imp = req->rq_import; int rc; LASSERT(req->rq_phase == RQ_PHASE_NEW); @@ -1669,7 +1669,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) continue; } - if (status != 0) { + if (status != 0) { req->rq_status = status; ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET); @@ -1969,8 +1969,8 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink) int ptlrpc_expired_set(void *data) { struct ptlrpc_request_set *set = data; - struct list_head *tmp; - time_t now = get_seconds(); + struct list_head *tmp; + time_t now = get_seconds(); LASSERT(set != NULL); @@ -2052,11 +2052,11 @@ EXPORT_SYMBOL(ptlrpc_interrupted_set); */ int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set) { - struct list_head *tmp; - time_t now = get_seconds(); - int timeout = 0; + struct list_head *tmp; + time_t now = get_seconds(); + int timeout = 0; struct ptlrpc_request *req; - int deadline; + int deadline; list_for_each(tmp, &set->set_requests) { req = list_entry(tmp, struct ptlrpc_request, rq_set_chain); @@ -2105,10 +2105,10 @@ EXPORT_SYMBOL(ptlrpc_set_next_timeout); */ int ptlrpc_set_wait(struct ptlrpc_request_set *set) { - struct list_head *tmp; + struct list_head *tmp; struct ptlrpc_request *req; - struct l_wait_info lwi; - int rc, timeout; + struct l_wait_info lwi; + int rc, timeout; if (set->set_producer) (void)ptlrpc_set_producer(set); @@ -2353,8 +2353,8 @@ EXPORT_SYMBOL(ptlrpc_req_xid); */ int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) { - int rc; - wait_queue_head_t *wq; + int rc; + wait_queue_head_t *wq; struct l_wait_info lwi; /* @@ -2471,7 +2471,7 @@ void ptlrpc_free_committed(struct obd_import *imp) { struct ptlrpc_request *req, *saved; struct ptlrpc_request *last_req = NULL; /* temporary fire escape */ - bool skip_committed_list = true; + bool skip_committed_list = true; LASSERT(imp != NULL); assert_spin_locked(&imp->imp_lock); @@ -3023,8 +3023,8 @@ EXPORT_SYMBOL(ptlrpc_sample_next_xid); * have delay before it really runs by ptlrpcd thread. */ struct ptlrpc_work_async_args { - int (*cb)(const struct lu_env *, void *); - void *cbdata; + int (*cb)(const struct lu_env *, void *); + void *cbdata; }; static void ptlrpcd_add_work_req(struct ptlrpc_request *req) @@ -3113,7 +3113,7 @@ void *ptlrpcd_alloc_work(struct obd_import *imp, CLASSERT(sizeof(*args) <= sizeof(req->rq_async_args)); args = ptlrpc_req_async_args(req); - args->cb = cb; + args->cb = cb; args->cbdata = cbdata; return req; diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 7f8644e01112..8cb1929fd31d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -53,7 +53,7 @@ lnet_handle_eq_t ptlrpc_eq_h; */ void request_out_callback(lnet_event_t *ev) { - struct ptlrpc_cb_id *cbid = ev->md.user_ptr; + struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request *req = cbid->cbid_arg; LASSERT(ev->type == LNET_EVENT_SEND || @@ -86,7 +86,7 @@ void request_out_callback(lnet_event_t *ev) */ void reply_in_callback(lnet_event_t *ev) { - struct ptlrpc_cb_id *cbid = ev->md.user_ptr; + struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request *req = cbid->cbid_arg; DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status); @@ -172,9 +172,9 @@ out_wake: */ void client_bulk_callback(lnet_event_t *ev) { - struct ptlrpc_cb_id *cbid = ev->md.user_ptr; + struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_bulk_desc *desc = cbid->cbid_arg; - struct ptlrpc_request *req; + struct ptlrpc_request *req; LASSERT((desc->bd_type == BULK_PUT_SINK && ev->type == LNET_EVENT_PUT) || @@ -245,9 +245,9 @@ void client_bulk_callback(lnet_event_t *ev) static void ptlrpc_req_add_history(struct ptlrpc_service_part *svcpt, struct ptlrpc_request *req) { - __u64 sec = req->rq_arrival_time.tv_sec; - __u32 usec = req->rq_arrival_time.tv_usec >> 4; /* usec / 16 */ - __u64 new_seq; + __u64 sec = req->rq_arrival_time.tv_sec; + __u32 usec = req->rq_arrival_time.tv_usec >> 4; /* usec / 16 */ + __u64 new_seq; /* set sequence ID for request and add it to history list, * it must be called with hold svcpt::scp_lock */ @@ -281,11 +281,11 @@ static void ptlrpc_req_add_history(struct ptlrpc_service_part *svcpt, */ void request_in_callback(lnet_event_t *ev) { - struct ptlrpc_cb_id *cbid = ev->md.user_ptr; + struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request_buffer_desc *rqbd = cbid->cbid_arg; - struct ptlrpc_service_part *svcpt = rqbd->rqbd_svcpt; - struct ptlrpc_service *service = svcpt->scp_service; - struct ptlrpc_request *req; + struct ptlrpc_service_part *svcpt = rqbd->rqbd_svcpt; + struct ptlrpc_service *service = svcpt->scp_service; + struct ptlrpc_request *req; LASSERT(ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK); @@ -380,7 +380,7 @@ void request_in_callback(lnet_event_t *ev) */ void reply_out_callback(lnet_event_t *ev) { - struct ptlrpc_cb_id *cbid = ev->md.user_ptr; + struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_reply_state *rs = cbid->cbid_arg; struct ptlrpc_service_part *svcpt = rs->rs_svcpt; @@ -433,17 +433,17 @@ static void ptlrpc_master_callback(lnet_event_t *ev) } int ptlrpc_uuid_to_peer(struct obd_uuid *uuid, - lnet_process_id_t *peer, lnet_nid_t *self) + lnet_process_id_t *peer, lnet_nid_t *self) { - int best_dist = 0; - __u32 best_order = 0; - int count = 0; - int rc = -ENOENT; - int portals_compatibility; - int dist; - __u32 order; - lnet_nid_t dst_nid; - lnet_nid_t src_nid; + int best_dist = 0; + __u32 best_order = 0; + int count = 0; + int rc = -ENOENT; + int portals_compatibility; + int dist; + __u32 order; + lnet_nid_t dst_nid; + lnet_nid_t src_nid; portals_compatibility = LNetCtl(IOC_LIBCFS_PORTALS_COMPATIBILITY, NULL); @@ -487,10 +487,10 @@ int ptlrpc_uuid_to_peer(struct obd_uuid *uuid, void ptlrpc_ni_fini(void) { - wait_queue_head_t waitq; - struct l_wait_info lwi; - int rc; - int retries; + wait_queue_head_t waitq; + struct l_wait_info lwi; + int rc; + int retries; /* Wait for the event queue to become idle since there may still be * messages in flight with pending events (i.e. the fire-and-forget @@ -523,7 +523,7 @@ void ptlrpc_ni_fini(void) lnet_pid_t ptl_get_pid(void) { - lnet_pid_t pid; + lnet_pid_t pid; pid = LUSTRE_SRV_LNET_PID; return pid; @@ -531,8 +531,8 @@ lnet_pid_t ptl_get_pid(void) int ptlrpc_ni_init(void) { - int rc; - lnet_pid_t pid; + int rc; + lnet_pid_t pid; pid = ptl_get_pid(); CDEBUG(D_NET, "My pid is: %x\n", pid); @@ -563,7 +563,7 @@ int ptlrpc_ni_init(void) int ptlrpc_init_portals(void) { - int rc = ptlrpc_ni_init(); + int rc = ptlrpc_ni_init(); if (rc != 0) { CERROR("network initialisation failed\n"); diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index d5fc689c008b..c9b8481dd384 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -119,7 +119,7 @@ int ptlrpc_init_import(struct obd_import *imp) spin_lock(&imp->imp_lock); imp->imp_generation++; - imp->imp_state = LUSTRE_IMP_NEW; + imp->imp_state = LUSTRE_IMP_NEW; spin_unlock(&imp->imp_lock); @@ -369,7 +369,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp) imp_unregistering)); } spin_unlock(&imp->imp_lock); - } + } } while (rc != 0); /* @@ -559,7 +559,7 @@ static int import_select_connection(struct obd_import *imp) ptlrpc_connection_put(imp->imp_connection); imp->imp_connection = ptlrpc_connection_addref(imp_conn->oic_conn); - dlmexp = class_conn2export(&imp->imp_dlm_handle); + dlmexp = class_conn2export(&imp->imp_dlm_handle); LASSERT(dlmexp != NULL); if (dlmexp->exp_connection) ptlrpc_connection_put(dlmexp->exp_connection); @@ -1490,7 +1490,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose) INITIAL_CONNECT_TIMEOUT); IMPORT_SET_STATE(imp, LUSTRE_IMP_CONNECTING); - req->rq_send_state = LUSTRE_IMP_CONNECTING; + req->rq_send_state = LUSTRE_IMP_CONNECTING; ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); ptlrpc_req_finished(req); diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index a42335e26de9..d14c20008850 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -807,11 +807,11 @@ struct req_capsule; /* * Request fields. */ -#define DEFINE_MSGF(name, flags, size, swabber, dumper) { \ - .rmf_name = (name), \ - .rmf_flags = (flags), \ - .rmf_size = (size), \ - .rmf_swabber = (void (*)(void *))(swabber), \ +#define DEFINE_MSGF(name, flags, size, swabber, dumper) { \ + .rmf_name = (name), \ + .rmf_flags = (flags), \ + .rmf_size = (size), \ + .rmf_swabber = (void (*)(void *))(swabber), \ .rmf_dumper = (void (*)(void *))(dumper) \ } @@ -1164,25 +1164,25 @@ EXPORT_SYMBOL(RMF_SWAP_LAYOUTS); struct req_format { const char *rf_name; - int rf_idx; + int rf_idx; struct { - int nr; + int nr; const struct req_msg_field **d; } rf_fields[RCL_NR]; }; -#define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) { \ - .rf_name = name, \ - .rf_fields = { \ +#define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) { \ + .rf_name = name, \ + .rf_fields = { \ [RCL_CLIENT] = { \ .nr = client_nr, \ - .d = client \ - }, \ + .d = client \ + }, \ [RCL_SERVER] = { \ .nr = server_nr, \ - .d = server \ - } \ - } \ + .d = server \ + } \ + } \ } #define DEFINE_REQ_FMT0(name, client, server) \ @@ -1769,10 +1769,10 @@ EXPORT_SYMBOL(req_capsule_set); * field of a \a pill's \a rc_fmt's RMF's. */ int req_capsule_filled_sizes(struct req_capsule *pill, - enum req_location loc) + enum req_location loc) { const struct req_format *fmt = pill->rc_fmt; - int i; + int i; LASSERT(fmt != NULL); @@ -1806,8 +1806,8 @@ EXPORT_SYMBOL(req_capsule_filled_sizes); int req_capsule_server_pack(struct req_capsule *pill) { const struct req_format *fmt; - int count; - int rc; + int count; + int rc; LASSERT(pill->rc_loc == RCL_SERVER); fmt = pill->rc_fmt; @@ -1857,11 +1857,11 @@ swabber_dumper_helper(struct req_capsule *pill, int offset, void *value, int len, int dump, void (*swabber)(void *)) { - void *p; - int i; - int n; - int do_swab; - int inout = loc == RCL_CLIENT; + void *p; + int i; + int n; + int do_swab; + int inout = loc == RCL_CLIENT; swabber = swabber ?: field->rmf_swabber; @@ -1936,10 +1936,10 @@ static void *__req_capsule_get(struct req_capsule *pill, int dump) { const struct req_format *fmt; - struct lustre_msg *msg; - void *value; - int len; - int offset; + struct lustre_msg *msg; + void *value; + int len; + int offset; void *(*getter)(struct lustre_msg *m, int n, int minlen); @@ -2000,10 +2000,10 @@ static void *__req_capsule_get(struct req_capsule *pill, */ static void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) { - const struct req_format *fmt; - const struct req_msg_field *field; - int len; - int i; + const struct req_format *fmt; + const struct req_msg_field *field; + int len; + int i; fmt = pill->rc_fmt; @@ -2350,9 +2350,9 @@ void req_capsule_shrink(struct req_capsule *pill, enum req_location loc) { const struct req_format *fmt; - struct lustre_msg *msg; - int len; - int offset; + struct lustre_msg *msg; + int len; + int offset; fmt = pill->rc_fmt; LASSERT(fmt != NULL); diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c index e9baf5bbee3a..1c701e0a0bc7 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c @@ -49,29 +49,29 @@ #include "../include/lustre_net.h" #include <linux/list.h> -#define LLOG_CLIENT_ENTRY(ctxt, imp) do { \ - mutex_lock(&ctxt->loc_mutex); \ - if (ctxt->loc_imp) { \ - imp = class_import_get(ctxt->loc_imp); \ - } else { \ - CERROR("ctxt->loc_imp == NULL for context idx %d." \ - "Unable to complete MDS/OSS recovery," \ - "but I'll try again next time. Not fatal.\n", \ - ctxt->loc_idx); \ - imp = NULL; \ - mutex_unlock(&ctxt->loc_mutex); \ - return (-EINVAL); \ - } \ - mutex_unlock(&ctxt->loc_mutex); \ +#define LLOG_CLIENT_ENTRY(ctxt, imp) do { \ + mutex_lock(&ctxt->loc_mutex); \ + if (ctxt->loc_imp) { \ + imp = class_import_get(ctxt->loc_imp); \ + } else { \ + CERROR("ctxt->loc_imp == NULL for context idx %d." \ + "Unable to complete MDS/OSS recovery," \ + "but I'll try again next time. Not fatal.\n", \ + ctxt->loc_idx); \ + imp = NULL; \ + mutex_unlock(&ctxt->loc_mutex); \ + return (-EINVAL); \ + } \ + mutex_unlock(&ctxt->loc_mutex); \ } while (0) -#define LLOG_CLIENT_EXIT(ctxt, imp) do { \ - mutex_lock(&ctxt->loc_mutex); \ - if (ctxt->loc_imp != imp) \ - CWARN("loc_imp has changed from %p to %p\n", \ - ctxt->loc_imp, imp); \ - class_import_put(imp); \ - mutex_unlock(&ctxt->loc_mutex); \ +#define LLOG_CLIENT_EXIT(ctxt, imp) do { \ + mutex_lock(&ctxt->loc_mutex); \ + if (ctxt->loc_imp != imp) \ + CWARN("loc_imp has changed from %p to %p\n", \ + ctxt->loc_imp, imp); \ + class_import_put(imp); \ + mutex_unlock(&ctxt->loc_mutex); \ } while (0) /* This is a callback from the llog_* functions. @@ -80,11 +80,11 @@ static int llog_client_open(const struct lu_env *env, struct llog_handle *lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param) { - struct obd_import *imp; - struct llogd_body *body; - struct llog_ctxt *ctxt = lgh->lgh_ctxt; + struct obd_import *imp; + struct llogd_body *body; + struct llog_ctxt *ctxt = lgh->lgh_ctxt; struct ptlrpc_request *req = NULL; - int rc; + int rc; LLOG_CLIENT_ENTRY(ctxt, imp); @@ -145,10 +145,10 @@ out: static int llog_client_destroy(const struct lu_env *env, struct llog_handle *loghandle) { - struct obd_import *imp; + struct obd_import *imp; struct ptlrpc_request *req = NULL; - struct llogd_body *body; - int rc; + struct llogd_body *body; + int rc; LLOG_CLIENT_ENTRY(loghandle->lgh_ctxt, imp); req = ptlrpc_request_alloc_pack(imp, &RQF_LLOG_ORIGIN_HANDLE_DESTROY, @@ -182,11 +182,11 @@ static int llog_client_next_block(const struct lu_env *env, int *cur_idx, int next_idx, __u64 *cur_offset, void *buf, int len) { - struct obd_import *imp; + struct obd_import *imp; struct ptlrpc_request *req = NULL; - struct llogd_body *body; - void *ptr; - int rc; + struct llogd_body *body; + void *ptr; + int rc; LLOG_CLIENT_ENTRY(loghandle->lgh_ctxt, imp); req = ptlrpc_request_alloc_pack(imp, &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK, @@ -240,11 +240,11 @@ static int llog_client_prev_block(const struct lu_env *env, struct llog_handle *loghandle, int prev_idx, void *buf, int len) { - struct obd_import *imp; + struct obd_import *imp; struct ptlrpc_request *req = NULL; - struct llogd_body *body; - void *ptr; - int rc; + struct llogd_body *body; + void *ptr; + int rc; LLOG_CLIENT_ENTRY(loghandle->lgh_ctxt, imp); req = ptlrpc_request_alloc_pack(imp, &RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK, @@ -292,12 +292,12 @@ err_exit: static int llog_client_read_header(const struct lu_env *env, struct llog_handle *handle) { - struct obd_import *imp; + struct obd_import *imp; struct ptlrpc_request *req = NULL; - struct llogd_body *body; - struct llog_log_hdr *hdr; - struct llog_rec_hdr *llh_hdr; - int rc; + struct llogd_body *body; + struct llog_log_hdr *hdr; + struct llog_rec_hdr *llh_hdr; + int rc; LLOG_CLIENT_ENTRY(handle->lgh_ctxt, imp); req = ptlrpc_request_alloc_pack(imp, &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER, diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index aeceef5152ac..aaaabbf5f1b9 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -181,19 +181,19 @@ static const char *ll_eopcode2str(__u32 opcode) return ll_eopcode_table[opcode].opname; } -#if defined(CONFIG_PROC_FS) -static void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, - char *name, - struct proc_dir_entry **procroot_ret, - struct lprocfs_stats **stats_ret) +static void +ptlrpc_ldebugfs_register(struct dentry *root, char *dir, + char *name, + struct dentry **debugfs_root_ret, + struct lprocfs_stats **stats_ret) { - struct proc_dir_entry *svc_procroot; + struct dentry *svc_debugfs_entry; struct lprocfs_stats *svc_stats; int i, rc; unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV; - LASSERT(*procroot_ret == NULL); + LASSERT(*debugfs_root_ret == NULL); LASSERT(*stats_ret == NULL); svc_stats = lprocfs_alloc_stats(EXTRA_MAX_OPCODES+LUSTRE_MAX_OPCODES, @@ -201,14 +201,14 @@ static void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, if (svc_stats == NULL) return; - if (dir) { - svc_procroot = lprocfs_register(dir, root, NULL, NULL); - if (IS_ERR(svc_procroot)) { + if (dir != NULL) { + svc_debugfs_entry = ldebugfs_register(dir, root, NULL, NULL); + if (IS_ERR(svc_debugfs_entry)) { lprocfs_free_stats(&svc_stats); return; } } else { - svc_procroot = root; + svc_debugfs_entry = root; } lprocfs_counter_init(svc_stats, PTLRPC_REQWAIT_CNTR, @@ -244,14 +244,14 @@ static void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, ll_opcode2str(opcode), "usec"); } - rc = lprocfs_register_stats(svc_procroot, name, svc_stats); + rc = ldebugfs_register_stats(svc_debugfs_entry, name, svc_stats); if (rc < 0) { - if (dir) - lprocfs_remove(&svc_procroot); + if (dir != NULL) + ldebugfs_remove(&svc_debugfs_entry); lprocfs_free_stats(&svc_stats); } else { - if (dir) - *procroot_ret = svc_procroot; + if (dir != NULL) + *debugfs_root_ret = svc_debugfs_entry; *stats_ret = svc_stats; } } @@ -261,8 +261,8 @@ ptlrpc_lprocfs_req_history_len_seq_show(struct seq_file *m, void *v) { struct ptlrpc_service *svc = m->private; struct ptlrpc_service_part *svcpt; - int total = 0; - int i; + int total = 0; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) total += svcpt->scp_hist_nrqbds; @@ -277,8 +277,8 @@ ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n) { struct ptlrpc_service *svc = m->private; struct ptlrpc_service_part *svcpt; - int total = 0; - int i; + int total = 0; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) total += svc->srv_hist_nrqbds_cpt_max; @@ -289,13 +289,13 @@ ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n) static ssize_t ptlrpc_lprocfs_req_history_max_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) + const char __user *buffer, + size_t count, loff_t *off) { struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; - int bufpages; - int val; - int rc; + int bufpages; + int val; + int rc; rc = lprocfs_write_helper(buffer, count, &val); if (rc < 0) @@ -324,23 +324,23 @@ ptlrpc_lprocfs_req_history_max_seq_write(struct file *file, } LPROC_SEQ_FOPS(ptlrpc_lprocfs_req_history_max); -static int -ptlrpc_lprocfs_threads_min_seq_show(struct seq_file *m, void *n) + +static ssize_t threads_min_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ptlrpc_service *svc = m->private; + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); - seq_printf(m, "%d\n", svc->srv_nthrs_cpt_init * svc->srv_ncpts); - return 0; + return sprintf(buf, "%d\n", svc->srv_nthrs_cpt_init * svc->srv_ncpts); } -static ssize_t -ptlrpc_lprocfs_threads_min_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t threads_min_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; - int val; - int rc = lprocfs_write_helper(buffer, count, &val); + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); + unsigned long val; + int rc = kstrtoul(buffer, 10, &val); if (rc < 0) return rc; @@ -360,41 +360,41 @@ ptlrpc_lprocfs_threads_min_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_min); +LUSTRE_RW_ATTR(threads_min); -static int -ptlrpc_lprocfs_threads_started_seq_show(struct seq_file *m, void *n) +static ssize_t threads_started_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct ptlrpc_service *svc = m->private; + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); struct ptlrpc_service_part *svcpt; - int total = 0; - int i; + int total = 0; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) total += svcpt->scp_nthrs_running; - seq_printf(m, "%d\n", total); - return 0; + return sprintf(buf, "%d\n", total); } -LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_threads_started); +LUSTRE_RO_ATTR(threads_started); -static int -ptlrpc_lprocfs_threads_max_seq_show(struct seq_file *m, void *n) +static ssize_t threads_max_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ptlrpc_service *svc = m->private; + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); - seq_printf(m, "%d\n", svc->srv_nthrs_cpt_limit * svc->srv_ncpts); - return 0; + return sprintf(buf, "%d\n", svc->srv_nthrs_cpt_limit * svc->srv_ncpts); } -static ssize_t -ptlrpc_lprocfs_threads_max_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t threads_max_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; - int val; - int rc = lprocfs_write_helper(buffer, count, &val); + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); + unsigned long val; + int rc = kstrtoul(buffer, 10, &val); if (rc < 0) return rc; @@ -414,7 +414,7 @@ ptlrpc_lprocfs_threads_max_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_max); +LUSTRE_RW_ATTR(threads_max); /** * \addtogoup nrs @@ -478,17 +478,17 @@ void nrs_policy_get_info_locked(struct ptlrpc_nrs_policy *policy, */ static int ptlrpc_lprocfs_nrs_seq_show(struct seq_file *m, void *n) { - struct ptlrpc_service *svc = m->private; - struct ptlrpc_service_part *svcpt; - struct ptlrpc_nrs *nrs; - struct ptlrpc_nrs_policy *policy; - struct ptlrpc_nrs_pol_info *infos; - struct ptlrpc_nrs_pol_info tmp; - unsigned num_pols; - unsigned pol_idx = 0; - bool hp = false; - int i; - int rc = 0; + struct ptlrpc_service *svc = m->private; + struct ptlrpc_service_part *svcpt; + struct ptlrpc_nrs *nrs; + struct ptlrpc_nrs_policy *policy; + struct ptlrpc_nrs_pol_info *infos; + struct ptlrpc_nrs_pol_info tmp; + unsigned num_pols; + unsigned pol_idx = 0; + bool hp = false; + int i; + int rc = 0; /** * Serialize NRS core lprocfs operations with policy registration/ @@ -638,15 +638,15 @@ unlock: * regular and high-priority (if the service has one) NRS head. */ static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) + const char __user *buffer, + size_t count, loff_t *off) { struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; - enum ptlrpc_nrs_queue_type queue = PTLRPC_NRS_QUEUE_BOTH; - char *cmd; - char *cmd_copy = NULL; - char *token; - int rc = 0; + enum ptlrpc_nrs_queue_type queue = PTLRPC_NRS_QUEUE_BOTH; + char *cmd; + char *cmd_copy = NULL; + char *token; + int rc = 0; if (count >= LPROCFS_NRS_WR_MAX_CMD) return -EINVAL; @@ -729,8 +729,8 @@ ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt, struct ptlrpc_srh_iterator *srhi, __u64 seq) { - struct list_head *e; - struct ptlrpc_request *req; + struct list_head *e; + struct ptlrpc_request *req; if (srhi->srhi_req != NULL && srhi->srhi_seq > svcpt->scp_hist_seq_culled && @@ -860,12 +860,12 @@ static void * ptlrpc_lprocfs_svc_req_history_next(struct seq_file *s, void *iter, loff_t *pos) { - struct ptlrpc_service *svc = s->private; - struct ptlrpc_srh_iterator *srhi = iter; - struct ptlrpc_service_part *svcpt; - __u64 seq; - int rc; - int i; + struct ptlrpc_service *svc = s->private; + struct ptlrpc_srh_iterator *srhi = iter; + struct ptlrpc_service_part *svcpt; + __u64 seq; + int rc; + int i; for (i = srhi->srhi_idx; i < svc->srv_ncpts; i++) { svcpt = svc->srv_parts[i]; @@ -923,11 +923,11 @@ EXPORT_SYMBOL(target_print_req); static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter) { - struct ptlrpc_service *svc = s->private; - struct ptlrpc_srh_iterator *srhi = iter; - struct ptlrpc_service_part *svcpt; - struct ptlrpc_request *req; - int rc; + struct ptlrpc_service *svc = s->private; + struct ptlrpc_srh_iterator *srhi = iter; + struct ptlrpc_service_part *svcpt; + struct ptlrpc_request *req; + int rc; LASSERT(srhi->srhi_idx < svc->srv_ncpts); @@ -972,28 +972,28 @@ ptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file) .next = ptlrpc_lprocfs_svc_req_history_next, .show = ptlrpc_lprocfs_svc_req_history_show, }; - struct seq_file *seqf; - int rc; + struct seq_file *seqf; + int rc; rc = seq_open(file, &sops); if (rc) return rc; seqf = file->private_data; - seqf->private = PDE_DATA(inode); + seqf->private = inode->i_private; return 0; } /* See also lprocfs_rd_timeouts */ static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n) { - struct ptlrpc_service *svc = m->private; - struct ptlrpc_service_part *svcpt; - struct dhms ts; - time_t worstt; - unsigned int cur; - unsigned int worst; - int i; + struct ptlrpc_service *svc = m->private; + struct ptlrpc_service_part *svcpt; + struct dhms ts; + time_t worstt; + unsigned int cur; + unsigned int worst; + int i; if (AT_OFF) { seq_printf(m, "adaptive timeouts off, using obd_timeout %u\n", @@ -1018,23 +1018,26 @@ static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n) } LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_timeouts); -static int ptlrpc_lprocfs_hp_ratio_seq_show(struct seq_file *m, void *v) +static ssize_t high_priority_ratio_show(struct kobject *kobj, + struct attribute *attr, + char *buf) { - struct ptlrpc_service *svc = m->private; - seq_printf(m, "%d", svc->srv_hpreq_ratio); - return 0; + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); + return sprintf(buf, "%d\n", svc->srv_hpreq_ratio); } -static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file, - const char __user *buffer, - size_t count, - loff_t *off) +static ssize_t high_priority_ratio_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; - int rc; - int val; + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); + int rc; + int val; - rc = lprocfs_write_helper(buffer, count, &val); + rc = kstrtoint(buffer, 10, &val); if (rc < 0) return rc; @@ -1047,30 +1050,62 @@ static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(ptlrpc_lprocfs_hp_ratio); +LUSTRE_RW_ATTR(high_priority_ratio); + +static struct attribute *ptlrpc_svc_attrs[] = { + &lustre_attr_threads_min.attr, + &lustre_attr_threads_started.attr, + &lustre_attr_threads_max.attr, + &lustre_attr_high_priority_ratio.attr, + NULL, +}; + +static void ptlrpc_sysfs_svc_release(struct kobject *kobj) +{ + struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service, + srv_kobj); + + complete(&svc->srv_kobj_unregister); +} + +static struct kobj_type ptlrpc_svc_ktype = { + .default_attrs = ptlrpc_svc_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = ptlrpc_sysfs_svc_release, +}; + +void ptlrpc_sysfs_unregister_service(struct ptlrpc_service *svc) +{ + /* Let's see if we had a chance at initialization first */ + if (svc->srv_kobj.kset) { + kobject_put(&svc->srv_kobj); + wait_for_completion(&svc->srv_kobj_unregister); + } +} -void ptlrpc_lprocfs_register_service(struct proc_dir_entry *entry, - struct ptlrpc_service *svc) +int ptlrpc_sysfs_register_service(struct kset *parent, + struct ptlrpc_service *svc) +{ + int rc; + + svc->srv_kobj.kset = parent; + init_completion(&svc->srv_kobj_unregister); + rc = kobject_init_and_add(&svc->srv_kobj, &ptlrpc_svc_ktype, NULL, + "%s", svc->srv_name); + + return rc; +} + +void ptlrpc_ldebugfs_register_service(struct dentry *entry, + struct ptlrpc_service *svc) { struct lprocfs_vars lproc_vars[] = { - {.name = "high_priority_ratio", - .fops = &ptlrpc_lprocfs_hp_ratio_fops, - .data = svc}, {.name = "req_buffer_history_len", .fops = &ptlrpc_lprocfs_req_history_len_fops, .data = svc}, {.name = "req_buffer_history_max", .fops = &ptlrpc_lprocfs_req_history_max_fops, .data = svc}, - {.name = "threads_min", - .fops = &ptlrpc_lprocfs_threads_min_fops, - .data = svc}, - {.name = "threads_max", - .fops = &ptlrpc_lprocfs_threads_max_fops, - .data = svc}, - {.name = "threads_started", - .fops = &ptlrpc_lprocfs_threads_started_fops, - .data = svc}, {.name = "timeouts", .fops = &ptlrpc_lprocfs_timeouts_fops, .data = svc}, @@ -1089,26 +1124,26 @@ void ptlrpc_lprocfs_register_service(struct proc_dir_entry *entry, int rc; - ptlrpc_lprocfs_register(entry, svc->srv_name, - "stats", &svc->srv_procroot, - &svc->srv_stats); + ptlrpc_ldebugfs_register(entry, svc->srv_name, + "stats", &svc->srv_debugfs_entry, + &svc->srv_stats); - if (svc->srv_procroot == NULL) + if (svc->srv_debugfs_entry == NULL) return; - lprocfs_add_vars(svc->srv_procroot, lproc_vars, NULL); + ldebugfs_add_vars(svc->srv_debugfs_entry, lproc_vars, NULL); - rc = lprocfs_seq_create(svc->srv_procroot, "req_history", - 0400, &req_history_fops, svc); + rc = ldebugfs_seq_create(svc->srv_debugfs_entry, "req_history", + 0400, &req_history_fops, svc); if (rc) CWARN("Error adding the req_history file\n"); } void ptlrpc_lprocfs_register_obd(struct obd_device *obddev) { - ptlrpc_lprocfs_register(obddev->obd_proc_entry, NULL, "stats", - &obddev->obd_svc_procroot, - &obddev->obd_svc_stats); + ptlrpc_ldebugfs_register(obddev->obd_debugfs_entry, NULL, "stats", + &obddev->obd_svc_debugfs_entry, + &obddev->obd_svc_stats); } EXPORT_SYMBOL(ptlrpc_lprocfs_register_obd); @@ -1156,8 +1191,8 @@ EXPORT_SYMBOL(ptlrpc_lprocfs_brw); void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc) { - if (svc->srv_procroot != NULL) - lprocfs_remove(&svc->srv_procroot); + if (svc->srv_debugfs_entry != NULL) + ldebugfs_remove(&svc->srv_debugfs_entry); if (svc->srv_stats) lprocfs_free_stats(&svc->srv_stats); @@ -1165,8 +1200,8 @@ void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc) void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd) { - if (obd->obd_svc_procroot) - lprocfs_remove(&obd->obd_svc_procroot); + if (!IS_ERR_OR_NULL(obd->obd_svc_debugfs_entry)) + ldebugfs_remove(&obd->obd_svc_debugfs_entry); if (obd->obd_svc_stats) lprocfs_free_stats(&obd->obd_svc_stats); @@ -1180,8 +1215,8 @@ int lprocfs_wr_evict_client(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct obd_device *obd = ((struct seq_file *)file->private_data)->private; - char *kbuf; - char *tmpbuf; + char *kbuf; + char *tmpbuf; kbuf = kzalloc(BUFLEN, GFP_NOFS); if (kbuf == NULL) @@ -1201,7 +1236,7 @@ int lprocfs_wr_evict_client(struct file *file, const char __user *buffer, /* Kludge code(deadlock situation): the lprocfs lock has been held * since the client is evicted by writing client's * uuid/nid to procfs "evict_client" entry. However, - * obd_export_evict_by_uuid() will call lprocfs_remove() to destroy + * obd_export_evict_by_uuid() will call ldebugfs_remove() to destroy * the proc entries under the being destroyed export{}, so I have * to drop the lock at first here. * - jay, jxiong@clusterfs.com */ @@ -1229,7 +1264,7 @@ int lprocfs_wr_ping(struct file *file, const char __user *buffer, { struct obd_device *obd = ((struct seq_file *)file->private_data)->private; struct ptlrpc_request *req; - int rc; + int rc; LPROCFS_CLIMP_CHECK(obd); req = ptlrpc_prep_ping(obd->u.cli.cl_import); @@ -1354,5 +1389,3 @@ int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer, } EXPORT_SYMBOL(lprocfs_wr_pinger_recov); - -#endif /* CONFIG_PROC_FS */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index 2fa2585584a3..92c746b44462 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -52,17 +52,17 @@ static int ptl_send_buf(lnet_handle_md_t *mdh, void *base, int len, struct ptlrpc_connection *conn, int portal, __u64 xid, unsigned int offset) { - int rc; - lnet_md_t md; + int rc; + lnet_md_t md; LASSERT(portal != 0); LASSERT(conn != NULL); CDEBUG(D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer)); - md.start = base; - md.length = len; + md.start = base; + md.length = len; md.threshold = (ack == LNET_ACK_REQ) ? 2 : 1; - md.options = PTLRPC_MD_OPTIONS; - md.user_ptr = cbid; + md.options = PTLRPC_MD_OPTIONS; + md.user_ptr = cbid; md.eq_handle = ptlrpc_eq_h; if (unlikely(ack == LNET_ACK_REQ && @@ -120,8 +120,8 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) int posted_md; int total_md; __u64 xid; - lnet_handle_me_t me_h; - lnet_md_t md; + lnet_handle_me_t me_h; + lnet_md_t md; if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_BULK_GET_NET)) return 0; @@ -243,9 +243,9 @@ EXPORT_SYMBOL(ptlrpc_register_bulk); int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async) { struct ptlrpc_bulk_desc *desc = req->rq_bulk; - wait_queue_head_t *wq; - struct l_wait_info lwi; - int rc; + wait_queue_head_t *wq; + struct l_wait_info lwi; + int rc; LASSERT(!in_interrupt()); /* might sleep */ @@ -301,8 +301,8 @@ EXPORT_SYMBOL(ptlrpc_unregister_bulk); static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) { - struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; - struct ptlrpc_service *svc = svcpt->scp_service; + struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; + struct ptlrpc_service *svc = svcpt->scp_service; int service_time = max_t(int, get_seconds() - req->rq_arrival_time.tv_sec, 1); @@ -353,8 +353,8 @@ static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) int ptlrpc_send_reply(struct ptlrpc_request *req, int flags) { struct ptlrpc_reply_state *rs = req->rq_reply_state; - struct ptlrpc_connection *conn; - int rc; + struct ptlrpc_connection *conn; + int rc; /* We must already have a reply buffer (only ptlrpc_error() may be * called without one). The reply generated by sptlrpc layer (e.g. @@ -491,8 +491,8 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) int rc2; int mpflag = 0; struct ptlrpc_connection *connection; - lnet_handle_me_t reply_me_h; - lnet_md_t reply_md; + lnet_handle_me_t reply_me_h; + lnet_md_t reply_md; struct obd_device *obd = request->rq_import->imp_obd; if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DROP_RPC)) @@ -594,15 +594,15 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) spin_unlock(&request->rq_lock); if (!noreply) { - reply_md.start = request->rq_repbuf; - reply_md.length = request->rq_repbuf_len; + reply_md.start = request->rq_repbuf; + reply_md.length = request->rq_repbuf_len; /* Allow multiple early replies */ reply_md.threshold = LNET_MD_THRESH_INF; /* Manage remote for early replies */ - reply_md.options = PTLRPC_MD_OPTIONS | LNET_MD_OP_PUT | + reply_md.options = PTLRPC_MD_OPTIONS | LNET_MD_OP_PUT | LNET_MD_MANAGE_REMOTE | LNET_MD_TRUNCATE; /* allow to make EOVERFLOW error */; - reply_md.user_ptr = &request->rq_reply_cbid; + reply_md.user_ptr = &request->rq_reply_cbid; reply_md.eq_handle = ptlrpc_eq_h; /* We must see the unlink callback to unset rq_reply_unlink, @@ -682,11 +682,11 @@ EXPORT_SYMBOL(ptl_send_rpc); */ int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd) { - struct ptlrpc_service *service = rqbd->rqbd_svcpt->scp_service; - static lnet_process_id_t match_id = {LNET_NID_ANY, LNET_PID_ANY}; - int rc; - lnet_md_t md; - lnet_handle_me_t me_h; + struct ptlrpc_service *service = rqbd->rqbd_svcpt->scp_service; + static lnet_process_id_t match_id = {LNET_NID_ANY, LNET_PID_ANY}; + int rc; + lnet_md_t md; + lnet_handle_me_t me_h; CDEBUG(D_NET, "LNetMEAttach: portal %d\n", service->srv_req_portal); @@ -709,12 +709,12 @@ int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd) LASSERT(rqbd->rqbd_refcount == 0); rqbd->rqbd_refcount = 1; - md.start = rqbd->rqbd_buffer; - md.length = service->srv_buf_size; - md.max_size = service->srv_max_req_size; + md.start = rqbd->rqbd_buffer; + md.length = service->srv_buf_size; + md.max_size = service->srv_max_req_size; md.threshold = LNET_MD_THRESH_INF; - md.options = PTLRPC_MD_OPTIONS | LNET_MD_OP_PUT | LNET_MD_MAX_SIZE; - md.user_ptr = &rqbd->rqbd_cbid; + md.options = PTLRPC_MD_OPTIONS | LNET_MD_OP_PUT | LNET_MD_MAX_SIZE; + md.user_ptr = &rqbd->rqbd_cbid; md.eq_handle = ptlrpc_eq_h; rc = LNetMDAttach(me_h, md, LNET_UNLINK, &rqbd->rqbd_md_h); diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c index 63a05f4a902d..9516acadb7a1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c +++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c @@ -188,8 +188,8 @@ static void nrs_policy_stop_primary(struct ptlrpc_nrs *nrs) */ static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy) { - struct ptlrpc_nrs *nrs = policy->pol_nrs; - int rc = 0; + struct ptlrpc_nrs *nrs = policy->pol_nrs; + int rc = 0; /** * Don't allow multiple starting which is too complex, and has no real @@ -377,15 +377,15 @@ static void nrs_resource_put(struct ptlrpc_nrs_resource *res) */ static struct ptlrpc_nrs_resource *nrs_resource_get(struct ptlrpc_nrs_policy *policy, - struct ptlrpc_nrs_request *nrq, - bool moving_req) + struct ptlrpc_nrs_request *nrq, + bool moving_req) { /** * Set to NULL to traverse the resource hierarchy from the top. */ struct ptlrpc_nrs_resource *res = NULL; struct ptlrpc_nrs_resource *tmp = NULL; - int rc; + int rc; while (1) { rc = policy->pol_desc->pd_ops->op_res_get(policy, nrq, res, @@ -432,8 +432,8 @@ static void nrs_resource_get_safe(struct ptlrpc_nrs *nrs, struct ptlrpc_nrs_resource **resp, bool moving_req) { - struct ptlrpc_nrs_policy *primary = NULL; - struct ptlrpc_nrs_policy *fallback = NULL; + struct ptlrpc_nrs_policy *primary = NULL; + struct ptlrpc_nrs_policy *fallback = NULL; memset(resp, 0, sizeof(resp[0]) * NRS_RES_MAX); @@ -478,14 +478,14 @@ static void nrs_resource_get_safe(struct ptlrpc_nrs *nrs, * * \param resp the resource hierarchy that is being released * - * \see ptlrpcnrs_req_hp_move() + * \see ptlrpc_nrs_req_hp_move() * \see ptlrpc_nrs_req_finalize() */ static void nrs_resource_put_safe(struct ptlrpc_nrs_resource **resp) { struct ptlrpc_nrs_policy *pols[NRS_RES_MAX]; - struct ptlrpc_nrs *nrs = NULL; - int i; + struct ptlrpc_nrs *nrs = NULL; + int i; for (i = 0; i < NRS_RES_MAX; i++) { if (resp[i] != NULL) { @@ -530,7 +530,7 @@ static void nrs_resource_put_safe(struct ptlrpc_nrs_resource **resp) */ static inline struct ptlrpc_nrs_request *nrs_request_get(struct ptlrpc_nrs_policy *policy, - bool peek, bool force) + bool peek, bool force) { struct ptlrpc_nrs_request *nrq; @@ -556,8 +556,8 @@ struct ptlrpc_nrs_request *nrs_request_get(struct ptlrpc_nrs_policy *policy, static inline void nrs_request_enqueue(struct ptlrpc_nrs_request *nrq) { struct ptlrpc_nrs_policy *policy; - int rc; - int i; + int rc; + int i; /** * Try in descending order, because the primary policy (if any) is @@ -628,8 +628,8 @@ static inline void nrs_request_stop(struct ptlrpc_nrs_request *nrq) static int nrs_policy_ctl(struct ptlrpc_nrs *nrs, char *name, enum ptlrpc_nrs_ctl opc, void *arg) { - struct ptlrpc_nrs_policy *policy; - int rc = 0; + struct ptlrpc_nrs_policy *policy; + int rc = 0; spin_lock(&nrs->nrs_lock); @@ -733,10 +733,10 @@ static int nrs_policy_unregister(struct ptlrpc_nrs *nrs, char *name) static int nrs_policy_register(struct ptlrpc_nrs *nrs, struct ptlrpc_nrs_pol_desc *desc) { - struct ptlrpc_nrs_policy *policy; - struct ptlrpc_nrs_policy *tmp; - struct ptlrpc_service_part *svcpt = nrs->nrs_svcpt; - int rc; + struct ptlrpc_nrs_policy *policy; + struct ptlrpc_nrs_policy *tmp; + struct ptlrpc_service_part *svcpt = nrs->nrs_svcpt; + int rc; LASSERT(svcpt != NULL); LASSERT(desc->pd_ops != NULL); @@ -752,10 +752,10 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs, if (policy == NULL) return -ENOMEM; - policy->pol_nrs = nrs; - policy->pol_desc = desc; - policy->pol_state = NRS_POL_STATE_STOPPED; - policy->pol_flags = desc->pd_flags; + policy->pol_nrs = nrs; + policy->pol_desc = desc; + policy->pol_state = NRS_POL_STATE_STOPPED; + policy->pol_flags = desc->pd_flags; INIT_LIST_HEAD(&policy->pol_list); INIT_LIST_HEAD(&policy->pol_list_queued); @@ -804,7 +804,7 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs, */ static void ptlrpc_nrs_req_add_nolock(struct ptlrpc_request *req) { - struct ptlrpc_nrs_policy *policy; + struct ptlrpc_nrs_policy *policy; LASSERT(req->rq_nrq.nr_initialized); LASSERT(!req->rq_nrq.nr_enqueued); @@ -829,7 +829,7 @@ static void ptlrpc_nrs_req_add_nolock(struct ptlrpc_request *req) */ static void ptlrpc_nrs_hpreq_add_nolock(struct ptlrpc_request *req) { - int opc = lustre_msg_get_opc(req->rq_reqmsg); + int opc = lustre_msg_get_opc(req->rq_reqmsg); spin_lock(&req->rq_lock); req->rq_hp = 1; @@ -872,9 +872,9 @@ static int nrs_register_policies_locked(struct ptlrpc_nrs *nrs) { struct ptlrpc_nrs_pol_desc *desc; /* for convenience */ - struct ptlrpc_service_part *svcpt = nrs->nrs_svcpt; - struct ptlrpc_service *svc = svcpt->scp_service; - int rc = -EINVAL; + struct ptlrpc_service_part *svcpt = nrs->nrs_svcpt; + struct ptlrpc_service *svc = svcpt->scp_service; + int rc = -EINVAL; LASSERT(mutex_is_locked(&nrs_core.nrs_mutex)); @@ -912,7 +912,7 @@ static int nrs_register_policies_locked(struct ptlrpc_nrs *nrs) static int nrs_svcpt_setup_locked0(struct ptlrpc_nrs *nrs, struct ptlrpc_service_part *svcpt) { - enum ptlrpc_nrs_queue_type queue; + enum ptlrpc_nrs_queue_type queue; LASSERT(mutex_is_locked(&nrs_core.nrs_mutex)); @@ -943,8 +943,8 @@ static int nrs_svcpt_setup_locked0(struct ptlrpc_nrs *nrs, */ static int nrs_svcpt_setup_locked(struct ptlrpc_service_part *svcpt) { - struct ptlrpc_nrs *nrs; - int rc; + struct ptlrpc_nrs *nrs; + int rc; LASSERT(mutex_is_locked(&nrs_core.nrs_mutex)); @@ -988,11 +988,11 @@ out: */ static void nrs_svcpt_cleanup_locked(struct ptlrpc_service_part *svcpt) { - struct ptlrpc_nrs *nrs; - struct ptlrpc_nrs_policy *policy; - struct ptlrpc_nrs_policy *tmp; - int rc; - bool hp = false; + struct ptlrpc_nrs *nrs; + struct ptlrpc_nrs_policy *policy; + struct ptlrpc_nrs_policy *tmp; + int rc; + bool hp = false; LASSERT(mutex_is_locked(&nrs_core.nrs_mutex)); @@ -1028,7 +1028,7 @@ again: */ static struct ptlrpc_nrs_pol_desc *nrs_policy_find_desc_locked(const char *name) { - struct ptlrpc_nrs_pol_desc *tmp; + struct ptlrpc_nrs_pol_desc *tmp; list_for_each_entry(tmp, &nrs_core.nrs_policies, pd_list) { if (strncmp(tmp->pd_name, name, NRS_POL_NAME_MAX) == 0) @@ -1051,11 +1051,11 @@ static struct ptlrpc_nrs_pol_desc *nrs_policy_find_desc_locked(const char *name) */ static int nrs_policy_unregister_locked(struct ptlrpc_nrs_pol_desc *desc) { - struct ptlrpc_nrs *nrs; - struct ptlrpc_service *svc; - struct ptlrpc_service_part *svcpt; - int i; - int rc = 0; + struct ptlrpc_nrs *nrs; + struct ptlrpc_service *svc; + struct ptlrpc_service_part *svcpt; + int i; + int rc = 0; LASSERT(mutex_is_locked(&nrs_core.nrs_mutex)); LASSERT(mutex_is_locked(&ptlrpc_all_services_mutex)); @@ -1115,9 +1115,9 @@ again: */ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) { - struct ptlrpc_service *svc; - struct ptlrpc_nrs_pol_desc *desc; - int rc = 0; + struct ptlrpc_service *svc; + struct ptlrpc_nrs_pol_desc *desc; + int rc = 0; LASSERT(conf != NULL); LASSERT(conf->nc_ops != NULL); @@ -1162,12 +1162,12 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) } strncpy(desc->pd_name, conf->nc_name, NRS_POL_NAME_MAX); - desc->pd_ops = conf->nc_ops; - desc->pd_compat = conf->nc_compat; + desc->pd_ops = conf->nc_ops; + desc->pd_compat = conf->nc_compat; desc->pd_compat_svc_name = conf->nc_compat_svc_name; if ((conf->nc_flags & PTLRPC_NRS_FL_REG_EXTERN) != 0) - desc->pd_owner = conf->nc_owner; - desc->pd_flags = conf->nc_flags; + desc->pd_owner = conf->nc_owner; + desc->pd_flags = conf->nc_flags; atomic_set(&desc->pd_refs, 0); /** @@ -1187,17 +1187,17 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) mutex_lock(&ptlrpc_all_services_mutex); list_for_each_entry(svc, &ptlrpc_all_services, srv_list) { - struct ptlrpc_service_part *svcpt; - int i; - int rc2; + struct ptlrpc_service_part *svcpt; + int i; + int rc2; if (!nrs_policy_compatible(svc, desc) || unlikely(svc->srv_is_stopping)) continue; ptlrpc_service_for_each_part(svcpt, i, svc) { - struct ptlrpc_nrs *nrs; - bool hp = false; + struct ptlrpc_nrs *nrs; + bool hp = false; again: nrs = nrs_svcpt2nrs(svcpt, hp); rc = nrs_policy_register(nrs, desc); @@ -1267,8 +1267,8 @@ EXPORT_SYMBOL(ptlrpc_nrs_policy_register); */ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) { - struct ptlrpc_nrs_pol_desc *desc; - int rc; + struct ptlrpc_nrs_pol_desc *desc; + int rc; LASSERT(conf != NULL); @@ -1331,10 +1331,10 @@ EXPORT_SYMBOL(ptlrpc_nrs_policy_unregister); */ int ptlrpc_service_nrs_setup(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - const struct ptlrpc_nrs_pol_desc *desc; - int i; - int rc = 0; + struct ptlrpc_service_part *svcpt; + const struct ptlrpc_nrs_pol_desc *desc; + int i; + int rc = 0; mutex_lock(&nrs_core.nrs_mutex); @@ -1376,9 +1376,9 @@ failed: */ void ptlrpc_service_nrs_cleanup(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - const struct ptlrpc_nrs_pol_desc *desc; - int i; + struct ptlrpc_service_part *svcpt; + const struct ptlrpc_nrs_pol_desc *desc; + int i; mutex_lock(&nrs_core.nrs_mutex); @@ -1417,7 +1417,7 @@ void ptlrpc_service_nrs_cleanup(struct ptlrpc_service *svc) void ptlrpc_nrs_req_initialize(struct ptlrpc_service_part *svcpt, struct ptlrpc_request *req, bool hp) { - struct ptlrpc_nrs *nrs = nrs_svcpt2nrs(svcpt, hp); + struct ptlrpc_nrs *nrs = nrs_svcpt2nrs(svcpt, hp); memset(&req->rq_nrq, 0, sizeof(req->rq_nrq)); nrs_resource_get_safe(nrs, &req->rq_nrq, req->rq_nrq.nr_res_ptrs, @@ -1525,8 +1525,8 @@ struct ptlrpc_request * ptlrpc_nrs_req_get_nolock0(struct ptlrpc_service_part *svcpt, bool hp, bool peek, bool force) { - struct ptlrpc_nrs *nrs = nrs_svcpt2nrs(svcpt, hp); - struct ptlrpc_nrs_policy *policy; + struct ptlrpc_nrs *nrs = nrs_svcpt2nrs(svcpt, hp); + struct ptlrpc_nrs_policy *policy; struct ptlrpc_nrs_request *nrq; /** @@ -1596,10 +1596,10 @@ bool ptlrpc_nrs_req_pending_nolock(struct ptlrpc_service_part *svcpt, bool hp) */ void ptlrpc_nrs_req_hp_move(struct ptlrpc_request *req) { - struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; - struct ptlrpc_nrs_request *nrq = &req->rq_nrq; - struct ptlrpc_nrs_resource *res1[NRS_RES_MAX]; - struct ptlrpc_nrs_resource *res2[NRS_RES_MAX]; + struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; + struct ptlrpc_nrs_request *nrq = &req->rq_nrq; + struct ptlrpc_nrs_resource *res1[NRS_RES_MAX]; + struct ptlrpc_nrs_resource *res2[NRS_RES_MAX]; /** * Obtain the high-priority NRS head resources. @@ -1661,9 +1661,9 @@ int ptlrpc_nrs_policy_control(const struct ptlrpc_service *svc, enum ptlrpc_nrs_queue_type queue, char *name, enum ptlrpc_nrs_ctl opc, bool single, void *arg) { - struct ptlrpc_service_part *svcpt; - int i; - int rc = 0; + struct ptlrpc_service_part *svcpt; + int i; + int rc = 0; LASSERT(opc != PTLRPC_NRS_CTL_INVALID); @@ -1711,7 +1711,7 @@ extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo; */ int ptlrpc_nrs_init(void) { - int rc; + int rc; mutex_init(&nrs_core.nrs_mutex); INIT_LIST_HEAD(&nrs_core.nrs_policies); diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c index 6a61c85cfb11..8e21f0cdc8f8 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c +++ b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c @@ -160,9 +160,9 @@ static int nrs_fifo_res_get(struct ptlrpc_nrs_policy *policy, */ static struct ptlrpc_nrs_request *nrs_fifo_req_get(struct ptlrpc_nrs_policy *policy, - bool peek, bool force) + bool peek, bool force) { - struct nrs_fifo_head *head = policy->pol_private; + struct nrs_fifo_head *head = policy->pol_private; struct ptlrpc_nrs_request *nrq; nrq = unlikely(list_empty(&head->fh_list)) ? NULL : diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index b51af9bf37b7..2787bfd67165 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -279,8 +279,8 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt) /* See if we have anything in a pool, and wait if nothing */ while (list_empty(&svcpt->scp_rep_idle)) { - struct l_wait_info lwi; - int rc; + struct l_wait_info lwi; + int rc; spin_unlock(&svcpt->scp_rep_lock); /* If we cannot get anything for some long time, we better @@ -321,7 +321,7 @@ int lustre_pack_reply_v2(struct ptlrpc_request *req, int count, __u32 *lens, char **bufs, int flags) { struct ptlrpc_reply_state *rs; - int msg_len, rc; + int msg_len, rc; LASSERT(req->rq_reply_state == NULL); @@ -440,8 +440,8 @@ EXPORT_SYMBOL(lustre_msg_buf); int lustre_shrink_msg_v2(struct lustre_msg_v2 *msg, int segment, unsigned int newlen, int move_data) { - char *tail = NULL, *newpos; - int tail_len = 0, n; + char *tail = NULL, *newpos; + int tail_len = 0, n; LASSERT(msg); LASSERT(msg->lm_bufcount > segment); @@ -1577,8 +1577,8 @@ int do_set_info_async(struct obd_import *imp, struct ptlrpc_request_set *set) { struct ptlrpc_request *req; - char *tmp; - int rc; + char *tmp; + int rc; req = ptlrpc_request_alloc(imp, &RQF_OBD_SET_INFO); if (req == NULL) @@ -1688,7 +1688,7 @@ void lustre_swab_connect(struct obd_connect_data *ocd) CLASSERT(offsetof(typeof(*ocd), paddingF) != 0); } -void lustre_swab_obdo(struct obdo *o) +void lustre_swab_obdo(struct obdo *o) { __swab64s(&o->o_valid); lustre_swab_ost_id(&o->o_oi); @@ -2179,7 +2179,7 @@ EXPORT_SYMBOL(lustre_swab_lov_user_md_objects); void lustre_swab_ldlm_res_id(struct ldlm_res_id *id) { - int i; + int i; for (i = 0; i < RES_NAME_SIZE; i++) __swab64s(&id->name[i]); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 5abb91cc87ff..d05c37c1fd30 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -91,7 +91,7 @@ int ptlrpc_obd_ping(struct obd_device *obd) } EXPORT_SYMBOL(ptlrpc_obd_ping); -int ptlrpc_ping(struct obd_import *imp) +static int ptlrpc_ping(struct obd_import *imp) { struct ptlrpc_request *req; @@ -110,7 +110,7 @@ int ptlrpc_ping(struct obd_import *imp) return 0; } -void ptlrpc_update_next_ping(struct obd_import *imp, int soon) +static void ptlrpc_update_next_ping(struct obd_import *imp, int soon) { int time = soon ? PING_INTERVAL_SHORT : PING_INTERVAL; if (imp->imp_state == LUSTRE_IMP_DISCON) { @@ -141,7 +141,7 @@ static inline int ptlrpc_next_reconnect(struct obd_import *imp) return cfs_time_shift(obd_timeout); } -long pinger_check_timeout(unsigned long time) +static long pinger_check_timeout(unsigned long time) { struct timeout_item *item; unsigned long timeout = PING_INTERVAL; @@ -289,12 +289,10 @@ static int ptlrpc_pinger_main(void *arg) thread_is_stopping(thread) || thread_is_event(thread), &lwi); - if (thread_test_and_clear_flags(thread, SVC_STOPPING)) { + if (thread_test_and_clear_flags(thread, SVC_STOPPING)) break; - } else { - /* woken after adding import to reset timer */ - thread_test_and_clear_flags(thread, SVC_EVENT); - } + /* woken after adding import to reset timer */ + thread_test_and_clear_flags(thread, SVC_EVENT); } } @@ -422,8 +420,8 @@ EXPORT_SYMBOL(ptlrpc_pinger_del_import); * Register a timeout callback to the pinger list, and the callback will * be called when timeout happens. */ -struct timeout_item *ptlrpc_new_timeout(int time, enum timeout_event event, - timeout_cb_t cb, void *data) +static struct timeout_item *ptlrpc_new_timeout(int time, + enum timeout_event event, timeout_cb_t cb, void *data) { struct timeout_item *ti; @@ -546,9 +544,9 @@ void ptlrpc_pinger_wake_up(void) #define PET_TERMINATE 2 static int pet_refcount; -static int pet_state; -static wait_queue_head_t pet_waitq; -LIST_HEAD(pet_list); +static int pet_state; +static wait_queue_head_t pet_waitq; +static LIST_HEAD(pet_list); static DEFINE_SPINLOCK(pet_lock); int ping_evictor_wake(struct obd_export *exp) diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index a66dc3c6da41..6dc3998dcd24 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -76,19 +76,16 @@ void ptlrpc_initiate_recovery(struct obd_import *imp); int lustre_unpack_req_ptlrpc_body(struct ptlrpc_request *req, int offset); int lustre_unpack_rep_ptlrpc_body(struct ptlrpc_request *req, int offset); -#if defined(CONFIG_PROC_FS) -void ptlrpc_lprocfs_register_service(struct proc_dir_entry *proc_entry, - struct ptlrpc_service *svc); +int ptlrpc_sysfs_register_service(struct kset *parent, + struct ptlrpc_service *svc); +void ptlrpc_sysfs_unregister_service(struct ptlrpc_service *svc); + +void ptlrpc_ldebugfs_register_service(struct dentry *debugfs_entry, + struct ptlrpc_service *svc); void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc); void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount); void ptlrpc_lprocfs_do_request_stat(struct ptlrpc_request *req, long q_usec, long work_usec); -#else -#define ptlrpc_lprocfs_register_service(params...) do {} while (0) -#define ptlrpc_lprocfs_unregister_service(params...) do {} while (0) -#define ptlrpc_lprocfs_rpc_sent(params...) do {} while (0) -#define ptlrpc_lprocfs_do_request_stat(params...) do {} while (0) -#endif /* CONFIG_PROC_FS */ /* NRS */ @@ -263,14 +260,8 @@ void sptlrpc_enc_pool_fini(void); int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v); /* sec_lproc.c */ -#if defined(CONFIG_PROC_FS) int sptlrpc_lproc_init(void); void sptlrpc_lproc_fini(void); -#else -static inline int sptlrpc_lproc_init(void) -{ return 0; } -static inline void sptlrpc_lproc_fini(void) {} -#endif /* sec_gc.c */ int sptlrpc_gc_init(void); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 5ba3e6ed5289..e591cff323ec 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -68,9 +68,9 @@ #include "ptlrpc_internal.h" struct ptlrpcd { - int pd_size; - int pd_index; - int pd_nthreads; + int pd_size; + int pd_index; + int pd_nthreads; struct ptlrpcd_ctl pd_thread_rcv; struct ptlrpcd_ctl pd_threads[0]; }; diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c index bcfd0b0b6f93..8798fab31f77 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -113,10 +113,10 @@ static struct ptlrpc_sec_policy *sptlrpc_wireflavor2policy(__u32 flavor) { static DEFINE_MUTEX(load_mutex); - static atomic_t loaded = ATOMIC_INIT(0); + static atomic_t loaded = ATOMIC_INIT(0); struct ptlrpc_sec_policy *policy; - __u16 number = SPTLRPC_FLVR_POLICY(flavor); - __u16 flag = 0; + __u16 number = SPTLRPC_FLVR_POLICY(flavor); + __u16 flag = 0; if (number >= SPTLRPC_POLICY_MAX) return NULL; @@ -339,7 +339,7 @@ int sptlrpc_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize) static int import_sec_check_expire(struct obd_import *imp) { - int adapt = 0; + int adapt = 0; spin_lock(&imp->imp_lock); if (imp->imp_sec_expire && @@ -359,7 +359,7 @@ static int import_sec_check_expire(struct obd_import *imp) static int import_sec_validate_get(struct obd_import *imp, struct ptlrpc_sec **sec) { - int rc; + int rc; if (unlikely(imp->imp_sec_expire)) { rc = import_sec_check_expire(imp); @@ -447,10 +447,10 @@ int sptlrpc_req_ctx_switch(struct ptlrpc_request *req, struct ptlrpc_cli_ctx *oldctx, struct ptlrpc_cli_ctx *newctx) { - struct sptlrpc_flavor old_flvr; - char *reqmsg = NULL; /* to workaround old gcc */ - int reqmsg_size; - int rc = 0; + struct sptlrpc_flavor old_flvr; + char *reqmsg = NULL; /* to workaround old gcc */ + int reqmsg_size; + int rc = 0; LASSERT(req->rq_reqmsg); LASSERT(req->rq_reqlen); @@ -514,7 +514,7 @@ int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req) { struct ptlrpc_cli_ctx *oldctx = req->rq_cli_ctx; struct ptlrpc_cli_ctx *newctx; - int rc; + int rc; LASSERT(oldctx); @@ -629,10 +629,10 @@ void req_off_ctx_list(struct ptlrpc_request *req, struct ptlrpc_cli_ctx *ctx) */ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout) { - struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx; - struct ptlrpc_sec *sec; - struct l_wait_info lwi; - int rc; + struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx; + struct ptlrpc_sec *sec; + struct l_wait_info lwi; + int rc; LASSERT(ctx); @@ -878,7 +878,7 @@ void sptlrpc_request_out_callback(struct ptlrpc_request *req) */ int sptlrpc_import_check_ctx(struct obd_import *imp) { - struct ptlrpc_sec *sec; + struct ptlrpc_sec *sec; struct ptlrpc_cli_ctx *ctx; struct ptlrpc_request *req = NULL; int rc; @@ -974,7 +974,7 @@ int sptlrpc_cli_wrap_request(struct ptlrpc_request *req) static int do_cli_unwrap_reply(struct ptlrpc_request *req) { struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx; - int rc; + int rc; LASSERT(ctx); LASSERT(ctx->cc_sec); @@ -1082,10 +1082,10 @@ int sptlrpc_cli_unwrap_reply(struct ptlrpc_request *req) int sptlrpc_cli_unwrap_early_reply(struct ptlrpc_request *req, struct ptlrpc_request **req_ret) { - struct ptlrpc_request *early_req; - char *early_buf; - int early_bufsz, early_size; - int rc; + struct ptlrpc_request *early_req; + char *early_buf; + int early_bufsz, early_size; + int rc; early_req = ptlrpc_request_cache_alloc(GFP_NOFS); if (early_req == NULL) @@ -1273,13 +1273,13 @@ EXPORT_SYMBOL(sptlrpc_sec_put); */ static struct ptlrpc_sec *sptlrpc_sec_create(struct obd_import *imp, - struct ptlrpc_svc_ctx *svc_ctx, - struct sptlrpc_flavor *sf, - enum lustre_sec_part sp) + struct ptlrpc_svc_ctx *svc_ctx, + struct sptlrpc_flavor *sf, + enum lustre_sec_part sp) { struct ptlrpc_sec_policy *policy; - struct ptlrpc_sec *sec; - char str[32]; + struct ptlrpc_sec *sec; + char str[32]; if (svc_ctx) { LASSERT(imp->imp_dlm_fake == 1); @@ -1369,7 +1369,7 @@ static void sptlrpc_import_sec_adapt_inplace(struct obd_import *imp, struct ptlrpc_sec *sec, struct sptlrpc_flavor *sf) { - char str1[32], str2[32]; + char str1[32], str2[32]; if (sec->ps_flvr.sf_flags != sf->sf_flags) CDEBUG(D_SEC, "changing sec flags: %s -> %s\n", @@ -1394,12 +1394,12 @@ int sptlrpc_import_sec_adapt(struct obd_import *imp, struct ptlrpc_svc_ctx *svc_ctx, struct sptlrpc_flavor *flvr) { - struct ptlrpc_connection *conn; - struct sptlrpc_flavor sf; - struct ptlrpc_sec *sec, *newsec; - enum lustre_sec_part sp; - char str[24]; - int rc = 0; + struct ptlrpc_connection *conn; + struct sptlrpc_flavor sf; + struct ptlrpc_sec *sec, *newsec; + enum lustre_sec_part sp; + char str[24]; + int rc = 0; might_sleep(); @@ -1436,7 +1436,7 @@ int sptlrpc_import_sec_adapt(struct obd_import *imp, sec = sptlrpc_import_sec_ref(imp); if (sec) { - char str2[24]; + char str2[24]; if (flavor_equal(&sf, &sec->ps_flvr)) goto out; @@ -1585,8 +1585,8 @@ void sptlrpc_cli_free_reqbuf(struct ptlrpc_request *req) void _sptlrpc_enlarge_msg_inplace(struct lustre_msg *msg, int segment, int newsize) { - void *src, *dst; - int oldsize, oldmsg_size, movesize; + void *src, *dst; + int oldsize, oldmsg_size, movesize; LASSERT(segment < msg->lm_bufcount); LASSERT(msg->lm_buflens[segment] <= newsize); @@ -1635,9 +1635,9 @@ EXPORT_SYMBOL(_sptlrpc_enlarge_msg_inplace); int sptlrpc_cli_enlarge_reqbuf(struct ptlrpc_request *req, int segment, int newsize) { - struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx; - struct ptlrpc_sec_cops *cops; - struct lustre_msg *msg = req->rq_reqmsg; + struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx; + struct ptlrpc_sec_cops *cops; + struct lustre_msg *msg = req->rq_reqmsg; LASSERT(ctx); LASSERT(msg); @@ -1748,7 +1748,7 @@ static int flavor_allowed(struct sptlrpc_flavor *exp, int sptlrpc_target_export_check(struct obd_export *exp, struct ptlrpc_request *req) { - struct sptlrpc_flavor flavor; + struct sptlrpc_flavor flavor; if (exp == NULL) return 0; @@ -1926,8 +1926,8 @@ EXPORT_SYMBOL(sptlrpc_target_export_check); void sptlrpc_target_update_exp_flavor(struct obd_device *obd, struct sptlrpc_rule_set *rset) { - struct obd_export *exp; - struct sptlrpc_flavor new_flvr; + struct obd_export *exp; + struct sptlrpc_flavor new_flvr; LASSERT(obd); @@ -2019,8 +2019,8 @@ static int sptlrpc_svc_check_from(struct ptlrpc_request *req, int svc_rc) int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req) { struct ptlrpc_sec_policy *policy; - struct lustre_msg *msg = req->rq_reqbuf; - int rc; + struct lustre_msg *msg = req->rq_reqbuf; + int rc; LASSERT(msg); LASSERT(req->rq_reqmsg == NULL); @@ -2231,8 +2231,8 @@ int sptlrpc_cli_unwrap_bulk_read(struct ptlrpc_request *req, struct ptlrpc_bulk_desc *desc, int nob) { - struct ptlrpc_cli_ctx *ctx; - int rc; + struct ptlrpc_cli_ctx *ctx; + int rc; LASSERT(req->rq_bulk_read && !req->rq_bulk_write); @@ -2256,8 +2256,8 @@ EXPORT_SYMBOL(sptlrpc_cli_unwrap_bulk_read); int sptlrpc_cli_unwrap_bulk_write(struct ptlrpc_request *req, struct ptlrpc_bulk_desc *desc) { - struct ptlrpc_cli_ctx *ctx; - int rc; + struct ptlrpc_cli_ctx *ctx; + int rc; LASSERT(!req->rq_bulk_read && req->rq_bulk_write); @@ -2329,7 +2329,7 @@ EXPORT_SYMBOL(sptlrpc_pack_user_desc); int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset, int swabbed) { struct ptlrpc_user_desc *pud; - int i; + int i; pud = lustre_msg_buf(msg, offset, sizeof(*pud)); if (!pud) diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index 97edc9174da3..ea35ca54e729 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -62,7 +62,7 @@ #define POINTERS_PER_PAGE (PAGE_CACHE_SIZE / sizeof(void *)) #define PAGES_PER_POOL (POINTERS_PER_PAGE) -#define IDLE_IDX_MAX (100) +#define IDLE_IDX_MAX (100) #define IDLE_IDX_WEIGHT (3) #define CACHE_QUIESCENT_PERIOD (20) @@ -173,8 +173,8 @@ int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v) static void enc_pools_release_free_pages(long npages) { - int p_idx, g_idx; - int p_idx_max1, p_idx_max2; + int p_idx, g_idx; + int p_idx_max1, p_idx_max2; LASSERT(npages > 0); LASSERT(npages <= page_pools.epp_free_pages); @@ -284,7 +284,7 @@ int npages_to_npools(unsigned long npages) static unsigned long enc_pools_cleanup(struct page ***pools, int npools) { unsigned long cleaned = 0; - int i, j; + int i, j; for (i = 0; i < npools; i++) { if (pools[i]) { @@ -311,9 +311,9 @@ static unsigned long enc_pools_cleanup(struct page ***pools, int npools) */ static void enc_pools_insert(struct page ***pools, int npools, int npages) { - int freeslot; - int op_idx, np_idx, og_idx, ng_idx; - int cur_npools, end_npools; + int freeslot; + int op_idx, np_idx, og_idx, ng_idx; + int cur_npools, end_npools; LASSERT(npages > 0); LASSERT(page_pools.epp_total_pages+npages <= page_pools.epp_max_pages); @@ -393,9 +393,9 @@ static void enc_pools_insert(struct page ***pools, int npools, int npages) static int enc_pools_add_pages(int npages) { static DEFINE_MUTEX(add_pages_mutex); - struct page ***pools; - int npools, alloced = 0; - int i, j, rc = -ENOMEM; + struct page ***pools; + int npools, alloced = 0; + int i, j, rc = -ENOMEM; if (npages < PTLRPC_MAX_BRW_PAGES) npages = PTLRPC_MAX_BRW_PAGES; @@ -494,12 +494,12 @@ static int enc_pools_should_grow(int page_needed, long now) */ int sptlrpc_enc_pool_get_pages(struct ptlrpc_bulk_desc *desc) { - wait_queue_t waitlink; - unsigned long this_idle = -1; - unsigned long tick = 0; - long now; - int p_idx, g_idx; - int i; + wait_queue_t waitlink; + unsigned long this_idle = -1; + unsigned long tick = 0; + long now; + int p_idx, g_idx; + int i; LASSERT(desc->bd_iov_count > 0); LASSERT(desc->bd_iov_count <= page_pools.epp_max_pages); @@ -609,8 +609,8 @@ EXPORT_SYMBOL(sptlrpc_enc_pool_get_pages); void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc) { - int p_idx, g_idx; - int i; + int p_idx, g_idx; + int i; if (desc->bd_enc_iov == NULL) return; @@ -658,7 +658,7 @@ EXPORT_SYMBOL(sptlrpc_enc_pool_put_pages); */ int sptlrpc_enc_pool_add_user(void) { - int need_grow = 0; + int need_grow = 0; spin_lock(&page_pools.epp_lock); if (page_pools.epp_growing == 0 && page_pools.epp_total_pages == 0) { @@ -842,11 +842,11 @@ EXPORT_SYMBOL(bulk_sec_desc_unpack); int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, void *buf, int buflen) { - struct cfs_crypto_hash_desc *hdesc; - int hashsize; - char hashbuf[64]; - unsigned int bufsize; - int i, err; + struct cfs_crypto_hash_desc *hdesc; + int hashsize; + char hashbuf[64]; + unsigned int bufsize; + int i, err; LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX); LASSERT(buflen >= 4); diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c index 16dbf3fcfc84..31da43e8b3c6 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c @@ -94,8 +94,8 @@ EXPORT_SYMBOL(sptlrpc_target_sec_part); */ int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr) { - char buf[32]; - char *bulk, *alg; + char buf[32]; + char *bulk, *alg; memset(flvr, 0, sizeof(*flvr)); @@ -182,8 +182,8 @@ static void sptlrpc_rule_init(struct sptlrpc_rule *rule) */ int sptlrpc_parse_rule(char *param, struct sptlrpc_rule *rule) { - char *flavor, *dir; - int rc; + char *flavor, *dir; + int rc; sptlrpc_rule_init(rule); @@ -309,9 +309,9 @@ static inline int rule_match_net(struct sptlrpc_rule *r1, int sptlrpc_rule_set_merge(struct sptlrpc_rule_set *rset, struct sptlrpc_rule *rule) { - struct sptlrpc_rule *p = rset->srs_rules; - int spec_dir, spec_net; - int rc, n, match = 0; + struct sptlrpc_rule *p = rset->srs_rules; + int spec_dir, spec_net; + int rc, n, match = 0; might_sleep(); @@ -403,8 +403,8 @@ int sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset, lnet_nid_t nid, struct sptlrpc_flavor *sf) { - struct sptlrpc_rule *r; - int n; + struct sptlrpc_rule *r; + int n; for (n = 0; n < rset->srs_nrule; n++) { r = &rset->srs_rules[n]; @@ -433,7 +433,7 @@ EXPORT_SYMBOL(sptlrpc_rule_set_choose); void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *rset) { struct sptlrpc_rule *r; - int n; + int n; for (n = 0; n < rset->srs_nrule; n++) { r = &rset->srs_rules[n]; @@ -474,8 +474,8 @@ static inline int is_hex(char c) static void target2fsname(const char *tgt, char *fsname, int buflen) { - const char *ptr; - int len; + const char *ptr; + int len; ptr = strrchr(tgt, '-'); if (ptr) { @@ -583,8 +583,8 @@ static int sptlrpc_conf_merge_rule(struct sptlrpc_conf *conf, const char *target, struct sptlrpc_rule *rule) { - struct sptlrpc_conf_tgt *conf_tgt; - struct sptlrpc_rule_set *rule_set; + struct sptlrpc_conf_tgt *conf_tgt; + struct sptlrpc_rule_set *rule_set; /* fsname == target means general rules for the whole fs */ if (strcmp(conf->sc_fsname, target) == 0) { @@ -610,10 +610,10 @@ static int sptlrpc_conf_merge_rule(struct sptlrpc_conf *conf, static int __sptlrpc_process_config(struct lustre_cfg *lcfg, struct sptlrpc_conf *conf) { - char *target, *param; - char fsname[MTI_NAME_MAXLEN]; - struct sptlrpc_rule rule; - int rc; + char *target, *param; + char fsname[MTI_NAME_MAXLEN]; + struct sptlrpc_rule rule; + int rc; target = lustre_cfg_string(lcfg, 1); if (target == NULL) { @@ -671,8 +671,8 @@ EXPORT_SYMBOL(sptlrpc_process_config); static int logname2fsname(const char *logname, char *buf, int buflen) { - char *ptr; - int len; + char *ptr; + int len; ptr = strrchr(logname, '-'); if (ptr == NULL || strcmp(ptr, "-sptlrpc")) { @@ -690,7 +690,7 @@ static int logname2fsname(const char *logname, char *buf, int buflen) void sptlrpc_conf_log_update_begin(const char *logname) { struct sptlrpc_conf *conf; - char fsname[16]; + char fsname[16]; if (logname2fsname(logname, fsname, sizeof(fsname))) return; @@ -716,7 +716,7 @@ EXPORT_SYMBOL(sptlrpc_conf_log_update_begin); void sptlrpc_conf_log_update_end(const char *logname) { struct sptlrpc_conf *conf; - char fsname[16]; + char fsname[16]; if (logname2fsname(logname, fsname, sizeof(fsname))) return; @@ -741,7 +741,7 @@ EXPORT_SYMBOL(sptlrpc_conf_log_update_end); void sptlrpc_conf_log_start(const char *logname) { - char fsname[16]; + char fsname[16]; if (logname2fsname(logname, fsname, sizeof(fsname))) return; @@ -755,7 +755,7 @@ EXPORT_SYMBOL(sptlrpc_conf_log_start); void sptlrpc_conf_log_stop(const char *logname) { struct sptlrpc_conf *conf; - char fsname[16]; + char fsname[16]; if (logname2fsname(logname, fsname, sizeof(fsname))) return; @@ -799,10 +799,10 @@ void sptlrpc_conf_choose_flavor(enum lustre_sec_part from, lnet_nid_t nid, struct sptlrpc_flavor *sf) { - struct sptlrpc_conf *conf; + struct sptlrpc_conf *conf; struct sptlrpc_conf_tgt *conf_tgt; - char name[MTI_NAME_MAXLEN]; - int len, rc = 0; + char name[MTI_NAME_MAXLEN]; + int len, rc = 0; target2fsname(target->uuid, name, sizeof(name)); @@ -858,7 +858,7 @@ EXPORT_SYMBOL(sptlrpc_target_choose_flavor); */ void sptlrpc_conf_client_adapt(struct obd_device *obd) { - struct obd_import *imp; + struct obd_import *imp; LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 || strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0); @@ -880,7 +880,7 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd) } EXPORT_SYMBOL(sptlrpc_conf_client_adapt); -int sptlrpc_conf_init(void) +int sptlrpc_conf_init(void) { mutex_init(&sptlrpc_conf_lock); return 0; @@ -888,7 +888,7 @@ int sptlrpc_conf_init(void) void sptlrpc_conf_fini(void) { - struct sptlrpc_conf *conf, *conf_next; + struct sptlrpc_conf *conf, *conf_next; mutex_lock(&sptlrpc_conf_lock); list_for_each_entry_safe(conf, conf_next, &sptlrpc_confs, sc_list) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c index 81de68edb04e..cdad608bdb8d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c @@ -164,7 +164,7 @@ static void sec_do_gc(struct ptlrpc_sec *sec) static int sec_gc_main(void *arg) { struct ptlrpc_thread *thread = (struct ptlrpc_thread *) arg; - struct l_wait_info lwi; + struct l_wait_info lwi; unshare_fs_struct(); diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c index 0d08145a6c7e..68fcac14b3ee 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c @@ -51,10 +51,6 @@ #include "ptlrpc_internal.h" - -struct proc_dir_entry *sptlrpc_proc_root = NULL; -EXPORT_SYMBOL(sptlrpc_proc_root); - static char *sec_flags2str(unsigned long flags, char *buf, int bufsize) { buf[0] = '\0'; @@ -78,7 +74,7 @@ static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v) struct obd_device *dev = seq->private; struct client_obd *cli = &dev->u.cli; struct ptlrpc_sec *sec = NULL; - char str[32]; + char str[32]; LASSERT(strcmp(dev->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 || strcmp(dev->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 || @@ -138,7 +134,7 @@ LPROC_SEQ_FOPS_RO(sptlrpc_ctxs_lprocfs); int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev) { - int rc; + int rc; if (strcmp(dev->obd_type->typ_name, LUSTRE_OSC_NAME) != 0 && strcmp(dev->obd_type->typ_name, LUSTRE_MDC_NAME) != 0 && @@ -148,16 +144,16 @@ int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev) return -EINVAL; } - rc = lprocfs_obd_seq_create(dev, "srpc_info", 0444, - &sptlrpc_info_lprocfs_fops, dev); + rc = ldebugfs_obd_seq_create(dev, "srpc_info", 0444, + &sptlrpc_info_lprocfs_fops, dev); if (rc) { CERROR("create proc entry srpc_info for %s: %d\n", dev->obd_name, rc); return rc; } - rc = lprocfs_obd_seq_create(dev, "srpc_contexts", 0444, - &sptlrpc_ctxs_lprocfs_fops, dev); + rc = ldebugfs_obd_seq_create(dev, "srpc_contexts", 0444, + &sptlrpc_ctxs_lprocfs_fops, dev); if (rc) { CERROR("create proc entry srpc_contexts for %s: %d\n", dev->obd_name, rc); @@ -174,17 +170,20 @@ static struct lprocfs_vars sptlrpc_lprocfs_vars[] = { { NULL } }; +static struct dentry *sptlrpc_debugfs_dir; + int sptlrpc_lproc_init(void) { - int rc; + int rc; - LASSERT(sptlrpc_proc_root == NULL); + LASSERT(sptlrpc_debugfs_dir == NULL); - sptlrpc_proc_root = lprocfs_register("sptlrpc", proc_lustre_root, - sptlrpc_lprocfs_vars, NULL); - if (IS_ERR(sptlrpc_proc_root)) { - rc = PTR_ERR(sptlrpc_proc_root); - sptlrpc_proc_root = NULL; + sptlrpc_debugfs_dir = ldebugfs_register("sptlrpc", debugfs_lustre_root, + sptlrpc_lprocfs_vars, NULL); + if (IS_ERR_OR_NULL(sptlrpc_debugfs_dir)) { + rc = sptlrpc_debugfs_dir ? PTR_ERR(sptlrpc_debugfs_dir) + : -ENOMEM; + sptlrpc_debugfs_dir = NULL; return rc; } return 0; @@ -192,8 +191,6 @@ int sptlrpc_lproc_init(void) void sptlrpc_lproc_fini(void) { - if (sptlrpc_proc_root) { - lprocfs_remove(&sptlrpc_proc_root); - sptlrpc_proc_root = NULL; - } + if (!IS_ERR_OR_NULL(sptlrpc_debugfs_dir)) + ldebugfs_remove(&sptlrpc_debugfs_dir); } diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c index 4e132435b450..8c28b6b7ff02 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c @@ -92,7 +92,7 @@ int null_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) static int null_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) { - __u32 cksums, cksumc; + __u32 cksums, cksumc; LASSERT(req->rq_repdata); @@ -226,9 +226,9 @@ int null_enlarge_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req, int segment, int newsize) { - struct lustre_msg *newbuf; - struct lustre_msg *oldbuf = req->rq_reqmsg; - int oldsize, newmsg_size, alloc_size; + struct lustre_msg *newbuf; + struct lustre_msg *oldbuf = req->rq_reqmsg; + int oldsize, newmsg_size, alloc_size; LASSERT(req->rq_reqbuf); LASSERT(req->rq_reqbuf == req->rq_reqmsg); diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c index 989cdcda27b5..ed39970417d8 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c @@ -136,7 +136,7 @@ static int plain_verify_bulk_csum(struct ptlrpc_bulk_desc *desc, struct plain_bulk_token *tokenr) { struct plain_bulk_token tokenv; - int rc; + int rc; if (hash_alg == BULK_HASH_ALG_NULL) return 0; @@ -154,8 +154,8 @@ static int plain_verify_bulk_csum(struct ptlrpc_bulk_desc *desc, static void corrupt_bulk_data(struct ptlrpc_bulk_desc *desc) { - char *ptr; - unsigned int off, i; + char *ptr; + unsigned int off, i; for (i = 0; i < desc->bd_iov_count; i++) { if (desc->bd_iov[i].kiov_len == 0) @@ -190,7 +190,7 @@ int plain_ctx_validate(struct ptlrpc_cli_ctx *ctx) static int plain_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) { - struct lustre_msg *msg = req->rq_reqbuf; + struct lustre_msg *msg = req->rq_reqbuf; struct plain_header *phdr; msg->lm_secflvr = req->rq_flvr.sf_rpc; @@ -214,10 +214,10 @@ int plain_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) static int plain_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) { - struct lustre_msg *msg = req->rq_repdata; + struct lustre_msg *msg = req->rq_repdata; struct plain_header *phdr; - __u32 cksum; - int swabbed; + __u32 cksum; + int swabbed; if (msg->lm_bufcount != PLAIN_PACK_SEGMENTS) { CERROR("unexpected reply buf count %u\n", msg->lm_bufcount); @@ -290,8 +290,8 @@ int plain_cli_wrap_bulk(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_bulk_desc *desc) { struct ptlrpc_bulk_sec_desc *bsd; - struct plain_bulk_token *token; - int rc; + struct plain_bulk_token *token; + int rc; LASSERT(req->rq_pack_bulk); LASSERT(req->rq_reqbuf->lm_bufcount == PLAIN_PACK_SEGMENTS); @@ -333,9 +333,9 @@ int plain_cli_unwrap_bulk(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_bulk_desc *desc) { struct ptlrpc_bulk_sec_desc *bsdv; - struct plain_bulk_token *tokenv; - int rc; - int i, nob; + struct plain_bulk_token *tokenv; + int rc; + int i, nob; LASSERT(req->rq_pack_bulk); LASSERT(req->rq_reqbuf->lm_bufcount == PLAIN_PACK_SEGMENTS); @@ -374,7 +374,7 @@ int plain_cli_unwrap_bulk(struct ptlrpc_cli_ctx *ctx, static struct ptlrpc_cli_ctx *plain_sec_install_ctx(struct plain_sec *plsec) { - struct ptlrpc_cli_ctx *ctx, *ctx_new; + struct ptlrpc_cli_ctx *ctx, *ctx_new; ctx_new = kzalloc(sizeof(*ctx_new), GFP_NOFS); @@ -413,7 +413,7 @@ struct ptlrpc_cli_ctx *plain_sec_install_ctx(struct plain_sec *plsec) static void plain_destroy_sec(struct ptlrpc_sec *sec) { - struct plain_sec *plsec = sec2plsec(sec); + struct plain_sec *plsec = sec2plsec(sec); LASSERT(sec->ps_policy == &plain_policy); LASSERT(sec->ps_import); @@ -437,9 +437,9 @@ struct ptlrpc_sec *plain_create_sec(struct obd_import *imp, struct ptlrpc_svc_ctx *svc_ctx, struct sptlrpc_flavor *sf) { - struct plain_sec *plsec; - struct ptlrpc_sec *sec; - struct ptlrpc_cli_ctx *ctx; + struct plain_sec *plsec; + struct ptlrpc_sec *sec; + struct ptlrpc_cli_ctx *ctx; LASSERT(SPTLRPC_FLVR_POLICY(sf->sf_rpc) == SPTLRPC_POLICY_PLAIN); @@ -483,8 +483,8 @@ struct ptlrpc_cli_ctx *plain_lookup_ctx(struct ptlrpc_sec *sec, struct vfs_cred *vcred, int create, int remove_dead) { - struct plain_sec *plsec = sec2plsec(sec); - struct ptlrpc_cli_ctx *ctx; + struct plain_sec *plsec = sec2plsec(sec); + struct ptlrpc_cli_ctx *ctx; read_lock(&plsec->pls_lock); ctx = plsec->pls_ctx; @@ -517,8 +517,8 @@ static int plain_flush_ctx_cache(struct ptlrpc_sec *sec, uid_t uid, int grace, int force) { - struct plain_sec *plsec = sec2plsec(sec); - struct ptlrpc_cli_ctx *ctx; + struct plain_sec *plsec = sec2plsec(sec); + struct ptlrpc_cli_ctx *ctx; /* do nothing unless caller want to flush for 'all' */ if (uid != -1) @@ -540,7 +540,7 @@ int plain_alloc_reqbuf(struct ptlrpc_sec *sec, int msgsize) { __u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, }; - int alloc_len; + int alloc_len; buflens[PLAIN_PACK_HDR_OFF] = sizeof(struct plain_header); buflens[PLAIN_PACK_MSG_OFF] = msgsize; @@ -635,9 +635,9 @@ int plain_enlarge_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req, int segment, int newsize) { - struct lustre_msg *newbuf; - int oldsize; - int newmsg_size, newbuf_size; + struct lustre_msg *newbuf; + int oldsize; + int newmsg_size, newbuf_size; LASSERT(req->rq_reqbuf); LASSERT(req->rq_reqbuf_len >= req->rq_reqlen); @@ -709,9 +709,9 @@ static struct ptlrpc_svc_ctx plain_svc_ctx = { static int plain_accept(struct ptlrpc_request *req) { - struct lustre_msg *msg = req->rq_reqbuf; + struct lustre_msg *msg = req->rq_reqbuf; struct plain_header *phdr; - int swabbed; + int swabbed; LASSERT(SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc) == SPTLRPC_POLICY_PLAIN); @@ -780,9 +780,9 @@ int plain_accept(struct ptlrpc_request *req) static int plain_alloc_rs(struct ptlrpc_request *req, int msgsize) { - struct ptlrpc_reply_state *rs; - __u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, }; - int rs_size = sizeof(*rs); + struct ptlrpc_reply_state *rs; + __u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, }; + int rs_size = sizeof(*rs); LASSERT(msgsize % 8 == 0); @@ -833,9 +833,9 @@ static int plain_authorize(struct ptlrpc_request *req) { struct ptlrpc_reply_state *rs = req->rq_reply_state; - struct lustre_msg_v2 *msg = rs->rs_repbuf; - struct plain_header *phdr; - int len; + struct lustre_msg_v2 *msg = rs->rs_repbuf; + struct plain_header *phdr; + int len; LASSERT(rs); LASSERT(msg); @@ -870,7 +870,7 @@ int plain_authorize(struct ptlrpc_request *req) lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0), lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF), NULL, 0, (unsigned char *)&msg->lm_cksum, &hsize); - req->rq_reply_off = 0; + req->rq_reply_off = 0; } return 0; @@ -880,10 +880,10 @@ static int plain_svc_unwrap_bulk(struct ptlrpc_request *req, struct ptlrpc_bulk_desc *desc) { - struct ptlrpc_reply_state *rs = req->rq_reply_state; + struct ptlrpc_reply_state *rs = req->rq_reply_state; struct ptlrpc_bulk_sec_desc *bsdr, *bsdv; - struct plain_bulk_token *tokenr; - int rc; + struct plain_bulk_token *tokenr; + int rc; LASSERT(req->rq_bulk_write); LASSERT(req->rq_pack_bulk); @@ -914,10 +914,10 @@ static int plain_svc_wrap_bulk(struct ptlrpc_request *req, struct ptlrpc_bulk_desc *desc) { - struct ptlrpc_reply_state *rs = req->rq_reply_state; + struct ptlrpc_reply_state *rs = req->rq_reply_state; struct ptlrpc_bulk_sec_desc *bsdr, *bsdv; - struct plain_bulk_token *tokenv; - int rc; + struct plain_bulk_token *tokenv; + int rc; LASSERT(req->rq_bulk_read); LASSERT(req->rq_pack_bulk); diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 3fa52f117424..25ccbcb1772f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -72,7 +72,7 @@ struct mutex ptlrpc_all_services_mutex; struct ptlrpc_request_buffer_desc * ptlrpc_alloc_rqbd(struct ptlrpc_service_part *svcpt) { - struct ptlrpc_service *svc = svcpt->scp_service; + struct ptlrpc_service *svc = svcpt->scp_service; struct ptlrpc_request_buffer_desc *rqbd; rqbd = kzalloc_node(sizeof(*rqbd), GFP_NOFS, @@ -121,10 +121,10 @@ ptlrpc_free_rqbd(struct ptlrpc_request_buffer_desc *rqbd) int ptlrpc_grow_req_bufs(struct ptlrpc_service_part *svcpt, int post) { - struct ptlrpc_service *svc = svcpt->scp_service; + struct ptlrpc_service *svc = svcpt->scp_service; struct ptlrpc_request_buffer_desc *rqbd; - int rc = 0; - int i; + int rc = 0; + int i; if (svcpt->scp_rqbd_allocating) goto try_post; @@ -186,7 +186,7 @@ ptlrpc_save_lock(struct ptlrpc_request *req, struct lustre_handle *lock, int mode, int no_ack) { struct ptlrpc_reply_state *rs = req->rq_reply_state; - int idx; + int idx; LASSERT(rs != NULL); LASSERT(rs->rs_nlocks < RS_MAX_LOCKS); @@ -275,8 +275,8 @@ static void rs_batch_init(struct rs_batch *b) static struct ptlrpc_hr_thread * ptlrpc_hr_select(struct ptlrpc_service_part *svcpt) { - struct ptlrpc_hr_partition *hrp; - unsigned int rotor; + struct ptlrpc_hr_partition *hrp; + unsigned int rotor; if (svcpt->scp_cpt >= 0 && svcpt->scp_service->srv_cptable == ptlrpc_hr.hr_cpt_table) { @@ -431,8 +431,8 @@ static int ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt) { struct ptlrpc_request_buffer_desc *rqbd; - int rc; - int posted = 0; + int rc; + int posted = 0; for (;;) { spin_lock(&svcpt->scp_lock); @@ -489,11 +489,11 @@ static void ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, struct ptlrpc_service_conf *conf) { - struct ptlrpc_service_thr_conf *tc = &conf->psc_thr; - unsigned init; - unsigned total; - unsigned nthrs; - int weight; + struct ptlrpc_service_thr_conf *tc = &conf->psc_thr; + unsigned init; + unsigned total; + unsigned nthrs; + int weight; /* * Common code for estimating & validating threads number. @@ -517,7 +517,7 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, * be up to 8 * nthrs_max */ total = min(tc->tc_nthrs_max * 8, tc->tc_nthrs_user); nthrs = total / svc->srv_ncpts; - init = max(init, nthrs); + init = max(init, nthrs); goto out; } @@ -531,7 +531,7 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, nthrs = tc->tc_nthrs_base; if (svc->srv_ncpts == 1) { - int i; + int i; /* NB: Increase the base number if it's single partition * and total number of cores/HTs is larger or equal to 4. @@ -543,7 +543,7 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, } if (tc->tc_thr_factor != 0) { - int factor = tc->tc_thr_factor; + int factor = tc->tc_thr_factor; const int fade = 4; /* @@ -595,9 +595,9 @@ ptlrpc_service_part_init(struct ptlrpc_service *svc, struct ptlrpc_service_part *svcpt, int cpt) { struct ptlrpc_at_array *array; - int size; - int index; - int rc; + int size; + int index; + int rc; svcpt->scp_cpt = cpt; INIT_LIST_HEAD(&svcpt->scp_threads); @@ -627,8 +627,8 @@ ptlrpc_service_part_init(struct ptlrpc_service *svc, array = &svcpt->scp_at_array; size = at_est2timeout(at_max); - array->paa_size = size; - array->paa_count = 0; + array->paa_size = size; + array->paa_count = 0; array->paa_deadline = -1; /* allocate memory for scp_at_array (ptlrpc_at_array) */ @@ -680,17 +680,18 @@ free_reqs_array: */ struct ptlrpc_service * ptlrpc_register_service(struct ptlrpc_service_conf *conf, - struct proc_dir_entry *proc_entry) -{ - struct ptlrpc_service_cpt_conf *cconf = &conf->psc_cpt; - struct ptlrpc_service *service; - struct ptlrpc_service_part *svcpt; - struct cfs_cpt_table *cptable; - __u32 *cpts = NULL; - int ncpts; - int cpt; - int rc; - int i; + struct kset *parent, + struct dentry *debugfs_entry) +{ + struct ptlrpc_service_cpt_conf *cconf = &conf->psc_cpt; + struct ptlrpc_service *service; + struct ptlrpc_service_part *svcpt; + struct cfs_cpt_table *cptable; + __u32 *cpts = NULL; + int ncpts; + int cpt; + int rc; + int i; LASSERT(conf->psc_buf.bc_nbufs > 0); LASSERT(conf->psc_buf.bc_buf_size >= @@ -706,7 +707,7 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, } else { ncpts = cfs_cpt_number(cptable); if (cconf->cc_pattern != NULL) { - struct cfs_expr_list *el; + struct cfs_expr_list *el; rc = cfs_expr_list_parse(cconf->cc_pattern, strlen(cconf->cc_pattern), @@ -736,9 +737,9 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, return ERR_PTR(-ENOMEM); } - service->srv_cptable = cptable; - service->srv_cpts = cpts; - service->srv_ncpts = ncpts; + service->srv_cptable = cptable; + service->srv_cpts = cpts; + service->srv_ncpts = ncpts; service->srv_cpt_bits = 0; /* it's zero already, easy to read... */ while ((1 << service->srv_cpt_bits) < cfs_cpt_number(cptable)) @@ -746,18 +747,18 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, /* public members */ spin_lock_init(&service->srv_lock); - service->srv_name = conf->psc_name; - service->srv_watchdog_factor = conf->psc_watchdog_factor; + service->srv_name = conf->psc_name; + service->srv_watchdog_factor = conf->psc_watchdog_factor; INIT_LIST_HEAD(&service->srv_list); /* for safety of cleanup */ /* buffer configuration */ - service->srv_nbuf_per_group = test_req_buffer_pressure ? + service->srv_nbuf_per_group = test_req_buffer_pressure ? 1 : conf->psc_buf.bc_nbufs; - service->srv_max_req_size = conf->psc_buf.bc_req_max_size + + service->srv_max_req_size = conf->psc_buf.bc_req_max_size + SPTLRPC_MAX_PAYLOAD; - service->srv_buf_size = conf->psc_buf.bc_buf_size; - service->srv_rep_portal = conf->psc_buf.bc_rep_portal; - service->srv_req_portal = conf->psc_buf.bc_req_portal; + service->srv_buf_size = conf->psc_buf.bc_buf_size; + service->srv_rep_portal = conf->psc_buf.bc_rep_portal; + service->srv_req_portal = conf->psc_buf.bc_req_portal; /* Increase max reply size to next power of two */ service->srv_max_reply_size = 1; @@ -765,10 +766,10 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, conf->psc_buf.bc_rep_max_size + SPTLRPC_MAX_PAYLOAD) service->srv_max_reply_size <<= 1; - service->srv_thread_name = conf->psc_thr.tc_thr_name; - service->srv_ctx_tags = conf->psc_thr.tc_ctx_tags; - service->srv_hpreq_ratio = PTLRPC_SVC_HP_RATIO; - service->srv_ops = conf->psc_ops; + service->srv_thread_name = conf->psc_thr.tc_thr_name; + service->srv_ctx_tags = conf->psc_thr.tc_ctx_tags; + service->srv_hpreq_ratio = PTLRPC_SVC_HP_RATIO; + service->srv_ops = conf->psc_ops; for (i = 0; i < ncpts; i++) { if (!conf->psc_thr.tc_cpu_affinity) @@ -798,8 +799,14 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, list_add(&service->srv_list, &ptlrpc_all_services); mutex_unlock(&ptlrpc_all_services_mutex); - if (proc_entry != NULL) - ptlrpc_lprocfs_register_service(proc_entry, service); + if (parent) { + rc = ptlrpc_sysfs_register_service(parent, service); + if (rc) + goto failed; + } + + if (!IS_ERR_OR_NULL(debugfs_entry)) + ptlrpc_ldebugfs_register_service(debugfs_entry, service); rc = ptlrpc_service_nrs_setup(service); if (rc != 0) @@ -852,11 +859,11 @@ static void ptlrpc_server_free_request(struct ptlrpc_request *req) void ptlrpc_server_drop_request(struct ptlrpc_request *req) { struct ptlrpc_request_buffer_desc *rqbd = req->rq_rqbd; - struct ptlrpc_service_part *svcpt = rqbd->rqbd_svcpt; - struct ptlrpc_service *svc = svcpt->scp_service; - int refcount; - struct list_head *tmp; - struct list_head *nxt; + struct ptlrpc_service_part *svcpt = rqbd->rqbd_svcpt; + struct ptlrpc_service *svc = svcpt->scp_service; + int refcount; + struct list_head *tmp; + struct list_head *nxt; if (!atomic_dec_and_test(&req->rq_refcount)) return; @@ -1380,7 +1387,7 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt) struct ptlrpc_at_array *array = &svcpt->scp_at_array; struct ptlrpc_request *rq, *n; struct list_head work_list; - __u32 index, count; + __u32 index, count; time_t deadline; time_t now = get_seconds(); long delay; @@ -1725,10 +1732,10 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, struct ptlrpc_thread *thread) { - struct ptlrpc_service *svc = svcpt->scp_service; - struct ptlrpc_request *req; - __u32 deadline; - int rc; + struct ptlrpc_service *svc = svcpt->scp_service; + struct ptlrpc_request *req; + __u32 deadline; + int rc; spin_lock(&svcpt->scp_lock); if (list_empty(&svcpt->scp_req_incoming)) { @@ -1869,11 +1876,11 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt, { struct ptlrpc_service *svc = svcpt->scp_service; struct ptlrpc_request *request; - struct timeval work_start; - struct timeval work_end; - long timediff; - int rc; - int fail_opc = 0; + struct timeval work_start; + struct timeval work_end; + long timediff; + int rc; + int fail_opc = 0; request = ptlrpc_server_request_get(svcpt, false); if (request == NULL) @@ -2025,10 +2032,10 @@ static int ptlrpc_handle_rs(struct ptlrpc_reply_state *rs) { struct ptlrpc_service_part *svcpt = rs->rs_svcpt; - struct ptlrpc_service *svc = svcpt->scp_service; - struct obd_export *exp; - int nlocks; - int been_handled; + struct ptlrpc_service *svc = svcpt->scp_service; + struct obd_export *exp; + int nlocks; + int been_handled; exp = rs->rs_export; @@ -2255,10 +2262,10 @@ ptlrpc_wait_event(struct ptlrpc_service_part *svcpt, */ static int ptlrpc_main(void *arg) { - struct ptlrpc_thread *thread = (struct ptlrpc_thread *)arg; - struct ptlrpc_service_part *svcpt = thread->t_svcpt; - struct ptlrpc_service *svc = svcpt->scp_service; - struct ptlrpc_reply_state *rs; + struct ptlrpc_thread *thread = (struct ptlrpc_thread *)arg; + struct ptlrpc_service_part *svcpt = thread->t_svcpt; + struct ptlrpc_service *svc = svcpt->scp_service; + struct ptlrpc_reply_state *rs; struct group_info *ginfo = NULL; struct lu_env *env; int counter = 0, rc = 0; @@ -2457,11 +2464,11 @@ static int hrt_dont_sleep(struct ptlrpc_hr_thread *hrt, */ static int ptlrpc_hr_main(void *arg) { - struct ptlrpc_hr_thread *hrt = (struct ptlrpc_hr_thread *)arg; - struct ptlrpc_hr_partition *hrp = hrt->hrt_partition; - LIST_HEAD (replies); - char threadname[20]; - int rc; + struct ptlrpc_hr_thread *hrt = (struct ptlrpc_hr_thread *)arg; + struct ptlrpc_hr_partition *hrp = hrt->hrt_partition; + LIST_HEAD (replies); + char threadname[20]; + int rc; snprintf(threadname, sizeof(threadname), "ptlrpc_hr%02d_%03d", hrp->hrp_cpt, hrt->hrt_id); @@ -2498,9 +2505,9 @@ static int ptlrpc_hr_main(void *arg) static void ptlrpc_stop_hr_threads(void) { - struct ptlrpc_hr_partition *hrp; - int i; - int j; + struct ptlrpc_hr_partition *hrp; + int i; + int j; ptlrpc_hr.hr_stopping = 1; @@ -2522,12 +2529,12 @@ static void ptlrpc_stop_hr_threads(void) static int ptlrpc_start_hr_threads(void) { - struct ptlrpc_hr_partition *hrp; - int i; - int j; + struct ptlrpc_hr_partition *hrp; + int i; + int j; cfs_percpt_for_each(hrp, i, ptlrpc_hr.hr_partitions) { - int rc = 0; + int rc = 0; for (j = 0; j < hrp->hrp_nthrs; j++) { struct ptlrpc_hr_thread *hrt = &hrp->hrp_thrs[j]; @@ -2554,9 +2561,9 @@ static int ptlrpc_start_hr_threads(void) static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) { - struct l_wait_info lwi = { 0 }; - struct ptlrpc_thread *thread; - LIST_HEAD (zombie); + struct l_wait_info lwi = { 0 }; + struct ptlrpc_thread *thread; + LIST_HEAD (zombie); CDEBUG(D_INFO, "Stopping threads for service %s\n", svcpt->scp_service->srv_name); @@ -2605,7 +2612,7 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) { struct ptlrpc_service_part *svcpt; - int i; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) { if (svcpt->scp_service != NULL) @@ -2616,9 +2623,9 @@ EXPORT_SYMBOL(ptlrpc_stop_all_threads); int ptlrpc_start_threads(struct ptlrpc_service *svc) { - int rc = 0; - int i; - int j; + int rc = 0; + int i; + int j; /* We require 2 threads min, see note in ptlrpc_server_handle_request */ LASSERT(svc->srv_nthrs_cpt_init >= PTLRPC_NTHRS_INIT); @@ -2647,10 +2654,10 @@ EXPORT_SYMBOL(ptlrpc_start_threads); int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) { - struct l_wait_info lwi = { 0 }; - struct ptlrpc_thread *thread; - struct ptlrpc_service *svc; - int rc; + struct l_wait_info lwi = { 0 }; + struct ptlrpc_thread *thread; + struct ptlrpc_service *svc; + int rc; LASSERT(svcpt != NULL); @@ -2752,12 +2759,12 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) int ptlrpc_hr_init(void) { - struct ptlrpc_hr_partition *hrp; - struct ptlrpc_hr_thread *hrt; - int rc; - int i; - int j; - int weight; + struct ptlrpc_hr_partition *hrp; + struct ptlrpc_hr_thread *hrt; + int rc; + int i; + int j; + int weight; memset(&ptlrpc_hr, 0, sizeof(ptlrpc_hr)); ptlrpc_hr.hr_cpt_table = cfs_cpt_table; @@ -2810,8 +2817,8 @@ out: void ptlrpc_hr_fini(void) { - struct ptlrpc_hr_partition *hrp; - int i; + struct ptlrpc_hr_partition *hrp; + int i; if (ptlrpc_hr.hr_partitions == NULL) return; @@ -2851,8 +2858,8 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt) static void ptlrpc_service_del_atimer(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - int i; + struct ptlrpc_service_part *svcpt; + int i; /* early disarm AT timer... */ ptlrpc_service_for_each_part(svcpt, i, svc) { @@ -2864,11 +2871,11 @@ ptlrpc_service_del_atimer(struct ptlrpc_service *svc) static void ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; + struct ptlrpc_service_part *svcpt; struct ptlrpc_request_buffer_desc *rqbd; - struct l_wait_info lwi; - int rc; - int i; + struct l_wait_info lwi; + int rc; + int i; /* All history will be culled when the next request buffer is * freed in ptlrpc_service_purge_all() */ @@ -2920,11 +2927,11 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc) static void ptlrpc_service_purge_all(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - struct ptlrpc_request_buffer_desc *rqbd; - struct ptlrpc_request *req; - struct ptlrpc_reply_state *rs; - int i; + struct ptlrpc_service_part *svcpt; + struct ptlrpc_request_buffer_desc *rqbd; + struct ptlrpc_request *req; + struct ptlrpc_reply_state *rs; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) { if (svcpt->scp_service == NULL) @@ -2988,9 +2995,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc) static void ptlrpc_service_free(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - struct ptlrpc_at_array *array; - int i; + struct ptlrpc_service_part *svcpt; + struct ptlrpc_at_array *array; + int i; ptlrpc_service_for_each_part(svcpt, i, svc) { if (svcpt->scp_service == NULL) @@ -3033,6 +3040,7 @@ int ptlrpc_unregister_service(struct ptlrpc_service *service) ptlrpc_service_nrs_cleanup(service); ptlrpc_lprocfs_unregister_service(service); + ptlrpc_sysfs_unregister_service(service); ptlrpc_service_free(service); @@ -3048,9 +3056,9 @@ EXPORT_SYMBOL(ptlrpc_unregister_service); * to be shot, so it's intentionally non-aggressive. */ int ptlrpc_svcpt_health_check(struct ptlrpc_service_part *svcpt) { - struct ptlrpc_request *request = NULL; - struct timeval right_now; - long timediff; + struct ptlrpc_request *request = NULL; + struct timeval right_now; + long timediff; do_gettimeofday(&right_now); @@ -3082,8 +3090,8 @@ int ptlrpc_svcpt_health_check(struct ptlrpc_service_part *svcpt) int ptlrpc_service_health_check(struct ptlrpc_service *svc) { - struct ptlrpc_service_part *svcpt; - int i; + struct ptlrpc_service_part *svcpt; + int i; if (svc == NULL) return 0; diff --git a/drivers/staging/lustre/sysfs-fs-lustre b/drivers/staging/lustre/sysfs-fs-lustre new file mode 100644 index 000000000000..1e302e8516ce --- /dev/null +++ b/drivers/staging/lustre/sysfs-fs-lustre @@ -0,0 +1,543 @@ +What: /sys/fs/lustre/version +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows current running lustre version. + +What: /sys/fs/lustre/pinger +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows if the lustre module has pinger support. + "on" means yes and "off" means no. + +What: /sys/fs/lustre/health +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows whenever current system state believed to be "healthy", + "NOT HEALTHY", or "LBUG" whenever lustre has experienced + an internal assertion failure + +What: /sys/fs/lustre/jobid_name +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Currently running job "name" for this node to be transferred + to Lustre servers for purposes of QoS and statistics gathering. + Writing into this file will change the name, reading outputs + currently set value. + +What: /sys/fs/lustre/jobid_var +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Control file for lustre "jobstats" functionality, write new + value from the list below to change the mode: + disable - disable job name reporting to the servers (default) + procname_uid - form the job name as the current running + command name and pid with a dot in between + e.g. dd.1253 + nodelocal - use jobid_name value from above. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/blocksize +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Biggest blocksize on object storage server for this filesystem. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/kbytestotal +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows total number of kilobytes of space on this filesystem + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/kbytesfree +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows total number of free kilobytes of space on this filesystem + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/kbytesavail +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows total number of free kilobytes of space on this filesystem + actually available for use (taking into account per-client + grants and filesystem reservations). + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/filestotal +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows total number of inodes on the filesystem. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/filesfree +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows estimated number of free inodes on the filesystem + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/client_type +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows whenever this filesystem considers this client to be + compute cluster-local or remote. Remote clients have + additional uid/gid convrting logic applied. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/fstype +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows filesystem type of the filesystem + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/uuid +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows this filesystem superblock uuid + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/max_read_ahead_mb +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Sets maximum number of megabytes in system memory to be + given to read-ahead cache. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/max_read_ahead_per_file_mb +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Sets maximum number of megabytes to read-ahead for a single file + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/max_read_ahead_whole_mb +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + For small reads, how many megabytes to actually request from + the server as initial read-ahead. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/checksum_pages +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Enables or disables per-page checksum at llite layer, before + the pages are actually given to lower level for network transfer + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/stats_track_pid +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Limit Lustre vfs operations gathering to just a single pid. + 0 to track everything. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/stats_track_ppid +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Limit Lustre vfs operations gathering to just a single ppid. + 0 to track everything. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/stats_track_gid +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Limit Lustre vfs operations gathering to just a single gid. + 0 to track everything. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/statahead_max +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls maximum number of statahead requests to send when + sequential readdir+stat pattern is detected. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/statahead_agl +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls if AGL (async glimpse ahead - obtain object information + from OSTs in parallel with MDS during statahead) should be + enabled or disabled. + 0 to disable, 1 to enable. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/lazystatfs +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls statfs(2) behaviour in the face of down servers. + If 0, always wait for all servers to come online, + if 1, ignote inactive servers. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/max_easize +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows maximum number of bytes file striping data could be + in current configuration of storage. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/default_easize +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows maximum observed file striping data seen by this + filesystem client instance. + +What: /sys/fs/lustre/llite/<fsname>-<uuid>/xattr_cache +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls extended attributes client-side cache. + 1 to enable, 0 to disable. + +What: /sys/fs/lustre/ldlm/cancel_unused_locks_before_replay +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls if client should replay unused locks during recovery + If a client tends to have a lot of unused locks in LRU, + recovery times might become prolonged. + 1 - just locally cancel unused locks (default) + 0 - replay unused locks. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/resource_count +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Displays number of lock resources (objects on which individual + locks are taken) currently allocated in this namespace. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/lock_count +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Displays number or locks allocated in this namespace. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/lru_size +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls and displays LRU size limit for unused locks for this + namespace. + 0 - LRU size is unlimited, controlled by server resources + positive number - number of locks to allow in lock LRU list + +What: /sys/fs/lustre/ldlm/namespaces/<name>/lock_unused_count +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Display number of locks currently sitting in the LRU list + of this namespace + +What: /sys/fs/lustre/ldlm/namespaces/<name>/lru_max_age +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Maximum number of milliseconds a lock could sit in LRU list + before client would voluntarily cancel it as unused. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/early_lock_cancel +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls "early lock cancellation" feature on this namespace + if supported by the server. + When enabled, tries to preemtively cancel locks that would be + cancelled by verious operations and bundle the cancellation + requests in the same RPC as the main operation, which results + in significant speedups due to reduced lock-pingpong RPCs. + 0 - disabled + 1 - enabled (default) + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/granted +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Displays number of granted locks in this namespace + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/grant_rate +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of granted locks in this namespace during last + time interval + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/cancel_rate +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of lock cancellations in this namespace during + last time interval + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/grant_speed +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Calculated speed of lock granting (grant_rate - cancel_rate) + in this namespace + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/grant_plan +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Estimated number of locks to be granted in the next time + interval in this namespace + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/limit +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls number of allowed locks in this pool. + When lru_size is 0, this is the actual limit then. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/lock_volume_factor +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Multiplier for all lock volume calculations above. + Default is 1. Increase to make the client to more agressively + clean it's lock LRU list for this namespace. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/server_lock_volume +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Calculated server lock volume. + +What: /sys/fs/lustre/ldlm/namespaces/<name>/pool/recalc_period +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls length of time between recalculation of above + values (in seconds). + +What: /sys/fs/lustre/ldlm/services/ldlm_cbd/threads_min +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls minimum number of ldlm callback threads to start. + +What: /sys/fs/lustre/ldlm/services/ldlm_cbd/threads_max +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls maximum number of ldlm callback threads to start. + +What: /sys/fs/lustre/ldlm/services/ldlm_cbd/threads_started +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows actual number of ldlm callback threads running. + +What: /sys/fs/lustre/ldlm/services/ldlm_cbd/high_priority_ratio +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls what percentage of ldlm callback threads is dedicated + to "high priority" incoming requests. + +What: /sys/fs/lustre/{obdtype}/{connection_name}/blocksize +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Blocksize on backend filesystem for service behind this obd + device (or biggest blocksize for compound devices like lov + and lmv) + +What: /sys/fs/lustre/{obdtype}/{connection_name}/kbytestotal +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Total number of kilobytes of space on backend filesystem + for service behind this obd (or total amount for compound + devices like lov lmv) + +What: /sys/fs/lustre/{obdtype}/{connection_name}/kbytesfree +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of free kilobytes on backend filesystem for service + behind this obd (or total amount for compound devices + like lov lmv) + +What: /sys/fs/lustre/{obdtype}/{connection_name}/kbytesavail +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of kilobytes of free space on backend filesystem + for service behind this obd (or total amount for compound + devices like lov lmv) that is actually available for use + (taking into account per-client and filesystem reservations). + +What: /sys/fs/lustre/{obdtype}/{connection_name}/filestotal +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of inodes on backend filesystem for service behind this + obd. + +What: /sys/fs/lustre/{obdtype}/{connection_name}/filesfree +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of free inodes on backend filesystem for service + behind this obd. + +What: /sys/fs/lustre/mdc/{connection_name}/max_pages_per_rpc +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Maximum number of readdir pages to fit into a single readdir + RPC. + +What: /sys/fs/lustre/{mdc,osc}/{connection_name}/max_rpcs_in_flight +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Maximum number of parallel RPCs on the wire to allow on + this connection. Increasing this number would help on higher + latency links, but has a chance of overloading a server + if you have too many clients like this. + Default: 8 + +What: /sys/fs/lustre/osc/{connection_name}/max_pages_per_rpc +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Maximum number of pages to fit into a single RPC. + Typically bigger RPCs allow for better performance. + Default: however many pages to form 1M of data (256 pages + for 4K page sized platforms) + +What: /sys/fs/lustre/osc/{connection_name}/active +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls accessibility of this connection. If set to 0, + fail all accesses immediately. + +What: /sys/fs/lustre/osc/{connection_name}/checksums +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls whenever to checksum bulk RPC data over the wire + to this target. + 1: enable (default) ; 0: disable + +What: /sys/fs/lustre/osc/{connection_name}/contention_seconds +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls for how long to consider a file contended once + indicated as such by the server. + When a file is considered contended, all operations switch to + synchronous lockless mode to avoid cache and lock pingpong. + +What: /sys/fs/lustre/osc/{connection_name}/cur_dirty_bytes +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Displays how many dirty bytes is presently in the cache for this + target. + +What: /sys/fs/lustre/osc/{connection_name}/cur_grant_bytes +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows how many bytes we have as a "dirty cache" grant from the + server. Writing a value smaller than shown allows to release + some grant back to the server. + Dirty cache grant is a way Lustre ensures that cached successful + writes on client do not end up discarded by the server due to + lack of space later on. + +What: /sys/fs/lustre/osc/{connection_name}/cur_lost_grant_bytes +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Shows how many granted bytes were released to the server due + to lack of write activity on this client. + +What: /sys/fs/lustre/osc/{connection_name}/grant_shrink_interval +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of seconds with no write activity for this target + to start releasing dirty grant back to the server. + +What: /sys/fs/lustre/osc/{connection_name}/destroys_in_flight +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of DESTROY RPCs currently in flight to this target. + +What: /sys/fs/lustre/osc/{connection_name}/lockless_truncate +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls whether lockless truncate RPCs are allowed to this + target. + Lockless truncate causes server to perform the locking which + is beneficial if the truncate is not followed by a write + immediately. + 1: enable ; 0: disable (default) + +What: /sys/fs/lustre/osc/{connection_name}/max_dirty_mb +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls how much dirty data this client can accumulate + for this target. This is orthogonal to dirty grant and is + a hard limit even if the server would allow a bigger dirty + cache. + While allowing higher dirty cache is beneficial for write + performance, flushing write cache takes longer and as such + the node might be more prone to OOMs. + Having this value set too low might result in not being able + to sent too many parallel WRITE RPCs. + Default: 32 + +What: /sys/fs/lustre/osc/{connection_name}/resend_count +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Controls how many times to try and resend RPCs to this target + that failed with "recoverable" status, such as EAGAIN, + ENOMEM. + +What: /sys/fs/lustre/lov/{connection_name}/numobd +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of OSC targets managed by this LOV instance. + +What: /sys/fs/lustre/lov/{connection_name}/activeobd +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of OSC targets managed by this LOV instance that are + actually active. + +What: /sys/fs/lustre/lmv/{connection_name}/numobd +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of MDC targets managed by this LMV instance. + +What: /sys/fs/lustre/lmv/{connection_name}/activeobd +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Number of MDC targets managed by this LMV instance that are + actually active. + +What: /sys/fs/lustre/lmv/{connection_name}/placement +Date: May 2015 +Contact: "Oleg Drokin" <oleg.drokin@intel.com> +Description: + Determines policy of inode placement in case of multiple + metadata servers: + CHAR - based on a hash of the file name used at creation time + (Default) + NID - based on a hash of creating client network id. diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig index b78643f907e7..072dac04a750 100644 --- a/drivers/staging/media/omap4iss/Kconfig +++ b/drivers/staging/media/omap4iss/Kconfig @@ -2,6 +2,7 @@ config VIDEO_OMAP4 bool "OMAP 4 Camera support" depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4 depends on HAS_DMA + select MFD_SYSCON select VIDEOBUF2_DMA_CONTIG ---help--- Driver for an OMAP 4 ISS controller. diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index e0ad5e520e2d..7ced940bd807 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -17,6 +17,7 @@ #include <linux/dma-mapping.h> #include <linux/i2c.h> #include <linux/interrupt.h> +#include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -1386,6 +1387,16 @@ static int iss_probe(struct platform_device *pdev) platform_set_drvdata(pdev, iss); + /* + * TODO: When implementing DT support switch to syscon regmap lookup by + * phandle. + */ + iss->syscon = syscon_regmap_lookup_by_compatible("syscon"); + if (IS_ERR(iss->syscon)) { + ret = PTR_ERR(iss->syscon); + goto error; + } + /* Clocks */ ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index 734cfeeb0314..35df8b4709e6 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h @@ -29,6 +29,8 @@ #include "iss_ipipe.h" #include "iss_resizer.h" +struct regmap; + #define to_iss_device(ptr_module) \ container_of(ptr_module, struct iss_device, ptr_module) #define to_device(ptr_module) \ @@ -79,6 +81,7 @@ struct iss_reg { /* * struct iss_device - ISS device structure. + * @syscon: Regmap for the syscon register space * @crashed: Bitmask of crashed entities (indexed by entity ID) */ struct iss_device { @@ -93,6 +96,7 @@ struct iss_device { struct resource *res[OMAP4_ISS_MEM_LAST]; void __iomem *regs[OMAP4_ISS_MEM_LAST]; + struct regmap *syscon; u64 raw_dmamask; diff --git a/drivers/staging/media/omap4iss/iss_csiphy.c b/drivers/staging/media/omap4iss/iss_csiphy.c index 7c3d55d811ef..748607f8918f 100644 --- a/drivers/staging/media/omap4iss/iss_csiphy.c +++ b/drivers/staging/media/omap4iss/iss_csiphy.c @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/device.h> +#include <linux/regmap.h> #include "../../../../arch/arm/mach-omap2/control.h" @@ -140,9 +141,11 @@ int omap4iss_csiphy_config(struct iss_device *iss, * - bit [18] : CSIPHY1 CTRLCLK enable * - bit [17:16] : CSIPHY1 config: 00 d-phy, 01/10 ccp2 */ - cam_rx_ctrl = omap4_ctrl_pad_readl( - OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX); - + /* + * TODO: When implementing DT support specify the CONTROL_CAMERA_RX + * register offset in the syscon property instead of hardcoding it. + */ + regmap_read(iss->syscon, 0x68, &cam_rx_ctrl); if (subdevs->interface == ISS_INTERFACE_CSI2A_PHY1) { cam_rx_ctrl &= ~(OMAP4_CAMERARX_CSI21_LANEENABLE_MASK | @@ -166,8 +169,7 @@ int omap4iss_csiphy_config(struct iss_device *iss, cam_rx_ctrl |= OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK; } - omap4_ctrl_pad_writel(cam_rx_ctrl, - OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX); + regmap_write(iss->syscon, 0x68, cam_rx_ctrl); /* Reset used lane count */ csi2->phy->used_data_lanes = 0; diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 1bdc8d001e65..164634d61ac5 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -916,7 +916,7 @@ static int tegra_nvec_remove(struct platform_device *pdev) nvec_unregister_notifier(nvec, &nvec->nvec_status_notifier); cancel_work_sync(&nvec->rx_work); cancel_work_sync(&nvec->tx_work); - /* FIXME: needs check wether nvec is responsible for power off */ + /* FIXME: needs check whether nvec is responsible for power off */ pm_power_off = NULL; return 0; diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 5ff4716b72c3..784b5ecfa849 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -746,8 +746,8 @@ void oz_hcd_pd_reset(void *hpd, void *hport) /* * Context: softirq */ -void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, - int length, int offset, int total_size) +void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status, const u8 *desc, + u8 length, u16 offset, u16 total_size) { struct oz_port *port = hport; struct urb *urb; @@ -759,8 +759,8 @@ void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, if (!urb) return; if (status == 0) { - int copy_len; - int required_size = urb->transfer_buffer_length; + unsigned int copy_len; + unsigned int required_size = urb->transfer_buffer_length; if (required_size > total_size) required_size = total_size; diff --git a/drivers/staging/ozwpan/ozusbif.h b/drivers/staging/ozwpan/ozusbif.h index 4249fa374012..d2a6085345be 100644 --- a/drivers/staging/ozwpan/ozusbif.h +++ b/drivers/staging/ozwpan/ozusbif.h @@ -29,8 +29,8 @@ void oz_usb_request_heartbeat(void *hpd); /* Confirmation functions. */ -void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, - const u8 *desc, int length, int offset, int total_size); +void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status, + const u8 *desc, u8 length, u16 offset, u16 total_size); void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data, int data_len); diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index d434d8c6fff6..301fee8625ed 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -326,7 +326,11 @@ static void oz_usb_handle_ep_data(struct oz_usb_ctx *usb_ctx, struct oz_multiple_fixed *body = (struct oz_multiple_fixed *)data_hdr; u8 *data = body->data; - int n = (len - sizeof(struct oz_multiple_fixed)+1) + unsigned int n; + if (!body->unit_size || + len < sizeof(struct oz_multiple_fixed) - 1) + break; + n = (len - (sizeof(struct oz_multiple_fixed) - 1)) / body->unit_size; while (n--) { oz_hcd_data_ind(usb_ctx->hport, body->endpoint, @@ -338,12 +342,16 @@ static void oz_usb_handle_ep_data(struct oz_usb_ctx *usb_ctx, case OZ_DATA_F_ISOC_FIXED: { struct oz_isoc_fixed *body = (struct oz_isoc_fixed *)data_hdr; - int data_len = len-sizeof(struct oz_isoc_fixed)+1; + int data_len; int unit_size = body->unit_size; u8 *data = body->data; int count; int i; + if (len < sizeof(struct oz_isoc_fixed) - 1) + break; + data_len = len - (sizeof(struct oz_isoc_fixed) - 1); + if (!unit_size) break; count = data_len/unit_size; @@ -390,10 +398,15 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt) case OZ_GET_DESC_RSP: { struct oz_get_desc_rsp *body = (struct oz_get_desc_rsp *)usb_hdr; - int data_len = elt->length - - sizeof(struct oz_get_desc_rsp) + 1; - u16 offs = le16_to_cpu(get_unaligned(&body->offset)); - u16 total_size = + u16 offs, total_size; + u8 data_len; + + if (elt->length < sizeof(struct oz_get_desc_rsp) - 1) + break; + data_len = elt->length - + (sizeof(struct oz_get_desc_rsp) - 1); + offs = le16_to_cpu(get_unaligned(&body->offset)); + total_size = le16_to_cpu(get_unaligned(&body->total_size)); oz_dbg(ON, "USB_REQ_GET_DESCRIPTOR - cnf\n"); oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id, @@ -418,6 +431,11 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt) case OZ_VENDOR_CLASS_RSP: { struct oz_vendor_class_rsp *body = (struct oz_vendor_class_rsp *)usb_hdr; + + if (elt->length < + sizeof(struct oz_vendor_class_rsp) - 1) + break; + oz_hcd_control_cnf(usb_ctx->hport, body->req_id, body->rcode, body->data, elt->length- sizeof(struct oz_vendor_class_rsp)+1); diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 1d8ed8b35375..d67049455253 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -775,12 +775,10 @@ static void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val) /* sleeps that many milliseconds with a reschedule */ static void long_sleep(int ms) { - if (in_interrupt()) { + if (in_interrupt()) mdelay(ms); - } else { - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ + 999) / 1000); - } + else + schedule_timeout_interruptible(msecs_to_jiffies(ms)); } /* send a serial byte to the LCD panel. The caller is responsible for locking @@ -2250,8 +2248,28 @@ static void panel_detach(struct parport *port) __func__, port->number, parport); return; } + if (scan_timer.function != NULL) + del_timer_sync(&scan_timer); + + if (pprt != NULL) { + if (keypad.enabled) { + misc_deregister(&keypad_dev); + keypad_initialized = 0; + } - unregister_reboot_notifier(&panel_notifier); + if (lcd.enabled) { + panel_lcd_print("\x0cLCD driver " PANEL_VERSION + "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); + misc_deregister(&lcd_dev); + lcd.initialized = false; + } + + /* TODO: free all input signals */ + parport_release(pprt); + parport_unregister_device(pprt); + pprt = NULL; + unregister_reboot_notifier(&panel_notifier); + } } static struct parport_driver panel_driver = { @@ -2384,28 +2402,6 @@ static int __init panel_init_module(void) static void __exit panel_cleanup_module(void) { - - if (scan_timer.function != NULL) - del_timer_sync(&scan_timer); - - if (pprt != NULL) { - if (keypad.enabled) { - misc_deregister(&keypad_dev); - keypad_initialized = 0; - } - - if (lcd.enabled) { - panel_lcd_print("\x0cLCD driver " PANEL_VERSION - "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); - misc_deregister(&lcd_dev); - lcd.initialized = false; - } - - /* TODO: free all input signals */ - parport_release(pprt); - parport_unregister_device(pprt); - pprt = NULL; - } parport_unregister_driver(&panel_driver); } diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 1d3f72800492..2b09972d4cb5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -83,12 +83,14 @@ static void update_BCNTIM(struct adapter *padapter) u8 *pbackup_remainder_ie = NULL; uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; - p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); + p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, + pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); if (p != NULL && tim_ielen > 0) { tim_ielen += 2; premainder_ie = p+tim_ielen; tim_ie_offset = (int)(p - pie); - remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen; + remainder_ielen = pnetwork_mlmeext->IELength - + tim_ie_offset - tim_ielen; /* append TIM IE from dst_ie offset */ dst_ie = p; } else { @@ -99,7 +101,10 @@ static void update_BCNTIM(struct adapter *padapter) offset += pnetwork_mlmeext->Ssid.SsidLength + 2; /* get supported rates len */ - p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); + p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, + _SUPPORTEDRATES_IE_, &tmp_len, + (pnetwork_mlmeext->IELength - + _BEACON_IE_OFFSET_)); if (p != NULL) offset += tmp_len+2; @@ -108,7 +113,8 @@ static void update_BCNTIM(struct adapter *padapter) premainder_ie = pie + offset; - remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; + remainder_ielen = pnetwork_mlmeext->IELength - + offset - tim_ielen; /* append TIM IE from offset */ dst_ie = pie + offset; @@ -117,11 +123,13 @@ static void update_BCNTIM(struct adapter *padapter) if (remainder_ielen > 0) { pbackup_remainder_ie = rtw_malloc(remainder_ielen); if (pbackup_remainder_ie && premainder_ie) - memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + memcpy(pbackup_remainder_ie, + premainder_ie, remainder_ielen); } *dst_ie++ = _TIM_IE_; - if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc)) + if ((pstapriv->tim_bitmap&0xff00) && + (pstapriv->tim_bitmap&0x00fc)) tim_ielen = 5; else tim_ielen = 4; @@ -156,7 +164,8 @@ static void update_BCNTIM(struct adapter *padapter) set_tx_beacon_cmd(padapter); } -void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 index, u8 *data, u8 len) +void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, + u8 index, u8 *data, u8 len) { struct ndis_802_11_var_ie *pIE; u8 bmatch = false; @@ -170,7 +179,8 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 if (pIE->ElementID > index) { break; - } else if (pIE->ElementID == index) { /* already exist the same IE */ + /* already exist the same IE */ + } else if (pIE->ElementID == index) { p = (u8 *)pIE; ielen = pIE->Length; bmatch = true; @@ -199,7 +209,8 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 if (remainder_ielen > 0) { pbackup_remainder_ie = rtw_malloc(remainder_ielen); if (pbackup_remainder_ie && premainder_ie) - memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + memcpy(pbackup_remainder_ie, + premainder_ie, remainder_ielen); } *dst_ie++ = index; @@ -219,7 +230,8 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 pnetwork->IELength = offset + remainder_ielen; } -void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 index) +void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, + u8 index) { u8 *p, *dst_ie = NULL, *premainder_ie = NULL; u8 *pbackup_remainder_ie = NULL; @@ -243,7 +255,8 @@ void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, if (remainder_ielen > 0) { pbackup_remainder_ie = rtw_malloc(remainder_ielen); if (pbackup_remainder_ie && premainder_ie) - memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + memcpy(pbackup_remainder_ie, + premainder_ie, remainder_ielen); } /* copy remainder IE */ @@ -261,8 +274,10 @@ static u8 chk_sta_is_alive(struct sta_info *psta) { u8 ret = false; - if ((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == - (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) + if ((psta->sta_stats.last_rx_data_pkts + + psta->sta_stats.last_rx_ctrl_pkts) == + (psta->sta_stats.rx_data_pkts + + psta->sta_stats.rx_ctrl_pkts)) ; else ret = true; @@ -344,13 +359,18 @@ void expire_timeout_chk(struct adapter *padapter) if (psta->state & WIFI_SLEEP_STATE) { if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { - /* to check if alive by another methods if station is at ps mode. */ + /* to check if alive by another methods + * if station is at ps mode. + */ psta->expire_to = pstapriv->expire_to; psta->state |= WIFI_STA_ALIVE_CHK_STATE; - /* to update bcn with tim_bitmap for this station */ + /* to update bcn with tim_bitmap + * for this station + */ pstapriv->tim_bitmap |= BIT(psta->aid); - update_beacon(padapter, _TIM_IE_, NULL, false); + update_beacon(padapter, _TIM_IE_, + NULL, false); if (!pmlmeext->active_keep_alive_check) continue; diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index b66746160223..dbaba2c6cce5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -31,7 +31,7 @@ enum{ VOLTAGE_V25 = 0x03, - LDOE25_SHIFT = 28 , + LDOE25_SHIFT = 28, }; /* diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 969150a48661..8c05cb021c46 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -642,21 +642,18 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) */ int rtw_set_country(struct adapter *adapter, const char *country_code) { + int i; int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G; DBG_88E("%s country_code:%s\n", __func__, country_code); + for (i = 0; i < ARRAY_SIZE(channel_table); i++) { + if (0 == strcmp(channel_table[i].name, country_code)) { + channel_plan = channel_table[i].channel_plan; + break; + } + } - /* TODO: should have a table to match country code and RT_CHANNEL_DOMAIN */ - /* TODO: should consider 2-character and 3-character country code */ - if (0 == strcmp(country_code, "US")) - channel_plan = RT_CHANNEL_DOMAIN_FCC; - else if (0 == strcmp(country_code, "EU")) - channel_plan = RT_CHANNEL_DOMAIN_ETSI; - else if (0 == strcmp(country_code, "JP")) - channel_plan = RT_CHANNEL_DOMAIN_MKK; - else if (0 == strcmp(country_code, "CN")) - channel_plan = RT_CHANNEL_DOMAIN_CHINA; - else + if (i == ARRAY_SIZE(channel_table)) DBG_88E("%s unknown country_code:%s\n", __func__, country_code); return rtw_set_chplan_cmd(adapter, channel_plan, 1); diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c index 94405dc44220..14461cf34037 100644 --- a/drivers/staging/rtl8188eu/core/rtw_led.c +++ b/drivers/staging/rtl8188eu/core/rtw_led.c @@ -477,7 +477,7 @@ void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); - if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) || + if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) || (!padapter->hw_init_completed)) return; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 6c91aa58d924..a0f9f9e63b7f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -141,7 +141,7 @@ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *f } plist = free_queue->queue.next; - pnetwork = container_of(plist , struct wlan_network, list); + pnetwork = container_of(plist, struct wlan_network, list); list_del_init(&pnetwork->list); @@ -219,7 +219,7 @@ struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr) plist = phead->next; while (plist != phead) { - pnetwork = container_of(plist, struct wlan_network , list); + pnetwork = container_of(plist, struct wlan_network, list); if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) break; plist = plist->next; @@ -724,11 +724,11 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) pmlmeext = &adapter->mlmeextpriv; } -void rtw_dummy_event_callback(struct adapter *adapter , u8 *pbuf) +void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf) { } -void rtw_fwdbg_event_callback(struct adapter *adapter , u8 *pbuf) +void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf) { } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 2da2e97647d6..052d0f456956 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -794,9 +794,7 @@ unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) /* Now, we are going to issue_auth... */ pstat->auth_seq = seq + 1; -#ifdef CONFIG_88EU_AP_MODE issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); -#endif if (pstat->state & WIFI_FW_AUTH_SUCCESS) pstat->auth_seq = 0; @@ -806,18 +804,16 @@ unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) auth_fail: if (pstat) - rtw_free_stainfo(padapter , pstat); + rtw_free_stainfo(padapter, pstat); pstat = &stat; memset((char *)pstat, '\0', sizeof(stat)); pstat->auth_seq = 2; memcpy(pstat->hwaddr, sa, 6); -#ifdef CONFIG_88EU_AP_MODE issue_auth(padapter, pstat, (unsigned short)status); -#endif -#endif +#endif /* CONFIG_88EU_AP_MODE */ return _FAIL; } @@ -1295,7 +1291,6 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame /* now the station is qualified to join our BSS... */ if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { -#ifdef CONFIG_88EU_AP_MODE /* 1 bss_cap_update & sta_info_update */ bss_cap_update_on_sta_join(padapter, pstat); sta_info_update(padapter, pstat); @@ -1312,30 +1307,23 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame /* 3-(1) report sta add event */ report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); -#endif } return _SUCCESS; asoc_class2_error: -#ifdef CONFIG_88EU_AP_MODE issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); -#endif return _FAIL; OnAssocReqFail: - -#ifdef CONFIG_88EU_AP_MODE pstat->aid = 0; if (frame_type == WIFI_ASSOCREQ) issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); else issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); -#endif - #endif /* CONFIG_88EU_AP_MODE */ diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c index dc9d0ddf6b3a..19b3a0d6de9a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c @@ -54,14 +54,12 @@ static void _rtw_init_stainfo(struct sta_info *psta) psta->bpairwise_key_installed = false; -#ifdef CONFIG_88EU_AP_MODE psta->nonerp_set = 0; psta->no_short_slot_time_set = 0; psta->no_short_preamble_set = 0; psta->no_ht_gf_set = 0; psta->no_ht_set = 0; psta->ht_20mhz_set = 0; -#endif psta->under_exist_checking = 0; @@ -158,7 +156,7 @@ static void rtw_mfree_all_stainfo(struct sta_priv *pstapriv) plist = phead->next; while (phead != plist) { - psta = container_of(plist, struct sta_info , list); + psta = container_of(plist, struct sta_info, list); plist = plist->next; } @@ -259,7 +257,7 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("alloc number_%d stainfo with hwaddr = %pM\n", - pstapriv->asoc_sta_count , hwaddr)); + pstapriv->asoc_sta_count, hwaddr)); init_addba_retry_timer(pstapriv->padapter, psta); @@ -293,7 +291,7 @@ exit: } /* using pstapriv->sta_hash_lock to protect */ -u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta) +u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) { int i; struct __queue *pfree_sta_queue; @@ -442,12 +440,12 @@ void rtw_free_all_stainfo(struct adapter *padapter) plist = phead->next; while (phead != plist) { - psta = container_of(plist, struct sta_info , hash_list); + psta = container_of(plist, struct sta_info, hash_list); plist = plist->next; if (pbcmc_stainfo != psta) - rtw_free_stainfo(padapter , psta); + rtw_free_stainfo(padapter, psta); } } spin_unlock_bh(&pstapriv->sta_hash_lock); diff --git a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c index 082f0ca198ef..15a176596305 100644 --- a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c +++ b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c @@ -87,7 +87,7 @@ static u8 DROPING_NECESSARY[RATESIZE] = { static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; static u16 DynamicTxRPTTiming[6] = { - 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12 , 0x927c}; /* 200ms-1200ms */ + 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /* 200ms-1200ms */ /* End Rate adaptive parameters */ diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index 4bdbed28774e..5edb5c41c8e7 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -202,6 +202,7 @@ s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) { s32 ret = _FAIL; + if (adapt->HalFunc.mgnt_xmit) ret = adapt->HalFunc.mgnt_xmit(adapt, pmgntframe); return ret; @@ -236,6 +237,7 @@ void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level) #ifdef CONFIG_88EU_AP_MODE struct sta_info *psta = NULL; struct sta_priv *pstapriv = &adapt->stapriv; + if ((mac_id-1) > 0) psta = pstapriv->sta_aid[(mac_id-1) - 1]; if (psta) diff --git a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c index 73e1f8b36b37..3e60b23819ae 100644 --- a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c +++ b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c @@ -37,7 +37,7 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers, do { pwrcfgcmd = pwrseqcmd[aryidx]; - RT_TRACE(_module_hal_init_c_ , _drv_info_, + RT_TRACE(_module_hal_init_c_, _drv_info_, ("rtl88eu_pwrseqcmdparsing: offset(%#x) cut_msk(%#x)" "fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x)" "msk(%#x) value(%#x)\n", diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 7b01d5aa6b23..872622214264 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -2077,7 +2077,6 @@ static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_l break; } - rate_bitmap = 0x0fffffff; rate_bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, mac_id, mask, rssi_level); DBG_88E("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n", __func__, mac_id, networkType, mask, rssi_level, rate_bitmap); diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h index c81317906adc..bcc74dcd8207 100644 --- a/drivers/staging/rtl8188eu/include/drv_types.h +++ b/drivers/staging/rtl8188eu/include/drv_types.h @@ -175,7 +175,6 @@ static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj) }; struct adapter { - int pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */ u16 chip_type; struct dvobj_priv *dvobj; diff --git a/drivers/staging/rtl8188eu/include/osdep_intf.h b/drivers/staging/rtl8188eu/include/osdep_intf.h index efa786887962..1521744d626c 100644 --- a/drivers/staging/rtl8188eu/include/osdep_intf.h +++ b/drivers/staging/rtl8188eu/include/osdep_intf.h @@ -31,7 +31,6 @@ u8 rtw_init_drv_sw(struct adapter *padapter); u8 rtw_free_drv_sw(struct adapter *padapter); u8 rtw_reset_drv_sw(struct adapter *padapter); -u32 rtw_start_drv_threads(struct adapter *padapter); void rtw_stop_drv_threads (struct adapter *padapter); void rtw_cancel_all_timer(struct adapter *padapter); @@ -40,7 +39,6 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); struct net_device *rtw_init_netdev(struct adapter *padapter); u16 rtw_recv_select_queue(struct sk_buff *skb); -void rtw_proc_init_one(struct net_device *dev); void rtw_proc_remove_one(struct net_device *dev); int pm_netdev_open(struct net_device *pnetdev, u8 bnormal); diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index 515e949629e2..00472e0c00a0 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -157,8 +157,6 @@ void rtw_free_netdev(struct net_device *netdev); #define FUNC_ADPT_FMT "%s(%s)" #define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name -#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1) - u64 rtw_modular64(u64 x, u64 y); /* Macros for handling unaligned memory accesses */ diff --git a/drivers/staging/rtl8188eu/include/recv_osdep.h b/drivers/staging/rtl8188eu/include/recv_osdep.h index 5aabd3984e58..0809963ce6aa 100644 --- a/drivers/staging/rtl8188eu/include/recv_osdep.h +++ b/drivers/staging/rtl8188eu/include/recv_osdep.h @@ -44,8 +44,5 @@ int rtw_os_recv_resource_alloc(struct adapter *adapt, int rtw_os_recvbuf_resource_alloc(struct adapter *adapt, struct recv_buf *buf); void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); -int _netdev_open(struct net_device *pnetdev); -int netdev_open(struct net_device *pnetdev); -int netdev_close(struct net_device *pnetdev); #endif /* */ diff --git a/drivers/staging/rtl8188eu/include/rtw_ap.h b/drivers/staging/rtl8188eu/include/rtw_ap.h index 923340159798..6128ccce91ba 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ap.h +++ b/drivers/staging/rtl8188eu/include/rtw_ap.h @@ -47,7 +47,6 @@ void rtw_set_macaddr_acl(struct adapter *padapter, int mode); int rtw_acl_add_sta(struct adapter *padapter, u8 *addr); int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr); -#ifdef CONFIG_88EU_AP_MODE void associated_clients_update(struct adapter *padapter, u8 updated); void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta); u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta); @@ -59,7 +58,6 @@ int rtw_sta_flush(struct adapter *padapter); int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset); void start_ap_mode(struct adapter *padapter); void stop_ap_mode(struct adapter *padapter); -#endif #endif /* end of CONFIG_88EU_AP_MODE */ #endif diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl.h index f3aa924f2029..ee2cb54a7552 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ioctl.h +++ b/drivers/staging/rtl8188eu/include/rtw_ioctl.h @@ -117,6 +117,4 @@ int drv_set_info(struct net_device *MiniportAdapterContext, u32 informationbufferlength, u32 *bytesread, u32 *bytesneeded); -extern int ui_pid[3]; - #endif /* #ifndef __INC_CEINFO_ */ diff --git a/drivers/staging/rtl8188eu/include/rtw_led.h b/drivers/staging/rtl8188eu/include/rtw_led.h index 7a5303d50d49..f2054ef70358 100644 --- a/drivers/staging/rtl8188eu/include/rtw_led.h +++ b/drivers/staging/rtl8188eu/include/rtw_led.h @@ -30,7 +30,7 @@ enum LED_CTL_MODE { LED_CTL_LINK, LED_CTL_NO_LINK, LED_CTL_TX, - LED_CTL_RX , + LED_CTL_RX, LED_CTL_SITE_SURVEY, LED_CTL_POWER_OFF, LED_CTL_START_TO_LINK, diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index 2bebf46b053a..1df586aa0a9a 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -191,6 +191,14 @@ struct rt_channel_plan_map { unsigned char Index2G; }; +static const struct { + int channel_plan; + char *name; +} channel_table[] = { { RT_CHANNEL_DOMAIN_FCC, "US" }, + { RT_CHANNEL_DOMAIN_ETSI, "EU" }, + { RT_CHANNEL_DOMAIN_MKK, "JP" }, + { RT_CHANNEL_DOMAIN_CHINA, "CN"} }; + enum Associated_AP { atherosAP = 0, broadcomAP = 1, @@ -751,7 +759,7 @@ enum rtw_c2h_event { GEN_EVT_CODE(_Survey), /*8*/ GEN_EVT_CODE(_SurveyDone), /*9*/ - GEN_EVT_CODE(_JoinBss) , /*10*/ + GEN_EVT_CODE(_JoinBss), /*10*/ GEN_EVT_CODE(_AddSTA), GEN_EVT_CODE(_DelSTA), GEN_EVT_CODE(_AtimDone), diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h index e9723a72af5e..abe7e21e6e20 100644 --- a/drivers/staging/rtl8188eu/include/rtw_security.h +++ b/drivers/staging/rtl8188eu/include/rtw_security.h @@ -328,7 +328,7 @@ static const unsigned long K[64] = { #define RORc(x, y) \ (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y)&31)) | \ ((unsigned long)(x) << (unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x, y , z) (z ^ (x & (y ^ z))) +#define Ch(x, y, z) (z ^ (x & (y ^ z))) #define Maj(x, y, z) (((x | y) & z) | (x & y)) #define S(x, n) RORc((x), (n)) #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c index 64c99f2e9077..218adaa574b5 100644 --- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c @@ -41,8 +41,6 @@ void rtw_os_indicate_connect(struct adapter *adapter) { rtw_indicate_wx_assoc_event(adapter); netif_carrier_on(adapter->pnetdev); - if (adapter->pid[2] != 0) - rtw_signal_process(adapter->pid[2], SIGALRM); } void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted) diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 78b5ad0528f0..2e96234cd253 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -185,17 +185,20 @@ MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P") module_param_named(debug, rtw_debug, int, 0444); MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)"); +static int netdev_open(struct net_device *pnetdev); +static int netdev_close(struct net_device *pnetdev); + /* dummy routines */ void rtw_proc_remove_one(struct net_device *dev) { } -void rtw_proc_init_one(struct net_device *dev) +static void rtw_proc_init_one(struct net_device *dev) { } #if 0 /* TODO: Convert these to /sys */ -void rtw_proc_init_one(struct net_device *dev) +static void rtw_proc_init_one(struct net_device *dev) { struct proc_dir_entry *dir_dev = NULL; struct proc_dir_entry *entry = NULL; @@ -531,11 +534,10 @@ void rtw_proc_remove_one(struct net_device *dev) } #endif -static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) +static void loadparam(struct adapter *padapter, struct net_device *pnetdev) { struct registry_priv *registry_par = &padapter->registrypriv; - GlobalDebugLevel = rtw_debug; registry_par->chip_version = (u8)rtw_chip_version; registry_par->rfintfs = (u8)rtw_rfintfs; @@ -602,7 +604,6 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->ifname, 16, "%s", ifname); snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; - return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -751,21 +752,21 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter) return pnetdev; } -u32 rtw_start_drv_threads(struct adapter *padapter) +static int rtw_start_drv_threads(struct adapter *padapter) { - u32 _status = _SUCCESS; + int err = 0; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n")); padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); if (IS_ERR(padapter->cmdThread)) - _status = _FAIL; + err = PTR_ERR(padapter->cmdThread); else /* wait for cmd_thread to run */ _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); - return _status; + return err; } void rtw_stop_drv_threads(struct adapter *padapter) @@ -975,9 +976,10 @@ u8 rtw_free_drv_sw(struct adapter *padapter) return _SUCCESS; } -int _netdev_open(struct net_device *pnetdev) +static int _netdev_open(struct net_device *pnetdev) { uint status; + int err; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; @@ -1001,8 +1003,8 @@ int _netdev_open(struct net_device *pnetdev) pr_info("MAC Address = %pM\n", pnetdev->dev_addr); - status = rtw_start_drv_threads(padapter); - if (status == _FAIL) { + err = rtw_start_drv_threads(padapter); + if (err) { pr_info("Initialize driver software resource Failed!\n"); goto netdev_open_error; } @@ -1046,7 +1048,7 @@ netdev_open_error: return -1; } -int netdev_open(struct net_device *pnetdev) +static int netdev_open(struct net_device *pnetdev) { int ret; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); @@ -1060,6 +1062,7 @@ int netdev_open(struct net_device *pnetdev) static int ips_netdrv_open(struct adapter *padapter) { int status = _SUCCESS; + padapter->net_closed = false; DBG_88E("===> %s.........\n", __func__); @@ -1092,6 +1095,7 @@ int rtw_ips_pwr_up(struct adapter *padapter) { int result; u32 start_time = jiffies; + DBG_88E("===> rtw_ips_pwr_up..............\n"); rtw_reset_drv_sw(padapter); @@ -1106,6 +1110,7 @@ int rtw_ips_pwr_up(struct adapter *padapter) void rtw_ips_pwr_down(struct adapter *padapter) { u32 start_time = jiffies; + DBG_88E("===> rtw_ips_pwr_down...................\n"); padapter->net_closed = true; @@ -1141,7 +1146,7 @@ int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) return status; } -int netdev_close(struct net_device *pnetdev) +static int netdev_close(struct net_device *pnetdev) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); struct hal_data_8188e *rtlhal = GET_HAL_DATA(padapter); diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 99ce077007f4..5f3337c281ee 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -79,7 +79,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) { int cmd_num; for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) - if (0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num], + if (0 == strncasecmp(cmdstr, android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num]))) break; return cmd_num; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index ef3c73e38172..d0d4335b444c 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -32,8 +32,6 @@ #include <usb_hal.h> #include <rtw_ioctl.h> -int ui_pid[3] = {0, 0, 0}; - #define USB_VENDER_ID_REALTEK 0x0bda /* DID_USB_v916_20130116 */ @@ -330,11 +328,6 @@ static int rtw_resume_process(struct adapter *padapter) _exit_pwrlock(&pwrpriv->lock); - if (padapter->pid[1] != 0) { - DBG_88E("pid[1]:%d\n", padapter->pid[1]); - rtw_signal_process(padapter->pid[1], SIGUSR2); - } - rtw_roaming(padapter, NULL); ret = 0; @@ -511,11 +504,6 @@ static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device goto free_dvobj; } - if (ui_pid[1] != 0) { - DBG_88E("ui_pid[1]:%d\n", ui_pid[1]); - rtw_signal_process(ui_pid[1], SIGUSR2); - } - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-871x_drv - drv_init, success!\n")); status = _SUCCESS; diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index aad3394392fe..69e0f8f7e3f8 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -74,8 +74,8 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) #define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ - ether_addr_equal_unaligned(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, \ - __pTa) + ether_addr_equal_unaligned( \ + GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) #define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h index b7bb71fa9ecd..d0b08301b88f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h @@ -144,19 +144,6 @@ enum rf_optype { RF_OP_MAX }; - -enum power_save_mode { - POWER_SAVE_MODE_ACTIVE, - POWER_SAVE_MODE_SAVE, -}; - -enum interface_select_8190pci { - INTF_SEL1_MINICARD = 0, - INTF_SEL0_PCIE = 1, - INTF_SEL2_RSV = 2, - INTF_SEL3_RSV = 3, -}; - struct bb_reg_definition { u32 rfintfs; u32 rfintfi; @@ -178,33 +165,6 @@ struct bb_reg_definition { u32 rfLSSIReadBackPi; }; -struct tx_fwinfo { - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; - u8 TxBandwidth:1; - u8 TxSubCarrier:2; - u8 STBC:2; - u8 AllowAggregation:1; - u8 RtsHT:1; - u8 RtsShort:1; - u8 RtsBandwidth:1; - u8 RtsSubcarrier:2; - u8 RtsSTBC:2; - u8 EnableCPUDur:1; - - u32 RxMF:2; - u32 RxAMD:3; - u32 Reserved1:3; - u32 TxAGCOffset:4; - u32 TxAGCSign:1; - u32 Tx_INFO_RSVD:6; - u32 PacketID:13; -}; - struct tx_fwinfo_8190pci { u8 TxRate:7; u8 CtsEnable:1; diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c index 01d2201afc94..facc6f1f302b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c @@ -47,8 +47,8 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, 0x0e, bMask12Bits, 0x021); } else { - RT_TRACE(COMP_ERR, - "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); + netdev_warn(dev, "%s(): Unknown HW version.\n", + __func__); } break; @@ -66,16 +66,15 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, 0x0e, bMask12Bits, 0x0e1); } else { - RT_TRACE(COMP_ERR, - "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); + netdev_warn(dev, "%s(): Unknown HW version.\n", + __func__); } break; default: - RT_TRACE(COMP_ERR, - "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n", - Bandwidth); + netdev_err(dev, "%s(): Unknown bandwidth: %#X\n", + __func__, Bandwidth); break; } @@ -139,9 +138,8 @@ bool phy_RF8256_Config_ParaFile(struct net_device *dev) rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (enum rf90_radio_path)eRFPath); if (!rtStatus) { - RT_TRACE(COMP_ERR, - "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", - eRFPath); + netdev_err(dev, "%s(): Failed to check RF Path %d.\n", + __func__, eRFPath); goto phy_RF8256_Config_ParaFile_Fail; } @@ -227,9 +225,9 @@ bool phy_RF8256_Config_ParaFile(struct net_device *dev) } if (ret) { - RT_TRACE(COMP_ERR, - "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", - eRFPath); + netdev_err(dev, + "%s(): Failed to initialize RF Path %d.\n", + __func__, eRFPath); goto phy_RF8256_Config_ParaFile_Fail; } @@ -239,7 +237,6 @@ bool phy_RF8256_Config_ParaFile(struct net_device *dev) return true; phy_RF8256_Config_ParaFile_Fail: - RT_TRACE(COMP_ERR, "PHY Initialization failed\n"); return false; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c index ecdd2e5c6bac..ebd08a16685e 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c @@ -88,293 +88,3 @@ bool cmpk_message_handle_tx( Failed: return rt_status; } - -static void -cmpk_count_txstatistic( - struct net_device *dev, - struct cmpk_txfb *pstx_fb) -{ - struct r8192_priv *priv = rtllib_priv(dev); -#ifdef ENABLE_PS - enum rt_rf_power_state rtState; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - if (rtState == eRfOff) - return; -#endif - - if (pstx_fb->tok) { - priv->stats.txfeedbackok++; - priv->stats.txoktotal++; - priv->stats.txokbytestotal += pstx_fb->pkt_length; - priv->stats.txokinperiod++; - - if (pstx_fb->pkt_type == PACKET_MULTICAST) { - priv->stats.txmulticast++; - priv->stats.txbytesmulticast += pstx_fb->pkt_length; - } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { - priv->stats.txbroadcast++; - priv->stats.txbytesbroadcast += pstx_fb->pkt_length; - } else { - priv->stats.txunicast++; - priv->stats.txbytesunicast += pstx_fb->pkt_length; - } - } else { - priv->stats.txfeedbackfail++; - priv->stats.txerrtotal++; - priv->stats.txerrbytestotal += pstx_fb->pkt_length; - - if (pstx_fb->pkt_type == PACKET_MULTICAST) - priv->stats.txerrmulticast++; - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - priv->stats.txerrbroadcast++; - else - priv->stats.txerrunicast++; - } - - priv->stats.txretrycount += pstx_fb->retry_cnt; - priv->stats.txfeedbackretry += pstx_fb->retry_cnt; -} - -static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct cmpk_txfb rx_tx_fb; - - priv->stats.txfeedback++; - - - memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(struct cmpk_txfb)); - cmpk_count_txstatistic(dev, &rx_tx_fb); -} - -static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if ((priv->rtllib->current_network.mode == IEEE_A) || - (priv->rtllib->current_network.mode == IEEE_N_5G) || - ((priv->rtllib->current_network.mode == IEEE_N_24G) && - (!priv->rtllib->pHTInfo->bCurSuppCCK))) - DMESG("send beacon frame tx rate is 6Mbpm\n"); - else - DMESG("send beacon frame tx rate is 1Mbpm\n"); -} - -static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) -{ - struct cmpk_intr_sta rx_intr_status; - struct r8192_priv *priv = rtllib_priv(dev); - - DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - - rx_intr_status.length = pmsg[1]; - if (rx_intr_status.length != (sizeof(struct cmpk_intr_sta) - 2)) { - DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); - return; - } - - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); - - DMESG("interrupt status = 0x%x\n", - rx_intr_status.interrupt_status); - - if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { - priv->rtllib->bibsscoordinator = true; - priv->stats.txbeaconokint++; - } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { - priv->rtllib->bibsscoordinator = false; - priv->stats.txbeaconerr++; - } - - if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) - cmdpkt_beacontimerinterrupt_819xusb(dev); - } - - DMESG("<---- cmpk_handle_interrupt_status()\n"); - -} - -static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) -{ - cmpk_query_cfg_t rx_query_cfg; - - - rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; - rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; - rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; - rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; - rx_query_cfg.cfg_offset = pmsg[7]; - rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | - (pmsg[10] << 8) | (pmsg[11] << 0); - rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | - (pmsg[14] << 8) | (pmsg[15] << 0); - -} - -static void cmpk_count_tx_status(struct net_device *dev, - struct cmpk_tx_status *pstx_status) -{ - struct r8192_priv *priv = rtllib_priv(dev); - -#ifdef ENABLE_PS - - enum rt_rf_power_state rtstate; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - if (rtState == eRfOff) - return; -#endif - - priv->stats.txfeedbackok += pstx_status->txok; - priv->stats.txoktotal += pstx_status->txok; - - priv->stats.txfeedbackfail += pstx_status->txfail; - priv->stats.txerrtotal += pstx_status->txfail; - - priv->stats.txretrycount += pstx_status->txretry; - priv->stats.txfeedbackretry += pstx_status->txretry; - - - priv->stats.txmulticast += pstx_status->txmcok; - priv->stats.txbroadcast += pstx_status->txbcok; - priv->stats.txunicast += pstx_status->txucok; - - priv->stats.txerrmulticast += pstx_status->txmcfail; - priv->stats.txerrbroadcast += pstx_status->txbcfail; - priv->stats.txerrunicast += pstx_status->txucfail; - - priv->stats.txbytesmulticast += pstx_status->txmclength; - priv->stats.txbytesbroadcast += pstx_status->txbclength; - priv->stats.txbytesunicast += pstx_status->txuclength; - - priv->stats.last_packet_rate = pstx_status->rate; -} - -static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) -{ - struct cmpk_tx_status rx_tx_sts; - - memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(struct cmpk_tx_status)); - cmpk_count_tx_status(dev, &rx_tx_sts); -} - -static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) -{ - struct cmpk_tx_rahis *ptxrate; - u8 i, j; - u16 length = sizeof(struct cmpk_tx_rahis); - u32 *ptemp; - struct r8192_priv *priv = rtllib_priv(dev); - -#ifdef ENABLE_PS - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - if (rtState == eRfOff) - return; -#endif - - ptemp = (u32 *)pmsg; - - for (i = 0; i < (length / 4); i++) { - u16 temp1, temp2; - - temp1 = ptemp[i] & 0x0000FFFF; - temp2 = ptemp[i] >> 16; - ptemp[i] = (temp1 << 16) | temp2; - } - - ptxrate = (struct cmpk_tx_rahis *)pmsg; - - if (ptxrate == NULL) - return; - - for (i = 0; i < 16; i++) { - if (i < 4) - priv->stats.txrate.cck[i] += ptxrate->cck[i]; - - if (i < 8) - priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; - - for (j = 0; j < 4; j++) - priv->stats.txrate.ht_mcs[j][i] += - ptxrate->ht_mcs[j][i]; - } -} - -u32 cmpk_message_handle_rx(struct net_device *dev, - struct rtllib_rx_stats *pstats) -{ - int total_length; - u8 cmd_length, exe_cnt = 0; - u8 element_id; - u8 *pcmd_buff; - - RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx()\n"); - - if (pstats == NULL) - return 0; - - total_length = pstats->Length; - - pcmd_buff = pstats->virtual_address; - - element_id = pcmd_buff[0]; - - while (total_length > 0 || exe_cnt++ > 100) { - element_id = pcmd_buff[0]; - - switch (element_id) { - case RX_TX_FEEDBACK: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n"); - cmpk_handle_tx_feedback(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - case RX_INTERRUPT_STATUS: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n"); - cmpk_handle_interrupt_status(dev, pcmd_buff); - cmd_length = sizeof(struct cmpk_intr_sta); - break; - case BOTH_QUERY_CONFIG: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n"); - cmpk_handle_query_config_rx(dev, pcmd_buff); - cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; - break; - case RX_TX_STATUS: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():RX_TX_STATUS\n"); - cmpk_handle_tx_status(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_STS_SIZE; - break; - case RX_TX_PER_PKT_FEEDBACK: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n"); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - case RX_TX_RATE_HISTORY: - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():RX_TX_HISTORY\n"); - cmpk_handle_tx_rate_history(dev, pcmd_buff); - cmd_length = CMPK_TX_RAHIS_SIZE; - break; - default: - - RT_TRACE(COMP_CMDPKT, - "---->cmpk_message_handle_rx():unknown CMD Element\n"); - return 1; - } - - total_length -= cmd_length; - pcmd_buff += cmd_length; - } - return 1; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h index 2693682644df..f714d5100059 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h @@ -18,142 +18,8 @@ ******************************************************************************/ #ifndef R819XUSB_CMDPKT_H #define R819XUSB_CMDPKT_H -#define CMPK_RX_TX_FB_SIZE sizeof(struct cmpk_txfb) -#define CMPK_TX_SET_CONFIG_SIZE sizeof(struct cmpk_set_cfg) -#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(struct cmpk_set_cfg) -#define CMPK_RX_TX_STS_SIZE sizeof(struct cmpk_tx_status) -#define CMPK_RX_DBG_MSG_SIZE sizeof(struct cmpk_rx_dbginfo) -#define CMPK_TX_RAHIS_SIZE sizeof(struct cmpk_tx_rahis) -#define ISR_TxBcnOk BIT27 -#define ISR_TxBcnErr BIT26 -#define ISR_BcnTimerIntr BIT13 - - -struct cmpk_txfb { - u8 element_id; - u8 length; - u8 TID:4; - u8 fail_reason:3; - u8 tok:1; - u8 reserve1:4; - u8 pkt_type:2; - u8 bandwidth:1; - u8 qos_pkt:1; - - u8 reserve2; - u8 retry_cnt; - u16 pkt_id; - - u16 seq_num; - u8 s_rate; - u8 f_rate; - - u8 s_rts_rate; - u8 f_rts_rate; - u16 pkt_length; - - u16 reserve3; - u16 duration; -}; - -struct cmpk_intr_sta { - u8 element_id; - u8 length; - u16 reserve; - u32 interrupt_status; -}; - - -struct cmpk_set_cfg { - u8 element_id; - u8 length; - u16 reserve1; - u8 cfg_reserve1:3; - u8 cfg_size:2; - u8 cfg_type:2; - u8 cfg_action:1; - u8 cfg_reserve2; - u8 cfg_page:4; - u8 cfg_reserve3:4; - u8 cfg_offset; - u32 value; - u32 mask; -}; - -#define cmpk_query_cfg_t struct cmpk_set_cfg - -struct cmpk_tx_status { - u16 reserve1; - u8 length; - u8 element_id; - - u16 txfail; - u16 txok; - - u16 txmcok; - u16 txretry; - - u16 txucok; - u16 txbcok; - - u16 txbcfail; - u16 txmcfail; - - u16 reserve2; - u16 txucfail; - - u32 txmclength; - u32 txbclength; - u32 txuclength; - - u16 reserve3_23; - u8 reserve3_1; - u8 rate; -} __packed; - -struct cmpk_rx_dbginfo { - u16 reserve1; - u8 length; - u8 element_id; - - -}; - -struct cmpk_tx_rahis { - u8 element_id; - u8 length; - u16 reserved1; - - u16 cck[4]; - - u16 ofdm[8]; - - - - - - u16 ht_mcs[4][16]; - -} __packed; - -enum cmpk_element { - RX_TX_FEEDBACK = 0, - RX_INTERRUPT_STATUS = 1, - TX_SET_CONFIG = 2, - BOTH_QUERY_CONFIG = 3, - RX_TX_STATUS = 4, - RX_DBGINFO_FEEDBACK = 5, - RX_TX_PER_PKT_FEEDBACK = 6, - RX_TX_RATE_HISTORY = 7, - RX_CMD_ELE_MAX -}; - -extern u32 cmpk_message_handle_rx(struct net_device *dev, - struct rtllib_rx_stats *pstats); extern bool cmpk_message_handle_tx(struct net_device *dev, u8 *codevirtualaddress, u32 packettype, u32 buffer_len); - - #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index aad5cc95c341..f6661bbae7a8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -30,7 +30,8 @@ #include "rtl_dm.h" #include "rtl_wx.h" -static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; +static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, + EDCAPARA_VO}; void rtl8192e_start_beacon(struct net_device *dev) { @@ -187,22 +188,21 @@ void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val) u8 u1bAIFS; u32 u4bAcParam; u8 mode = priv->rtllib->mode; - struct rtllib_qos_parameters *qos_parameters = + struct rtllib_qos_parameters *qop = &priv->rtllib->current_network.qos_data.parameters; - u1bAIFS = qos_parameters->aifs[pAcParam] * + u1bAIFS = qop->aifs[pAcParam] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; dm_init_edca_turbo(dev); - u4bAcParam = (((le16_to_cpu( - qos_parameters->tx_op_limit[pAcParam])) << - AC_PARAM_TXOP_LIMIT_OFFSET) | - ((le16_to_cpu(qos_parameters->cw_max[pAcParam])) << - AC_PARAM_ECW_MAX_OFFSET) | - ((le16_to_cpu(qos_parameters->cw_min[pAcParam])) << - AC_PARAM_ECW_MIN_OFFSET) | - (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); + u4bAcParam = (le16_to_cpu(qop->tx_op_limit[pAcParam]) << + AC_PARAM_TXOP_LIMIT_OFFSET) | + ((le16_to_cpu(qop->cw_max[pAcParam])) << + AC_PARAM_ECW_MAX_OFFSET) | + ((le16_to_cpu(qop->cw_min[pAcParam])) << + AC_PARAM_ECW_MIN_OFFSET) | + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET); RT_TRACE(COMP_DBG, "%s():HW_VAR_AC_PARAM eACI:%x:%x\n", __func__, eACI, u4bAcParam); @@ -316,19 +316,18 @@ void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val) static void rtl8192_read_eeprom_info(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - + const u8 bMac_Tmp_Addr[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; u8 tempval; u8 ICVer8192, ICVer8256; u16 i, usValue, IC_Version; u16 EEPROMId; - u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n"); EEPROMId = eprom_read(dev, 0); if (EEPROMId != RTL8190_EEPROM_ID) { - RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", - EEPROMId, RTL8190_EEPROM_ID); + netdev_err(dev, "%s(): Invalid EEPROM ID: %x\n", __func__, + EEPROMId); priv->AutoloadFailFlag = true; } else { priv->AutoloadFailFlag = false; @@ -383,7 +382,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) *(u16 *)(&dev->dev_addr[i]) = usValue; } } else { - memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); + ether_addr_copy(dev->dev_addr, bMac_Tmp_Addr); } RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", @@ -737,9 +736,8 @@ start: else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY) ulRegRead |= CPU_GEN_FIRMWARE_RESET; else - RT_TRACE(COMP_ERR, - "ERROR in %s(): undefined firmware state(%d)\n", - __func__, priv->pFirmware->firmware_status); + netdev_err(dev, "%s(): undefined firmware state: %d.\n", + __func__, priv->pFirmware->firmware_status); write_nic_dword(dev, CPU_GEN, ulRegRead); @@ -755,7 +753,7 @@ start: RT_TRACE(COMP_INIT, "BB Config Start!\n"); rtStatus = rtl8192_BBConfig(dev); if (!rtStatus) { - RT_TRACE(COMP_ERR, "BB Config failed\n"); + netdev_warn(dev, "%s(): Failed to configure BB\n", __func__); return rtStatus; } RT_TRACE(COMP_INIT, "BB Config Finished!\n"); @@ -769,8 +767,8 @@ start: else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK) ulRegRead |= CPU_CCK_LOOPBACK; else - RT_TRACE(COMP_ERR, - "Serious error: wrong loopback mode setting\n"); + netdev_err(dev, "%s: Invalid loopback mode setting.\n", + __func__); write_nic_dword(dev, CPU_GEN, ulRegRead); @@ -868,7 +866,7 @@ start: RT_TRACE(COMP_INIT, "RF Config Started!\n"); rtStatus = rtl8192_phy_RFConfig(dev); if (!rtStatus) { - RT_TRACE(COMP_ERR, "RF Config failed\n"); + netdev_info(dev, "RF Config failed\n"); return rtStatus; } RT_TRACE(COMP_INIT, "RF Config Finished!\n"); @@ -1138,7 +1136,8 @@ static u8 MRateToHwRate8190Pci(u8 rate) return ret; } -static u8 rtl8192_MapHwQueueToFirmwareQueue(u8 QueueID, u8 priority) +static u8 rtl8192_MapHwQueueToFirmwareQueue(struct net_device *dev, u8 QueueID, + u8 priority) { u8 QueueSelect = 0x0; @@ -1171,9 +1170,8 @@ static u8 rtl8192_MapHwQueueToFirmwareQueue(u8 QueueID, u8 priority) QueueSelect = QSLT_HIGH; break; default: - RT_TRACE(COMP_ERR, - "TransmitTCB(): Impossible Queue Selection: %d\n", - QueueID); + netdev_warn(dev, "%s(): Impossible Queue Selection: %d\n", + __func__, QueueID); break; } return QueueSelect; @@ -1197,7 +1195,7 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, cb_desc); if (pci_dma_mapping_error(priv->pdev, mapping)) - RT_TRACE(COMP_ERR, "DMA Mapping error\n"); + netdev_err(dev, "%s(): DMA Mapping error\n", __func__); if (cb_desc->bAMPDUEnable) { pTxFwInfo->AllowAggregation = 1; pTxFwInfo->RxMF = cb_desc->ampdu_factor; @@ -1273,7 +1271,7 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, pdesc->PktId = 0x0; - pdesc->QueueSelect = rtl8192_MapHwQueueToFirmwareQueue( + pdesc->QueueSelect = rtl8192_MapHwQueueToFirmwareQueue(dev, cb_desc->queue_index, cb_desc->priority); pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci); @@ -1297,7 +1295,7 @@ void rtl8192_tx_fill_cmd_desc(struct net_device *dev, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(priv->pdev, mapping)) - RT_TRACE(COMP_ERR, "DMA Mapping error\n"); + netdev_err(dev, "%s(): DMA Mapping error\n", __func__); memset(entry, 0, 12); entry->LINIP = cb_desc->bLastIniPkt; entry->FirstSeg = 1; @@ -2201,14 +2199,6 @@ rtl8192_InitializeVariables(struct net_device *dev) priv->ShortRetryLimit = 0x30; priv->LongRetryLimit = 0x30; - priv->EarlyRxThreshold = 7; - priv->pwrGroupCnt = 0; - - priv->bIgnoreSilentReset = false; - priv->enable_gpio0 = 0; - - priv->TransmitConfig = 0; - priv->ReceiveConfig = RCR_ADD3 | RCR_AMF | RCR_ADF | RCR_AICV | @@ -2223,9 +2213,6 @@ rtl8192_InitializeVariables(struct net_device *dev) IMR_RDU | IMR_RXFOVW | IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); - - priv->MidHighPwrTHR_L1 = 0x3B; - priv->MidHighPwrTHR_L2 = 0x40; priv->PwrDomainProtect = false; priv->bfirst_after_down = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c index c465f8749acd..17d2a1540cc8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c @@ -116,7 +116,7 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) } if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) { - RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n"); + netdev_err(dev, "Firmware download failed.\n"); goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; } else { RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n"); @@ -135,15 +135,16 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) mdelay(2); } - if (!(CPU_status&CPU_GEN_BOOT_RDY)) + if (!(CPU_status&CPU_GEN_BOOT_RDY)) { + netdev_err(dev, "Firmware boot failed.\n"); goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; - else - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); + } + + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); return rt_status; CPUCheckMainCodeOKAndTurnOnCPU_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); rt_status = false; return rt_status; } @@ -171,7 +172,6 @@ static bool CPUcheck_firmware_ready(struct net_device *dev) return rt_status; CPUCheckFirmwareReady_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); rt_status = false; return rt_status; @@ -230,7 +230,7 @@ bool init_firmware(struct net_device *dev) u32 file_length = 0; u8 *mapped_file = NULL; - u8 init_step = 0; + u8 i = 0; enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; @@ -250,10 +250,9 @@ bool init_firmware(struct net_device *dev) "PlatformInitFirmware: undefined firmware state\n"); } - for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; - init_step++) { + for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) { if (rst_opt == OPT_SYSTEM_RESET) { - if (pfirmware->firmware_buf_size[init_step] == 0) { + if (pfirmware->firmware_buf_size[i] == 0) { const char *fw_name[3] = { RTL8192E_BOOT_IMG_FW, RTL8192E_MAIN_IMG_FW, @@ -263,7 +262,7 @@ bool init_firmware(struct net_device *dev) int rc; rc = request_firmware(&fw_entry, - fw_name[init_step], + fw_name[i], &priv->pdev->dev); if (rc < 0) { RT_TRACE(COMP_FIRMWARE, @@ -271,24 +270,24 @@ bool init_firmware(struct net_device *dev) goto download_firmware_fail; } if (fw_entry->size > - sizeof(pfirmware->firmware_buf[init_step])) { + sizeof(pfirmware->firmware_buf[i])) { RT_TRACE(COMP_FIRMWARE, "img file size exceed the container struct buffer fail!\n"); goto download_firmware_fail; } - if (init_step != FW_INIT_STEP1_MAIN) { - memcpy(pfirmware->firmware_buf[init_step], + if (i != FW_INIT_STEP1_MAIN) { + memcpy(pfirmware->firmware_buf[i], fw_entry->data, fw_entry->size); - pfirmware->firmware_buf_size[init_step] = + pfirmware->firmware_buf_size[i] = fw_entry->size; } else { - memset(pfirmware->firmware_buf[init_step], + memset(pfirmware->firmware_buf[i], 0, 128); - memcpy(&pfirmware->firmware_buf[init_step][128], + memcpy(&pfirmware->firmware_buf[i][128], fw_entry->data, fw_entry->size); - pfirmware->firmware_buf_size[init_step] = + pfirmware->firmware_buf_size[i] = fw_entry->size + 128; } @@ -297,14 +296,14 @@ bool init_firmware(struct net_device *dev) } } - mapped_file = pfirmware->firmware_buf[init_step]; - file_length = pfirmware->firmware_buf_size[init_step]; + mapped_file = pfirmware->firmware_buf[i]; + file_length = pfirmware->firmware_buf_size[i]; rt_status = fw_download_code(dev, mapped_file, file_length); if (!rt_status) goto download_firmware_fail; - if (!firmware_check_ready(dev, init_step)) + if (!firmware_check_ready(dev, i)) goto download_firmware_fail; } @@ -312,7 +311,7 @@ bool init_firmware(struct net_device *dev) return rt_status; download_firmware_fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); + netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__); rt_status = false; return rt_status; diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h index 94fa16b4993d..d79e54203199 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h @@ -52,11 +52,6 @@ enum firmware_status { FW_STATUS_5_READY = 5, }; -struct fw_seg_container { - u16 seg_size; - u8 *seg_ptr; -}; - struct rt_firmware { enum firmware_status firmware_status; u16 cmdpacket_frag_thresold; diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h index d804876dd92f..5bd3b3530aa6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h @@ -23,12 +23,6 @@ #include <linux/types.h> -#define BootArrayLengthPciE 344 -extern u8 Rtl8192PciEFwBootArray[BootArrayLengthPciE]; -#define MainArrayLengthPciE 43012 -extern u8 Rtl8192PciEFwMainArray[MainArrayLengthPciE]; -#define DataArrayLengthPciE 848 -extern u8 Rtl8192PciEFwDataArray[DataArrayLengthPciE]; #define PHY_REGArrayLengthPciE 1 extern u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLengthPciE]; #define PHY_REG_1T2RArrayLengthPciE 296 diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index eea2e39ff594..fba7654160e8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -504,13 +504,15 @@ bool rtl8192_phy_checkBBAndRF(struct net_device *dev, WriteAddr[HW90_BLOCK_RF] = 0x3; RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __func__, CheckBlock); + + if (CheckBlock == HW90_BLOCK_MAC) { + netdev_warn(dev, "%s(): No checks available for MAC block.\n", + __func__); + return ret; + } + for (i = 0; i < CheckTimes; i++) { switch (CheckBlock) { - case HW90_BLOCK_MAC: - RT_TRACE(COMP_ERR, - "PHY_CheckBBRFOK(): Never Write 0x100 here!"); - break; - case HW90_BLOCK_PHY0: case HW90_BLOCK_PHY1: write_nic_dword(dev, WriteAddr[CheckBlock], @@ -537,9 +539,7 @@ bool rtl8192_phy_checkBBAndRF(struct net_device *dev, if (dwRegRead != WriteData[i]) { - RT_TRACE(COMP_ERR, - "====>error=====dwRegRead: %x, WriteData: %x\n", - dwRegRead, WriteData[i]); + netdev_warn(dev, "%s(): Check failed.\n", __func__); ret = false; break; } @@ -628,8 +628,8 @@ void rtl8192_phy_getTxPower(struct net_device *dev) priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1); RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", - priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], - priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); + priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], + priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3); priv->framesyncC34 = read_nic_dword(dev, rOFDM0_RxDetector2); @@ -685,8 +685,7 @@ void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel) case RF_8258: break; default: - RT_TRACE(COMP_ERR, "unknown rf chip in function %s()\n", - __func__); + netdev_err(dev, "Invalid RF Chip ID.\n"); break; } } @@ -709,7 +708,7 @@ bool rtl8192_phy_RFConfig(struct net_device *dev) break; default: - RT_TRACE(COMP_ERR, "error chip id\n"); + netdev_err(dev, "Invalid RF Chip ID.\n"); break; } return rtStatus; @@ -802,13 +801,13 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) case RF_8258: break; default: - RT_TRACE(COMP_ERR, - "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n"); + netdev_warn(dev, "%s(): Invalid RF Chip ID\n", __func__); break; } } -static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, +static u8 rtl8192_phy_SetSwChnlCmdArray(struct net_device *dev, + struct sw_chnl_cmd *CmdTable, u32 CmdTableIdx, u32 CmdTableSz, enum sw_chnl_cmd_id CmdID, u32 Para1, u32 Para2, u32 msDelay) @@ -816,14 +815,11 @@ static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, struct sw_chnl_cmd *pCmd; if (CmdTable == NULL) { - RT_TRACE(COMP_ERR, - "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n"); + netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__); return false; } if (CmdTableIdx >= CmdTableSz) { - RT_TRACE(COMP_ERR, - "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n", - CmdTableIdx, CmdTableSz); + netdev_err(dev, "%s(): Invalid index requested.\n", __func__); return false; } @@ -851,24 +847,23 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, __func__, *stage, *step, channel); if (!rtllib_legal_channel(priv->rtllib, channel)) { - RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", - channel); + netdev_err(dev, "Invalid channel requested: %d\n", channel); return true; } { PreCommonCmdCnt = 0; - rtl8192_phy_SetSwChnlCmdArray(ieee->PreCommonCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, CmdID_SetTxPowerLevel, 0, 0, 0); - rtl8192_phy_SetSwChnlCmdArray(ieee->PreCommonCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, CmdID_End, 0, 0, 0); PostCommonCmdCnt = 0; - rtl8192_phy_SetSwChnlCmdArray(ieee->PostCommonCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT, CmdID_End, 0, 0, 0); @@ -876,32 +871,32 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, switch (priv->rf_chip) { case RF_8225: if (!(channel >= 1 && channel <= 14)) { - RT_TRACE(COMP_ERR, - "illegal channel for Zebra 8225: %d\n", - channel); + netdev_err(dev, + "Invalid channel requested for 8225: %d\n", + channel); return false; } - rtl8192_phy_SetSwChnlCmdArray(ieee->RfDependCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10); - rtl8192_phy_SetSwChnlCmdArray(ieee->RfDependCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, CmdID_End, 0, 0, 0); break; case RF_8256: if (!(channel >= 1 && channel <= 14)) { - RT_TRACE(COMP_ERR, - "illegal channel for Zebra 8256: %d\n", - channel); + netdev_err(dev, + "Invalid channel requested for 8256: %d\n", + channel); return false; } - rtl8192_phy_SetSwChnlCmdArray(ieee->RfDependCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, CmdID_RF_WriteReg, rZebra1_Channel, channel, 10); - rtl8192_phy_SetSwChnlCmdArray(ieee->RfDependCmd, + rtl8192_phy_SetSwChnlCmdArray(dev, ieee->RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, @@ -912,8 +907,7 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, break; default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", - priv->rf_chip); + netdev_warn(dev, "Unknown RF Chip ID\n"); return false; } @@ -1013,7 +1007,7 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) RT_TRACE(COMP_PHY, "=====>%s()\n", __func__); if (!priv->up) { - RT_TRACE(COMP_ERR, "%s(): ERR !! driver is not up\n", __func__); + netdev_err(dev, "%s(): Driver is not initialized\n", __func__); return false; } if (priv->SwChnlInProgress) @@ -1024,20 +1018,26 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) case WIRELESS_MODE_A: case WIRELESS_MODE_N_5G: if (channel <= 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14"); + netdev_warn(dev, + "Channel %d not available in 802.11a.\n", + channel); return false; } break; case WIRELESS_MODE_B: if (channel > 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14"); + netdev_warn(dev, + "Channel %d not available in 802.11b.\n", + channel); return false; } break; case WIRELESS_MODE_G: case WIRELESS_MODE_N_24G: if (channel > 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14"); + netdev_warn(dev, + "Channel %d not available in 802.11g.\n", + channel); return false; } break; @@ -1180,7 +1180,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) return; } if (!priv->up) { - RT_TRACE(COMP_ERR, "%s(): ERR!! driver is not up\n", __func__); + netdev_err(dev, "%s(): Driver is not initialized\n", __func__); return; } regBwOpMode = read_nic_byte(dev, BW_OPMODE); @@ -1197,9 +1197,8 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) break; default: - RT_TRACE(COMP_ERR, - "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n", - priv->CurrentChannelBW); + netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__, + priv->CurrentChannelBW); break; } @@ -1239,9 +1238,8 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); break; default: - RT_TRACE(COMP_ERR, - "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n", - priv->CurrentChannelBW); + netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__, + priv->CurrentChannelBW); break; } @@ -1261,7 +1259,8 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) break; default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); + netdev_info(dev, "%s(): Unknown RFChipID: %d\n", __func__, + priv->rf_chip); break; } @@ -1452,9 +1451,9 @@ static bool SetRFPowerState8190(struct net_device *dev, } while (!rtstatus && (InitilizeCount > 0)); if (!rtstatus) { - RT_TRACE(COMP_ERR, - "%s():Initialize Adapter fail,return\n", - __func__); + netdev_err(dev, + "%s(): Failed to initialize Adapter.\n", + __func__); priv->SetRFPowerStateInProgress = false; return false; } @@ -1555,16 +1554,16 @@ static bool SetRFPowerState8190(struct net_device *dev, default: bResult = false; - RT_TRACE(COMP_ERR, - "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", - eRFPowerState); + netdev_warn(dev, + "%s(): Unknown state requested: 0x%X.\n", + __func__, eRFPowerState); break; } break; default: - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); + netdev_warn(dev, "%s(): Unknown RF type\n", __func__); break; } @@ -1576,8 +1575,7 @@ static bool SetRFPowerState8190(struct net_device *dev, break; default: - RT_TRACE(COMP_ERR, - "SetRFPowerState8190(): Unknown RF type\n"); + netdev_warn(dev, "%s(): Unknown RF type\n", __func__); break; } } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h index 7318f8857af2..18bc58240fbe 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h @@ -41,13 +41,7 @@ #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray -extern u32 rtl819XMACPHY_Array_PG[]; -extern u32 rtl819XPHY_REG_1T2RArray[]; extern u32 rtl819XAGCTAB_Array[]; -extern u32 rtl819XRadioA_Array[]; -extern u32 rtl819XRadioB_Array[]; -extern u32 rtl819XRadioC_Array[]; -extern u32 rtl819XRadioD_Array[]; enum hw90_block { HW90_BLOCK_MAC = 0, diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index 41b025e250fe..f246222e5fc9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -36,18 +36,6 @@ void CamResetAllEntry(struct net_device *dev) write_nic_dword(dev, RWCAM, ulcommand); } -void write_cam(struct net_device *dev, u8 addr, u32 data) -{ - write_nic_dword(dev, WCAMI, data); - write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff)); -} - -u32 read_cam(struct net_device *dev, u8 addr) -{ - write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff)); - return read_nic_dword(dev, 0xa8); -} - void EnableHWSecurityConfig8192(struct net_device *dev) { u8 SECR_value = 0x0; @@ -81,7 +69,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev) } void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, - u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh) + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh) { struct r8192_priv *priv = rtllib_priv(dev); struct rtllib_device *ieee = priv->rtllib; @@ -100,7 +88,7 @@ void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, } void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, - u8 *MacAddr, u8 DefaultKey, u32 *KeyContent) + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent) { u32 TargetCommand = 0; u32 TargetContent = 0; @@ -113,8 +101,8 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, if (priv->rtllib->PowerSaveControl.bInactivePs) { if (rtState == eRfOff) { if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", - __func__); + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); return; } down(&priv->rtllib->ips_sem); @@ -124,7 +112,7 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, } priv->rtllib->is_set_key = true; if (EntryNo >= TOTAL_CAM_ENTRY) - RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); + netdev_info(dev, "%s(): Invalid CAM entry\n", __func__); RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d,KeyType:%d, MacAddr %pM\n", @@ -243,9 +231,9 @@ void CamRestoreAllEntry(struct net_device *dev) (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]) ); } else { - RT_TRACE(COMP_ERR, - "===>%s():ERR!! ADHOC TKIP ,but 0 entry is have no data\n", - __func__); + netdev_warn(dev, + "%s(): ADHOC TKIP: missing key entry.\n", + __func__); return; } } @@ -267,9 +255,9 @@ void CamRestoreAllEntry(struct net_device *dev) CAM_CONST_ADDR[0], 0, (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0])); } else { - RT_TRACE(COMP_ERR, - "===>%s():ERR!! ADHOC CCMP ,but 0 entry is have no data\n", - __func__); + netdev_warn(dev, + "%s(): ADHOC CCMP: missing key entry.\n", + __func__); return; } } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h index 3c4c0e61c181..f23ab46c77e7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h @@ -31,14 +31,9 @@ struct net_device; void CamResetAllEntry(struct net_device *dev); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, - u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, - u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh); -void CamPrintDbgReg(struct net_device *dev); - -u32 read_cam(struct net_device *dev, u8 addr); -void write_cam(struct net_device *dev, u8 addr, u32 data); - + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh); void CamRestoreAllEntry(struct net_device *dev); #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 47b5aadcb2bf..4c53c873aff1 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -343,8 +343,9 @@ bool MgntActSet_RF_State(struct net_device *dev, mdelay(1); if (RFWaitCounter > 100) { - RT_TRACE(COMP_ERR, - "MgntActSet_RF_State(): Wait too logn to set RF\n"); + netdev_warn(dev, + "%s(): Timeout waiting for RF change.\n", + __func__); return false; } } @@ -897,9 +898,9 @@ void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode) } else if ((bSupportMode & WIRELESS_MODE_B)) { wireless_mode = WIRELESS_MODE_B; } else { - RT_TRACE(COMP_ERR, - "%s(), No valid wireless mode supported (%x)!!!\n", - __func__, bSupportMode); + netdev_info(dev, + "%s(): Unsupported mode requested. Fallback to 802.11b\n", + __func__); wireless_mode = WIRELESS_MODE_B; } } @@ -946,8 +947,7 @@ static int _rtl8192_sta_up(struct net_device *dev, bool is_silent_reset) priv->bfirst_init = true; init_status = priv->ops->initialize_adapter(dev); if (!init_status) { - RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n", - __func__); + netdev_err(dev, "%s(): Initialization failed!\n", __func__); priv->bfirst_init = false; return -1; } @@ -1087,16 +1087,6 @@ static void rtl8192_init_priv_constant(struct net_device *dev) &(priv->rtllib->PowerSaveControl); pPSC->RegMaxLPSAwakeIntvl = 5; - - priv->RegPciASPM = 2; - - priv->RegDevicePciASPMSetting = 0x03; - - priv->RegHostPciASPMSetting = 0x02; - - priv->RegHwSwRfOffD3 = 2; - - priv->RegSupportPciASPM = 2; } @@ -1109,16 +1099,12 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; priv->rtllib->hwscan_sem_up = 1; priv->rtllib->status = 0; - priv->H2CTxCmdSeq = 0; - priv->bDisableFrameBursting = false; - priv->bDMInitialGainEnable = true; priv->polling_timer_on = 0; priv->up_first_time = 1; priv->blinked_ingpio = false; priv->bDriverIsGoingToUnload = false; priv->being_init_adapter = false; priv->initialized_at_probe = false; - priv->sw_radio_on = true; priv->bdisable_nic = false; priv->bfirst_init = false; priv->txringcount = 64; @@ -1126,12 +1112,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->rxringcount = MAX_RX_COUNT; priv->irq_enabled = 0; priv->chan = 1; - priv->RegWirelessMode = WIRELESS_MODE_AUTO; priv->RegChannelPlan = 0xf; - priv->nrxAMPDU_size = 0; - priv->nrxAMPDU_aggr_num = 0; - priv->last_rxdesc_tsf_high = 0; - priv->last_rxdesc_tsf_low = 0; priv->rtllib->mode = WIRELESS_MODE_AUTO; priv->rtllib->iw_mode = IW_MODE_INFRA; priv->rtllib->bNetPromiscuousMode = false; @@ -1177,12 +1158,6 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->rtllib->sta_sleep = LPS_IS_WAKE; priv->rtllib->eRFPowerState = eRfOn; - priv->txpower_checkcnt = 0; - priv->thermal_readback_index = 0; - priv->txpower_tracking_callback_cnt = 0; - priv->ccktxpower_adjustcnt_ch14 = 0; - priv->ccktxpower_adjustcnt_not_ch14 = 0; - priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; priv->rtllib->iw_mode = IW_MODE_INFRA; priv->rtllib->active_scan = 1; @@ -1199,13 +1174,11 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->card_type = PCI; - priv->AcmControl = 0; priv->pFirmware = vzalloc(sizeof(struct rt_firmware)); if (!priv->pFirmware) netdev_err(dev, "rtl8192e: Unable to allocate space for firmware\n"); - skb_queue_head_init(&priv->rx_queue); skb_queue_head_init(&priv->skb_queue); for (i = 0; i < MAX_QUEUE_SIZE; i++) @@ -1216,14 +1189,10 @@ static void rtl8192_init_priv_variable(struct net_device *dev) static void rtl8192_init_priv_lock(struct r8192_priv *priv) { - spin_lock_init(&priv->fw_scan_lock); spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->rf_ps_lock); spin_lock_init(&priv->ps_lock); - spin_lock_init(&priv->rf_lock); - spin_lock_init(&priv->rt_h2c_lock); sema_init(&priv->wx_sem, 1); sema_init(&priv->rf_sem, 1); mutex_init(&priv->mutex); @@ -1268,9 +1237,8 @@ static short rtl8192_get_channel_map(struct net_device *dev) if ((priv->rf_chip != RF_8225) && (priv->rf_chip != RF_8256) && (priv->rf_chip != RF_6052)) { - RT_TRACE(COMP_ERR, - "%s: unknown rf chip, can't set channel map\n", - __func__); + netdev_err(dev, "%s: unknown rf chip, can't set channel map\n", + __func__); return -1; } @@ -1499,9 +1467,8 @@ RESET_START: LeisurePSLeave(dev); if (priv->up) { - RT_TRACE(COMP_ERR, - "%s():the driver is not up! return\n", - __func__); + netdev_info(dev, "%s():the driver is not up.\n", + __func__); up(&priv->wx_sem); return; } @@ -1555,9 +1522,8 @@ RESET_START: reset_times++; goto RESET_START; } else { - RT_TRACE(COMP_ERR, - " ERR!!! %s(): Reset Failed!!\n", - __func__); + netdev_warn(dev, "%s(): Reset Failed\n", + __func__); } } @@ -1730,7 +1696,7 @@ void rtl819x_watchdog_wqcallback(void *data) if (priv->check_roaming_cnt > 0) { if (ieee->eRFPowerState == eRfOff) - RT_TRACE(COMP_ERR, "========>%s()\n", __func__); + netdev_info(dev, "%s(): RF is off\n", __func__); netdev_info(dev, "===>%s(): AP is power off, chan:%d, connect another one\n", @@ -1885,8 +1851,9 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, return; } - assert(queue_index != TXCMD_QUEUE); - + if (queue_index != TXCMD_QUEUE) + netdev_warn(dev, "%s(): queue index != TXCMD_QUEUE\n", + __func__); memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); skb_push(skb, priv->rtllib->tx_headroom); @@ -1999,9 +1966,8 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) u32 fwinfo_size = 0; if (priv->bdisable_nic) { - RT_TRACE(COMP_ERR, - "%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", - __func__, skb->len, tcb_desc->queue_index); + netdev_warn(dev, "%s: Nic is disabled! Can't tx packet.\n", + __func__); return skb->len; } @@ -2038,10 +2004,10 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) pdesc = &ring->desc[idx]; if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { - RT_TRACE(COMP_ERR, - "No more TX desc@%d, ring->idx = %d, idx = %d, skblen = 0x%x queuelen=%d", - tcb_desc->queue_index, ring->idx, idx, skb->len, - skb_queue_len(&ring->queue)); + netdev_warn(dev, + "No more TX desc@%d, ring->idx = %d, idx = %d, skblen = 0x%x queuelen=%d", + tcb_desc->queue_index, ring->idx, idx, skb->len, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&priv->irq_th_lock, flags); return skb->len; } @@ -2067,13 +2033,12 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) int i, rx_queue_idx; for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { - priv->rx_ring[rx_queue_idx] = - pci_zalloc_consistent(priv->pdev, + priv->rx_ring[rx_queue_idx] = pci_zalloc_consistent(priv->pdev, sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount, &priv->rx_ring_dma[rx_queue_idx]); if (!priv->rx_ring[rx_queue_idx] || (unsigned long)priv->rx_ring[rx_queue_idx] & 0xFF) { - RT_TRACE(COMP_ERR, "Cannot allocate RX ring\n"); + netdev_warn(dev, "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -2119,8 +2084,7 @@ static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, ring = pci_zalloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); if (!ring || (unsigned long)ring & 0xFF) { - RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", - prio); + netdev_warn(dev, "Cannot allocate TX ring (prio = %d)\n", prio); return -ENOMEM; } @@ -2311,7 +2275,7 @@ static void rtl8192_rx_normal(struct net_device *dev) struct rtllib_rx_stats stats = { .signal = 0, - .noise = -98, + .noise = (u8) -98, .rate = 0, .freq = RTLLIB_24GHZ_BAND, }; @@ -2573,8 +2537,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int ret = -1; struct rtllib_device *ieee = priv->rtllib; u32 key[4]; - u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 zero_addr[6] = {0}; + const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct iw_point *p = &wrq->u.data; struct ieee_param *ipw = NULL; @@ -2611,8 +2574,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } if (ieee->pairwise_key_type) { - if (memcmp(ieee->ap_mac_addr, zero_addr, - 6) == 0) + if (is_zero_ether_addr(ieee->ap_mac_addr)) ieee->iw_mode = IW_MODE_ADHOC; memcpy((u8 *)key, ipw->u.crypt.key, 16); EnableHWSecurityConfig8192(dev); @@ -2851,7 +2813,7 @@ static int rtl8192_pci_probe(struct pci_dev *pdev, RT_TRACE(COMP_INIT, "Configuring chip resources"); if (pci_enable_device(pdev)) { - RT_TRACE(COMP_ERR, "Failed to enable PCI device"); + dev_err(&pdev->dev, "Failed to enable PCI device"); return -EIO; } @@ -2889,21 +2851,21 @@ static int rtl8192_pci_probe(struct pci_dev *pdev, pmem_flags = pci_resource_flags(pdev, 1); if (!(pmem_flags & IORESOURCE_MEM)) { - RT_TRACE(COMP_ERR, "region #1 not a MMIO resource, aborting"); + netdev_err(dev, "region #1 not a MMIO resource, aborting"); goto err_rel_rtllib; } dev_info(&pdev->dev, "Memory mapped space start: 0x%08lx\n", pmem_start); if (!request_mem_region(pmem_start, pmem_len, DRV_NAME)) { - RT_TRACE(COMP_ERR, "request_mem_region failed!"); + netdev_err(dev, "request_mem_region failed!"); goto err_rel_rtllib; } ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len); if (ioaddr == (unsigned long)NULL) { - RT_TRACE(COMP_ERR, "ioremap failed!"); + netdev_err(dev, "ioremap failed!"); goto err_rel_mem; } @@ -2939,7 +2901,7 @@ static int rtl8192_pci_probe(struct pci_dev *pdev, RT_TRACE(COMP_INIT, "Driver probe completed1\n"); if (rtl8192_init(dev) != 0) { - RT_TRACE(COMP_ERR, "Initialization failed"); + netdev_warn(dev, "Initialization failed"); goto err_free_irq; } @@ -3002,8 +2964,6 @@ static void rtl8192_pci_disconnect(struct pci_dev *pdev) } free_rtllib(dev); - kfree(priv->scan_cmd); - if (dev->mem_start != 0) { iounmap((void __iomem *)dev->mem_start); release_mem_region(pci_resource_start(pdev, 1), @@ -3025,8 +2985,7 @@ bool NicIFEnableNIC(struct net_device *dev) (&(priv->rtllib->PowerSaveControl)); if (!priv->up) { - RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n", - __func__); + netdev_warn(dev, "%s(): Driver is already down!\n", __func__); priv->bdisable_nic = false; return false; } @@ -3035,8 +2994,7 @@ bool NicIFEnableNIC(struct net_device *dev) priv->bfirst_init = true; init_status = priv->ops->initialize_adapter(dev); if (!init_status) { - RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n", - __func__); + netdev_warn(dev, "%s(): Initialization failed!\n", __func__); priv->bdisable_nic = false; return false; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 0640e76f2a7a..776d950655cb 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -68,74 +68,19 @@ #define DRV_AUTHOR "<wlanfae@realtek.com>" #define DRV_VERSION "0014.0401.2010" -#define IS_HARDWARE_TYPE_819xP(_priv) \ - ((((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8190P) || \ - (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192E)) #define IS_HARDWARE_TYPE_8192SE(_priv) \ (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE) -#define IS_HARDWARE_TYPE_8192CE(_priv) \ - (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192CE) -#define IS_HARDWARE_TYPE_8192CU(_priv) \ - (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192CU) -#define IS_HARDWARE_TYPE_8192DE(_priv) \ - (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192DE) -#define IS_HARDWARE_TYPE_8192DU(_priv) \ - (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192DU) #define RTL_PCI_DEVICE(vend, dev, cfg) \ .vendor = (vend), .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ .driver_data = (kernel_ulong_t)&(cfg) -#define RTL_MAX_SCAN_SIZE 128 - -#define RTL_RATE_MAX 30 - #define TOTAL_CAM_ENTRY 32 #define CAM_CONTENT_COUNT 8 -#ifndef BIT -#define BIT(_i) (1<<(_i)) -#endif - -#define IS_ADAPTER_SENDS_BEACON(dev) 0 - -#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 -#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00 -#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 #define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 -#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 #define HAL_HW_PCI_REVISION_ID_8192SE 0x10 -#define HAL_HW_PCI_REVISION_ID_8192CE 0x1 -#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 -#define HAL_HW_PCI_REVISION_ID_8192DE 0x0 -#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 - -#define HAL_HW_PCI_8180_DEVICE_ID 0x8180 -#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 -#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 -#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 -#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 -#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 -#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 -#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 -#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 -#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 -#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 -#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 -#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 -#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 -#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 -#define HAL_HW_PCI_700F_DEVICE_ID 0x700F -#define HAL_HW_PCI_701F_DEVICE_ID 0x701F -#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304 -#define HAL_HW_PCI_8192CET_DEVICE_ID 0x8191 -#define HAL_HW_PCI_8192CE_DEVICE_ID 0x8178 -#define HAL_HW_PCI_8191CE_DEVICE_ID 0x8177 -#define HAL_HW_PCI_8188CE_DEVICE_ID 0x8176 -#define HAL_HW_PCI_8192CU_DEVICE_ID 0x8191 -#define HAL_HW_PCI_8192DE_DEVICE_ID 0x092D -#define HAL_HW_PCI_8192DU_DEVICE_ID 0x092D #define RTL819X_DEFAULT_RF_TYPE RF_1T2R @@ -150,16 +95,12 @@ (1600 + (MAX_802_11_HEADER_LENGTH + ENCRYPTION_MAX_OVERHEAD) * \ MAX_FRAGMENT_COUNT) -#define scrclng 4 - #define DEFAULT_FRAG_THRESHOLD 2342U #define MIN_FRAG_THRESHOLD 256U #define DEFAULT_BEACONINTERVAL 0x64U -#define DEFAULT_SSID "" #define DEFAULT_RETRY_RTS 7 #define DEFAULT_RETRY_DATA 7 -#define PRISM_HDR_SIZE 64 #define PHY_RSSI_SLID_WIN_MAX 100 @@ -183,29 +124,6 @@ extern int hwwep; -enum RTL819x_PHY_PARAM { - RTL819X_PHY_MACPHY_REG = 0, - RTL819X_PHY_MACPHY_REG_PG = 1, - RTL8188C_PHY_MACREG = 2, - RTL8192C_PHY_MACREG = 3, - RTL819X_PHY_REG = 4, - RTL819X_PHY_REG_1T2R = 5, - RTL819X_PHY_REG_to1T1R = 6, - RTL819X_PHY_REG_to1T2R = 7, - RTL819X_PHY_REG_to2T2R = 8, - RTL819X_PHY_REG_PG = 9, - RTL819X_AGC_TAB = 10, - RTL819X_PHY_RADIO_A = 11, - RTL819X_PHY_RADIO_A_1T = 12, - RTL819X_PHY_RADIO_A_2T = 13, - RTL819X_PHY_RADIO_B = 14, - RTL819X_PHY_RADIO_B_GM = 15, - RTL819X_PHY_RADIO_C = 16, - RTL819X_PHY_RADIO_D = 17, - RTL819X_EEPROM_MAP = 18, - RTL819X_EFUSE_MAP = 19, -}; - enum nic_t { NIC_UNKNOWN = 0, NIC_8192E = 1, @@ -220,7 +138,6 @@ enum nic_t { enum rt_eeprom_type { EEPROM_93C46, EEPROM_93C56, - EEPROM_BOOT_EFUSE, }; enum dcmg_txcmd_op { @@ -242,19 +159,6 @@ enum rt_rf_type_819xu { RF_PSEUDO_11N = 5, }; -enum rf_step { - RF_STEP_INIT = 0, - RF_STEP_NORMAL, - RF_STEP_MAX -}; - -enum rt_status { - RT_STATUS_SUCCESS, - RT_STATUS_FAILURE, - RT_STATUS_PENDING, - RT_STATUS_RESOURCE -}; - enum rt_customer_id { RT_CID_DEFAULT = 0, RT_CID_8187_ALPHA0 = 1, @@ -294,58 +198,9 @@ enum reset_type { RESET_TYPE_SILENT = 0x02 }; -enum ic_inferiority_8192s { - IC_INFERIORITY_A = 0, - IC_INFERIORITY_B = 1, -}; - -enum pci_bridge_vendor { - PCI_BRIDGE_VENDOR_INTEL = 0x0, - PCI_BRIDGE_VENDOR_ATI, - PCI_BRIDGE_VENDOR_AMD, - PCI_BRIDGE_VENDOR_SIS, - PCI_BRIDGE_VENDOR_UNKNOWN, - PCI_BRIDGE_VENDOR_MAX, -}; - -struct buffer { - struct buffer *next; - u32 *buf; - dma_addr_t dma; - -}; - -struct rtl_reg_debug { - unsigned int cmd; - struct { - unsigned char type; - unsigned char addr; - unsigned char page; - unsigned char length; - } head; - unsigned char buf[0xff]; -}; - -struct rt_tx_rahis { - u32 cck[4]; - u32 ofdm[8]; - u32 ht_mcs[4][16]; -}; - -struct rt_smooth_data_4rf { - char elements[4][100]; - u32 index; - u32 TotalNum; - u32 TotalVal[4]; -}; - struct rt_stats { - unsigned long txrdu; unsigned long rxrdu; unsigned long rxok; - unsigned long rxframgment; - unsigned long rxurberr; - unsigned long rxstaterr; unsigned long rxdatacrcerr; unsigned long rxmgmtcrcerr; unsigned long rxcrcerrmin; @@ -353,8 +208,6 @@ struct rt_stats { unsigned long rxcrcerrmax; unsigned long received_rate_histogram[4][32]; unsigned long received_preamble_GI[2][32]; - unsigned long rx_AMPDUsize_histogram[5]; - unsigned long rx_AMPDUnum_histogram[5]; unsigned long numpacket_matchbssid; unsigned long numpacket_toself; unsigned long num_process_phyinfo; @@ -362,58 +215,24 @@ struct rt_stats { unsigned long numqry_phystatusCCK; unsigned long numqry_phystatusHT; unsigned long received_bwtype[5]; - unsigned long txnperr; - unsigned long txnpdrop; - unsigned long txresumed; unsigned long rxoverflow; unsigned long rxint; - unsigned long txnpokint; unsigned long ints; unsigned long shints; unsigned long txoverflow; - unsigned long txlpokint; - unsigned long txlpdrop; - unsigned long txlperr; unsigned long txbeokint; - unsigned long txbedrop; - unsigned long txbeerr; unsigned long txbkokint; - unsigned long txbkdrop; - unsigned long txbkerr; unsigned long txviokint; - unsigned long txvidrop; - unsigned long txvierr; unsigned long txvookint; - unsigned long txvodrop; - unsigned long txvoerr; unsigned long txbeaconokint; - unsigned long txbeacondrop; unsigned long txbeaconerr; unsigned long txmanageokint; - unsigned long txmanagedrop; - unsigned long txmanageerr; unsigned long txcmdpktokint; - unsigned long txdatapkt; - unsigned long txfeedback; - unsigned long txfeedbackok; - unsigned long txoktotal; - unsigned long txokbytestotal; - unsigned long txokinperiod; - unsigned long txmulticast; unsigned long txbytesmulticast; - unsigned long txbroadcast; unsigned long txbytesbroadcast; - unsigned long txunicast; unsigned long txbytesunicast; unsigned long rxbytesunicast; - unsigned long txfeedbackfail; - unsigned long txerrtotal; - unsigned long txerrbytestotal; - unsigned long txerrmulticast; - unsigned long txerrbroadcast; - unsigned long txerrunicast; unsigned long txretrycount; - unsigned long txfeedbackretry; u8 last_packet_rate; unsigned long slide_signal_strength[100]; unsigned long slide_evm[100]; @@ -426,10 +245,8 @@ struct rt_stats { u8 rx_rssi_percentage[4]; u8 rx_evm_percentage[2]; long rxSNRdB[4]; - struct rt_tx_rahis txrate; u32 Slide_Beacon_pwdb[100]; u32 Slide_Beacon_Total; - struct rt_smooth_data_4rf cck_adc_pwdb; u32 CurrentShowTxate; }; @@ -442,15 +259,6 @@ struct channel_access_setting { u16 CWmaxIndex; }; -enum two_port_status { - TWO_PORT_STATUS__DEFAULT_ONLY, - TWO_PORT_STATUS__EXTENSION_ONLY, - TWO_PORT_STATUS__EXTENSION_FOLLOW_DEFAULT, - TWO_PORT_STATUS__DEFAULT_G_EXTENSION_N20, - TWO_PORT_STATUS__ADHOC, - TWO_PORT_STATUS__WITHOUT_ANY_ASSOCIATE -}; - struct init_gain { u8 xaagccore1; u8 xbagccore1; @@ -531,17 +339,11 @@ struct r8192_priv { struct delayed_work txpower_tracking_wq; struct delayed_work rfpath_check_wq; struct delayed_work gpio_change_rf_wq; - struct delayed_work initialgain_operate_wq; - struct delayed_work check_hw_scan_wq; - struct delayed_work hw_scan_simu_wq; - struct delayed_work start_hw_scan_wq; struct workqueue_struct *priv_wq; struct channel_access_setting ChannelAccessSetting; - struct mp_adapter NdisAdapter; - struct rtl819x_ops *ops; struct rtllib_device *rtllib; @@ -553,7 +355,6 @@ struct r8192_priv { enum rt_rf_type_819xu rf_chip; - enum ic_inferiority_8192s IC_Class; enum ht_channel_width CurrentChannelBW; struct bb_reg_definition PHYRegDef[4]; struct rate_adaptive rate_adaptive; @@ -567,17 +368,11 @@ struct r8192_priv { struct timer_list fsync_timer; struct timer_list gpio_polling_timer; - spinlock_t fw_scan_lock; - spinlock_t irq_lock; spinlock_t irq_th_lock; spinlock_t tx_lock; spinlock_t rf_ps_lock; - spinlock_t rw_lock; - spinlock_t rt_h2c_lock; - spinlock_t rf_lock; spinlock_t ps_lock; - struct sk_buff_head rx_queue; struct sk_buff_head skb_queue; struct tasklet_struct irq_rx_tasklet; @@ -590,12 +385,9 @@ struct r8192_priv { struct rt_stats stats; struct iw_statistics wstats; - struct proc_dir_entry *dir_dev; short (*rf_set_sens)(struct net_device *dev, short sens); u8 (*rf_set_chan)(struct net_device *dev, u8 ch); - void (*rf_close)(struct net_device *dev); - void (*rf_init)(struct net_device *dev); struct rx_desc *rx_ring[MAX_RX_QUEUE]; struct sk_buff *rx_buf[MAX_RX_QUEUE][MAX_RX_COUNT]; @@ -606,29 +398,19 @@ struct r8192_priv { u64 LastRxDescTSF; - u16 EarlyRxThreshold; u32 ReceiveConfig; - u8 AcmControl; - u8 RFProgType; u8 retry_data; u8 retry_rts; u16 rts; struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; int txringcount; - int txbuffsize; - int txfwbuffersize; atomic_t tx_pending[0x10]; u16 ShortRetryLimit; u16 LongRetryLimit; - u32 TransmitConfig; - u8 RegCWinMin; - u8 keepAliveLevel; - bool sw_radio_on; bool bHwRadioOff; - bool pwrdown; bool blinked_ingpio; u8 polling_timer_on; @@ -641,17 +423,11 @@ struct r8192_priv { struct work_struct qos_activate; - u8 bIbssCoordinator; - short promisc; - short crcmon; - - int txbeaconcount; short chan; short sens; short max_sens; - u32 rx_prevlen; u8 ScanDelay; bool ps_force; @@ -662,114 +438,43 @@ struct r8192_priv { enum nic_t card_8192; u8 card_8192_version; - short enable_gpio0; - u8 rf_type; u8 IC_Cut; char nick[IW_ESSID_MAX_SIZE + 1]; - - u8 RegBcnCtrlVal; - bool bHwAntDiv; - - bool bTKIPinNmodeFromReg; - bool bWEPinNmodeFromReg; - - bool bLedOpenDrain; - u8 check_roaming_cnt; - bool bIgnoreSilentReset; - u32 SilentResetRxSoltNum; u32 SilentResetRxSlotIndex; u32 SilentResetRxStuckEvent[MAX_SILENT_RESET_RX_SLOT_NUM]; - void *scan_cmd; - u8 hwscan_bw_40; - - u16 nrxAMPDU_size; - u8 nrxAMPDU_aggr_num; - - u32 last_rxdesc_tsf_high; - u32 last_rxdesc_tsf_low; - u16 basic_rate; u8 short_preamble; u8 dot11CurrentPreambleMode; u8 slot_time; u16 SifsTime; - u8 RegWirelessMode; - - u8 firmware_version; - u16 FirmwareSubVersion; - u16 rf_pathmap; bool AutoloadFailFlag; - u8 RegPciASPM; - u8 RegAMDPciASPM; - u8 RegHwSwRfOffD3; - u8 RegSupportPciASPM; - bool bSupportASPM; - - u32 RfRegChnlVal[2]; - - u8 ShowRateMode; - u8 RATRTableBitmap; - - u8 EfuseMap[2][HWSET_MAX_SIZE_92S]; - u16 EfuseUsedBytes; - u8 EfuseUsedPercentage; - short epromtype; u16 eeprom_vid; u16 eeprom_did; - u16 eeprom_svid; - u16 eeprom_smid; u8 eeprom_CustomerID; u16 eeprom_ChannelPlan; - u8 eeprom_version; - - u8 EEPROMRegulatory; - u8 EEPROMPwrGroup[2][3]; - u8 EEPROMOptional; u8 EEPROMTxPowerLevelCCK[14]; u8 EEPROMTxPowerLevelOFDM24G[14]; - u8 EEPROMTxPowerLevelOFDM5G[24]; u8 EEPROMRfACCKChnl1TxPwLevel[3]; u8 EEPROMRfAOfdmChnlTxPwLevel[3]; u8 EEPROMRfCCCKChnl1TxPwLevel[3]; u8 EEPROMRfCOfdmChnlTxPwLevel[3]; - u16 EEPROMTxPowerDiff; u16 EEPROMAntPwDiff; u8 EEPROMThermalMeter; - u8 EEPROMPwDiff; u8 EEPROMCrystalCap; - u8 EEPROMBluetoothCoexist; - u8 EEPROMBluetoothType; - u8 EEPROMBluetoothAntNum; - u8 EEPROMBluetoothAntIsolation; - u8 EEPROMBluetoothRadioShared; - - - u8 EEPROMSupportWoWLAN; - u8 EEPROMBoardType; - u8 EEPROM_Def_Ver; - u8 EEPROMHT2T_TxPwr[6]; - u8 EEPROMTSSI_A; - u8 EEPROMTSSI_B; - u8 EEPROMTxPowerLevelCCK_V1[3]; u8 EEPROMLegacyHTTxPowerDiff; - u8 BluetoothCoexist; - u8 CrystalCap; u8 ThermalMeter[2]; - u16 FwCmdIOMap; - u32 FwCmdIOParam; - u8 SwChnlInProgress; u8 SwChnlStage; u8 SwChnlStep; @@ -785,60 +490,16 @@ struct r8192_priv { u16 RegChannelPlan; u16 ChannelPlan; - bool bChnlPlanFromHW; bool RegRfOff; bool isRFOff; bool bInPowerSaveMode; u8 bHwRfOffAction; - bool aspm_clkreq_enable; - u32 pci_bridge_vendor; - u8 RegHostPciASPMSetting; - u8 RegDevicePciASPMSetting; - bool RFChangeInProgress; bool SetRFPowerStateInProgress; bool bdisable_nic; - u8 pwrGroupCnt; - - u8 ThermalValue_LCK; - u8 ThermalValue_IQK; - bool bRfPiEnable; - - u32 APKoutput[2][2]; - bool bAPKdone; - - long RegE94; - long RegE9C; - long RegEB4; - long RegEBC; - - u32 RegC04; - u32 Reg874; - u32 RegC08; - u32 ADDA_backup[16]; - u32 IQK_MAC_backup[3]; - - bool SetFwCmdInProgress; - u8 CurrentFwCmdIO; - - u8 rssi_level; - - bool bInformFWDriverControlDM; - u8 PwrGroupHT20[2][14]; - u8 PwrGroupHT40[2][14]; - - u8 ThermalValue; - long EntryMinUndecoratedSmoothedPWDB; - long EntryMaxUndecoratedSmoothedPWDB; - u8 DynamicTxHighPowerLvl; - u8 LastDTPLvl; - u32 CurrentRATR0; - struct false_alarm_stats FalseAlmCnt; - - u8 DMFlag; u8 DM_Type; u8 CckPwEnl; @@ -848,54 +509,32 @@ struct r8192_priv { u8 CCKPresentAttentuation_40Mdefault; char CCKPresentAttentuation_difference; char CCKPresentAttentuation; - u8 bCckHighPower; long undecorated_smoothed_pwdb; - long undecorated_smoothed_cck_adc_pwdb[4]; u32 MCSTxPowerLevelOriginalOffset[6]; - u32 CCKTxPowerLevelOriginalOffset; u8 TxPowerLevelCCK[14]; u8 TxPowerLevelCCK_A[14]; u8 TxPowerLevelCCK_C[14]; u8 TxPowerLevelOFDM24G[14]; - u8 TxPowerLevelOFDM5G[14]; u8 TxPowerLevelOFDM24G_A[14]; u8 TxPowerLevelOFDM24G_C[14]; u8 LegacyHTTxPowerDiff; - u8 TxPowerDiff; s8 RF_C_TxPwDiff; - s8 RF_B_TxPwDiff; - u8 RfTxPwrLevelCck[2][14]; - u8 RfTxPwrLevelOfdm1T[2][14]; - u8 RfTxPwrLevelOfdm2T[2][14]; u8 AntennaTxPwDiff[3]; - u8 TxPwrHt20Diff[2][14]; - u8 TxPwrLegacyHtDiff[2][14]; - u8 TxPwrSafetyFlag; - u8 HT2T_TxPwr_A[14]; - u8 HT2T_TxPwr_B[14]; - u8 CurrentCckTxPwrIdx; - u8 CurrentOfdm24GTxPwrIdx; - - bool bdynamic_txpower; + bool bDynamicTxHighPower; bool bDynamicTxLowPower; bool bLastDTPFlag_High; bool bLastDTPFlag_Low; - bool bstore_last_dtpflag; - bool bstart_txctrl_bydtp; - u8 rfa_txpowertrackingindex; u8 rfa_txpowertrackingindex_real; u8 rfa_txpowertracking_default; u8 rfc_txpowertrackingindex; u8 rfc_txpowertrackingindex_real; - u8 rfc_txpowertracking_default; bool btxpower_tracking; bool bcck_in_ch14; - u8 TxPowerTrackControl; u8 txpower_count; bool btxpower_trackingInit; @@ -911,11 +550,6 @@ struct r8192_priv { bool bcurrent_turbo_EDCA; bool bis_cur_rdlstate; - bool bCCKinCH14; - - u8 MidHighPwrTHR_L1; - u8 MidHighPwrTHR_L2; - bool bfsync_processing; u32 rate_record; u32 rateCountDiffRecord; @@ -925,56 +559,21 @@ struct r8192_priv { u32 framesyncC34; u8 framesyncMonitor; - bool bDMInitialGainEnable; - bool MutualAuthenticationFail; - - bool bDisableFrameBursting; - u32 reset_count; - bool bpbc_pressed; - - u32 txpower_checkcnt; - u32 txpower_tracking_callback_cnt; - u8 thermal_read_val[40]; - u8 thermal_readback_index; - u32 ccktxpower_adjustcnt_not_ch14; - u32 ccktxpower_adjustcnt_ch14; enum reset_type ResetProgress; bool bForcedSilentReset; bool bDisableNormalResetCheck; u16 TxCounter; u16 RxCounter; - int IrpPendingCount; bool bResetInProgress; bool force_reset; bool force_lps; - u8 InitialGainOperateType; bool chan_forced; - bool bSingleCarrier; - bool RegBoard; - bool bCckContTx; - bool bOfdmContTx; - bool bStartContTx; - u8 RegPaModel; - u8 btMpCckTxPower; - u8 btMpOfdmTxPower; - - u32 MptActType; - u32 MptIoOffset; - u32 MptIoValue; - u32 MptRfPath; - - u32 MptBandWidth; - u32 MptRateIndex; - u8 MptChannelToSw; - u32 MptRCR; u8 PwrDomainProtect; u8 H2CTxCmdSeq; - - }; extern const struct ethtool_ops rtl819x_ethtool_ops; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h b/drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h deleted file mode 100644 index ee57c0f4fa69..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Scatterlist Cryptographic API. - * - * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> - * Copyright (c) 2002 David S. Miller (davem@redhat.com) - * - * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> - * and Nettle, by Niels Mé°ˆler. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - */ -#ifndef _LINUX_CRYPTO_H -#define _LINUX_CRYPTO_H - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/string.h> -#include <asm/page.h> -#include <linux/errno.h> - -#define crypto_register_alg crypto_register_alg_rsl -#define crypto_unregister_alg crypto_unregister_alg_rsl -#define crypto_alloc_tfm crypto_alloc_tfm_rsl -#define crypto_free_tfm crypto_free_tfm_rsl -#define crypto_alg_available crypto_alg_available_rsl - -/* - * Algorithm masks and types. - */ -#define CRYPTO_ALG_TYPE_MASK 0x000000ff -#define CRYPTO_ALG_TYPE_CIPHER 0x00000001 -#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 -#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 - -/* - * Transform masks and values (for crt_flags). - */ -#define CRYPTO_TFM_MODE_MASK 0x000000ff -#define CRYPTO_TFM_REQ_MASK 0x000fff00 -#define CRYPTO_TFM_RES_MASK 0xfff00000 - -#define CRYPTO_TFM_MODE_ECB 0x00000001 -#define CRYPTO_TFM_MODE_CBC 0x00000002 -#define CRYPTO_TFM_MODE_CFB 0x00000004 -#define CRYPTO_TFM_MODE_CTR 0x00000008 - -#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 -#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 -#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 -#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 -#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 -#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 - -/* - * Miscellaneous stuff. - */ -#define CRYPTO_UNSPEC 0 -#define CRYPTO_MAX_ALG_NAME 64 - -struct scatterlist; - -/* - * Algorithms: modular crypto algorithm implementations, managed - * via crypto_register_alg() and crypto_unregister_alg(). - */ -struct cipher_alg { - unsigned int cia_min_keysize; - unsigned int cia_max_keysize; - int (*cia_setkey)(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags); - void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); - void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); -}; - -struct digest_alg { - unsigned int dia_digestsize; - void (*dia_init)(void *ctx); - void (*dia_update)(void *ctx, const u8 *data, unsigned int len); - void (*dia_final)(void *ctx, u8 *out); - int (*dia_setkey)(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags); -}; - -struct compress_alg { - int (*coa_init)(void *ctx); - void (*coa_exit)(void *ctx); - int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); - int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); -}; - -#define cra_cipher cra_u.cipher -#define cra_digest cra_u.digest -#define cra_compress cra_u.compress - -struct crypto_alg { - struct list_head cra_list; - u32 cra_flags; - unsigned int cra_blocksize; - unsigned int cra_ctxsize; - const char cra_name[CRYPTO_MAX_ALG_NAME]; - - union { - struct cipher_alg cipher; - struct digest_alg digest; - struct compress_alg compress; - } cra_u; - - struct module *cra_module; -}; - -/* - * Algorithm registration interface. - */ -int crypto_register_alg(struct crypto_alg *alg); -int crypto_unregister_alg(struct crypto_alg *alg); - -/* - * Algorithm query interface. - */ -int crypto_alg_available(const char *name, u32 flags); - -/* - * Transforms: user-instantiated objects which encapsulate algorithms - * and core processing logic. Managed via crypto_alloc_tfm() and - * crypto_free_tfm(), as well as the various helpers below. - */ -struct crypto_tfm; - -struct cipher_tfm { - void *cit_iv; - unsigned int cit_ivsize; - u32 cit_mode; - int (*cit_setkey)(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen); - int (*cit_encrypt)(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes); - int (*cit_encrypt_iv)(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv); - int (*cit_decrypt)(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes); - int (*cit_decrypt_iv)(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv); - void (*cit_xor_block)(u8 *dst, const u8 *src); -}; - -struct digest_tfm { - void (*dit_init)(struct crypto_tfm *tfm); - void (*dit_update)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); - void (*dit_final)(struct crypto_tfm *tfm, u8 *out); - void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, - unsigned int nsg, u8 *out); - int (*dit_setkey)(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen); -}; - -struct compress_tfm { - int (*cot_compress)(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); - int (*cot_decompress)(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); -}; - -#define crt_cipher crt_u.cipher -#define crt_digest crt_u.digest -#define crt_compress crt_u.compress - -struct crypto_tfm { - - u32 crt_flags; - - union { - struct cipher_tfm cipher; - struct digest_tfm digest; - struct compress_tfm compress; - } crt_u; - - struct crypto_alg *__crt_alg; -}; - -/* - * Transform user interface. - */ - -/* - * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. - * If that fails and the kernel supports dynamically loadable modules, it - * will then attempt to load a module of the same name or alias. A refcount - * is grabbed on the algorithm which is then associated with the new transform. - * - * crypto_free_tfm() frees up the transform and any associated resources, - * then drops the refcount on the associated algorithm. - */ -struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); -void crypto_free_tfm(struct crypto_tfm *tfm); - -/* - * Transform helpers which query the underlying algorithm. - */ -static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm) -{ - return tfm->__crt_alg->cra_name; -} - -static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) -{ - struct crypto_alg *alg = tfm->__crt_alg; - - if (alg->cra_module) - return alg->cra_module->name; - else - return NULL; -} - -static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) -{ - return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; -} - -static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->__crt_alg->cra_cipher.cia_min_keysize; -} - -static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->__crt_alg->cra_cipher.cia_max_keysize; -} - -static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_ivsize; -} - -static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) -{ - return tfm->__crt_alg->cra_blocksize; -} - -static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - return tfm->__crt_alg->cra_digest.dia_digestsize; -} - -/* - * API wrappers. - */ -static inline void crypto_digest_init(struct crypto_tfm *tfm) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - tfm->crt_digest.dit_init(tfm); -} - -static inline void crypto_digest_update(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - tfm->crt_digest.dit_update(tfm, sg, nsg); -} - -static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - tfm->crt_digest.dit_final(tfm, out); -} - -static inline void crypto_digest_digest(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg, u8 *out) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - tfm->crt_digest.dit_digest(tfm, sg, nsg, out); -} - -static inline int crypto_digest_setkey(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); - if (tfm->crt_digest.dit_setkey == NULL) - return -ENOSYS; - return tfm->crt_digest.dit_setkey(tfm, key, keylen); -} - -static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_setkey(tfm, key, keylen); -} - -static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); -} - -static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); - return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); -} - -static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); -} - -static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); - return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); -} - -static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, - const u8 *src, unsigned int len) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - memcpy(tfm->crt_cipher.cit_iv, src, len); -} - -static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, - u8 *dst, unsigned int len) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - memcpy(dst, tfm->crt_cipher.cit_iv, len); -} - -static inline int crypto_comp_compress(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); - return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); -} - -static inline int crypto_comp_decompress(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen) -{ - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); - return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); -} - -#endif /* _LINUX_CRYPTO_H */ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index ba69157a86b4..d8696293c6e1 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -248,7 +248,8 @@ void init_hal_dm(struct net_device *dev) if (IS_HARDWARE_TYPE_8192SE(dev)) dm_Init_WA_Broadcom_IOT(dev); - INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, (void *)dm_CheckRfCtrlGPIO, dev); + INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, + (void *)dm_CheckRfCtrlGPIO, dev); } void deinit_hal_dm(struct net_device *dev) @@ -288,8 +289,8 @@ void hal_dm_watchdog(struct net_device *dev) static void dm_check_ac_dc_power(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; - char *argv[] = {ac_dc_check_script_path, DRV_NAME, NULL}; + static char *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; + char *argv[] = {ac_dc_script, DRV_NAME, NULL}; static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", @@ -303,7 +304,7 @@ static void dm_check_ac_dc_power(struct net_device *dev) if (priv->rtllib->state != RTLLIB_LINKED) return; - call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC); + call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC); return; }; @@ -313,7 +314,7 @@ void init_rate_adaptive(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive; + struct rate_adaptive *pra = &priv->rate_adaptive; pra->ratr_state = DM_RATR_STA_MAX; pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; @@ -354,14 +355,15 @@ static void dm_check_rate_adaptive(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; - struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive; + struct rate_adaptive *pra = &priv->rate_adaptive; u32 currentRATR, targetRATR = 0; u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; bool bshort_gi_enabled = false; static u8 ping_rssi_state; if (!priv->up) { - RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); + RT_TRACE(COMP_RATE, + "<---- dm_check_rate_adaptive(): driver is going to unload\n"); return; } @@ -374,44 +376,52 @@ static void dm_check_rate_adaptive(struct net_device *dev) if (priv->rtllib->state == RTLLIB_LINKED) { - bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || - (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); - + bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && + pHTInfo->bCurShortGI40MHz) || + (!pHTInfo->bCurTxBW40MHz && + pHTInfo->bCurShortGI20MHz); pra->upper_rssi_threshold_ratr = - (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + (pra->upper_rssi_threshold_ratr & (~BIT31)) | + ((bshort_gi_enabled) ? BIT31 : 0); pra->middle_rssi_threshold_ratr = - (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + (pra->middle_rssi_threshold_ratr & (~BIT31)) | + ((bshort_gi_enabled) ? BIT31 : 0); if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | + ((bshort_gi_enabled) ? BIT31 : 0); } else { pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | + ((bshort_gi_enabled) ? BIT31 : 0); } pra->ping_rssi_ratr = - (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + (pra->ping_rssi_ratr & (~BIT31)) | + ((bshort_gi_enabled) ? BIT31 : 0); if (pra->ratr_state == DM_RATR_STA_HIGH) { - HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); } else if (pra->ratr_state == DM_RATR_STA_LOW) { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M); } else { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); } - if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) { + if (priv->undecorated_smoothed_pwdb >= + (long)HighRSSIThreshForRA) { pra->ratr_state = DM_RATR_STA_HIGH; targetRATR = pra->upper_rssi_threshold_ratr; - } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) { + } else if (priv->undecorated_smoothed_pwdb >= + (long)LowRSSIThreshForRA) { pra->ratr_state = DM_RATR_STA_MIDDLE; targetRATR = pra->middle_rssi_threshold_ratr; } else { @@ -420,8 +430,10 @@ static void dm_check_rate_adaptive(struct net_device *dev) } if (pra->ping_rssi_enable) { - if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) { - if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || + if (priv->undecorated_smoothed_pwdb < + (long)(pra->ping_rssi_thresh_for_ra+5)) { + if ((priv->undecorated_smoothed_pwdb < + (long)pra->ping_rssi_thresh_for_ra) || ping_rssi_state) { pra->ratr_state = DM_RATR_STA_LOW; targetRATR = pra->ping_rssi_ratr; @@ -722,7 +734,8 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) if (viviflag) { write_nic_byte(dev, Pw_Track_Flag, 0); viviflag = false; - RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); + RT_TRACE(COMP_POWER_TRACKING, + "we filted this data\n"); for (k = 0; k < 5; k++) tmp_report[k] = 0; break; @@ -731,12 +744,13 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) for (k = 0; k < 5; k++) Avg_TSSI_Meas_from_driver += tmp_report[k]; - Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5; + Avg_TSSI_Meas_from_driver *= 100 / 5; RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver); TSSI_13dBm = priv->TSSI_13dBm; - RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm); + RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", + TSSI_13dBm); if (Avg_TSSI_Meas_from_driver > TSSI_13dBm) delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; @@ -815,11 +829,13 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); - if (priv->CCKPresentAttentuation_difference <= -12 || priv->CCKPresentAttentuation_difference >= 24) { + if (priv->CCKPresentAttentuation_difference <= -12 || + priv->CCKPresentAttentuation_difference >= 24) { priv->rtllib->bdynamic_txpower_enable = true; write_nic_byte(dev, Pw_Track_Flag, 0); write_nic_byte(dev, FW_Busy_Flag, 0); - RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); + RT_TRACE(COMP_POWER_TRACKING, + "tx power track--->limited\n"); return; } @@ -844,12 +860,15 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev) int i = 0, CCKSwingNeedUpdate = 0; if (!priv->btxpower_trackingInit) { - tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); + tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord); for (i = 0; i < OFDM_Table_Length; i++) { if (tmpRegA == OFDMSwingTable[i]) { priv->OFDM_index[0] = (u8)i; - RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n", - rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index[0]); + RT_TRACE(COMP_POWER_TRACKING, + "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n", + rOFDM0_XATxIQImbalance, tmpRegA, + priv->OFDM_index[0]); } } @@ -997,7 +1016,8 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) if (tx_power_track_counter >= 180) { - queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0); + queue_delayed_work_rsl(priv->priv_wq, + &priv->txpower_tracking_wq, 0); tx_power_track_counter = 0; } @@ -1084,53 +1104,57 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) } } -static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) +static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, + bool bInCH14) { u32 TempVal; struct r8192_priv *priv = rtllib_priv(dev); TempVal = 0; if (!bInCH14) { - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8); + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1] << 8); rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter1, TempVal); - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); + RT_TRACE(COMP_POWER_TRACKING, + "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, + TempVal); + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3] << 8) + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4] << 16)+ + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5] << 24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter2, TempVal); - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8); + RT_TRACE(COMP_POWER_TRACKING, + "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, + TempVal); + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7] << 8); rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_DebugPort, TempVal); + RT_TRACE(COMP_POWER_TRACKING, + "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort, + TempVal); } else { - TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + - (CCKSwingTable_Ch14[priv->CCK_index][1]<<8); + TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + + (CCKSwingTable_Ch14[priv->CCK_index][1] << 8); rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); - TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + - (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ - (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); + TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + + (CCKSwingTable_Ch14[priv->CCK_index][3] << 8) + + (CCKSwingTable_Ch14[priv->CCK_index][4] << 16)+ + (CCKSwingTable_Ch14[priv->CCK_index][5] << 24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); - TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + - (CCKSwingTable_Ch14[priv->CCK_index][7]<<8); + TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8); rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort, TempVal); } - } +} void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) { @@ -1181,7 +1205,8 @@ void dm_restore_dynamic_mechanism_state(struct net_device *dev) u32 ratr_value; if (!priv->up) { - RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); + RT_TRACE(COMP_RATE, + "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); return; } @@ -1211,18 +1236,28 @@ static void dm_bb_initialgain_restore(struct net_device *dev) return; rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); - rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1); + rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, + (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, + (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, + (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, + (u32)priv->initgain_backup.xdagccore1); bit_mask = bMaskByte2; - rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); - - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca); + rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, + (u32)priv->initgain_backup.cca); + + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", + priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", + priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", + priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", + priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", + priv->initgain_backup.cca); rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); } @@ -1255,58 +1290,17 @@ static void dm_bb_initialgain_backup(struct net_device *dev) bit_mask = bMaskByte2; priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca); - -} + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", + priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", + priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", + priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", + priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", + priv->initgain_backup.cca); -void dm_change_dynamic_initgain_thresh(struct net_device *dev, - u32 dm_type, u32 dm_value) -{ - if (dm_type == DIG_TYPE_THRESH_HIGH) { - dm_digtable.rssi_high_thresh = dm_value; - } else if (dm_type == DIG_TYPE_THRESH_LOW) { - dm_digtable.rssi_low_thresh = dm_value; - } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { - dm_digtable.rssi_high_power_highthresh = dm_value; - } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) { - dm_digtable.rssi_high_power_lowthresh = dm_value; - } else if (dm_type == DIG_TYPE_ENABLE) { - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_enable_flag = true; - } else if (dm_type == DIG_TYPE_DISABLE) { - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_enable_flag = false; - } else if (dm_type == DIG_TYPE_DBG_MODE) { - if (dm_value >= DM_DBG_MAX) - dm_value = DM_DBG_OFF; - dm_digtable.dbg_mode = (u8)dm_value; - } else if (dm_type == DIG_TYPE_RSSI) { - if (dm_value > 100) - dm_value = 30; - dm_digtable.rssi_val = (long)dm_value; - } else if (dm_type == DIG_TYPE_ALGORITHM) { - if (dm_value >= DIG_ALGO_MAX) - dm_value = DIG_ALGO_BY_FALSE_ALARM; - if (dm_digtable.dig_algorithm != (u8)dm_value) - dm_digtable.dig_algorithm_switch = 1; - dm_digtable.dig_algorithm = (u8)dm_value; - } else if (dm_type == DIG_TYPE_BACKOFF) { - if (dm_value > 30) - dm_value = 30; - dm_digtable.backoff_val = (u8)dm_value; - } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) { - if (dm_value == 0) - dm_value = 0x1; - dm_digtable.rx_gain_range_min = (u8)dm_value; - } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) { - if (dm_value > 0x50) - dm_value = 0x50; - dm_digtable.rx_gain_range_max = (u8)dm_value; - } } static void dm_dig_init(struct net_device *dev) @@ -1314,27 +1308,20 @@ static void dm_dig_init(struct net_device *dev) struct r8192_priv *priv = rtllib_priv(dev); dm_digtable.dig_enable_flag = true; - dm_digtable.Backoff_Enable_Flag = true; dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; - dm_digtable.Dig_TwoPort_Algorithm = DIG_TWO_PORT_ALGO_RSSI; - dm_digtable.Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX; dm_digtable.dbg_mode = DM_DBG_OFF; dm_digtable.dig_algorithm_switch = 0; dm_digtable.dig_state = DM_STA_DIG_MAX; dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.CurSTAConnectState = dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT; - dm_digtable.CurAPConnectState = dm_digtable.PreAPConnectState = DIG_AP_DISCONNECT; - dm_digtable.initialgain_lowerbound_state = false; + dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; + dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT; dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; - dm_digtable.FALowThresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable.FAHighThresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; @@ -1345,9 +1332,6 @@ static void dm_dig_init(struct net_device *dev) dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; else dm_digtable.rx_gain_range_min = DM_DIG_MIN; - - dm_digtable.BackoffVal_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable.BackoffVal_range_min = DM_DIG_BACKOFF_MIN; } static void dm_ctrl_initgain_byrssi(struct net_device *dev) @@ -1512,11 +1496,14 @@ static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev) struct r8192_priv *priv = rtllib_priv(dev); static u32 reset_cnt_highpwr; - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) + if ((priv->undecorated_smoothed_pwdb > + dm_digtable.rssi_high_power_lowthresh) && + (priv->undecorated_smoothed_pwdb < + dm_digtable.rssi_high_power_highthresh)) return; - if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { + if (priv->undecorated_smoothed_pwdb >= + dm_digtable.rssi_high_power_highthresh) { if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && (priv->reset_count == reset_cnt_highpwr)) return; @@ -1532,8 +1519,10 @@ static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev) return; dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; - if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && - priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { + if ((priv->undecorated_smoothed_pwdb < + dm_digtable.rssi_high_power_lowthresh) && + (priv->undecorated_smoothed_pwdb >= + dm_digtable.rssi_high_thresh)) { if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); else @@ -1562,12 +1551,12 @@ static void dm_initial_gain(struct net_device *dev) if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { - if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max) - dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max; - else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; + long gain_range = dm_digtable.rssi_val + 10 - + dm_digtable.backoff_val; + gain_range = clamp_t(long, gain_range, + dm_digtable.rx_gain_range_min, + dm_digtable.rx_gain_range_max); + dm_digtable.cur_ig_value = gain_range; } else { if (dm_digtable.cur_ig_value == 0) dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; @@ -1613,15 +1602,23 @@ static void dm_pd_th(struct net_device *dev) if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { - if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) - dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; - else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && - (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) - dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; + if (dm_digtable.rssi_val >= + dm_digtable.rssi_high_power_highthresh) + dm_digtable.curpd_thstate = + DIG_PD_AT_HIGH_POWER; + else if (dm_digtable.rssi_val <= + dm_digtable.rssi_low_thresh) + dm_digtable.curpd_thstate = + DIG_PD_AT_LOW_POWER; + else if ((dm_digtable.rssi_val >= + dm_digtable.rssi_high_thresh) && + (dm_digtable.rssi_val < + dm_digtable.rssi_high_power_lowthresh)) + dm_digtable.curpd_thstate = + DIG_PD_AT_NORMAL_POWER; else - dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; + dm_digtable.curpd_thstate = + dm_digtable.prepd_thstate; } else { dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; } @@ -1641,7 +1638,8 @@ static void dm_pd_th(struct net_device *dev) write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); else write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); - } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) { + } else if (dm_digtable.curpd_thstate == + DIG_PD_AT_NORMAL_POWER) { if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); else @@ -1760,10 +1758,12 @@ static void dm_check_edca_turbo(struct net_device *dev) if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { if (priv->rtllib->mode == WIRELESS_MODE_G) - write_nic_dword(dev, EDCAPARA_BE, + write_nic_dword(dev, + EDCAPARA_BE, edca_setting_DL_GMode[pHTInfo->IOTPeer]); else - write_nic_dword(dev, EDCAPARA_BE, + write_nic_dword(dev, + EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); priv->bis_cur_rdlstate = true; } @@ -1771,12 +1771,15 @@ static void dm_check_edca_turbo(struct net_device *dev) priv->bcurrent_turbo_EDCA = true; } else { if (curRxOkCnt > 4*curTxOkCnt) { - if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { + if (!priv->bis_cur_rdlstate || + !priv->bcurrent_turbo_EDCA) { if (priv->rtllib->mode == WIRELESS_MODE_G) - write_nic_dword(dev, EDCAPARA_BE, + write_nic_dword(dev, + EDCAPARA_BE, edca_setting_DL_GMode[pHTInfo->IOTPeer]); else - write_nic_dword(dev, EDCAPARA_BE, + write_nic_dword(dev, + EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); priv->bis_cur_rdlstate = true; } @@ -1796,7 +1799,8 @@ static void dm_check_edca_turbo(struct net_device *dev) if (priv->bcurrent_turbo_EDCA) { u8 tmp = AC0_BE; - priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&tmp)); + priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, + (u8 *)(&tmp)); priv->bcurrent_turbo_EDCA = false; } } @@ -1866,7 +1870,8 @@ void dm_CheckRfCtrlGPIO(void *data) bool bActuallySet = false; char *argv[3]; static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; - static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; + static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", + NULL}; bActuallySet = false; @@ -1897,7 +1902,8 @@ void dm_CheckRfCtrlGPIO(void *data) if (bActuallySet) { mdelay(1000); priv->bHwRfOffAction = 1; - MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true); + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, + true); if (priv->bHwRadioOff) argv[1] = "RFOFF"; else @@ -2501,28 +2507,6 @@ void dm_check_fsync(struct net_device *dev) } } -void dm_shadow_init(struct net_device *dev) -{ - u8 page; - u16 offset; - - for (page = 0; page < 5; page++) - for (offset = 0; offset < 256; offset++) - dm_shadow[page][offset] = read_nic_byte(dev, - offset+page * 256); - - for (page = 8; page < 11; page++) - for (offset = 0; offset < 256; offset++) - dm_shadow[page][offset] = read_nic_byte(dev, - offset+page * 256); - - for (page = 12; page < 15; page++) - for (offset = 0; offset < 256; offset++) - dm_shadow[page][offset] = read_nic_byte(dev, - offset+page*256); - -} - /*---------------------------Define function prototype------------------------*/ static void dm_init_dynamic_txpower(struct net_device *dev) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h index 6be8e8bd640a..b0d936703515 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h @@ -87,17 +87,12 @@ struct dig_t { u8 dig_enable_flag; u8 dig_algorithm; - u8 Dig_TwoPort_Algorithm; - u8 Dig_Ext_Port_Stage; u8 dbg_mode; u8 dig_algorithm_switch; long rssi_low_thresh; long rssi_high_thresh; - u32 FALowThresh; - u32 FAHighThresh; - long rssi_high_power_lowthresh; long rssi_high_power_highthresh; @@ -105,8 +100,6 @@ struct dig_t { u8 dig_highpwr_state; u8 CurSTAConnectState; u8 PreSTAConnectState; - u8 CurAPConnectState; - u8 PreAPConnectState; u8 curpd_thstate; u8 prepd_thstate; @@ -116,13 +109,9 @@ struct dig_t { u32 pre_ig_value; u32 cur_ig_value; - u8 Backoff_Enable_Flag; u8 backoff_val; - char BackoffVal_range_max; - char BackoffVal_range_min; u8 rx_gain_range_max; u8 rx_gain_range_min; - bool initialgain_lowerbound_state; long rssi_val; }; @@ -166,26 +155,6 @@ enum dm_dig_alg { DIG_ALGO_MAX }; -enum dm_dig_two_port_alg { - DIG_TWO_PORT_ALGO_RSSI = 0, - DIG_TWO_PORT_ALGO_FALSE_ALARM = 1, -}; - - -enum dm_dig_ext_port_alg { - DIG_EXT_PORT_STAGE_0 = 0, - DIG_EXT_PORT_STAGE_1 = 1, - DIG_EXT_PORT_STAGE_2 = 2, - DIG_EXT_PORT_STAGE_3 = 3, - DIG_EXT_PORT_STAGE_MAX = 4, -}; - -enum dm_dig_dbg { - DIG_DBG_OFF = 0, - DIG_DBG_ON = 1, - DIG_DBG_MAX -}; - enum dm_dig_connect { DIG_STA_DISCONNECT = 0, DIG_STA_CONNECT = 1, @@ -251,8 +220,6 @@ extern struct dig_t dm_digtable; extern u8 dm_shadow[16][256]; extern struct drx_path_sel DM_RxPathSelTable; -extern u8 test_flag; - /* Pre-calculated gain tables */ extern const u32 dm_tx_bb_gain[TxBBGainTableLength]; extern const u8 dm_cck_tx_bb_gain[CCKTxBBGainTableLength][8]; @@ -279,47 +246,10 @@ extern void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); -extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, - u32 dm_type, - u32 dm_value); -extern void DM_ChangeFsyncSetting(struct net_device *dev, - s32 DM_Type, - s32 DM_Value); -extern void dm_force_tx_fw_info(struct net_device *dev, - u32 force_type, - u32 force_value); extern void dm_init_edca_turbo(struct net_device *dev); -extern void dm_rf_operation_test_callback(unsigned long data); extern void dm_rf_pathcheck_workitemcallback(void *data); extern void dm_fsync_timer_callback(unsigned long data); extern void dm_check_fsync(struct net_device *dev); -extern void dm_shadow_init(struct net_device *dev); extern void dm_initialize_txpower_tracking(struct net_device *dev); extern void dm_CheckRfCtrlGPIO(void *data); -extern void dm_InitRateAdaptiveMask(struct net_device *dev); -extern void init_hal_dm(struct net_device *dev); -extern void deinit_hal_dm(struct net_device *dev); -extern void hal_dm_watchdog(struct net_device *dev); -extern void init_rate_adaptive(struct net_device *dev); -extern void dm_txpower_trackingcallback(void *data); -extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); -extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); -extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, - u32 dm_type, - u32 dm_value); -extern void DM_ChangeFsyncSetting(struct net_device *dev, - s32 DM_Type, - s32 DM_Value); -extern void dm_force_tx_fw_info(struct net_device *dev, - u32 force_type, - u32 force_value); -extern void dm_init_edca_turbo(struct net_device *dev); -extern void dm_rf_operation_test_callback(unsigned long data); -extern void dm_rf_pathcheck_workitemcallback(void *data); -extern void dm_fsync_timer_callback(unsigned long data); -extern void dm_check_fsync(struct net_device *dev); -extern void dm_shadow_init(struct net_device *dev); -extern void dm_initialize_txpower_tracking(struct net_device *dev); -extern void dm_CheckRfCtrlGPIO(void *data); - #endif /*__R8192UDM_H__ */ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c index e8065c0ed05f..6bbd1c626e24 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c @@ -34,10 +34,8 @@ static void rtl8192_parse_pci_configuration(struct pci_dev *pdev, u16 LinkCtrlReg; pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &LinkCtrlReg); - priv->NdisAdapter.LinkCtrlReg = (u8)LinkCtrlReg; - RT_TRACE(COMP_INIT, "Link Control Register =%x\n", - priv->NdisAdapter.LinkCtrlReg); + RT_TRACE(COMP_INIT, "Link Control Register =%x\n", LinkCtrlReg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT4; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h index 4b94653c50d9..e8d5527a5f04 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h @@ -28,23 +28,6 @@ #include <linux/types.h> #include <linux/pci.h> -struct mp_adapter { - u8 LinkCtrlReg; - - u8 BusNumber; - u8 DevNumber; - u8 FuncNumber; - - u8 PciBridgeBusNum; - u8 PciBridgeDevNum; - u8 PciBridgeFuncNum; - u8 PciBridgeVendor; - u16 PciBridgeVendorId; - u16 PciBridgeDeviceId; - u8 PciBridgePCIeHdrOffset; - u8 PciBridgeLinkCtrlReg; -}; - struct net_device; bool rtl8192_pci_findadapter(struct pci_dev *pdev, struct net_device *dev); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c index ca6ecfc8299e..e4908672421c 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c @@ -57,10 +57,8 @@ int rtl8192E_suspend(struct pci_dev *pdev, pm_message_t state) write_nic_byte(dev, MacBlkCtrl, 0xa); } out_pci_suspend: - netdev_info(dev, "r8192E support WOL call??????????????????????\n"); - if (priv->rtllib->bSupportRemoteWakeUp) - RT_TRACE(COMP_POWER, - "r8192E support WOL call!!!!!!!!!!!!!!!!!!.\n"); + netdev_info(dev, "WOL is %s\n", priv->rtllib->bSupportRemoteWakeUp ? + "Supported" : "Not supported"); pci_save_state(pdev); pci_disable_device(pdev); pci_enable_wake(pdev, pci_choose_state(pdev, state), diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 0bbffec0c2ae..404cb83153d9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -28,6 +28,7 @@ #include "r8192E_phyreg.h" #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ #include "r8192E_cmdpkt.h" +#include <linux/jiffies.h> static void rtl8192_hw_sleep_down(struct net_device *dev) { @@ -93,19 +94,21 @@ void rtl8192_hw_to_sleep(struct net_device *dev, u64 time) u32 tmp; unsigned long flags; + unsigned long timeout; spin_lock_irqsave(&priv->ps_lock, flags); time -= msecs_to_jiffies(8 + 16 + 7); - if ((time - jiffies) <= msecs_to_jiffies(MIN_SLEEP_TIME)) { + timeout = jiffies + msecs_to_jiffies(MIN_SLEEP_TIME); + if (time_before((unsigned long)time, timeout)) { spin_unlock_irqrestore(&priv->ps_lock, flags); netdev_info(dev, "too short to sleep::%lld < %ld\n", time - jiffies, msecs_to_jiffies(MIN_SLEEP_TIME)); return; } - - if ((time - jiffies) > msecs_to_jiffies(MAX_SLEEP_TIME)) { + timeout = jiffies + msecs_to_jiffies(MAX_SLEEP_TIME); + if (time_after((unsigned long)time, timeout)) { netdev_info(dev, "========>too long to sleep:%lld > %ld\n", time - jiffies, msecs_to_jiffies(MAX_SLEEP_TIME)); spin_unlock_irqrestore(&priv->ps_lock, flags); @@ -199,8 +202,8 @@ void rtllib_ips_leave_wq(struct net_device *dev) if (priv->rtllib->PowerSaveControl.bInactivePs) { if (rtState == eRfOff) { if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", - __func__); + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); return; } netdev_info(dev, "=========>%s(): IPSLeave\n", diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 8d6a109e023b..f5e4961677d2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -116,9 +116,8 @@ static int r8192_wx_set_power(struct net_device *dev, struct r8192_priv *priv = rtllib_priv(dev); if (priv->bHwRadioOff) { - RT_TRACE(COMP_ERR, - "%s():Hw is Radio Off, we can't set Power,return\n", - __func__); + netdev_warn(dev, "%s(): Can't set Power: Radio is Off.\n", + __func__); return 0; } down(&priv->wx_sem); @@ -175,48 +174,6 @@ static int r8192_wx_force_reset(struct net_device *dev, } -static int r8192_wx_force_mic_error(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - down(&priv->wx_sem); - - RT_TRACE(COMP_DBG, "%s(): force mic error !\n", __func__); - ieee->force_mic_error = true; - up(&priv->wx_sem); - return 0; - -} - -#define MAX_ADHOC_PEER_NUM 64 -struct adhoc_peer_entry { - unsigned char MacAddr[ETH_ALEN]; - unsigned char WirelessMode; - unsigned char bCurTxBW40MHz; -}; -struct adhoc_peers_info { - struct adhoc_peer_entry Entry[MAX_ADHOC_PEER_NUM]; - unsigned char num; -}; - -static int r8192_wx_get_adhoc_peers(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - return 0; -} - - -static int r8191se_wx_get_firm_version(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrqu, char *extra) -{ - return 0; -} - static int r8192_wx_adapter_power_status(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -247,28 +204,6 @@ static int r8192_wx_adapter_power_status(struct net_device *dev, return 0; } -static int r8192se_wx_set_radio(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - down(&priv->wx_sem); - - netdev_info(dev, "%s(): set radio ! extra is %d\n", __func__, *extra); - if ((*extra != 0) && (*extra != 1)) { - RT_TRACE(COMP_ERR, - "%s(): set radio an err value,must 0(radio off) or 1(radio on)\n", - __func__); - up(&priv->wx_sem); - return -1; - } - priv->sw_radio_on = *extra; - up(&priv->wx_sem); - return 0; - -} - static int r8192se_wx_set_lps_awake_interval(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -342,8 +277,8 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, if (rtState == eRfOff) { if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", - __func__); + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); up(&priv->wx_sem); return -1; } @@ -502,9 +437,8 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, if (rtState == eRfOff) { if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { - RT_TRACE(COMP_ERR, - "%s(): RF is OFF.\n", - __func__); + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); up(&priv->wx_sem); return -1; } @@ -613,7 +547,8 @@ static int r8192_wx_set_nick(struct net_device *dev, if (wrqu->data.length > IW_ESSID_MAX_SIZE) return -E2BIG; down(&priv->wx_sem); - wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick)); + wrqu->data.length = min_t(size_t, wrqu->data.length, + sizeof(priv->nick)); memset(priv->nick, 0, sizeof(priv->nick)); memcpy(priv->nick, extra, wrqu->data.length); up(&priv->wx_sem); @@ -987,8 +922,8 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra); { - u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 zero[6] = {0}; + const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const u8 zero[ETH_ALEN] = {0}; u32 key[4] = {0}; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; struct iw_point *encoding = &wrqu->encoding; @@ -1239,21 +1174,10 @@ static const struct iw_priv_args r8192_private_args[] = { SIOCIWFIRSTPRIV + 0x3, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" }, { - SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_mic_error" - }, { - SIOCIWFIRSTPRIV + 0x5, - IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1, - "firm_ver" - }, { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, "set_power" }, { - SIOCIWFIRSTPRIV + 0x9, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, - "radio" - }, { SIOCIWFIRSTPRIV + 0xa, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, "lps_interv" @@ -1262,9 +1186,6 @@ static const struct iw_priv_args r8192_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, "lps_force" }, { - SIOCIWFIRSTPRIV + 0xc, - 0, IW_PRIV_TYPE_CHAR|2047, "adhoc_peer_list" - }, { SIOCIWFIRSTPRIV + 0x16, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc" }, { @@ -1279,15 +1200,15 @@ static iw_handler r8192_private_handler[] = { (iw_handler)r8192_wx_set_scan_type, (iw_handler)r8192_wx_set_rawtx, (iw_handler)r8192_wx_force_reset, - (iw_handler)r8192_wx_force_mic_error, - (iw_handler)r8191se_wx_get_firm_version, + (iw_handler)NULL, + (iw_handler)NULL, (iw_handler)r8192_wx_adapter_power_status, (iw_handler)NULL, (iw_handler)NULL, - (iw_handler)r8192se_wx_set_radio, + (iw_handler)NULL, (iw_handler)r8192se_wx_set_lps_awake_interval, (iw_handler)r8192se_wx_set_force_lps, - (iw_handler)r8192_wx_get_adhoc_peers, + (iw_handler)NULL, (iw_handler)NULL, (iw_handler)NULL, (iw_handler)NULL, diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h index 58398517f5b3..771284019e08 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h @@ -20,11 +20,7 @@ #ifndef R819x_WX_H #define R819x_WX_H -struct net_device; struct iw_handler_def; -struct iw_statistics; extern const struct iw_handler_def r8192_wx_handlers_def; -u16 rtl8192_11n_user_show_rates(struct net_device *dev); - #endif diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 26258ea8de4a..60f536c295ab 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -18,6 +18,7 @@ ******************************************************************************/ #include <asm/byteorder.h> #include <asm/unaligned.h> +#include <linux/etherdevice.h> #include "rtllib.h" #include "rtl819x_BA.h" @@ -83,18 +84,16 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, u8 *tag = NULL; u16 len = ieee->tx_headroom + 9; - RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, - "========>%s(), frame(%d) sentd to: %pM, ieee->dev:%p\n", - __func__, type, Dst, ieee->dev); + netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n", + __func__, type, Dst, ieee->dev); + if (pBA == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA is NULL\n"); + netdev_warn(ieee->dev, "pBA is NULL\n"); return NULL; } skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); - if (skb == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + if (skb == NULL) return NULL; - } memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); @@ -103,10 +102,10 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, BAReq = (struct rtllib_hdr_3addr *)skb_put(skb, sizeof(struct rtllib_hdr_3addr)); - memcpy(BAReq->addr1, Dst, ETH_ALEN); - memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); + ether_addr_copy(BAReq->addr1, Dst); + ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr); - memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(BAReq->addr3, ieee->current_network.bssid); BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); tag = (u8 *)skb_put(skb, 9); @@ -132,7 +131,10 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, tag += 2; } - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("rtllib_ADDBA(): ", DUMP_PREFIX_NONE, skb->data, + skb->len); +#endif return skb; } @@ -147,9 +149,8 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) - RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, - "========>%s(), ReasonCode(%d) sentd to: %pM\n", - __func__, ReasonCode, dst); + netdev_dbg(ieee->dev, "%s(): ReasonCode(%d) sentd to: %pM\n", + __func__, ReasonCode, dst); memset(&DelbaParamSet, 0, 2); @@ -157,19 +158,17 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); - if (skb == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + if (skb == NULL) return NULL; - } skb_reserve(skb, ieee->tx_headroom); Delba = (struct rtllib_hdr_3addr *) skb_put(skb, sizeof(struct rtllib_hdr_3addr)); - memcpy(Delba->addr1, dst, ETH_ALEN); - memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(Delba->addr1, dst); + ether_addr_copy(Delba->addr2, ieee->dev->dev_addr); + ether_addr_copy(Delba->addr3, ieee->current_network.bssid); Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); tag = (u8 *)skb_put(skb, 6); @@ -184,10 +183,10 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, put_unaligned_le16(ReasonCode, tag); tag += 2; - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); - if (net_ratelimit()) - RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", - __func__); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("rtllib_DELBA(): ", DUMP_PREFIX_NONE, skb->data, + skb->len); +#endif return skb; } @@ -202,8 +201,7 @@ static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, RT_TRACE(COMP_DBG, "====>to send ADDBAREQ!!!!!\n"); softmac_mgmt_xmit(skb, ieee); } else { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "alloc skb error in function %s()\n", __func__); + netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n"); } } @@ -216,8 +214,7 @@ static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, if (skb) softmac_mgmt_xmit(skb, ieee); else - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "alloc skb error in function %s()\n", __func__); + netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n"); } static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, @@ -230,8 +227,7 @@ static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, if (skb) softmac_mgmt_xmit(skb, ieee); else - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "alloc skb error in function %s()\n", __func__); + netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n"); } int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) @@ -246,14 +242,16 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) struct rx_ts_record *pTS = NULL; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - " Invalid skb len in BAREQ(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n", + (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 9)); return -1; } - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("rtllib_rx_ADDBAReq(): ", DUMP_PREFIX_NONE, + skb->data, skb->len); +#endif req = (struct rtllib_hdr_3addr *) skb->data; tag = (u8 *)req; @@ -269,24 +267,24 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) (ieee->pHTInfo->bCurrentHTSupport == false) || (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) { rc = ADDBA_STATUS_REFUSED; - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", - ieee->current_network.qos_data.active, - ieee->pHTInfo->bCurrentHTSupport); + netdev_warn(ieee->dev, + "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", + ieee->current_network.qos_data.active, + ieee->pHTInfo->bCurrentHTSupport); goto OnADDBAReq_Fail; } if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, (u8)(pBaParamSet->field.TID), RX_DIR, true)) { rc = ADDBA_STATUS_REFUSED; - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); + netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); goto OnADDBAReq_Fail; } pBA = &pTS->RxAdmittedBARecord; if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { rc = ADDBA_STATUS_INVALID_PARAM; - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "BA Policy is not correct in %s()\n", __func__); + netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n", + __func__); goto OnADDBAReq_Fail; } @@ -333,10 +331,9 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) u16 ReasonCode; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "Invalid skb len in BARSP(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n", + (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 9)); return -1; } rsp = (struct rtllib_hdr_3addr *)skb->data; @@ -352,11 +349,11 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) if (ieee->current_network.qos_data.active == 0 || ieee->pHTInfo->bCurrentHTSupport == false || ieee->pHTInfo->bCurrentAMPDUEnable == false) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", - ieee->current_network.qos_data.active, - ieee->pHTInfo->bCurrentHTSupport, - ieee->pHTInfo->bCurrentAMPDUEnable); + netdev_warn(ieee->dev, + "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", + ieee->current_network.qos_data.active, + ieee->pHTInfo->bCurrentHTSupport, + ieee->pHTInfo->bCurrentAMPDUEnable); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } @@ -364,7 +361,7 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, (u8)(pBaParamSet->field.TID), TX_DIR, false)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); + netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } @@ -375,19 +372,20 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) if (pAdmittedBA->bValid == true) { - RTLLIB_DEBUG(RTLLIB_DL_BA, - "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it!\n"); + netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n", + __func__); return -1; } else if ((pPendingBA->bValid == false) || (*pDialogToken != pPendingBA->DialogToken)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA!\n"); + netdev_warn(ieee->dev, + "%s(): ADDBA Rsp. BA invalid, DELBA!\n", + __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } else { - RTLLIB_DEBUG(RTLLIB_DL_BA, - "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", - *pStatusCode); + netdev_dbg(ieee->dev, + "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", + __func__, *pStatusCode); DeActivateBAEntry(ieee, pPendingBA); } @@ -434,23 +432,25 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) u8 *dst = NULL; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "Invalid skb len in DELBA(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 6)); + netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n", + (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 6)); return -1; } if (ieee->current_network.qos_data.active == 0 || ieee->pHTInfo->bCurrentHTSupport == false) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "received DELBA while QOS or HT is not supported(%d, %d)\n", - ieee->current_network. qos_data.active, - ieee->pHTInfo->bCurrentHTSupport); + netdev_warn(ieee->dev, + "received DELBA while QOS or HT is not supported(%d, %d)\n", + ieee->current_network. qos_data.active, + ieee->pHTInfo->bCurrentHTSupport); return -1; } - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("rtllib_rx_DELBA(): ", DUMP_PREFIX_NONE, skb->data, + skb->len); +#endif delba = (struct rtllib_hdr_3addr *)skb->data; dst = (u8 *)(&delba->addr2[0]); delba += sizeof(struct rtllib_hdr_3addr); @@ -462,10 +462,10 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, (u8)pDelBaParamSet->field.TID, RX_DIR, false)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "can't get TS for RXTS in %s().dst: %pM TID:%d\n", - __func__, dst, - (u8)pDelBaParamSet->field.TID); + netdev_warn(ieee->dev, + "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", + __func__, dst, + (u8)pDelBaParamSet->field.TID); return -1; } @@ -475,9 +475,8 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, (u8)pDelBaParamSet->field.TID, TX_DIR, false)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "can't get TS for TXTS in %s()\n", - __func__); + netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n", + __func__); return -1; } diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 7f103114d5d2..dcf8db1a7d29 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -217,8 +217,7 @@ static void HTIOTPeerDetermine(struct rtllib_device *ieee) else pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; - RTLLIB_DEBUG(RTLLIB_DL_IOT, "Joseph debug!! IOTPEER: %x\n", - pHTInfo->IOTPeer); + netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer); } static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) @@ -237,7 +236,8 @@ static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) return false; } -static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, u8 *PeerMacAddr) +static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, + u8 *PeerMacAddr) { return false; } @@ -291,8 +291,8 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, struct ht_capab_ele *pCapELE = NULL; if ((posHTCap == NULL) || (pHT == NULL)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n"); + netdev_warn(ieee->dev, + "%s(): posHTCap and pHTInfo are null\n", __func__); return; } memset(posHTCap, 0, *len); @@ -328,9 +328,9 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, pCapELE->LSigTxopProtect = 0; - RTLLIB_DEBUG(RTLLIB_DL_HT, - "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", - pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); + netdev_dbg(ieee->dev, + "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", + pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); if (IsEncrypt) { pCapELE->MPDUDensity = 7; @@ -373,8 +373,9 @@ void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n"); + netdev_warn(ieee->dev, + "%s(): posHTInfo and pHTInfoEle are null\n", + __func__); return; } @@ -413,8 +414,7 @@ void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, u8 *len) { if (posRT2RTAgg == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n"); + netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__); return; } memset(posRT2RTAgg, 0, *len); @@ -437,8 +437,7 @@ static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) u8 i; if (pOperateMCS == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "pOperateMCS can't be null in HT_PickMCSRate()\n"); + netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__); return false; } @@ -472,8 +471,9 @@ u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, u8 availableMcsRate[16]; if (pMCSRateSet == NULL || pMCSFilter == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n"); + netdev_warn(ieee->dev, + "%s(): pMCSRateSet and pMCSFilter are null\n", + __func__); return false; } for (i = 0; i < 16; i++) @@ -538,11 +538,10 @@ void HTOnAssocRsp(struct rtllib_device *ieee) static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; if (pHTInfo->bCurrentHTSupport == false) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "<=== HTOnAssocRsp(): HT_DISABLE\n"); + netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); return; } - RTLLIB_DEBUG(RTLLIB_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); + netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); @@ -555,8 +554,11 @@ void HTOnAssocRsp(struct rtllib_device *ieee) else pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA | RTLLIB_DL_HT, pPeerHTCap, - sizeof(struct ht_capab_ele)); + +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("HTOnAssocRsp(): ", DUMP_PREFIX_NONE, + pPeerHTCap, sizeof(struct ht_capab_ele)); +#endif HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? @@ -647,7 +649,7 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; - RTLLIB_DEBUG(RTLLIB_DL_HT, "===========>%s()\n", __func__); + netdev_vdbg(ieee->dev, "%s()\n", __func__); pHTInfo->bCurrentHTSupport = false; pHTInfo->bCurBW40MHz = false; @@ -717,7 +719,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; u8 bIOTAction = 0; - RTLLIB_DEBUG(RTLLIB_DL_HT, "==============>%s()\n", __func__); + netdev_vdbg(ieee->dev, "%s()\n", __func__); /* unmark bEnableHT flag here is the same reason why unmarked in * function rtllib_softmac_new_net. WB 2008.09.10 */ @@ -841,8 +843,7 @@ u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) { if (ieee->pHTInfo->bCurrentHTSupport) { if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { - RTLLIB_DEBUG(RTLLIB_DL_HT, - "HT CONTROL FILED EXIST!!\n"); + netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); return true; } } @@ -853,7 +854,8 @@ static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; - RTLLIB_DEBUG(RTLLIB_DL_HT, "======>%s()\n", __func__); + netdev_vdbg(ieee->dev, "%s()\n", __func__); + if (pHTInfo->bCurBW40MHz) { if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) ieee->set_chan(ieee->dev, diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h index 55ef7ec33f65..3aa35ced2b8b 100644 --- a/drivers/staging/rtl8192e/rtl819x_Qos.h +++ b/drivers/staging/rtl8192e/rtl819x_Qos.h @@ -91,122 +91,22 @@ union tspec_body { } f; }; -struct wmm_tspec { - u8 ID; - u8 Length; - u8 OUI[3]; - u8 OUI_Type; - u8 OUI_SubType; - u8 Version; - union tspec_body Body; -}; - struct octet_string { u8 *Octet; u16 Length; }; -#define MAX_WMMELE_LENGTH 64 - -#define QOS_MODE u32 - -#define QOS_DISABLE 0 -#define QOS_WMM 1 -#define QOS_WMMSA 2 -#define QOS_EDCA 4 -#define QOS_HCCA 8 -#define QOS_WMM_UAPSD 16 - -#define WMM_PARAM_ELE_BODY_LEN 18 - -#define MAX_STA_TS_COUNT 16 -#define MAX_AP_TS_COUNT 32 -#define QOS_TSTREAM_KEY_SIZE 13 - -#define WMM_ACTION_CATEGORY_CODE 17 -#define WMM_PARAM_ELE_BODY_LEN 18 - -#define MAX_TSPEC_TSID 15 -#define SESSION_REJECT_TSID 0xfe -#define DEFAULT_TSID 0xff - -#define ADDTS_TIME_SLOT 100 - -#define ACM_TIMEOUT 1000 -#define SESSION_REJECT_TIMEOUT 60000 - enum ack_policy { eAckPlc0_ACK = 0x00, eAckPlc1_NoACK = 0x01, }; - -#define SET_WMM_QOS_INFO_FIELD(_pStart, _val) \ - WriteEF1Byte(_pStart, _val) - -#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 0, 4) -#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val) - -#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 7, 1) -#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 0, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 1, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 2, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 3, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart) \ - LE_BITS_TO_1BYTE(_pStart, 5, 2) -#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val) \ - SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val) - -enum qos_ie_source { - QOSIE_SRC_ADDTSREQ, - QOSIE_SRC_ADDTSRSP, - QOSIE_SRC_REASOCREQ, - QOSIE_SRC_REASOCRSP, - QOSIE_SRC_DELTS, -}; - - -#define AC_CODING u32 - #define AC0_BE 0 #define AC1_BK 1 #define AC2_VI 2 #define AC3_VO 3 #define AC_MAX 4 - -#define AC_PARAM_SIZE 4 - -#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE)) - -enum qos_ele_subtype { - QOSELE_TYPE_INFO = 0x00, - QOSELE_TYPE_PARAM = 0x01, -}; - - enum direction_value { DIR_UP = 0, DIR_DOWN = 1, @@ -227,22 +127,6 @@ struct acm { u8 HwAcmCtl; }; - - -#define AC_UAPSD u8 - -#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0) -#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0) - -#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1) -#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1) - -#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2) -#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2) - -#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3) -#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3) - union qos_tclas { struct _TYPE_GENERAL { @@ -255,8 +139,8 @@ union qos_tclas { u8 Priority; u8 ClassifierType; u8 Mask; - u8 SrcAddr[6]; - u8 DstAddr[6]; + u8 SrcAddr[ETH_ALEN]; + u8 DstAddr[ETH_ALEN]; u16 Type; } TYPE0_ETH; @@ -294,65 +178,6 @@ union qos_tclas { } TYPE2_8021Q; }; -struct qos_tstream { - - bool bUsed; - u16 MsduLifetime; - bool bEstablishing; - u8 TimeSlotCount; - u8 DialogToken; - struct wmm_tspec TSpec; - struct wmm_tspec OutStandingTSpec; - u8 NominalPhyRate; -}; - -struct sta_qos { - u8 WMMIEBuf[MAX_WMMELE_LENGTH]; - u8 *WMMIE; - - QOS_MODE QosCapability; - QOS_MODE CurrentQosMode; - - AC_UAPSD b4ac_Uapsd; - AC_UAPSD Curr4acUapsd; - u8 bInServicePeriod; - u8 MaxSPLength; - int NumBcnBeforeTrigger; - - u8 *pWMMInfoEle; - u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE]; - - struct acm acm[4]; - enum acm_method AcmMethod; - - struct qos_tstream StaTsArray[MAX_STA_TS_COUNT]; - u8 DialogToken; - struct wmm_tspec TSpec; - - u8 QBssWirelessMode; - - bool bNoAck; - - bool bEnableRxImmBA; - -}; - -#define QBSS_LOAD_SIZE 5 - -struct bss_qos { - QOS_MODE bdQoSMode; - u8 bdWMMIEBuf[MAX_WMMELE_LENGTH]; - struct octet_string bdWMMIE; - - enum qos_ele_subtype EleSubType; - - u8 *pWMMInfoEle; - u8 *pWMMParamEle; - - u8 QBssLoad[QBSS_LOAD_SIZE]; - bool bQBssLoadValid; -}; - #define IsACValid(ac) ((ac >= 0 && ac <= 7) ? true : false) @@ -367,23 +192,4 @@ union aci_aifsn { } f; }; -union ecw { - u8 charData; - struct { - u8 ECWmin:4; - u8 ECWmax:4; - } f; -}; - -union ac_param { - u32 longData; - u8 charData[4]; - - struct { - union aci_aifsn AciAifsn; - union ecw Ecw; - u16 TXOPLimit; - } f; -}; - #endif diff --git a/drivers/staging/rtl8192e/rtl819x_TS.h b/drivers/staging/rtl8192e/rtl819x_TS.h index 8601b1ad217d..b3e721bf975c 100644 --- a/drivers/staging/rtl8192e/rtl819x_TS.h +++ b/drivers/staging/rtl8192e/rtl819x_TS.h @@ -35,7 +35,7 @@ struct ts_common_info { struct list_head List; struct timer_list SetupTimer; struct timer_list InactTimer; - u8 Addr[6]; + u8 Addr[ETH_ALEN]; union tspec_body TSpec; union qos_tclas TClass[TCLAS_NUM]; u8 TClasProc; diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c index 7d77d056228d..8a5dd6ef8074 100644 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -49,8 +49,10 @@ static void RxPktPendingTimeout(unsigned long data) if (index == 0) pRxTs->RxIndicateSeq = pReorderEntry->SeqNum; - if (SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)) { + if (SN_LESS(pReorderEntry->SeqNum, + pRxTs->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, + pRxTs->RxIndicateSeq)) { list_del_init(&pReorderEntry->List); if (SN_EQUAL(pReorderEntry->SeqNum, @@ -58,9 +60,9 @@ static void RxPktPendingTimeout(unsigned long data) pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096; - RTLLIB_DEBUG(RTLLIB_DL_REORDER, - "%s(): Indicate SeqNum: %d\n", - __func__, pReorderEntry->SeqNum); + netdev_dbg(ieee->dev, + "%s(): Indicate SeqNum: %d\n", + __func__, pReorderEntry->SeqNum); ieee->stats_IndicateArray[index] = pReorderEntry->prxb; index++; @@ -78,8 +80,9 @@ static void RxPktPendingTimeout(unsigned long data) pRxTs->RxTimeoutIndicateSeq = 0xffff; if (index > REORDER_WIN_SIZE) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "RxReorderIndicatePacket(): Rx Reorder struct buffer full!!\n"); + netdev_warn(ieee->dev, + "%s(): Rx Reorder struct buffer full\n", + __func__); spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); return; @@ -91,7 +94,8 @@ static void RxPktPendingTimeout(unsigned long data) if (bPktInBuf && (pRxTs->RxTimeoutIndicateSeq == 0xffff)) { pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; mod_timer(&pRxTs->RxPktPendingTimer, jiffies + - msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime)); + msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime) + ); } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); } @@ -104,8 +108,7 @@ static void TsAddBaProcess(unsigned long data) TxTsRecord[num]); TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); - RTLLIB_DEBUG(RTLLIB_DL_BA, - "TsAddBaProcess(): ADDBA Req is started!!\n"); + netdev_dbg(ieee->dev, "%s(): ADDBA Req is started\n", __func__); } static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) @@ -144,7 +147,7 @@ void TSInitialize(struct rtllib_device *ieee) struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; u8 count = 0; - RTLLIB_DEBUG(RTLLIB_DL_TS, "==========>%s()\n", __func__); + netdev_vdbg(ieee->dev, "%s()\n", __func__); INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); @@ -269,10 +272,10 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, if (!search_dir[dir]) continue; list_for_each_entry(pRet, psearch_list, List) { - if (memcmp(pRet->Addr, Addr, 6) == 0) - if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) - if (pRet->TSpec.f.TSInfo.field.ucDirection == dir) - break; + if (memcmp(pRet->Addr, Addr, 6) == 0 && + pRet->TSpec.f.TSInfo.field.ucTSID == TID && + pRet->TSpec.f.TSInfo.field.ucDirection == dir) + break; } if (&pRet->List != psearch_list) @@ -318,17 +321,15 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, enum direction_value Dir; if (is_multicast_ether_addr(Addr)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "ERR! get TS for Broadcast or Multicast\n"); + netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n"); return false; } if (ieee->current_network.qos_data.supported == 0) { UP = 0; } else { if (!IsACValid(TID)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "ERR! in %s(), TID(%d) is not valid\n", - __func__, TID); + netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n", + __func__, TID); return false; } @@ -357,8 +358,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, return true; if (!bAddNewTs) { - RTLLIB_DEBUG(RTLLIB_DL_TS, - "add new TS failed(tid:%d)\n", UP); + netdev_dbg(ieee->dev, "add new TS failed(tid:%d)\n", UP); return false; } @@ -374,7 +374,6 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) : ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN); - RTLLIB_DEBUG(RTLLIB_DL_TS, "to add Ts\n"); if (!list_empty(pUnusedList)) { (*ppTS) = list_entry(pUnusedList->next, struct ts_common_info, List); @@ -393,9 +392,9 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, ResetRxTsEntry(tmp); } - RTLLIB_DEBUG(RTLLIB_DL_TS, - "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n", - UP, Dir, Addr, *ppTS); + netdev_dbg(ieee->dev, + "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n", + UP, Dir, Addr, *ppTS); pTSInfo->field.ucTrafficType = 0; pTSInfo->field.ucTSID = UP; pTSInfo->field.ucDirection = Dir; @@ -413,14 +412,14 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, return true; } - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "ERR!!in function %s() There is not enough dir=%d(0=up down=1) TS record to be used!!", - __func__, Dir); + netdev_warn(ieee->dev, + "There is not enough dir=%d(0=up down=1) TS record to be used!", + Dir); return false; } -static void RemoveTsEntry(struct rtllib_device *ieee, struct ts_common_info *pTs, - enum tr_select TxRxSelect) +static void RemoveTsEntry(struct rtllib_device *ieee, + struct ts_common_info *pTs, enum tr_select TxRxSelect) { del_timer_sync(&pTs->SetupTimer); del_timer_sync(&pTs->InactTimer); @@ -437,9 +436,8 @@ static void RemoveTsEntry(struct rtllib_device *ieee, struct ts_common_info *pTs pRxReorderEntry = (struct rx_reorder_entry *) list_entry(pRxTS->RxPendingPktList.prev, struct rx_reorder_entry, List); - RTLLIB_DEBUG(RTLLIB_DL_REORDER, - "%s(): Delete SeqNum %d!\n", __func__, - pRxReorderEntry->SeqNum); + netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n", + __func__, pRxReorderEntry->SeqNum); list_del_init(&pRxReorderEntry->List); { int i = 0; @@ -539,16 +537,13 @@ void TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS) pTxTS->bAddBaReqInProgress = true; if (pTxTS->bAddBaReqDelayed) { - RTLLIB_DEBUG(RTLLIB_DL_BA, - "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"); + netdev_dbg(ieee->dev, "Start ADDBA after 60 sec!!\n"); mod_timer(&pTxTS->TsAddBaTimer, jiffies + msecs_to_jiffies(TS_ADDBA_DELAY)); } else { - RTLLIB_DEBUG(RTLLIB_DL_BA, - "TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"); + netdev_dbg(ieee->dev, "Immediately Start ADDBA\n"); mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); } } else - RTLLIB_DEBUG(RTLLIB_DL_BA, "%s()==>BA timer is already added\n", - __func__); + netdev_dbg(ieee->dev, "BA timer is already added\n"); } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index bfec4fde01d1..5c3a9793171b 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -641,81 +641,6 @@ enum wireless_network_type { #define OUI_SUBTYPE_WMM_PARAM 1 #define OUI_SUBTYPE_QOS_CAPABI 5 -/* debug macros */ -extern u32 rtllib_debug_level; -#define RTLLIB_DEBUG(level, fmt, args...) \ -do { \ - if (rtllib_debug_level & (level)) \ - printk(KERN_DEBUG "rtllib: " fmt, ## args); \ -} while (0) - -#define RTLLIB_DEBUG_DATA(level, data, datalen) \ - do { \ - if ((rtllib_debug_level & (level)) == (level)) { \ - printk(KERN_DEBUG "rtllib: %s()\n", __func__); \ - print_hex_dump_bytes(KERN_DEBUG, DUMP_PREFIX_NONE, \ - data, datalen); \ - } \ - } while (0) - -/* To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define RTLLIB_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a RTLLIB_xxxx_DEBUG() macro definition for your - * classification, or use RTLLIB_DEBUG(RTLLIB_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/ipw/debug_level - * - * you simply need to add your entry to the ipw_debug_levels array. - */ - -#define RTLLIB_DL_INFO (1<<0) -#define RTLLIB_DL_WX (1<<1) -#define RTLLIB_DL_SCAN (1<<2) -#define RTLLIB_DL_STATE (1<<3) -#define RTLLIB_DL_MGMT (1<<4) -#define RTLLIB_DL_FRAG (1<<5) -#define RTLLIB_DL_EAP (1<<6) -#define RTLLIB_DL_DROP (1<<7) - -#define RTLLIB_DL_TX (1<<8) -#define RTLLIB_DL_RX (1<<9) - -#define RTLLIB_DL_HT (1<<10) -#define RTLLIB_DL_BA (1<<11) -#define RTLLIB_DL_TS (1<<12) -#define RTLLIB_DL_QOS (1<<13) -#define RTLLIB_DL_REORDER (1<<14) -#define RTLLIB_DL_IOT (1<<15) -#define RTLLIB_DL_IPS (1<<16) -#define RTLLIB_DL_TRACE (1<<29) -#define RTLLIB_DL_DATA (1<<30) -#define RTLLIB_DL_ERR (1<<31) -#define RTLLIB_ERROR(f, a...) pr_err("rtllib: " f, ## a) -#define RTLLIB_WARNING(f, a...) pr_warn("rtllib: " f, ## a) -#define RTLLIB_DEBUG_INFO(f, a...) RTLLIB_DEBUG(RTLLIB_DL_INFO, f, ## a) - -#define RTLLIB_DEBUG_WX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_WX, f, ## a) -#define RTLLIB_DEBUG_SCAN(f, a...) RTLLIB_DEBUG(RTLLIB_DL_SCAN, f, ## a) -#define RTLLIB_DEBUG_STATE(f, a...) RTLLIB_DEBUG(RTLLIB_DL_STATE, f, ## a) -#define RTLLIB_DEBUG_MGMT(f, a...) RTLLIB_DEBUG(RTLLIB_DL_MGMT, f, ## a) -#define RTLLIB_DEBUG_FRAG(f, a...) RTLLIB_DEBUG(RTLLIB_DL_FRAG, f, ## a) -#define RTLLIB_DEBUG_EAP(f, a...) RTLLIB_DEBUG(RTLLIB_DL_EAP, f, ## a) -#define RTLLIB_DEBUG_DROP(f, a...) RTLLIB_DEBUG(RTLLIB_DL_DROP, f, ## a) -#define RTLLIB_DEBUG_TX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_TX, f, ## a) -#define RTLLIB_DEBUG_RX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_RX, f, ## a) -#define RTLLIB_DEBUG_QOS(f, a...) RTLLIB_DEBUG(RTLLIB_DL_QOS, f, ## a) - #ifndef ETH_P_PAE #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ @@ -1531,7 +1456,7 @@ struct rtllib_network { u16 CcxRmState[2]; bool bMBssidValid; u8 MBssidMask; - u8 MBssid[6]; + u8 MBssid[ETH_ALEN]; bool bWithCcxVerNum; u8 BssCcxVerNumber; /* These are network statistics */ @@ -1866,7 +1791,7 @@ struct rt_link_detect { struct sw_cam_table { - u8 macaddr[6]; + u8 macaddr[ETH_ALEN]; bool bused; u8 key_buf[16]; u16 key_type; @@ -1912,10 +1837,10 @@ enum ratr_table_mode_8192s { #define NUM_PMKID_CACHE 16 struct rt_pmkid_list { - u8 bUsed; - u8 Bssid[6]; + u8 Bssid[ETH_ALEN]; u8 PMKID[16]; u8 SsidBuf[33]; + u8 bUsed; u8 *ssid_octet; u16 ssid_length; }; @@ -1979,7 +1904,6 @@ struct rtllib_device { u8 hwsec_active; bool is_silent_reset; - bool force_mic_error; bool is_roaming; bool ieee_up; bool cannot_notify; @@ -2083,7 +2007,7 @@ struct rtllib_device { u8 *wpa_ie; size_t wps_ie_len; u8 *wps_ie; - u8 ap_mac_addr[6]; + u8 ap_mac_addr[ETH_ALEN]; u16 pairwise_key_type; u16 group_key_type; diff --git a/drivers/staging/rtl8192e/rtllib_crypt.c b/drivers/staging/rtl8192e/rtllib_crypt.c deleted file mode 100644 index 1e6ae9bead23..000000000000 --- a/drivers/staging/rtl8192e/rtllib_crypt.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - * - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/errno.h> - -#include "rtllib.h" - -struct rtllib_crypto_alg { - struct list_head list; - struct lib80211_crypto_ops *ops; -}; - - -struct rtllib_crypto { - struct list_head algs; - spinlock_t lock; -}; - -static struct rtllib_crypto *hcrypt; - -void rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info, - int force) -{ - struct list_head *ptr, *n; - struct lib80211_crypt_data *entry; - - for (ptr = info->crypt_deinit_list.next, n = ptr->next; - ptr != &info->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct lib80211_crypt_data, list); - - if (atomic_read(&entry->refcnt) != 0 && !force) - continue; - - list_del(ptr); - - if (entry->ops) - entry->ops->deinit(entry->priv); - kfree(entry); - } -} -EXPORT_SYMBOL(rtllib_crypt_deinit_entries); - -void rtllib_crypt_deinit_handler(unsigned long data) -{ - struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; - unsigned long flags; - - spin_lock_irqsave(info->lock, flags); - rtllib_crypt_deinit_entries(info, 0); - if (!list_empty(&info->crypt_deinit_list)) { - printk(KERN_DEBUG - "%s: entries remaining in delayed crypt deletion list\n", - info->name); - info->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&info->crypt_deinit_timer); - } - spin_unlock_irqrestore(info->lock, flags); - -} -EXPORT_SYMBOL(rtllib_crypt_deinit_handler); - -void rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info, - struct lib80211_crypt_data **crypt) -{ - struct lib80211_crypt_data *tmp; - unsigned long flags; - - if (*crypt == NULL) - return; - - tmp = *crypt; - *crypt = NULL; - - /* must not run ops->deinit() while there may be pending encrypt or - * decrypt operations. Use a list of delayed deinits to avoid needing - * locking. - */ - - spin_lock_irqsave(info->lock, flags); - list_add(&tmp->list, &info->crypt_deinit_list); - if (!timer_pending(&info->crypt_deinit_timer)) { - info->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&info->crypt_deinit_timer); - } - spin_unlock_irqrestore(info->lock, flags); -} -EXPORT_SYMBOL(rtllib_crypt_delayed_deinit); - -int rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops) -{ - unsigned long flags; - struct rtllib_crypto_alg *alg; - - if (hcrypt == NULL) - return -1; - - alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) - return -ENOMEM; - - alg->ops = ops; - - spin_lock_irqsave(&hcrypt->lock, flags); - list_add(&alg->list, &hcrypt->algs); - spin_unlock_irqrestore(&hcrypt->lock, flags); - - printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n", - ops->name); - - return 0; -} -EXPORT_SYMBOL(rtllib_register_crypto_ops); - -int rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops) -{ - unsigned long flags; - struct list_head *ptr; - struct rtllib_crypto_alg *del_alg = NULL; - - if (hcrypt == NULL) - return -1; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct rtllib_crypto_alg *alg = - (struct rtllib_crypto_alg *) ptr; - if (alg->ops == ops) { - list_del(&alg->list); - del_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (del_alg) { - printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm '%s'\n", - ops->name); - kfree(del_alg); - } - - return del_alg ? 0 : -1; -} -EXPORT_SYMBOL(rtllib_unregister_crypto_ops); - - -struct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name) -{ - unsigned long flags; - struct list_head *ptr; - struct rtllib_crypto_alg *found_alg = NULL; - - if (hcrypt == NULL) - return NULL; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct rtllib_crypto_alg *alg = - (struct rtllib_crypto_alg *) ptr; - if (strcmp(alg->ops->name, name) == 0) { - found_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (found_alg) - return found_alg->ops; - else - return NULL; -} -EXPORT_SYMBOL(rtllib_get_crypto_ops); - - -static void *rtllib_crypt_null_init(int keyidx) { return (void *) 1; } -static void rtllib_crypt_null_deinit(void *priv) {} - -static struct lib80211_crypto_ops rtllib_crypt_null = { - .name = "NULL", - .init = rtllib_crypt_null_init, - .deinit = rtllib_crypt_null_deinit, - .encrypt_mpdu = NULL, - .decrypt_mpdu = NULL, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = NULL, - .get_key = NULL, - .extra_mpdu_prefix_len = 0, - .extra_mpdu_postfix_len = 0, - .extra_msdu_prefix_len = 0, - .extra_msdu_postfix_len = 0, - .owner = THIS_MODULE, -}; - - -int __init rtllib_crypto_init(void) -{ - int ret = -ENOMEM; - - hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); - if (!hcrypt) - goto out; - - INIT_LIST_HEAD(&hcrypt->algs); - spin_lock_init(&hcrypt->lock); - - ret = lib80211_register_crypto_ops(&rtllib_crypt_null); - if (ret < 0) { - kfree(hcrypt); - hcrypt = NULL; - } -out: - return ret; -} - - -void __exit rtllib_crypto_deinit(void) -{ - struct list_head *ptr, *n; - - if (hcrypt == NULL) - return; - - for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; - ptr = n, n = ptr->next) { - struct rtllib_crypto_alg *alg = - (struct rtllib_crypto_alg *) ptr; - list_del(ptr); - printk(KERN_DEBUG - "rtllib_crypt: unregistered algorithm '%s' (deinit)\n", - alg->ops->name); - kfree(alg); - } - - kfree(hcrypt); -} - -module_init(rtllib_crypto_init); -module_exit(rtllib_crypto_deinit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rtl8192e/rtllib_crypt.h b/drivers/staging/rtl8192e/rtllib_crypt.h deleted file mode 100644 index b8cf59f39a60..000000000000 --- a/drivers/staging/rtl8192e/rtllib_crypt.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Original code based on Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * <jketreno@linux.intel.com> - * - * Copyright (c) 2004, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -/* This file defines the interface to the rtllib crypto module. - */ -#ifndef RTLLIB_CRYPT_H -#define RTLLIB_CRYPT_H - -#include <linux/skbuff.h> - -int rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops); -int rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops); -struct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name); -void rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info, int force); -void rtllib_crypt_deinit_handler(unsigned long data); -void rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info, - struct lib80211_crypt_data **crypt); -#endif diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index 7d486e8887f8..496de4f6a7bc 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -69,7 +69,7 @@ static void *rtllib_ccmp_init(int key_idx) priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { - pr_debug("rtllib_crypt_ccmp: could not allocate crypto API aes\n"); + pr_debug("Could not allocate crypto API aes\n"); priv->tfm = NULL; goto fail; } diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 656b4b359c50..2096d78913bd 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -21,6 +21,7 @@ #include <linux/crypto.h> #include <linux/scatterlist.h> #include <linux/crc32.h> +#include <linux/etherdevice.h> #include "rtllib.h" @@ -52,7 +53,8 @@ struct rtllib_tkip_data { struct crypto_blkcipher *tx_tfm_arc4; struct crypto_hash *tx_tfm_michael; /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; + u8 rx_hdr[16]; + u8 tx_hdr[16]; }; static void *rtllib_tkip_init(int key_idx) @@ -66,8 +68,7 @@ static void *rtllib_tkip_init(int key_idx) priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG - "rtllib_crypt_tkip: could not allocate crypto API arc4\n"); + pr_debug("Could not allocate crypto API arc4\n"); priv->tx_tfm_arc4 = NULL; goto fail; } @@ -75,8 +76,7 @@ static void *rtllib_tkip_init(int key_idx) priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG - "rtllib_crypt_tkip: could not allocate crypto API michael_mic\n"); + pr_debug("Could not allocate crypto API michael_mic\n"); priv->tx_tfm_michael = NULL; goto fail; } @@ -84,8 +84,7 @@ static void *rtllib_tkip_init(int key_idx) priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG - "rtllib_crypt_tkip: could not allocate crypto API arc4\n"); + pr_debug("Could not allocate crypto API arc4\n"); priv->rx_tfm_arc4 = NULL; goto fail; } @@ -93,8 +92,7 @@ static void *rtllib_tkip_init(int key_idx) priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG - "rtllib_crypt_tkip: could not allocate crypto API michael_mic\n"); + pr_debug("Could not allocate crypto API michael_mic\n"); priv->rx_tfm_michael = NULL; goto fail; } @@ -401,24 +399,24 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) keyidx = pos[3]; if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { - printk(KERN_DEBUG - "TKIP: received packet without ExtIV flag from %pM\n", - hdr->addr2); + netdev_dbg(skb->dev, + "Received packet without ExtIV flag from %pM\n", + hdr->addr2); } return -2; } keyidx >>= 6; if (tkey->key_idx != keyidx) { - printk(KERN_DEBUG - "TKIP: RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", - tkey->key_idx, keyidx, priv); + netdev_dbg(skb->dev, + "RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", + tkey->key_idx, keyidx, priv); return -6; } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG - "TKIP: received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); + netdev_dbg(skb->dev, + "Received packet from %pM with keyid=%d that does not have a configured key\n", + hdr->addr2, keyidx); } return -3; } @@ -431,10 +429,10 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) && tkey->initialized) { if (net_ratelimit()) { - printk(KERN_DEBUG - "TKIP: replay detected: STA= %pM previous TSC %08x%04x received TSC %08x%04x\n", - hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, - iv32, iv16); + netdev_dbg(skb->dev, + "Replay detected: STA= %pM previous TSC %08x%04x received TSC %08x%04x\n", + hdr->addr2, tkey->rx_iv32, + tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; return -4; @@ -455,9 +453,9 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { - printk(KERN_DEBUG - ": TKIP: failed to decrypt received packet from %pM\n", - hdr->addr2); + netdev_dbg(skb->dev, + "Failed to decrypt received packet from %pM\n", + hdr->addr2); } return -7; } @@ -477,9 +475,9 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) tkey->rx_phase1_done = 0; } if (net_ratelimit()) { - printk(KERN_DEBUG - "TKIP: ICV error detected: STA= %pM\n", - hdr->addr2); + netdev_dbg(skb->dev, + "ICV error detected: STA= %pM\n", + hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -532,20 +530,20 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) switch (le16_to_cpu(hdr11->frame_ctl) & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { case RTLLIB_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + ether_addr_copy(hdr, hdr11->addr3); /* DA */ + ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */ break; case RTLLIB_FCTL_FROMDS: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ + ether_addr_copy(hdr, hdr11->addr1); /* DA */ + ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */ break; case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ + ether_addr_copy(hdr, hdr11->addr3); /* DA */ + ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */ break; case 0: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + ether_addr_copy(hdr, hdr11->addr1); /* DA */ + ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */ break; } @@ -564,9 +562,9 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) hdr = (struct rtllib_hdr_4addr *) skb->data; if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - printk(KERN_DEBUG - "Invalid packet for Michael MIC add (tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); + netdev_dbg(skb->dev, + "Invalid packet for Michael MIC add (tailroom=%d hdr_len=%d skb->len=%d)\n", + skb_tailroom(skb), hdr_len, skb->len); return -1; } @@ -598,7 +596,7 @@ static void rtllib_michael_mic_failure(struct net_device *dev, else ev.flags |= IW_MICFAILURE_PAIRWISE; ev.src_addr.sa_family = ARPHRD_ETHER; - memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); + ether_addr_copy(ev.src_addr.sa_data, hdr->addr2); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = sizeof(ev); wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); @@ -628,12 +626,11 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, struct rtllib_hdr_4addr *hdr; hdr = (struct rtllib_hdr_4addr *) skb->data; - printk(KERN_DEBUG - "%s: Michael MIC verification failed for MSDU from %pM keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", hdr->addr2, - keyidx); - printk(KERN_DEBUG "%d\n", - memcmp(mic, skb->data + skb->len - 8, 8) != 0); + netdev_dbg(skb->dev, + "Michael MIC verification failed for MSDU from %pM keyidx=%d\n", + hdr->addr2, keyidx); + netdev_dbg(skb->dev, "%d\n", + memcmp(mic, skb->data + skb->len - 8, 8) != 0); if (skb->dev) { pr_info("skb->dev != NULL\n"); rtllib_michael_mic_failure(skb->dev, hdr, keyidx); diff --git a/drivers/staging/rtl8192e/rtllib_debug.h b/drivers/staging/rtl8192e/rtllib_debug.h index 6df8df134367..42e88d69ae63 100644 --- a/drivers/staging/rtl8192e/rtllib_debug.h +++ b/drivers/staging/rtl8192e/rtllib_debug.h @@ -76,12 +76,4 @@ do { \ printk(KERN_DEBUG DRV_NAME ":" x "\n", ##args);\ } while (0) -#define assert(expr) \ -do { \ - if (!(expr)) { \ - pr_info("Assertion failed! %s,%s,%s,line=%d\n", \ - #expr, __FILE__, __func__, __LINE__); \ - } \ -} while (0) - #endif diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 32cc8df9d3a7..845d9b8a4aa2 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -103,11 +103,11 @@ struct net_device *alloc_rtllib(int sizeof_priv) struct net_device *dev; int i, err; - RTLLIB_DEBUG_INFO("Initializing...\n"); + pr_debug("rtllib: Initializing...\n"); dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv); if (!dev) { - RTLLIB_ERROR("Unable to network device.\n"); + pr_err("Unable to allocate net_device.\n"); return NULL; } ieee = (struct rtllib_device *)netdev_priv_rsl(dev); @@ -116,8 +116,7 @@ struct net_device *alloc_rtllib(int sizeof_priv) err = rtllib_networks_allocate(ieee); if (err) { - RTLLIB_ERROR("Unable to allocate beacon storage: %d\n", - err); + pr_err("Unable to allocate beacon storage: %d\n", err); goto failed; } rtllib_networks_initialize(ieee); @@ -197,69 +196,13 @@ void free_rtllib(struct net_device *dev) } EXPORT_SYMBOL(free_rtllib); -u32 rtllib_debug_level; -static int debug = RTLLIB_DL_ERR; -static struct proc_dir_entry *rtllib_proc; - -static int show_debug_level(struct seq_file *m, void *v) -{ - seq_printf(m, "0x%08X\n", rtllib_debug_level); - - return 0; -} - -static ssize_t write_debug_level(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - unsigned long val; - int err = kstrtoul_from_user(buffer, count, 0, &val); - - if (err) - return err; - rtllib_debug_level = val; - return count; -} - -static int open_debug_level(struct inode *inode, struct file *file) -{ - return single_open(file, show_debug_level, NULL); -} - -static const struct file_operations fops = { - .open = open_debug_level, - .read = seq_read, - .llseek = seq_lseek, - .write = write_debug_level, - .release = single_release, -}; - static int __init rtllib_init(void) { - struct proc_dir_entry *e; - - rtllib_debug_level = debug; - rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net); - if (rtllib_proc == NULL) { - RTLLIB_ERROR("Unable to create " DRV_NAME - " proc directory\n"); - return -EIO; - } - e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops); - if (!e) { - remove_proc_entry(DRV_NAME, init_net.proc_net); - rtllib_proc = NULL; - return -EIO; - } return 0; } static void __exit rtllib_exit(void) { - if (rtllib_proc) { - remove_proc_entry("debug_level", rtllib_proc); - remove_proc_entry(DRV_NAME, init_net.proc_net); - rtllib_proc = NULL; - } } module_init(rtllib_init); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index bb789cc9208d..2bef1f63be79 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -45,8 +45,9 @@ #include "dot11d.h" static inline void rtllib_monitor_rx(struct rtllib_device *ieee, - struct sk_buff *skb, struct rtllib_rx_stats *rx_status, - size_t hdr_length) + struct sk_buff *skb, + struct rtllib_rx_stats *rx_status, + size_t hdr_length) { skb->dev = ieee->dev; skb_reset_mac_header(skb); @@ -69,9 +70,9 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, entry = &ieee->frag_cache[tid][i]; if (entry->skb != NULL && time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - RTLLIB_DEBUG_FRAG( - "expiring fragment cache entry seq=%u last_frag=%u\n", - entry->seq, entry->last_frag); + netdev_dbg(ieee->dev, + "expiring fragment cache entry seq=%u last_frag=%u\n", + entry->seq, entry->last_frag); dev_kfree_skb_any(entry->skb); entry->skb = NULL; } @@ -101,7 +102,8 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, struct rtllib_hdr_4addrqos *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + RTLLIB_QOS_HAS_SEQ(fc)) { hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); @@ -123,7 +125,8 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, 2 /* alignment */ + 8 /* WEP */ + ETH_ALEN /* WDS */ + - (RTLLIB_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */); + /* QOS Control */ + (RTLLIB_QOS_HAS_SEQ(fc) ? 2 : 0)); if (skb == NULL) return NULL; @@ -139,8 +142,8 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, entry->seq = seq; entry->last_frag = frag; entry->skb = skb; - memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); - memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); + ether_addr_copy(entry->src_addr, hdr->addr2); + ether_addr_copy(entry->dst_addr, hdr->addr1); } else { /* received a fragment of a frame for which the head fragment * should have already been received @@ -169,7 +172,8 @@ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, struct rtllib_hdr_4addrqos *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + RTLLIB_QOS_HAS_SEQ(fc)) { hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); @@ -187,8 +191,9 @@ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, hdr->addr1); if (entry == NULL) { - RTLLIB_DEBUG_FRAG( - "could not invalidate fragment cache entry (seq=%u)\n", seq); + netdev_dbg(ieee->dev, + "Couldn't invalidate fragment cache entry (seq=%u)\n", + seq); return -1; } @@ -290,7 +295,8 @@ rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, return 0; if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *) + (skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; @@ -305,11 +311,12 @@ rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { - RTLLIB_DEBUG_DROP( - "decryption failed (SA= %pM) res=%d\n", hdr->addr2, res); + netdev_dbg(ieee->dev, "decryption failed (SA= %pM) res=%d\n", + hdr->addr2, res); if (res == -2) - RTLLIB_DEBUG_DROP("Decryption failed ICV mismatch (key %d)\n", - skb->data[hdrlen + 3] >> 6); + netdev_dbg(ieee->dev, + "Decryption failed ICV mismatch (key %d)\n", + skb->data[hdrlen + 3] >> 6); ieee->ieee_stats.rx_discards_undecryptable++; return -1; } @@ -329,7 +336,8 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *) + (skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; @@ -344,8 +352,9 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { - printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n", - ieee->dev->name, hdr->addr2, keyidx); + netdev_dbg(ieee->dev, + "MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n", + hdr->addr2, keyidx); return -1; } @@ -368,7 +377,8 @@ static int is_duplicate_packet(struct rtllib_device *ieee, struct rtllib_hdr_4addrqos *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + RTLLIB_QOS_HAS_SEQ(fc)) { hdr_4addrqos = (struct rtllib_hdr_4addrqos *)header; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); @@ -396,11 +406,12 @@ static int is_duplicate_packet(struct rtllib_device *ieee, break; } if (p == &ieee->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); + entry = kmalloc(sizeof(struct ieee_ibss_seq), + GFP_ATOMIC); if (!entry) return 0; - memcpy(entry->mac, mac, ETH_ALEN); + ether_addr_copy(entry->mac, mac); entry->seq_num[tid] = seq; entry->frag_num[tid] = frag; entry->packet_time[tid] = jiffies; @@ -466,7 +477,8 @@ static bool AddReorderEntry(struct rx_ts_record *pTS, return true; } -void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prxbIndicateArray, u8 index) +void rtllib_indicate_packets(struct rtllib_device *ieee, + struct rtllib_rxb **prxbIndicateArray, u8 index) { struct net_device_stats *stats = &ieee->stats; u8 i = 0, j = 0; @@ -481,9 +493,12 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx /* convert hdr + possible LLC headers into Ethernet header */ ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; if (sub_skb->len >= 8 && - ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { + ((memcmp(sub_skb->data, rfc1042_header, + SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && + ethertype != ETH_P_IPX) || + memcmp(sub_skb->data, bridge_tunnel_header, + SNAP_SIZE) == 0)) { /* remove RFC1042 or Bridge-Tunnel encapsulation * and replace EtherType */ @@ -505,11 +520,13 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx stats->rx_bytes += sub_skb->len; memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev); + sub_skb->protocol = eth_type_trans(sub_skb, + ieee->dev); sub_skb->dev = ieee->dev; sub_skb->dev->stats.rx_packets++; sub_skb->dev->stats.rx_bytes += sub_skb->len; - sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + /* 802.11 crc not sufficient */ + sub_skb->ip_summed = CHECKSUM_NONE; ieee->last_rx_ps_time = jiffies; netif_rx(sub_skb); } @@ -519,7 +536,8 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx } } -void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, struct rx_ts_record *pTS) +void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, + struct rx_ts_record *pTS) { struct rx_reorder_entry *pRxReorderEntry; u8 RfdCnt = 0; @@ -533,14 +551,18 @@ void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, struct rx_ts_record break; } - pRxReorderEntry = (struct rx_reorder_entry *)list_entry(pTS->RxPendingPktList.prev, struct rx_reorder_entry, List); - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum %d!\n", __func__, pRxReorderEntry->SeqNum); + pRxReorderEntry = (struct rx_reorder_entry *) + list_entry(pTS->RxPendingPktList.prev, + struct rx_reorder_entry, List); + netdev_dbg(ieee->dev, "%s(): Indicate SeqNum %d!\n", __func__, + pRxReorderEntry->SeqNum); list_del_init(&pRxReorderEntry->List); ieee->RfdArray[RfdCnt] = pRxReorderEntry->prxb; RfdCnt = RfdCnt + 1; - list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List); + list_add_tail(&pRxReorderEntry->List, + &ieee->RxReorder_Unused_List); } rtllib_indicate_packets(ieee, ieee->RfdArray, RfdCnt); @@ -559,8 +581,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, bool bMatchWinStart = false, bPktInBuf = false; unsigned long flags; - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq is %d, WinSize is %d\n", __func__, SeqNum, - pTS->RxIndicateSeq, WinSize); + netdev_dbg(ieee->dev, + "%s(): Seq is %d, pTS->RxIndicateSeq is %d, WinSize is %d\n", + __func__, SeqNum, pTS->RxIndicateSeq, WinSize); spin_lock_irqsave(&(ieee->reorder_spinlock), flags); @@ -571,8 +594,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, /* Drop out the packet which SeqNum is smaller than WinStart */ if (SN_LESS(SeqNum, pTS->RxIndicateSeq)) { - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", - pTS->RxIndicateSeq, SeqNum); + netdev_dbg(ieee->dev, + "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); pHTInfo->RxReorderDropCounter++; { int i; @@ -597,8 +621,11 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, if (SeqNum >= (WinSize - 1)) pTS->RxIndicateSeq = SeqNum + 1 - WinSize; else - pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum + 1)) + 1; - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum); + pTS->RxIndicateSeq = 4095 - + (WinSize - (SeqNum + 1)) + 1; + netdev_dbg(ieee->dev, + "Window Shift! IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); } /* Indication process. @@ -613,8 +640,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, */ if (bMatchWinStart) { /* Current packet is going to be indicated.*/ - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n", - pTS->RxIndicateSeq, SeqNum); + netdev_dbg(ieee->dev, + "Packets indication! IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); ieee->prxbIndicateArray[0] = prxb; index = 1; } else { @@ -625,28 +653,30 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, struct rx_reorder_entry, List); list_del_init(&pReorderEntry->List); - /* Make a reorder entry and insert into a the packet list.*/ + /* Make a reorder entry and insert + * into a the packet list. + */ pReorderEntry->SeqNum = SeqNum; pReorderEntry->prxb = prxb; if (!AddReorderEntry(pTS, pReorderEntry)) { - RTLLIB_DEBUG(RTLLIB_DL_REORDER, - "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", - __func__, pTS->RxIndicateSeq, - SeqNum); + int i; + + netdev_dbg(ieee->dev, + "%s(): Duplicate packet is dropped. IndicateSeq: %d, NewSeq: %d\n", + __func__, pTS->RxIndicateSeq, + SeqNum); list_add_tail(&pReorderEntry->List, - &ieee->RxReorder_Unused_List); { - int i; + &ieee->RxReorder_Unused_List); - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - kfree(prxb); - prxb = NULL; - } + for (i = 0; i < prxb->nr_subframes; i++) + dev_kfree_skb(prxb->subframes[i]); + kfree(prxb); + prxb = NULL; } else { - RTLLIB_DEBUG(RTLLIB_DL_REORDER, - "Pkt insert into struct buffer!! IndicateSeq: %d, NewSeq: %d\n", - pTS->RxIndicateSeq, SeqNum); + netdev_dbg(ieee->dev, + "Pkt insert into struct buffer. IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); } } else { /* Packets are dropped if there are not enough reorder @@ -654,7 +684,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, * indicate all the packets in struct buffer and get * reorder entries. */ - RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n"); + netdev_err(ieee->dev, + "%s(): There is no reorder entry! Packet is dropped!\n", + __func__); { int i; @@ -668,15 +700,20 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, /* Check if there is any packet need indicate.*/ while (!list_empty(&pTS->RxPendingPktList)) { - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): start RREORDER indicate\n", __func__); + netdev_dbg(ieee->dev, "%s(): start RREORDER indicate\n", + __func__); - pReorderEntry = (struct rx_reorder_entry *)list_entry(pTS->RxPendingPktList.prev, - struct rx_reorder_entry, List); + pReorderEntry = (struct rx_reorder_entry *) + list_entry(pTS->RxPendingPktList.prev, + struct rx_reorder_entry, + List); if (SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { + SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { /* This protect struct buffer from overflow. */ if (index >= REORDER_WIN_SIZE) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!!\n"); + netdev_err(ieee->dev, + "%s(): Buffer overflow!\n", + __func__); bPktInBuf = true; break; } @@ -684,10 +721,12 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, list_del_init(&pReorderEntry->List); if (SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) - pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; + pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % + 4096; ieee->prxbIndicateArray[index] = pReorderEntry->prxb; - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum %d!\n", __func__, pReorderEntry->SeqNum); + netdev_dbg(ieee->dev, "%s(): Indicate SeqNum %d!\n", + __func__, pReorderEntry->SeqNum); index++; list_add_tail(&pReorderEntry->List, @@ -707,7 +746,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, pTS->RxTimeoutIndicateSeq = 0xffff; if (index > REORDER_WIN_SIZE) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder struct buffer full!!\n"); + netdev_err(ieee->dev, + "%s(): Rx Reorder struct buffer full!\n", + __func__); spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); return; @@ -717,8 +758,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, } if (bPktInBuf && pTS->RxTimeoutIndicateSeq == 0xffff) { - RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): SET rx timeout timer\n", - __func__); + netdev_dbg(ieee->dev, "%s(): SET rx timeout timer\n", __func__); pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq; mod_timer(&pTS->RxPktPendingTimer, jiffies + msecs_to_jiffies(pHTInfo->RxReorderPendingTime)); @@ -834,7 +874,8 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb, sub_skb->dev = ieee->dev; rxb->subframes[rxb->nr_subframes++] = sub_skb; if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { - RTLLIB_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n"); + netdev_dbg(ieee->dev, + "ParseSubframe(): Too many Subframes! Packets dropped!\n"); break; } skb_pull(skb, nSubframe_Length); @@ -896,7 +937,8 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, !ieee->current_network.qos_data.active || !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { - if (!((type == RTLLIB_FTYPE_MGMT) && (stype == RTLLIB_STYPE_BEACON))) { + if (!((type == RTLLIB_FTYPE_MGMT) && + (stype == RTLLIB_STYPE_BEACON))) { if (is_duplicate_packet(ieee, hdr)) return -1; } @@ -911,7 +953,8 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, pRxTS->RxLastFragNum = frag; pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc); } else { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n", __func__); + netdev_warn(ieee->dev, "%s(): No TS! Skip the check!\n", + __func__); return -1; } } @@ -927,24 +970,24 @@ static void rtllib_rx_extract_addr(struct rtllib_device *ieee, switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { case RTLLIB_FCTL_FROMDS: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - memcpy(bssid, hdr->addr2, ETH_ALEN); + ether_addr_copy(dst, hdr->addr1); + ether_addr_copy(src, hdr->addr3); + ether_addr_copy(bssid, hdr->addr2); break; case RTLLIB_FCTL_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr1, ETH_ALEN); + ether_addr_copy(dst, hdr->addr3); + ether_addr_copy(src, hdr->addr2); + ether_addr_copy(bssid, hdr->addr1); break; case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(dst, hdr->addr3); + ether_addr_copy(src, hdr->addr4); + ether_addr_copy(bssid, ieee->current_network.bssid); break; case 0: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr3, ETH_ALEN); + ether_addr_copy(dst, hdr->addr1); + ether_addr_copy(src, hdr->addr2); + ether_addr_copy(bssid, hdr->addr3); break; } } @@ -984,9 +1027,9 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, stype != RTLLIB_STYPE_DATA_CFACKPOLL && stype != RTLLIB_STYPE_QOS_DATA) { if (stype != RTLLIB_STYPE_NULLFUNC) - RTLLIB_DEBUG_DROP( - "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n", - type, stype); + netdev_dbg(ieee->dev, + "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n", + type, stype); return -1; } } @@ -998,7 +1041,8 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, /* {broad,multi}cast packets to our BSS go through */ if (is_multicast_ether_addr(dst)) { - if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) + if (memcmp(bssid, ieee->current_network.bssid, + ETH_ALEN)) return -1; } } @@ -1030,8 +1074,9 @@ static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ - RTLLIB_DEBUG_DROP("Decryption failed (not set) (SA= %pM)\n", - hdr->addr2); + netdev_dbg(ieee->dev, + "Decryption failed (not set) (SA= %pM)\n", + hdr->addr2); ieee->ieee_stats.rx_discards_undecryptable++; return -1; } @@ -1070,13 +1115,13 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, int flen; struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr); - RTLLIB_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); + netdev_dbg(ieee->dev, "Rx Fragment received (%u)\n", frag); if (!frag_skb) { - RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG, - "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n", - (fc & RTLLIB_FCTL_MOREFRAGS) != 0, - WLAN_GET_SEQ_SEQ(sc), frag); + netdev_dbg(ieee->dev, + "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n", + (fc & RTLLIB_FCTL_MOREFRAGS) != 0, + WLAN_GET_SEQ_SEQ(sc), frag); return -1; } flen = skb->len; @@ -1141,12 +1186,13 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, */ struct eapol *eap = (struct eapol *)(skb->data + 24); - RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); + netdev_dbg(ieee->dev, + "RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); } else { - RTLLIB_DEBUG_DROP( - "encryption configured, but RX frame not encrypted (SA= %pM)\n", - hdr->addr2); + netdev_dbg(ieee->dev, + "encryption configured, but RX frame not encrypted (SA= %pM)\n", + hdr->addr2); return -1; } } @@ -1155,15 +1201,16 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, rtllib_is_eapol_frame(ieee, skb, hdrlen)) { struct eapol *eap = (struct eapol *)(skb->data + 24); - RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); + netdev_dbg(ieee->dev, + "RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); } if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep && !rtllib_is_eapol_frame(ieee, skb, hdrlen)) { - RTLLIB_DEBUG_DROP( - "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n", - hdr->addr2); + netdev_dbg(ieee->dev, + "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n", + hdr->addr2); return -1; } @@ -1173,7 +1220,8 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, return 0; } -static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, u8 nr_subframes) +static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, + u8 nr_subframes) { if (unicast) { @@ -1208,25 +1256,33 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, struct sk_buff *sub_skb = rxb->subframes[i]; if (sub_skb) { - /* convert hdr + possible LLC headers into Ethernet header */ + /* convert hdr + possible LLC headers + * into Ethernet header + */ ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; if (sub_skb->len >= 8 && ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType + /* remove RFC1042 or Bridge-Tunnel encapsulation + * and replace EtherType */ skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + ether_addr_copy(skb_push(sub_skb, ETH_ALEN), + src); + ether_addr_copy(skb_push(sub_skb, ETH_ALEN), + dst); } else { u16 len; - /* Leave Ethernet header part of hdr and full payload */ + /* Leave Ethernet header part of hdr + * and full payload + */ len = sub_skb->len; memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + ether_addr_copy(skb_push(sub_skb, ETH_ALEN), + src); + ether_addr_copy(skb_push(sub_skb, ETH_ALEN), + dst); } ieee->stats.rx_packets++; @@ -1241,7 +1297,8 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, sub_skb->dev = dev; sub_skb->dev->stats.rx_packets++; sub_skb->dev->stats.rx_bytes += sub_skb->len; - sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + /* 802.11 crc not sufficient */ + sub_skb->ip_summed = CHECKSUM_NONE; netif_rx(sub_skb); } } @@ -1258,7 +1315,11 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, struct rx_ts_record *pTS = NULL; u16 fc, sc, SeqNum = 0; u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0; - u8 dst[ETH_ALEN], src[ETH_ALEN], bssid[ETH_ALEN] = {0}, *payload; + u8 *payload; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 bssid[ETH_ALEN] = {0}; + size_t hdrlen = 0; bool bToOtherSTA = false; int ret = 0, i = 0; @@ -1282,7 +1343,8 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /*Filter pkt has too small length */ hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats); if (skb->len < hdrlen) { - netdev_info(dev, "%s():ERR!!! skb->len is smaller than hdrlen\n", + netdev_info(dev, + "%s():ERR!!! skb->len is smaller than hdrlen\n", __func__); goto rx_dropped; } @@ -1327,10 +1389,13 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, goto rx_dropped; /* Send pspoll based on moredata */ - if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP) - && (ieee->polling) && (!bToOtherSTA)) { + if ((ieee->iw_mode == IW_MODE_INFRA) && + (ieee->sta_sleep == LPS_IS_SLEEP) && + (ieee->polling) && (!bToOtherSTA)) { if (WLAN_FC_MORE_DATA(fc)) { - /* more data bit is set, let's request a new frame from the AP */ + /* more data bit is set, let's request a new frame + * from the AP + */ rtllib_sta_ps_send_pspoll_frame(ieee); } else { ieee->polling = false; @@ -1356,7 +1421,8 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, && (!bToOtherSTA)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); - GetTs(ieee, (struct ts_common_info **) &pTS, hdr->addr2, TID, RX_DIR, true); + GetTs(ieee, (struct ts_common_info **) &pTS, hdr->addr2, TID, + RX_DIR, true); if (TID != 0 && TID != 3) ieee->bis_any_nonbepkts = true; } @@ -1371,7 +1437,9 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* to parse amsdu packets */ /* qos data packets & reserved bit is 1 */ if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) { - /* only to free rxb, and not submit the packets to upper layer */ + /* only to free rxb, and not submit the packets + * to upper layer + */ for (i = 0; i < rxb->nr_subframes; i++) dev_kfree_skb(rxb->subframes[i]); kfree(rxb); @@ -1393,7 +1461,8 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, } /* Indicate packets to upper layer or Rx Reorder */ - if (ieee->pHTInfo->bCurRxReorderEnable == false || pTS == NULL || bToOtherSTA) + if (ieee->pHTInfo->bCurRxReorderEnable == false || pTS == NULL || + bToOtherSTA) rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src); else RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); @@ -1522,8 +1591,9 @@ static int rtllib_verify_qos_info(struct rtllib_qos_information_element /* Parse a QoS parameter element */ static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info - *element_param, struct rtllib_info_element - *info_element) + *element_param, + struct rtllib_info_element + *info_element) { int ret = 0; u16 size = sizeof(struct rtllib_qos_parameter_info) - 2; @@ -1545,10 +1615,10 @@ static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info } /* Parse a QoS information element */ -static int rtllib_read_qos_info_element(struct - rtllib_qos_information_element - *element_info, struct rtllib_info_element - *info_element) +static int rtllib_read_qos_info_element(struct rtllib_qos_information_element + *element_info, + struct rtllib_info_element + *info_element) { int ret = 0; u16 size = sizeof(struct rtllib_qos_information_element) - 2; @@ -1558,7 +1628,8 @@ static int rtllib_read_qos_info_element(struct if (info_element == NULL) return -1; - if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) { + if ((info_element->id == QOS_ELEMENT_ID) && + (info_element->len == size)) { memcpy(element_info->qui, info_element->data, info_element->len); element_info->elementID = info_element->id; @@ -1568,14 +1639,14 @@ static int rtllib_read_qos_info_element(struct if (ret == 0) ret = rtllib_verify_qos_info(element_info, - QOS_OUI_INFO_SUB_TYPE); + QOS_OUI_INFO_SUB_TYPE); return ret; } /* Write QoS parameters from the ac parameters. */ static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm, - struct rtllib_qos_data *qos_data) + struct rtllib_qos_data *qos_data) { struct rtllib_qos_ac_parameter *ac_params; struct rtllib_qos_parameters *qos_param = &(qos_data->parameters); @@ -1619,11 +1690,13 @@ static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ - qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci]; + qos_param->aifs[aci] = max_t(u8, qos_param->aifs[aci], 2); - qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & 0x0F); + qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & + 0x0F); - qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max & 0xF0) >> 4); + qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max & + 0xF0) >> 4); qos_param->flag[aci] = (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; @@ -1636,9 +1709,10 @@ static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info * parameters element. check the information element length to decide * which type to read */ -static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element +static int rtllib_parse_qos_info_param_IE(struct rtllib_device *ieee, + struct rtllib_info_element *info_element, - struct rtllib_network *network) + struct rtllib_network *network) { int rc = 0; struct rtllib_qos_information_element qos_info_element; @@ -1663,7 +1737,7 @@ static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element } if (rc == 0) { - RTLLIB_DEBUG_QOS("QoS is supported\n"); + netdev_dbg(ieee->dev, "QoS is supported\n"); network->qos_data.supported = 1; } return rc; @@ -1713,15 +1787,19 @@ static inline void rtllib_extract_country_ie( { if (IS_DOT11D_ENABLE(ieee)) { if (info_element->len != 0) { - memcpy(network->CountryIeBuf, info_element->data, info_element->len); + memcpy(network->CountryIeBuf, info_element->data, + info_element->len); network->CountryIeLen = info_element->len; if (!IS_COUNTRY_IE_VALID(ieee)) { - if (rtllib_act_scanning(ieee, false) && ieee->FirstIe_InScan) + if (rtllib_act_scanning(ieee, false) && + ieee->FirstIe_InScan) netdev_info(ieee->dev, "Received beacon ContryIE, SSID: <%s>\n", network->ssid); - Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); + Dot11d_UpdateCountryIe(ieee, addr2, + info_element->len, + info_element->data); } } @@ -1731,6 +1809,238 @@ static inline void rtllib_extract_country_ie( } +static void rtllib_parse_mife_generic(struct rtllib_device *ieee, + struct rtllib_info_element *info_element, + struct rtllib_network *network, + u16 *tmp_htcap_len, + u16 *tmp_htinfo_len) +{ + u16 ht_realtek_agg_len = 0; + u8 ht_realtek_agg_buf[MAX_IE_LEN]; + + if (!rtllib_parse_qos_info_param_IE(ieee, info_element, network)) + return; + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x01) { + network->wpa_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->wpa_ie, info_element, network->wpa_ie_len); + return; + } + if (info_element->len == 7 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x01 && + info_element->data[4] == 0x02) + network->Turbo_Enable = 1; + + if (*tmp_htcap_len == 0) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x033) { + *tmp_htcap_len = min_t(u8, info_element->len, + MAX_IE_LEN); + if (*tmp_htcap_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = min_t(u16, *tmp_htcap_len, sizeof(network->bssht.bdHTCapBuf)); + memcpy(network->bssht.bdHTCapBuf, + info_element->data, + network->bssht.bdHTCapLen); + } + } + if (*tmp_htcap_len != 0) { + network->bssht.bdSupportHT = true; + network->bssht.bdHT1R = ((((struct ht_capab_ele *)(network->bssht.bdHTCapBuf))->MCS[1]) == 0); + } else { + network->bssht.bdSupportHT = false; + network->bssht.bdHT1R = false; + } + } + + + if (*tmp_htinfo_len == 0) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x034) { + *tmp_htinfo_len = min_t(u8, info_element->len, + MAX_IE_LEN); + if (*tmp_htinfo_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTInfoLen = min_t(u16, *tmp_htinfo_len, sizeof(network->bssht.bdHTInfoBuf)); + memcpy(network->bssht.bdHTInfoBuf, + info_element->data, + network->bssht.bdHTInfoLen); + } + + } + } + + if (ieee->aggregation) { + if (network->bssht.bdSupportHT) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x02) { + ht_realtek_agg_len = min_t(u8, + info_element->len, + MAX_IE_LEN); + memcpy(ht_realtek_agg_buf, + info_element->data, + info_element->len); + } + if (ht_realtek_agg_len >= 5) { + network->realtek_cap_exit = true; + network->bssht.bdRT2RTAggregation = true; + + if ((ht_realtek_agg_buf[4] == 1) && + (ht_realtek_agg_buf[5] & 0x02)) + network->bssht.bdRT2RTLongSlotTime = true; + + if ((ht_realtek_agg_buf[4] == 1) && + (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE)) + network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; + } + } + if (ht_realtek_agg_len >= 5) { + if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP)) + network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP; + } + } + + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x05 && + info_element->data[2] == 0xb5) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0a && + info_element->data[2] == 0xf7) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x10 && + info_element->data[2] == 0x18)) { + network->broadcom_cap_exist = true; + } + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0c && + info_element->data[2] == 0x43) + network->ralink_cap_exist = true; + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x03 && + info_element->data[2] == 0x7f) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x13 && + info_element->data[2] == 0x74)) + network->atheros_cap_exist = true; + + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0x43)) + network->marvell_cap_exist = true; + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96) + network->cisco_cap_exist = true; + + + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0a && + info_element->data[2] == 0xf5) + network->airgo_cap_exist = true; + + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x01) { + if (info_element->len == 6) { + memcpy(network->CcxRmState, &info_element[4], 2); + if (network->CcxRmState[0] != 0) + network->bCcxRmEnable = true; + else + network->bCcxRmEnable = false; + network->MBssidMask = network->CcxRmState[1] & 0x07; + if (network->MBssidMask != 0) { + network->bMBssidValid = true; + network->MBssidMask = 0xff << + (network->MBssidMask); + ether_addr_copy(network->MBssid, + network->bssid); + network->MBssid[5] &= network->MBssidMask; + } else { + network->bMBssidValid = false; + } + } else { + network->bCcxRmEnable = false; + } + } + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x03) { + if (info_element->len == 5) { + network->bWithCcxVerNum = true; + network->BssCcxVerNumber = info_element->data[4]; + } else { + network->bWithCcxVerNum = false; + network->BssCcxVerNumber = 0; + } + } + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x04) { + netdev_dbg(ieee->dev, "MFIE_TYPE_WZC: %d bytes\n", + info_element->len); + network->wzc_ie_len = min(info_element->len+2, MAX_WZC_IE_LEN); + memcpy(network->wzc_ie, info_element, network->wzc_ie_len); + } +} + +static void rtllib_parse_mfie_ht_cap(struct rtllib_info_element *info_element, + struct rtllib_network *network, + u16 *tmp_htcap_len) +{ + struct bss_ht *ht = &network->bssht; + + *tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); + if (*tmp_htcap_len != 0) { + ht->bdHTSpecVer = HT_SPEC_VER_EWC; + ht->bdHTCapLen = min_t(u16, *tmp_htcap_len, + sizeof(ht->bdHTCapBuf)); + memcpy(ht->bdHTCapBuf, info_element->data, ht->bdHTCapLen); + + ht->bdSupportHT = true; + ht->bdHT1R = ((((struct ht_capab_ele *) + ht->bdHTCapBuf))->MCS[1]) == 0; + + ht->bdBandWidth = (enum ht_channel_width) + (((struct ht_capab_ele *) + (ht->bdHTCapBuf))->ChlWidth); + } else { + ht->bdSupportHT = false; + ht->bdHT1R = false; + ht->bdBandWidth = HT_CHANNEL_WIDTH_20; + } +} + int rtllib_parse_info_param(struct rtllib_device *ieee, struct rtllib_info_element *info_element, u16 length, @@ -1741,17 +2051,15 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, short offset; u16 tmp_htcap_len = 0; u16 tmp_htinfo_len = 0; - u16 ht_realtek_agg_len = 0; - u8 ht_realtek_agg_buf[MAX_IE_LEN]; char rates_str[64]; char *p; while (length >= sizeof(*info_element)) { if (sizeof(*info_element) + info_element->len > length) { - RTLLIB_DEBUG_MGMT("Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + - sizeof(*info_element), - length, info_element->id); + netdev_dbg(ieee->dev, + "Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + sizeof(*info_element), + length, info_element->id); /* We stop processing but don't return an error here * because some misbehaviour APs break this rule. ie. * Orinoco AP1000. @@ -1769,13 +2077,14 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, network->ssid_len = min(info_element->len, (u8) IW_ESSID_MAX_SIZE); - memcpy(network->ssid, info_element->data, network->ssid_len); + memcpy(network->ssid, info_element->data, + network->ssid_len); if (network->ssid_len < IW_ESSID_MAX_SIZE) memset(network->ssid + network->ssid_len, 0, IW_ESSID_MAX_SIZE - network->ssid_len); - RTLLIB_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n", - network->ssid, network->ssid_len); + netdev_dbg(ieee->dev, "MFIE_TYPE_SSID: '%s' len=%d.\n", + network->ssid, network->ssid_len); break; case MFIE_TYPE_RATES: @@ -1802,8 +2111,8 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, } } - RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); + netdev_dbg(ieee->dev, "MFIE_TYPE_RATES: '%s' (%d)\n", + rates_str, network->rates_len); break; case MFIE_TYPE_RATES_EX: @@ -1825,22 +2134,22 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, } } - RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); + netdev_dbg(ieee->dev, "MFIE_TYPE_RATES_EX: '%s' (%d)\n", + rates_str, network->rates_ex_len); break; case MFIE_TYPE_DS_SET: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n", - info_element->data[0]); + netdev_dbg(ieee->dev, "MFIE_TYPE_DS_SET: %d\n", + info_element->data[0]); network->channel = info_element->data[0]; break; case MFIE_TYPE_FH_SET: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n"); + netdev_dbg(ieee->dev, "MFIE_TYPE_FH_SET: ignored\n"); break; case MFIE_TYPE_CF_SET: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n"); + netdev_dbg(ieee->dev, "MFIE_TYPE_CF_SET: ignored\n"); break; case MFIE_TYPE_TIM: @@ -1879,212 +2188,31 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, case MFIE_TYPE_ERP: network->erp_value = info_element->data[0]; network->flags |= NETWORK_HAS_ERP_VALUE; - RTLLIB_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", - network->erp_value); + netdev_dbg(ieee->dev, "MFIE_TYPE_ERP_SET: %d\n", + network->erp_value); break; case MFIE_TYPE_IBSS_SET: network->atim_window = info_element->data[0]; - RTLLIB_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n", - network->atim_window); + netdev_dbg(ieee->dev, "MFIE_TYPE_IBSS_SET: %d\n", + network->atim_window); break; case MFIE_TYPE_CHALLENGE: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n"); + netdev_dbg(ieee->dev, "MFIE_TYPE_CHALLENGE: ignored\n"); break; case MFIE_TYPE_GENERIC: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n", - info_element->len); - if (!rtllib_parse_qos_info_param_IE(info_element, - network)) - break; - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - network->wpa_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->wpa_ie, info_element, - network->wpa_ie_len); - break; - } - if (info_element->len == 7 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x01 && - info_element->data[4] == 0x02) - network->Turbo_Enable = 1; - - if (tmp_htcap_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x033) { - - tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); - if (tmp_htcap_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = min_t(u16, tmp_htcap_len, sizeof(network->bssht.bdHTCapBuf)); - memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); - } - } - if (tmp_htcap_len != 0) { - network->bssht.bdSupportHT = true; - network->bssht.bdHT1R = ((((struct ht_capab_ele *)(network->bssht.bdHTCapBuf))->MCS[1]) == 0); - } else { - network->bssht.bdSupportHT = false; - network->bssht.bdHT1R = false; - } - } - + netdev_dbg(ieee->dev, "MFIE_TYPE_GENERIC: %d bytes\n", + info_element->len); - if (tmp_htinfo_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x034) { - tmp_htinfo_len = min_t(u8, info_element->len, MAX_IE_LEN); - if (tmp_htinfo_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTInfoLen = min_t(u16, tmp_htinfo_len, sizeof(network->bssht.bdHTInfoBuf)); - memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); - } - - } - } - - if (ieee->aggregation) { - if (network->bssht.bdSupportHT) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x02) { - ht_realtek_agg_len = min_t(u8, info_element->len, MAX_IE_LEN); - memcpy(ht_realtek_agg_buf, info_element->data, info_element->len); - } - if (ht_realtek_agg_len >= 5) { - network->realtek_cap_exit = true; - network->bssht.bdRT2RTAggregation = true; - - if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) - network->bssht.bdRT2RTLongSlotTime = true; - - if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE)) - network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; - } - } - if (ht_realtek_agg_len >= 5) { - if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP)) - network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP; - } - } - - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x05 && - info_element->data[2] == 0xb5) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf7) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x10 && - info_element->data[2] == 0x18)) { - network->broadcom_cap_exist = true; - } - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0c && - info_element->data[2] == 0x43) - network->ralink_cap_exist = true; - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x03 && - info_element->data[2] == 0x7f) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x13 && - info_element->data[2] == 0x74)) - network->atheros_cap_exist = true; - - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0x43)) - network->marvell_cap_exist = true; - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96) - network->cisco_cap_exist = true; - - - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf5) - network->airgo_cap_exist = true; - - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x01) { - if (info_element->len == 6) { - memcpy(network->CcxRmState, &info_element[4], 2); - if (network->CcxRmState[0] != 0) - network->bCcxRmEnable = true; - else - network->bCcxRmEnable = false; - network->MBssidMask = network->CcxRmState[1] & 0x07; - if (network->MBssidMask != 0) { - network->bMBssidValid = true; - network->MBssidMask = 0xff << (network->MBssidMask); - memcpy(network->MBssid, network->bssid, ETH_ALEN); - network->MBssid[5] &= network->MBssidMask; - } else { - network->bMBssidValid = false; - } - } else { - network->bCcxRmEnable = false; - } - } - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x03) { - if (info_element->len == 5) { - network->bWithCcxVerNum = true; - network->BssCcxVerNumber = info_element->data[4]; - } else { - network->bWithCcxVerNum = false; - network->BssCcxVerNumber = 0; - } - } - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x04) { - RTLLIB_DEBUG_MGMT("MFIE_TYPE_WZC: %d bytes\n", - info_element->len); - network->wzc_ie_len = min(info_element->len+2, - MAX_WZC_IE_LEN); - memcpy(network->wzc_ie, info_element, - network->wzc_ie_len); - } + rtllib_parse_mife_generic(ieee, info_element, network, + &tmp_htcap_len, + &tmp_htinfo_len); break; case MFIE_TYPE_RSN: - RTLLIB_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n", - info_element->len); + netdev_dbg(ieee->dev, "MFIE_TYPE_RSN: %d bytes\n", + info_element->len); network->rsn_ie_len = min(info_element->len + 2, MAX_WPA_IE_LEN); memcpy(network->rsn_ie, info_element, @@ -2092,36 +2220,19 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, break; case MFIE_TYPE_HT_CAP: - RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", - info_element->len); - tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); - if (tmp_htcap_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? - sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf, - info_element->data, - network->bssht.bdHTCapLen); + netdev_dbg(ieee->dev, "MFIE_TYPE_HT_CAP: %d bytes\n", + info_element->len); - network->bssht.bdSupportHT = true; - network->bssht.bdHT1R = ((((struct ht_capab_ele *) - network->bssht.bdHTCapBuf))->MCS[1]) == 0; - - network->bssht.bdBandWidth = (enum ht_channel_width) - (((struct ht_capab_ele *) - (network->bssht.bdHTCapBuf))->ChlWidth); - } else { - network->bssht.bdSupportHT = false; - network->bssht.bdHT1R = false; - network->bssht.bdBandWidth = HT_CHANNEL_WIDTH_20; - } + rtllib_parse_mfie_ht_cap(info_element, network, + &tmp_htcap_len); break; case MFIE_TYPE_HT_INFO: - RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", - info_element->len); - tmp_htinfo_len = min_t(u8, info_element->len, MAX_IE_LEN); + netdev_dbg(ieee->dev, "MFIE_TYPE_HT_INFO: %d bytes\n", + info_element->len); + tmp_htinfo_len = min_t(u8, info_element->len, + MAX_IE_LEN); if (tmp_htinfo_len) { network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; network->bssht.bdHTInfoLen = tmp_htinfo_len > @@ -2135,8 +2246,8 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, break; case MFIE_TYPE_AIRONET: - RTLLIB_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", - info_element->len); + netdev_dbg(ieee->dev, "MFIE_TYPE_AIRONET: %d bytes\n", + info_element->len); if (info_element->len > IE_CISCO_FLAG_POSITION) { network->bWithAironetIE = true; @@ -2158,17 +2269,17 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, break; case MFIE_TYPE_COUNTRY: - RTLLIB_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", - info_element->len); + netdev_dbg(ieee->dev, "MFIE_TYPE_COUNTRY: %d bytes\n", + info_element->len); rtllib_extract_country_ie(ieee, info_element, network, network->bssid); break; /* TODO */ default: - RTLLIB_DEBUG_MGMT - ("Unsupported info element: %s (%d)\n", - get_info_element_string(info_element->id), - info_element->id); + netdev_dbg(ieee->dev, + "Unsupported info element: %s (%d)\n", + get_info_element_string(info_element->id), + info_element->id); break; } @@ -2206,7 +2317,7 @@ static inline int rtllib_network_init( memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data)); /* Pull out fixed field data */ - memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); + ether_addr_copy(network->bssid, beacon->header.addr3); network->capability = le16_to_cpu(beacon->capability); network->last_scanned = jiffies; network->time_stamp[0] = beacon->time_stamp[0]; @@ -2266,10 +2377,9 @@ static inline int rtllib_network_init( } if (network->mode == 0) { - RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' network.\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid); + netdev_dbg(ieee->dev, "Filtered out '%s (%pM)' network.\n", + escape_essid(network->ssid, network->ssid_len), + network->bssid); return 1; } @@ -2309,7 +2419,8 @@ static inline int is_same_network(struct rtllib_network *src, } -static inline void update_network(struct rtllib_network *dst, +static inline void update_network(struct rtllib_device *ieee, + struct rtllib_network *dst, struct rtllib_network *src) { int qos_active; @@ -2383,12 +2494,12 @@ static inline void update_network(struct rtllib_network *dst, sizeof(struct rtllib_qos_data)); if (dst->qos_data.supported == 1) { if (dst->ssid_len) - RTLLIB_DEBUG_QOS - ("QoS the network %s is QoS supported\n", - dst->ssid); + netdev_dbg(ieee->dev, + "QoS the network %s is QoS supported\n", + dst->ssid); else - RTLLIB_DEBUG_QOS - ("QoS the network is QoS supported\n"); + netdev_dbg(ieee->dev, + "QoS the network is QoS supported\n"); } dst->qos_data.active = qos_active; dst->qos_data.old_param_count = old_param; @@ -2419,9 +2530,9 @@ static inline void update_network(struct rtllib_network *dst, dst->BssCcxVerNumber = src->BssCcxVerNumber; } -static inline int is_beacon(__le16 fc) +static inline int is_beacon(u16 fc) { - return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == RTLLIB_STYPE_BEACON); + return (WLAN_FC_GET_STYPE(fc) == RTLLIB_STYPE_BEACON); } static int IsPassiveChannel(struct rtllib_device *rtllib, u8 channel) @@ -2462,40 +2573,37 @@ static inline void rtllib_process_probe_response( short renew; struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), GFP_ATOMIC); + u16 frame_ctl = le16_to_cpu(beacon->header.frame_ctl); if (!network) return; - RTLLIB_DEBUG_SCAN( - "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - (le16_to_cpu(beacon->capability) & (1<<0xf)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0xe)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0xd)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0xc)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0xb)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0xa)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x9)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x8)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x7)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x6)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x5)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x4)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x3)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x2)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x1)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1<<0x0)) ? '1' : '0'); + netdev_dbg(ieee->dev, + "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + escape_essid(info_element->data, info_element->len), + beacon->header.addr3, + (le16_to_cpu(beacon->capability) & (1<<0xf)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xe)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xd)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xc)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xb)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xa)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x9)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x8)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x7)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x6)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x5)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x4)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x3)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x2)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x1)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x0)) ? '1' : '0'); if (rtllib_network_init(ieee, beacon, network, stats)) { - RTLLIB_DEBUG_SCAN("Dropped '%s' ( %pM) via %s.\n", - escape_essid(info_element->data, - info_element->len), - beacon->header.addr3, - WLAN_FC_GET_STYPE( - le16_to_cpu(beacon->header.frame_ctl)) == - RTLLIB_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); + netdev_dbg(ieee->dev, "Dropped '%s' ( %pM) via %s.\n", + escape_essid(info_element->data, info_element->len), + beacon->header.addr3, + is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); goto free_network; } @@ -2503,8 +2611,7 @@ static inline void rtllib_process_probe_response( if (!rtllib_legal_channel(ieee, network->channel)) goto free_network; - if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) == - RTLLIB_STYPE_PROBE_RESP) { + if (WLAN_FC_GET_STYPE(frame_ctl) == RTLLIB_STYPE_PROBE_RESP) { if (IsPassiveChannel(ieee, network->channel)) { netdev_info(ieee->dev, "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", @@ -2528,7 +2635,7 @@ static inline void rtllib_process_probe_response( spin_lock_irqsave(&ieee->lock, flags); if (is_same_network(&ieee->current_network, network, (network->ssid_len ? 1 : 0))) { - update_network(&ieee->current_network, network); + update_network(ieee, &ieee->current_network, network); if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G) && ieee->current_network.berp_info_valid) { @@ -2537,7 +2644,7 @@ static inline void rtllib_process_probe_response( else ieee->current_network.buseprotection = false; } - if (is_beacon(beacon->header.frame_ctl)) { + if (is_beacon(frame_ctl)) { if (ieee->state >= RTLLIB_LINKED) ieee->LinkDetectInfo.NumRecvBcnInPeriod++; } @@ -2559,10 +2666,10 @@ static inline void rtllib_process_probe_response( /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from network list.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid); + netdev_dbg(ieee->dev, + "Expired '%s' ( %pM) from network list.\n", + escape_essid(target->ssid, target->ssid_len), + target->bssid); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -2570,26 +2677,20 @@ static inline void rtllib_process_probe_response( list_del(ieee->network_free_list.next); } + netdev_dbg(ieee->dev, "Adding '%s' ( %pM) via %s.\n", + escape_essid(network->ssid, network->ssid_len), + network->bssid, + is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); - RTLLIB_DEBUG_SCAN("Adding '%s' ( %pM) via %s.\n", - escape_essid(network->ssid, - network->ssid_len), network->bssid, - WLAN_FC_GET_STYPE( - le16_to_cpu(beacon->header.frame_ctl)) == - RTLLIB_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); memcpy(target, network, sizeof(*target)); list_add_tail(&target->list, &ieee->network_list); if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) rtllib_softmac_new_net(ieee, network); } else { - RTLLIB_DEBUG_SCAN("Updating '%s' ( %pM) via %s.\n", - escape_essid(target->ssid, - target->ssid_len), target->bssid, - WLAN_FC_GET_STYPE( - le16_to_cpu(beacon->header.frame_ctl)) == - RTLLIB_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); + netdev_dbg(ieee->dev, "Updating '%s' ( %pM) via %s.\n", + escape_essid(target->ssid, target->ssid_len), + target->bssid, + is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); /* we have an entry and we are going to update it. But this * entry may be already expired. In this case we do the same @@ -2604,13 +2705,13 @@ static inline void rtllib_process_probe_response( network->ssid_len) == 0) && (ieee->state == RTLLIB_NOLINK)))) renew = 1; - update_network(target, network); + update_network(ieee, target, network); if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) rtllib_softmac_new_net(ieee, network); } spin_unlock_irqrestore(&ieee->lock, flags); - if (is_beacon(beacon->header.frame_ctl) && + if (is_beacon(frame_ctl) && is_same_network(&ieee->current_network, network, (network->ssid_len ? 1 : 0)) && (ieee->state == RTLLIB_LINKED)) { @@ -2637,9 +2738,8 @@ void rtllib_rx_mgt(struct rtllib_device *ieee, switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) { case RTLLIB_STYPE_BEACON: - RTLLIB_DEBUG_MGMT("received BEACON (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); - RTLLIB_DEBUG_SCAN("Beacon\n"); + netdev_dbg(ieee->dev, "received BEACON (%d)\n", + WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); rtllib_process_probe_response( ieee, (struct rtllib_probe_response *)header, stats); @@ -2652,17 +2752,14 @@ void rtllib_rx_mgt(struct rtllib_device *ieee, break; case RTLLIB_STYPE_PROBE_RESP: - RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); - RTLLIB_DEBUG_SCAN("Probe response\n"); + netdev_dbg(ieee->dev, "received PROBE RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); rtllib_process_probe_response(ieee, (struct rtllib_probe_response *)header, stats); break; case RTLLIB_STYPE_PROBE_REQ: - RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n", - WLAN_FC_GET_STYPE( - le16_to_cpu(header->frame_ctl))); - RTLLIB_DEBUG_SCAN("Probe request\n"); + netdev_dbg(ieee->dev, "received PROBE RESQUEST (%d)\n", + WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && ((ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) && diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 8f5e88b802c8..9dce121d660e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -272,9 +272,10 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) ieee->seq_ctrl[0]++; /* check whether the managed packet queued greater than 5 */ - if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) || - (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) || - (ieee->queue_stop)) { + if (!ieee->check_nic_enough_desc(ieee->dev, + tcb_desc->queue_index) || + skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) || + ieee->queue_stop) { /* insert the skb packet to the management queue * * as for the completion function, it does not need @@ -372,7 +373,7 @@ static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) req->header.duration_id = 0; memset(req->header.addr1, 0xff, ETH_ALEN); - memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + ether_addr_copy(req->header.addr2, ieee->dev->dev_addr); memset(req->header.addr3, 0xff, ETH_ALEN); tag = (u8 *) skb_put(skb, len + 2 + rate_len); @@ -815,9 +816,9 @@ inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon, auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP); auth->header.duration_id = cpu_to_le16(0x013a); - memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); + ether_addr_copy(auth->header.addr1, beacon->bssid); + ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(auth->header.addr3, beacon->bssid); if (ieee->auth_mode == 0) auth->algorithm = WLAN_AUTH_OPEN; else if (ieee->auth_mode == 1) @@ -832,7 +833,8 @@ inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon, return skb; } -static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest) +static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, + const u8 *dest) { u8 *tag; int beacon_size; @@ -908,9 +910,9 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest) beacon_buf = (struct rtllib_probe_response *) skb_put(skb, (beacon_size - ieee->tx_headroom)); - memcpy(beacon_buf->header.addr1, dest, ETH_ALEN); - memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(beacon_buf->header.addr1, dest); + ether_addr_copy(beacon_buf->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(beacon_buf->header.addr3, ieee->current_network.bssid); beacon_buf->header.duration_id = 0; beacon_buf->beacon_interval = @@ -1005,9 +1007,9 @@ static struct sk_buff *rtllib_assoc_resp(struct rtllib_device *ieee, u8 *dest) skb_put(skb, sizeof(struct rtllib_assoc_response_frame)); assoc->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_RESP); - memcpy(assoc->header.addr1, dest, ETH_ALEN); - memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + ether_addr_copy(assoc->header.addr1, dest); + ether_addr_copy(assoc->header.addr3, ieee->dev->dev_addr); + ether_addr_copy(assoc->header.addr2, ieee->dev->dev_addr); assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS); @@ -1062,9 +1064,9 @@ static struct sk_buff *rtllib_auth_resp(struct rtllib_device *ieee, int status, auth->transaction = cpu_to_le16(2); auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); - memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr1, dest, ETH_ALEN); + ether_addr_copy(auth->header.addr3, ieee->dev->dev_addr); + ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(auth->header.addr1, dest); auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH); return skb; @@ -1085,9 +1087,9 @@ static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr) hdr = (struct rtllib_hdr_3addr *)skb_put(skb, sizeof(struct rtllib_hdr_3addr)); - memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(hdr->addr1, ieee->current_network.bssid); + ether_addr_copy(hdr->addr2, ieee->dev->dev_addr); + ether_addr_copy(hdr->addr3, ieee->current_network.bssid); hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA | RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS | @@ -1112,8 +1114,8 @@ static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee) hdr = (struct rtllib_pspoll_hdr *)skb_put(skb, sizeof(struct rtllib_pspoll_hdr)); - memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN); + ether_addr_copy(hdr->bssid, ieee->current_network.bssid); + ether_addr_copy(hdr->ta, ieee->dev->dev_addr); hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL | @@ -1265,11 +1267,11 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, hdr->header.frame_ctl = RTLLIB_STYPE_ASSOC_REQ; hdr->header.duration_id = cpu_to_le16(37); - memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); + ether_addr_copy(hdr->header.addr1, beacon->bssid); + ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(hdr->header.addr3, beacon->bssid); - memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); + ether_addr_copy(ieee->ap_mac_addr, beacon->bssid); hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS); if (beacon->capability & WLAN_CAPABILITY_PRIVACY) @@ -1438,10 +1440,10 @@ void rtllib_associate_abort(struct rtllib_device *ieee) * with, so we retry or just get back to NO_LINK and scanning */ if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING) { - RTLLIB_DEBUG_MGMT("Authentication failed\n"); + netdev_dbg(ieee->dev, "Authentication failed\n"); ieee->softmac_stats.no_auth_rs++; } else { - RTLLIB_DEBUG_MGMT("Association failed\n"); + netdev_dbg(ieee->dev, "Association failed\n"); ieee->softmac_stats.no_ass_rs++; } @@ -1463,7 +1465,7 @@ static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr) struct rtllib_network *beacon = &ieee->current_network; struct sk_buff *skb; - RTLLIB_DEBUG_MGMT("Stopping scan\n"); + netdev_dbg(ieee->dev, "Stopping scan\n"); ieee->softmac_stats.tx_auth_rq++; @@ -1473,7 +1475,7 @@ static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr) rtllib_associate_abort(ieee); else { ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATING; - RTLLIB_DEBUG_MGMT("Sending authentication request\n"); + netdev_dbg(ieee->dev, "Sending authentication request\n"); softmac_mgmt_xmit(skb, ieee); if (!timer_pending(&ieee->associate_timer)) { ieee->associate_timer.expires = jiffies + (HZ / 2); @@ -1482,7 +1484,8 @@ static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr) } } -static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, int chlen) +static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, + int chlen) { u8 *c; struct sk_buff *skb; @@ -1501,7 +1504,8 @@ static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, int *(c++) = chlen; memcpy(c, challenge, chlen); - RTLLIB_DEBUG_MGMT("Sending authentication challenge response\n"); + netdev_dbg(ieee->dev, + "Sending authentication challenge response\n"); rtllib_encrypt_fragment(ieee, skb, sizeof(struct rtllib_hdr_3addr)); @@ -1519,7 +1523,7 @@ static void rtllib_associate_step2(struct rtllib_device *ieee) del_timer_sync(&ieee->associate_timer); - RTLLIB_DEBUG_MGMT("Sending association request\n"); + netdev_dbg(ieee->dev, "Sending association request\n"); ieee->softmac_stats.tx_ass_rq++; skb = rtllib_association_req(beacon, ieee); @@ -1738,7 +1742,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, /* Join the network for the first time */ ieee->AsocRetryCount = 0; if ((ieee->current_network.qos_data.supported == 1) && - ieee->current_network.bssht.bdSupportHT) + ieee->current_network.bssht.bdSupportHT) HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); else @@ -1753,14 +1757,19 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, &ieee->associate_procedure_wq, 0); } else { if (rtllib_is_54g(&ieee->current_network) && - (ieee->modulation & RTLLIB_OFDM_MODULATION)) { + (ieee->modulation & + RTLLIB_OFDM_MODULATION)) { ieee->rate = 108; - ieee->SetWirelessMode(ieee->dev, IEEE_G); - netdev_info(ieee->dev, "Using G rates\n"); + ieee->SetWirelessMode(ieee->dev, + IEEE_G); + netdev_info(ieee->dev, + "Using G rates\n"); } else { ieee->rate = 22; - ieee->SetWirelessMode(ieee->dev, IEEE_B); - netdev_info(ieee->dev, "Using B rates\n"); + ieee->SetWirelessMode(ieee->dev, + IEEE_B); + netdev_info(ieee->dev, + "Using B rates\n"); } memset(ieee->dot11HTOperationalRateSet, 0, 16); ieee->state = RTLLIB_LINKED; @@ -1792,14 +1801,15 @@ void rtllib_softmac_check_all_nets(struct rtllib_device *ieee) spin_unlock_irqrestore(&ieee->lock, flags); } -static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) +static inline u16 auth_parse(struct net_device *dev, struct sk_buff *skb, + u8 **challenge, int *chlen) { struct rtllib_authentication *a; u8 *t; if (skb->len < (sizeof(struct rtllib_authentication) - sizeof(struct rtllib_info_element))) { - RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len); return 0xcafe; } *challenge = NULL; @@ -1814,22 +1824,21 @@ static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) return -ENOMEM; } } - return cpu_to_le16(a->status); + return le16_to_cpu(a->status); } -static int auth_rq_parse(struct sk_buff *skb, u8 *dest) +static int auth_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest) { struct rtllib_authentication *a; if (skb->len < (sizeof(struct rtllib_authentication) - sizeof(struct rtllib_info_element))) { - RTLLIB_DEBUG_MGMT("invalid len in auth request: %d\n", - skb->len); + netdev_dbg(dev, "invalid len in auth request: %d\n", skb->len); return -1; } a = (struct rtllib_authentication *) skb->data; - memcpy(dest, a->header.addr2, ETH_ALEN); + ether_addr_copy(dest, a->header.addr2); if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; @@ -1852,12 +1861,12 @@ static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, return -1; /* corrupted */ bssid_match = - (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) && + (!ether_addr_equal(header->addr3, ieee->current_network.bssid)) && (!is_broadcast_ether_addr(header->addr3)); if (bssid_match) return -1; - memcpy(src, header->addr2, ETH_ALEN); + ether_addr_copy(src, header->addr2); skbend = (u8 *)skb->data + skb->len; @@ -1883,20 +1892,19 @@ static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, return !strncmp(ssid, ieee->current_network.ssid, ssidlen); } -static int assoc_rq_parse(struct sk_buff *skb, u8 *dest) +static int assoc_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest) { struct rtllib_assoc_request_frame *a; if (skb->len < (sizeof(struct rtllib_assoc_request_frame) - sizeof(struct rtllib_info_element))) { - - RTLLIB_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len); + netdev_dbg(dev, "invalid len in auth request:%d\n", skb->len); return -1; } a = (struct rtllib_assoc_request_frame *) skb->data; - memcpy(dest, a->header.addr2, ETH_ALEN); + ether_addr_copy(dest, a->header.addr2); return 0; } @@ -1908,7 +1916,8 @@ static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, u16 status_code; if (skb->len < sizeof(struct rtllib_assoc_response_frame)) { - RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n", + skb->len); return 0xcafe; } @@ -1948,7 +1957,7 @@ static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee, ieee->softmac_stats.rx_auth_rq++; - status = auth_rq_parse(skb, dest); + status = auth_rq_parse(ieee->dev, skb, dest); if (status != -1) rtllib_resp_to_auth(ieee, status, dest); } @@ -1956,11 +1965,11 @@ static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee, static inline void rtllib_rx_assoc_rq(struct rtllib_device *ieee, struct sk_buff *skb) { - u8 dest[ETH_ALEN]; + ieee->softmac_stats.rx_ass_rq++; - if (assoc_rq_parse(skb, dest) != -1) + if (assoc_rq_parse(ieee->dev, skb, dest) != -1) rtllib_resp_to_assoc_rq(ieee, dest); netdev_info(ieee->dev, "New client associated: %pM\n", dest); @@ -2021,7 +2030,7 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) if (ieee->bAwakePktSent) { pPSC->LPSAwakeIntvl = 1; } else { - u8 MaxPeriod = 1; + u8 MaxPeriod = 1; if (pPSC->LPSAwakeIntvl == 0) pPSC->LPSAwakeIntvl = 1; @@ -2192,15 +2201,16 @@ void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success) } EXPORT_SYMBOL(rtllib_ps_tx_ack); -static void rtllib_process_action(struct rtllib_device *ieee, struct sk_buff *skb) +static void rtllib_process_action(struct rtllib_device *ieee, + struct sk_buff *skb) { struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; u8 *act = rtllib_get_payload((struct rtllib_hdr *)header); u8 category = 0; if (act == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "error to get payload of action frame\n"); + netdev_warn(ieee->dev, + "Error getting payload of action frame\n"); return; } @@ -2234,8 +2244,8 @@ inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_assoc_response_frame *assoc_resp; struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; - RTLLIB_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); + netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATED && @@ -2296,9 +2306,6 @@ inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, netdev_info(ieee->dev, "Association response status code 0x%x\n", errcode); - RTLLIB_DEBUG_MGMT( - "Association response status code 0x%x\n", - errcode); if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) queue_delayed_work_rsl(ieee->wq, &ieee->associate_procedure_wq, 0); @@ -2316,13 +2323,10 @@ static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb) int chlen = 0; bool bSupportNmode = true, bHalfSupportNmode = false; - errcode = auth_parse(skb, &challenge, &chlen); + errcode = auth_parse(ieee->dev, skb, &challenge, &chlen); if (errcode) { ieee->softmac_stats.rx_auth_rs_err++; - RTLLIB_DEBUG_MGMT("Authentication respose status code 0x%x", - errcode); - netdev_info(ieee->dev, "Authentication respose status code 0x%x", errcode); rtllib_associate_abort(ieee); @@ -2372,7 +2376,8 @@ inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb, if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) { if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING && (ieee->iw_mode == IW_MODE_INFRA)) { - RTLLIB_DEBUG_MGMT("Received authentication response"); + netdev_dbg(ieee->dev, + "Received authentication response"); rtllib_rx_auth_resp(ieee, skb); } else if (ieee->iw_mode == IW_MODE_MASTER) { rtllib_rx_auth_rq(ieee, skb); @@ -2651,7 +2656,7 @@ void rtllib_start_master_bss(struct rtllib_device *ieee) ieee->ssid_set = 1; } - memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); + ether_addr_copy(ieee->current_network.bssid, ieee->dev->dev_addr); ieee->set_chan(ieee->dev, ieee->current_network.channel); ieee->state = RTLLIB_LINKED; @@ -2911,7 +2916,7 @@ exit: struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee) { - u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct sk_buff *skb; struct rtllib_probe_response *b; @@ -3073,7 +3078,7 @@ void rtllib_softmac_init(struct rtllib_device *ieee) ieee->seq_ctrl[i] = 0; ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); if (!ieee->pDot11dInfo) - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for DOT11D\n"); + netdev_err(ieee->dev, "Can't alloc memory for DOT11D\n"); ieee->LinkDetectInfo.SlotIndex = 0; ieee->LinkDetectInfo.SlotNum = 2; ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; @@ -3518,9 +3523,9 @@ inline struct sk_buff *rtllib_disauth_skb(struct rtllib_network *beacon, disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH); disauth->header.duration_id = 0; - memcpy(disauth->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(disauth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(disauth->header.addr3, beacon->bssid, ETH_ALEN); + ether_addr_copy(disauth->header.addr1, beacon->bssid); + ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(disauth->header.addr3, beacon->bssid); disauth->reason = cpu_to_le16(asRsn); return skb; @@ -3545,9 +3550,9 @@ inline struct sk_buff *rtllib_disassociate_skb(struct rtllib_network *beacon, disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC); disass->header.duration_id = 0; - memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); + ether_addr_copy(disass->header.addr1, beacon->bssid); + ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr); + ether_addr_copy(disass->header.addr3, beacon->bssid); disass->reason = cpu_to_le16(asRsn); return skb; @@ -3677,8 +3682,8 @@ static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) } -static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, - u8 asRsn) +static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, + u8 *asSta, u8 asRsn) { u8 i; u8 OpMode; diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 9715a793fd37..86f52ac7d33e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -160,7 +160,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, if (is_zero_ether_addr(temp->sa_data)) { spin_lock_irqsave(&ieee->lock, flags); - memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); + ether_addr_copy(ieee->current_network.bssid, temp->sa_data); ieee->wap_set = 0; spin_unlock_irqrestore(&ieee->lock, flags); ret = -1; @@ -177,7 +177,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, spin_lock_irqsave(&ieee->lock, flags); ieee->cannot_notify = false; - memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); + ether_addr_copy(ieee->current_network.bssid, temp->sa_data); ieee->wap_set = !is_zero_ether_addr(temp->sa_data); spin_unlock_irqrestore(&ieee->lock, flags); @@ -454,13 +454,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee, proto_started = ieee->proto_started; - len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : - IW_ESSID_MAX_SIZE; - - if (len > IW_ESSID_MAX_SIZE) { - ret = -E2BIG; - goto out; - } + len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE); if (ieee->iw_mode == IW_MODE_MONITOR) { ret = -1; @@ -575,9 +569,9 @@ int rtllib_wx_set_power(struct rtllib_device *ieee, if ((!ieee->sta_wake_up) || (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "%s(): PS mode is tried to be use but driver missed a callback\n\n", - __func__); + netdev_warn(ieee->dev, + "%s(): PS mode is tried to be use but driver missed a callback\n", + __func__); return -1; } diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 3b159638bba2..e99ea5e67ef9 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -57,18 +57,19 @@ * * * 802.11 frame_control for data frames - 2 bytes - * ,-----------------------------------------------------------------------------------------. - * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| - * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| - * desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | - * | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | - * '-----------------------------------------------------------------------------------------' - * /\ - * | - * 802.11 Data Frame | - * ,--------- 'ctrl' expands to >-----------' + * ,--------------------------------------------------------------------. + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | + * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| + * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | + * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| + * desc | ver | type | ^-subtype-^ |to |from|more|retry| pwr |more |wep | + * | | | x=0 data |DS | DS |frag| | mgm |data | | + * | | | x=1 data+ack | | | | | | | | + * '--------------------------------------------------------------------' + * /\ + * | + * 802.11 Data Frame | + * ,--------- 'ctrl' expands to >---' * | * ,--'---,-------------------------------------------------------------. * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | @@ -112,15 +113,15 @@ * `-----------------------------------------' * Total: 18 non-data bytes * - * In the event that fragmentation is required, the incoming payload is split into - * N parts of size ieee->fts. The first fragment contains the SNAP header and the - * remaining packets are just data. + * In the event that fragmentation is required, the incoming payload is split + * into N parts of size ieee->fts. The first fragment contains the SNAP header + * and the remaining packets are just data. * - * If encryption is enabled, each fragment payload size is reduced by enough space - * to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) - * So if you have 1500 bytes of payload with ieee->fts set to 500 without - * encryption it will take 3 frames. With WEP it will take 4 frames as the - * payload of each frame is reduced to 492 bytes. + * If encryption is enabled, each fragment payload size is reduced by enough + * space to add the prefix and postfix (IV and ICV totalling 8 bytes in + * the case of WEP) So if you have 1500 bytes of payload with ieee->fts set to + * 500 without encryption it will take 3 frames. With WEP it will take 4 frames + * as the payload of each frame is reduced to 492 bytes. * * SKB visualization * @@ -260,7 +261,10 @@ static int rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu) if (eth->h_proto != htons(ETH_P_IP)) return 0; - RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA, skb->data, skb->len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("rtllib_classify(): ", DUMP_PREFIX_NONE, skb->data, + skb->len); +#endif ip = ip_hdr(skb); switch (ip->tos & 0xfc) { case 0x20: @@ -579,8 +583,9 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) .seq_ctl = 0, .qos_ctl = 0 }; - u8 dest[ETH_ALEN], src[ETH_ALEN]; int qos_actived = ieee->current_network.qos_data.active; + u8 dest[ETH_ALEN]; + u8 src[ETH_ALEN]; struct lib80211_crypt_data *crypt = NULL; struct cb_desc *tcb_desc; u8 bIsMulticast = false; @@ -608,8 +613,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) goto success; } /* Save source and destination addresses */ - memcpy(dest, skb->data, ETH_ALEN); - memcpy(src, skb->data+ETH_ALEN, ETH_ALEN); + ether_addr_copy(dest, skb->data); + ether_addr_copy(src, skb->data + ETH_ALEN); memset(skb->cb, 0, sizeof(skb->cb)); ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); @@ -669,8 +674,9 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) struct eapol *eap = (struct eapol *)(skb->data + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); - RTLLIB_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); + netdev_dbg(ieee->dev, + "TX: IEEE 802.11 EAPOL frame: %s\n", + eap_get_type(eap->type)); } /* Advance the SKB to the start of the payload */ @@ -694,22 +700,22 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* To DS: Addr1 = BSSID, Addr2 = SA, * Addr3 = DA */ - memcpy(&header.addr1, ieee->current_network.bssid, - ETH_ALEN); - memcpy(&header.addr2, &src, ETH_ALEN); + ether_addr_copy(header.addr1, + ieee->current_network.bssid); + ether_addr_copy(header.addr2, src); if (IsAmsdu) - memcpy(&header.addr3, - ieee->current_network.bssid, ETH_ALEN); + ether_addr_copy(header.addr3, + ieee->current_network.bssid); else - memcpy(&header.addr3, &dest, ETH_ALEN); + ether_addr_copy(header.addr3, dest); } else if (ieee->iw_mode == IW_MODE_ADHOC) { /* not From/To DS: Addr1 = DA, Addr2 = SA, * Addr3 = BSSID */ - memcpy(&header.addr1, dest, ETH_ALEN); - memcpy(&header.addr2, src, ETH_ALEN); - memcpy(&header.addr3, ieee->current_network.bssid, - ETH_ALEN); + ether_addr_copy(header.addr1, dest); + ether_addr_copy(header.addr2, src); + ether_addr_copy(header.addr3, + ieee->current_network.bssid); } bIsMulticast = is_multicast_ether_addr(header.addr1); diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index 6234aae5b069..f31d864df6cc 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -266,7 +266,7 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee, int i = 0; int err = 0; - RTLLIB_DEBUG_WX("Getting scan\n"); + netdev_dbg(ieee->dev, "Getting scan\n"); down(&ieee->wx_sem); spin_lock_irqsave(&ieee->lock, flags); @@ -281,11 +281,13 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee, ev = rtl819x_translate_scan(ieee, ev, stop, network, info); else - RTLLIB_DEBUG_SCAN("Not showing network '%s ( %pM)' due to age (%lums).\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - (jiffies - network->last_scanned) / (HZ / 100)); + netdev_dbg(ieee->dev, + "Network '%s ( %pM)' hidden due to age (%lums).\n", + escape_essid(network->ssid, + network->ssid_len), + network->bssid, + (jiffies - network->last_scanned) / + (HZ / 100)); } spin_unlock_irqrestore(&ieee->lock, flags); @@ -293,7 +295,7 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee, wrqu->data.length = ev - extra; wrqu->data.flags = 0; - RTLLIB_DEBUG_WX("exit: %d networks returned.\n", i); + netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i); return err; } @@ -311,7 +313,7 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, int i, key, key_provided, len; struct lib80211_crypt_data **crypt; - RTLLIB_DEBUG_WX("SET_ENCODE\n"); + netdev_dbg(ieee->dev, "%s()\n", __func__); key = erq->flags & IW_ENCODE_INDEX; if (key) { @@ -324,16 +326,16 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, key = ieee->crypt_info.tx_keyidx; } - RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? + netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ? "provided" : "default"); crypt = &ieee->crypt_info.crypt[key]; if (erq->flags & IW_ENCODE_DISABLED) { if (key_provided && *crypt) { - RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n", - key); + netdev_dbg(ieee->dev, + "Disabling encryption on key %d.\n", key); lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); } else - RTLLIB_DEBUG_WX("Disabling encryption.\n"); + netdev_dbg(ieee->dev, "Disabling encryption.\n"); /* Check all the keys to see if any are still configured, * and if no key index was provided, de-init them all @@ -405,9 +407,9 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, if (len > erq->length) memset(sec.keys[key] + erq->length, 0, len - erq->length); - RTLLIB_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", - key, escape_essid(sec.keys[key], len), - erq->length, len); + netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n", + key, escape_essid(sec.keys[key], len), erq->length, + len); sec.key_sizes[key] = len; (*crypt)->ops->set_key(sec.keys[key], len, NULL, (*crypt)->priv); @@ -436,8 +438,8 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, /* No key data - just set the default TX key index */ if (key_provided) { - RTLLIB_DEBUG_WX("Setting key %d to default Tx key.\n", - key); + netdev_dbg(ieee->dev, + "Setting key %d as default Tx key.\n", key); ieee->crypt_info.tx_keyidx = key; sec.active_key = key; sec.flags |= SEC_ACTIVE_KEY; @@ -449,7 +451,7 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, WLAN_AUTH_SHARED_KEY; sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; sec.flags |= SEC_AUTH_MODE; - RTLLIB_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? + netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? "OPEN" : "SHARED KEY"); /* For now we just support WEP, so only set that security level... @@ -485,7 +487,7 @@ int rtllib_wx_get_encode(struct rtllib_device *ieee, int len, key; struct lib80211_crypt_data *crypt; - RTLLIB_DEBUG_WX("GET_ENCODE\n"); + netdev_dbg(ieee->dev, "%s()\n", __func__); if (ieee->iw_mode == IW_MODE_MONITOR) return -1; @@ -508,7 +510,8 @@ int rtllib_wx_get_encode(struct rtllib_device *ieee, return 0; } len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); - erq->length = (len >= 0 ? len : 0); + + erq->length = max(len, 0); erq->flags |= IW_ENCODE_ENABLED; @@ -592,8 +595,7 @@ int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, module = "rtllib_crypt_ccmp"; break; default: - RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); + netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg); ret = -EINVAL; goto done; } @@ -673,7 +675,7 @@ done: if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && ieee->reset_port && ieee->reset_port(dev)) { - RTLLIB_DEBUG_WX("%s: reset_port failed\n", dev->name); + netdev_dbg(ieee->dev, "Port reset failed\n"); return -EINVAL; } return ret; @@ -850,8 +852,7 @@ int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len) if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) { - ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len) : - (MAX_WZC_IE_LEN); + ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN); buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index 0a17f84bb809..681611dc93d3 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -19,7 +19,7 @@ #include "ieee80211.h" #include <linux/crypto.h> - #include <linux/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/crc32.h> MODULE_AUTHOR("Jouni Malinen"); @@ -43,38 +43,24 @@ static void *prism2_wep_init(int keyidx) priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) - goto fail; + return NULL; priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tx_tfm)) { - pr_debug("ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); - priv->tx_tfm = NULL; - goto fail; - } + if (IS_ERR(priv->tx_tfm)) + goto free_priv; priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->rx_tfm)) { - pr_debug("ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); - priv->rx_tfm = NULL; - goto fail; - } + if (IS_ERR(priv->rx_tfm)) + goto free_tx; /* start WEP IV from a random value */ get_random_bytes(&priv->iv, 4); return priv; - -fail: - if (priv) { - if (priv->tx_tfm) - crypto_free_blkcipher(priv->tx_tfm); - if (priv->rx_tfm) - crypto_free_blkcipher(priv->rx_tfm); - kfree(priv); - } - +free_tx: + crypto_free_blkcipher(priv->tx_tfm); +free_priv: + kfree(priv); return NULL; } @@ -142,9 +128,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Copy rest of the WEP key (the secret part) */ memcpy(key + 3, wep->key, wep->key_len); - if (!tcb_desc->bHwSec) - { - + if (!tcb_desc->bHwSec) { /* Append little-endian CRC32 and encrypt it to produce ICV */ crc = ~crc32_le(~0, pos, len); icv = skb_put(skb, 4); @@ -201,8 +185,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Apply RC4 to data and compute CRC32 over decrypted data */ plen = skb->len - hdr_len - 8; - if (!tcb_desc->bHwSec) - { + if (!tcb_desc->bHwSec) { crypto_blkcipher_setkey(wep->rx_tfm, key, klen); sg_init_one(&sg, pos, plen+4); @@ -293,6 +276,4 @@ void __exit ieee80211_crypto_wep_exit(void) void ieee80211_wep_null(void) { -// printk("============>%s()\n", __func__); - return; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index d2e8b125b989..b00f5fd31abf 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -660,8 +660,11 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be auth = (struct ieee80211_authentication *) skb_put(skb, sizeof(struct ieee80211_authentication)); - auth->header.frame_ctl = IEEE80211_STYPE_AUTH; - if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP; + if (challengelen) + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH + | IEEE80211_FCTL_WEP); + else + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); auth->header.duration_id = 0x013a; //FIXME @@ -1364,12 +1367,10 @@ static void ieee80211_associate_complete_wq(struct work_struct *work) ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; } ieee->link_change(ieee->dev); - if(ieee->is_silent_reset == 0){ + if (!ieee->is_silent_reset) { printk("============>normal associate\n"); - notify_wx_assoc_event(ieee); - } - else if(ieee->is_silent_reset == 1) - { + notify_wx_assoc_event(ieee); + } else { printk("==================>silent reset associate\n"); ieee->is_silent_reset = false; } @@ -1558,7 +1559,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) } } - return cpu_to_le16(a->status); + return le16_to_cpu(a->status); } diff --git a/drivers/staging/rtl8192u/r819xU_firmware.h b/drivers/staging/rtl8192u/r819xU_firmware.h index cfa222350a9a..24b63f2ec509 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.h +++ b/drivers/staging/rtl8192u/r819xU_firmware.h @@ -2,15 +2,8 @@ #define __INC_FIRMWARE_H #define RTL8190_CPU_START_OFFSET 0x80 -/* TODO: this definition is TBD */ -//#define USB_HWDESC_HEADER_LEN 0 - -/* It should be double word alignment */ -//#if DEV_BUS_TYPE==PCI_INTERFACE -//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) 4*(v/4) - 8 -//#else -#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN) -//#endif +#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) \ + (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN) typedef enum _firmware_init_step { FW_INIT_STEP0_BOOT = 0, diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 6e776e5433f6..5d551a1ba3dc 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -122,13 +122,11 @@ module_param(low_power, int, 0644); MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); MODULE_PARM_DESC(initmac, "MAC-Address, default: use FUSE"); -static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev); static int netdev_open(struct net_device *pnetdev); static int netdev_close(struct net_device *pnetdev); -static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev) +static void loadparam(struct _adapter *padapter, struct net_device *pnetdev) { - uint status = _SUCCESS; struct registry_priv *registry_par = &padapter->registrypriv; registry_par->chip_version = (u8)chip_version; @@ -172,7 +170,6 @@ static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev) registry_par->low_power = (u8)low_power; registry_par->wifi_test = (u8) wifi_test; r8712_initmac = initmac; - return status; } static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -181,7 +178,7 @@ static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p) struct sockaddr *addr = p; if (padapter->bup == false) - memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN); + ether_addr_copy(pnetdev->dev_addr, addr->sa_data); return 0; } @@ -228,7 +225,6 @@ struct net_device *r8712_init_netdev(void) pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ pnetdev->wireless_handlers = (struct iw_handler_def *) &r871x_handlers_def; - /*step 2.*/ loadparam(padapter, pnetdev); netif_carrier_off(pnetdev); padapter->pid = 0; /* Initial the PID value used for HW PBC.*/ diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 799a0f9a5b2d..4201ce776e0c 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -132,9 +132,9 @@ void r8712_recv_indicatepkt(struct _adapter *padapter, return; _recv_indicatepkt_drop: /*enqueue back to free_recv_queue*/ - if (precv_frame) + if (precv_frame) r8712_free_recvframe(precv_frame, pfree_recv_queue); - precvpriv->rx_drop++; + precvpriv->rx_drop++; } static void _r8712_reordering_ctrl_timeout_handler (unsigned long data) diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index f1d47a0676c3..ada8d5dafd49 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -898,11 +898,11 @@ static void SwLedControlMode1(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -921,11 +921,11 @@ static void SwLedControlMode1(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedLinkBlinkInProgress = true; @@ -946,15 +946,15 @@ static void SwLedControlMode1(struct _adapter *padapter, if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; @@ -975,11 +975,11 @@ static void SwLedControlMode1(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } pLed->bLedBlinkInProgress = true; @@ -998,19 +998,19 @@ static void SwLedControlMode1(struct _adapter *padapter, case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; @@ -1025,23 +1025,23 @@ static void SwLedControlMode1(struct _adapter *padapter, break; case LED_CTL_STOP_WPS: if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); else pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS_STOP; @@ -1057,7 +1057,7 @@ static void SwLedControlMode1(struct _adapter *padapter, break; case LED_CTL_STOP_WPS_FAIL: if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -1073,23 +1073,23 @@ static void SwLedControlMode1(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedNoLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } mod_timer(&pLed->BlinkTimer, @@ -1116,7 +1116,7 @@ static void SwLedControlMode2(struct _adapter *padapter, return; if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; @@ -1154,11 +1154,11 @@ static void SwLedControlMode2(struct _adapter *padapter, pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } @@ -1170,11 +1170,11 @@ static void SwLedControlMode2(struct _adapter *padapter, case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; @@ -1214,15 +1214,15 @@ static void SwLedControlMode2(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } mod_timer(&pLed->BlinkTimer, @@ -1248,7 +1248,7 @@ static void SwLedControlMode3(struct _adapter *padapter, if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; @@ -1286,11 +1286,11 @@ static void SwLedControlMode3(struct _adapter *padapter, pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } mod_timer(&pLed->BlinkTimer, @@ -1300,11 +1300,11 @@ static void SwLedControlMode3(struct _adapter *padapter, case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; @@ -1319,7 +1319,7 @@ static void SwLedControlMode3(struct _adapter *padapter, break; case LED_CTL_STOP_WPS: if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&(pLed->BlinkTimer)); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } else pLed->bLedWPSBlinkInProgress = true; @@ -1336,7 +1336,7 @@ static void SwLedControlMode3(struct _adapter *padapter, break; case LED_CTL_STOP_WPS_FAIL: if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->CurrLedState = LED_OFF; @@ -1357,15 +1357,15 @@ static void SwLedControlMode3(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } mod_timer(&pLed->BlinkTimer, @@ -1388,7 +1388,7 @@ static void SwLedControlMode4(struct _adapter *padapter, case LED_CTL_START_TO_LINK: if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&pLed1->BlinkTimer); + del_timer(&pLed1->BlinkTimer); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) @@ -1400,11 +1400,11 @@ static void SwLedControlMode4(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } pLed->bLedStartToLinkBlinkInProgress = true; @@ -1426,7 +1426,7 @@ static void SwLedControlMode4(struct _adapter *padapter, if (LedAction == LED_CTL_LINK) { if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&pLed1->BlinkTimer); + del_timer(&pLed1->BlinkTimer); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) @@ -1439,7 +1439,7 @@ static void SwLedControlMode4(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -1460,11 +1460,11 @@ static void SwLedControlMode4(struct _adapter *padapter, if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; @@ -1485,7 +1485,7 @@ static void SwLedControlMode4(struct _adapter *padapter, IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } pLed->bLedBlinkInProgress = true; @@ -1503,7 +1503,7 @@ static void SwLedControlMode4(struct _adapter *padapter, case LED_CTL_START_WPS_BOTTON: if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&(pLed1->BlinkTimer)); + del_timer(&pLed1->BlinkTimer); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) @@ -1512,15 +1512,15 @@ static void SwLedControlMode4(struct _adapter *padapter, } if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; @@ -1538,7 +1538,7 @@ static void SwLedControlMode4(struct _adapter *padapter, break; case LED_CTL_STOP_WPS: /*WPS connect success*/ if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -1552,7 +1552,7 @@ static void SwLedControlMode4(struct _adapter *padapter, break; case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -1565,7 +1565,7 @@ static void SwLedControlMode4(struct _adapter *padapter, msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); /*LED1 settings*/ if (pLed1->bLedWPSBlinkInProgress) - del_timer_sync(&pLed1->BlinkTimer); + del_timer(&pLed1->BlinkTimer); else pLed1->bLedWPSBlinkInProgress = true; pLed1->CurrLedState = LED_BLINK_WPS_STOP; @@ -1578,7 +1578,7 @@ static void SwLedControlMode4(struct _adapter *padapter, break; case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; @@ -1591,7 +1591,7 @@ static void SwLedControlMode4(struct _adapter *padapter, msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); /*LED1 settings*/ if (pLed1->bLedWPSBlinkInProgress) - del_timer_sync(&pLed1->BlinkTimer); + del_timer(&pLed1->BlinkTimer); else pLed1->bLedWPSBlinkInProgress = true; pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; @@ -1607,31 +1607,31 @@ static void SwLedControlMode4(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedNoLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedStartToLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedStartToLinkBlinkInProgress = false; } if (pLed1->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed1->BlinkTimer); + del_timer(&pLed1->BlinkTimer); pLed1->bLedWPSBlinkInProgress = false; } pLed1->BlinkingLedState = LED_UNKNOWN; @@ -1671,7 +1671,7 @@ static void SwLedControlMode5(struct _adapter *padapter, ; /* dummy branch */ else if (pLed->bLedScanBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; @@ -1705,7 +1705,7 @@ static void SwLedControlMode5(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } SwLedOff(padapter, pLed); @@ -1756,7 +1756,7 @@ static void SwLedControlMode6(struct _adapter *padapter, case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; @@ -1772,7 +1772,7 @@ static void SwLedControlMode6(struct _adapter *padapter, case LED_CTL_STOP_WPS_FAIL: case LED_CTL_STOP_WPS: if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } pLed->CurrLedState = LED_ON; @@ -1784,11 +1784,11 @@ static void SwLedControlMode6(struct _adapter *padapter, pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); + del_timer(&pLed->BlinkTimer); pLed->bLedWPSBlinkInProgress = false; } SwLedOff(padapter, pLed); diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 50227b598e0c..fcb8c61b2884 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -1056,7 +1056,8 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) /* for first fragment packet, driver need allocate 1536 + * drvinfo_sz + RXDESC_SIZE to defrag packet. */ if ((mf == 1) && (frag == 0)) - alloc_sz = 1658;/*1658+6=1664, 1664 is 128 alignment.*/ + /*1658+6=1664, 1664 is 128 alignment.*/ + alloc_sz = max_t(u16, tmp_len, 1658); else alloc_sz = tmp_len; /* 2 is for IP header 4 bytes alignment in QoS packet case. diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 1a1c38f885d6..e35854d28f90 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -910,7 +910,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter, if (pcmd->res != H2C_SUCCESS) mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(1)); - del_timer_sync(&pmlmepriv->assoc_timer); + del_timer(&pmlmepriv->assoc_timer); #ifdef __BIG_ENDIAN /* endian_convert */ pnetwork->Length = le32_to_cpu(pnetwork->Length); diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 42fba3f5b593..cb0b6387789f 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -1900,23 +1900,20 @@ static int r871x_mp_ioctl_hdl(struct net_device *dev, struct mp_ioctl_handler *phandler; struct mp_ioctl_param *poidparam; unsigned long BytesRead, BytesWritten, BytesNeeded; - u8 *pparmbuf = NULL, bset; + u8 *pparmbuf, bset; u16 len; uint status; int ret = 0; - if ((!p->length) || (!p->pointer)) { - ret = -EINVAL; - goto _r871x_mp_ioctl_hdl_exit; - } + if ((!p->length) || (!p->pointer)) + return -EINVAL; + bset = (u8)(p->flags & 0xFFFF); len = p->length; - pparmbuf = NULL; pparmbuf = memdup_user(p->pointer, len); - if (IS_ERR(pparmbuf)) { - ret = PTR_ERR(pparmbuf); - goto _r871x_mp_ioctl_hdl_exit; - } + if (IS_ERR(pparmbuf)) + return PTR_ERR(pparmbuf); + poidparam = (struct mp_ioctl_param *)pparmbuf; if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { ret = -EINVAL; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index fb2b195b90af..c044b0e55ba9 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -582,7 +582,7 @@ void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { - del_timer_sync(&pmlmepriv->scan_to_timer); + del_timer(&pmlmepriv->scan_to_timer); _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); } @@ -696,7 +696,7 @@ void r8712_ind_disconnect(struct _adapter *padapter) } if (padapter->pwrctrlpriv.pwr_mode != padapter->registrypriv.power_mgnt) { - del_timer_sync(&pmlmepriv->dhcp_timer); + del_timer(&pmlmepriv->dhcp_timer); r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, padapter->registrypriv.smart_ps); } @@ -910,7 +910,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) r8712_indicate_connect(adapter); - del_timer_sync(&pmlmepriv->assoc_timer); + del_timer(&pmlmepriv->assoc_timer); } else goto ignore_joinbss_callback; } else { diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index aaa584435c87..9bc04f474d18 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -103,7 +103,7 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter, if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) return; - del_timer_sync(&padapter->pwrctrlpriv.rpwm_check_timer); + del_timer(&padapter->pwrctrlpriv.rpwm_check_timer); _enter_pwrlock(&pwrpriv->lock); pwrpriv->cpwm = (preportpwrstate->state) & 0xf; if (pwrpriv->cpwm >= PS_STATE_S2) { diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 7bb96c47f188..6ae8cdc1bfd1 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -198,7 +198,7 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta) * cancel reordering_ctrl_timer */ for (i = 0; i < 16; i++) { preorder_ctrl = &psta->recvreorder_ctrl[i]; - del_timer_sync(&preorder_ctrl->reordering_ctrl_timer); + del_timer(&preorder_ctrl->reordering_ctrl_timer); } spin_lock(&(pfree_sta_queue->lock)); /* insert into free_sta_queue; 20061114 */ @@ -270,12 +270,10 @@ void r8712_init_bcmc_stainfo(struct _adapter *padapter) struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter) { - struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - psta = r8712_get_stainfo(pstapriv, bc_addr); - return psta; + return r8712_get_stainfo(pstapriv, bc_addr); } diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 196beafde6f0..142f214108c6 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -3803,8 +3803,6 @@ void issue_action_BA23a(struct rtw_adapter *padapter, pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1; - status = cpu_to_le16(status); - switch (action) { case WLAN_ACTION_ADDBA_REQ: pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req); @@ -3908,8 +3906,8 @@ void issue_action_BA23a(struct rtw_adapter *padapter, put_unaligned_le16(BA_para_set, &mgmt->u.action.u.addba_resp.capab); - put_unaligned_le16(pmlmeinfo->ADDBA_req.BA_timeout_value, - &mgmt->u.action.u.addba_resp.timeout); + mgmt->u.action.u.addba_resp.timeout + = pmlmeinfo->ADDBA_req.BA_timeout_value; pattrib->pktlen += 8; break; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 11e1108d0c56..9733aa6ef908 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -55,7 +55,7 @@ int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 h2c_box_num; u32 msgbox_addr; u32 msgbox_ex_addr; - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); + struct hal_data_8723a *pHalData; u32 h2c_cmd = 0; u16 h2c_cmd_ex = 0; int ret = _FAIL; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index efe173072ad5..cb5076abda8b 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -1485,7 +1485,7 @@ void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo) u16 EEPROMId; /* Checl 0x8129 again for making sure autoload status!! */ - EEPROMId = le16_to_cpu(*((u16 *) hwinfo)); + EEPROMId = le16_to_cpu(*((__le16 *) hwinfo)); if (EEPROMId != RTL_EEPROM_ID) { DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId); pEEPROM->bautoload_fail_flag = true; diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index 83696360c293..b8848c25beb4 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c @@ -172,7 +172,7 @@ MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)"); static int netdev_close(struct net_device *pnetdev); -static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) +static void loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) { struct registry_priv *registry_par = &padapter->registrypriv; @@ -233,7 +233,6 @@ static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; registry_par->regulatory_tid = (u8)rtw_regulatory_id; - return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -372,7 +371,6 @@ struct net_device *rtw_init_netdev23a(struct rtw_adapter *old_padapter) pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ - /* step 2. */ loadparam(padapter, pnetdev); return pnetdev; } diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index d64b6ed9c0c9..1bcadba07fd0 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -537,7 +537,7 @@ static int rtsx_polling_thread(void *__dev) for (;;) { set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(POLLING_INTERVAL); + schedule_timeout(msecs_to_jiffies(POLLING_INTERVAL)); /* lock the device pointers */ mutex_lock(&(dev->dev_mutex)); diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h index aa1e034f7f45..1396263e13e6 100644 --- a/drivers/staging/rts5208/rtsx.h +++ b/drivers/staging/rts5208/rtsx.h @@ -48,9 +48,6 @@ #define CR_DRIVER_NAME "rts5208" -#define pci_get_bus_and_slot(bus, devfn) \ - pci_get_domain_bus_and_slot(0, (bus), (devfn)) - /* * macros for easy use */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 8a5d6a8e780f..60871f3022b1 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -915,6 +915,8 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); sec_cnt = srb->cmnd[4]; + if (sec_cnt == 0) + sec_cnt = 256; } else if ((srb->cmnd[0] == VENDOR_CMND) && (srb->cmnd[1] == SCSI_APP_CMD) && ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { @@ -2904,9 +2906,11 @@ void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) + else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { sec_cnt = srb->cmnd[4]; - else + if (sec_cnt == 0) + sec_cnt = 256; + } else return; if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { diff --git a/drivers/staging/skein/skein_api.h b/drivers/staging/skein/skein_api.h index 171b87549548..7da8b386a28c 100644 --- a/drivers/staging/skein/skein_api.h +++ b/drivers/staging/skein/skein_api.h @@ -121,7 +121,7 @@ struct skein_ctx { * @param size * Which Skein size to use. * @return - * SKEIN_SUCESS of SKEIN_FAIL + * SKEIN_SUCCESS of SKEIN_FAIL */ int skein_ctx_prepare(struct skein_ctx *ctx, enum skein_size size); @@ -136,7 +136,7 @@ int skein_ctx_prepare(struct skein_ctx *ctx, enum skein_size size); * @param hash_bit_len * Number of MAC hash bits to compute * @return - * SKEIN_SUCESS of SKEIN_FAIL + * SKEIN_SUCCESS of SKEIN_FAIL * @see skein_reset */ int skein_init(struct skein_ctx *ctx, size_t hash_bit_len); @@ -171,7 +171,7 @@ void skein_reset(struct skein_ctx *ctx); * @param hash_bit_len * Number of MAC hash bits to compute * @return - * SKEIN_SUCESS of SKEIN_FAIL + * SKEIN_SUCCESS of SKEIN_FAIL */ int skein_mac_init(struct skein_ctx *ctx, const u8 *key, size_t key_len, size_t hash_bit_len); diff --git a/drivers/staging/slicoss/TODO b/drivers/staging/slicoss/TODO index 20cc9abdc466..9019729b7be6 100644 --- a/drivers/staging/slicoss/TODO +++ b/drivers/staging/slicoss/TODO @@ -25,7 +25,6 @@ TODO: - state variables for things that are easily available and shouldn't be kept in card structure, cardnum, ... slotnumber, events, ... - - get rid of slic_spinlock wrapper - volatile == bad design => bad code - locking too fine grained, not designed just throw more locks at problem diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h index 3a5aa882b957..67a8c9eb2dca 100644 --- a/drivers/staging/slicoss/slic.h +++ b/drivers/staging/slicoss/slic.h @@ -56,11 +56,6 @@ static u32 OasisRcvUCodeLen = 512; static u32 GBRcvUCodeLen = 512; #define SECTION_SIZE 65536 -struct slic_spinlock { - spinlock_t lock; - unsigned long flags; -}; - #define SLIC_RSPQ_PAGES_GB 10 #define SLIC_RSPQ_BUFSINPAGE (PAGE_SIZE / SLIC_RSPBUF_SIZE) @@ -165,7 +160,7 @@ struct slic_cmdqueue { struct slic_hostcmd *head; struct slic_hostcmd *tail; int count; - struct slic_spinlock lock; + spinlock_t lock; }; #define SLIC_MAX_CARDS 32 @@ -346,7 +341,7 @@ struct physcard { }; struct base_driver { - struct slic_spinlock driver_lock; + spinlock_t driver_lock; u32 num_slic_cards; u32 num_slic_ports; u32 num_slic_ports_active; @@ -401,8 +396,8 @@ struct adapter { uint card_size; uint chipid; struct net_device *netdev; - struct slic_spinlock adapter_lock; - struct slic_spinlock reset_lock; + spinlock_t adapter_lock; + spinlock_t reset_lock; struct pci_dev *pcidev; uint busnumber; uint slotnumber; @@ -419,7 +414,6 @@ struct adapter { u32 intrregistered; uint isp_initialized; uint gennumber; - u32 curaddrupper; struct slic_shmem *pshmem; dma_addr_t phys_shmem; u32 isrcopy; @@ -441,8 +435,8 @@ struct adapter { u32 pingtimerset; struct timer_list loadtimer; u32 loadtimerset; - struct slic_spinlock upr_lock; - struct slic_spinlock bit64reglock; + spinlock_t upr_lock; + spinlock_t bit64reglock; struct slic_rspqueue rspqueue; struct slic_rcvqueue rcvqueue; struct slic_cmdqueue cmdq_free; @@ -457,7 +451,7 @@ struct adapter { /* Free object handles*/ struct slic_handle *pfree_slic_handles; /* Object handle list lock*/ - struct slic_spinlock handle_lock; + spinlock_t handle_lock; ushort slic_handle_ix; u32 xmitq_full; diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index c2bda1d38e41..a609f3e67256 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -144,17 +144,14 @@ static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg, u32 value, void __iomem *regh, u32 paddrh, bool flush) { - spin_lock_irqsave(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); - if (paddrh != adapter->curaddrupper) { - adapter->curaddrupper = paddrh; - writel(paddrh, regh); - } + unsigned long flags; + + spin_lock_irqsave(&adapter->bit64reglock, flags); + writel(paddrh, regh); writel(value, reg); if (flush) mb(); - spin_unlock_irqrestore(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); + spin_unlock_irqrestore(&adapter->bit64reglock, flags); } static void slic_mcast_set_bit(struct adapter *adapter, char *address) @@ -936,9 +933,10 @@ static int slic_upr_request(struct adapter *adapter, u32 upr_data_h, u32 upr_buffer, u32 upr_buffer_h) { + unsigned long flags; int rc; - spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags); + spin_lock_irqsave(&adapter->upr_lock, flags); rc = slic_upr_queue_request(adapter, upr_request, upr_data, @@ -948,8 +946,7 @@ static int slic_upr_request(struct adapter *adapter, slic_upr_start(adapter); err_unlock_irq: - spin_unlock_irqrestore(&adapter->upr_lock.lock, - adapter->upr_lock.flags); + spin_unlock_irqrestore(&adapter->upr_lock, flags); return rc; } @@ -1029,12 +1026,12 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr) { struct sliccard *card = adapter->card; struct slic_upr *upr; + unsigned long flags; - spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags); + spin_lock_irqsave(&adapter->upr_lock, flags); upr = adapter->upr_list; if (!upr) { - spin_unlock_irqrestore(&adapter->upr_lock.lock, - adapter->upr_lock.flags); + spin_unlock_irqrestore(&adapter->upr_lock, flags); return; } adapter->upr_list = upr->next; @@ -1127,8 +1124,7 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr) } kfree(upr); slic_upr_start(adapter); - spin_unlock_irqrestore(&adapter->upr_lock.lock, - adapter->upr_lock.flags); + spin_unlock_irqrestore(&adapter->upr_lock, flags); } static int slic_config_get(struct adapter *adapter, u32 config, u32 config_h) @@ -1310,6 +1306,7 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page) u32 phys_addrl; u32 phys_addrh; struct slic_handle *pslic_handle; + unsigned long flags; cmdaddr = page; cmd = (struct slic_hostcmd *)cmdaddr; @@ -1324,12 +1321,10 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page) while ((cmdcnt < SLIC_CMDQ_CMDSINPAGE) && (adapter->slic_handle_ix < 256)) { /* Allocate and initialize a SLIC_HANDLE for this command */ - spin_lock_irqsave(&adapter->handle_lock.lock, - adapter->handle_lock.flags); + spin_lock_irqsave(&adapter->handle_lock, flags); pslic_handle = adapter->pfree_slic_handles; adapter->pfree_slic_handles = pslic_handle->next; - spin_unlock_irqrestore(&adapter->handle_lock.lock, - adapter->handle_lock.flags); + spin_unlock_irqrestore(&adapter->handle_lock, flags); pslic_handle->type = SLIC_HANDLE_CMD; pslic_handle->address = (void *) cmd; pslic_handle->offset = (ushort) adapter->slic_handle_ix++; @@ -1356,11 +1351,11 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page) tail->next_all = cmdq->head; cmdq->head = prev; cmdq = &adapter->cmdq_free; - spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags); + spin_lock_irqsave(&cmdq->lock, flags); cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */ tail->next = cmdq->head; cmdq->head = prev; - spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags); + spin_unlock_irqrestore(&cmdq->lock, flags); } static int slic_cmdq_init(struct adapter *adapter) @@ -1371,9 +1366,9 @@ static int slic_cmdq_init(struct adapter *adapter) memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue)); memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue)); memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue)); - spin_lock_init(&adapter->cmdq_all.lock.lock); - spin_lock_init(&adapter->cmdq_free.lock.lock); - spin_lock_init(&adapter->cmdq_done.lock.lock); + spin_lock_init(&adapter->cmdq_all.lock); + spin_lock_init(&adapter->cmdq_free.lock); + spin_lock_init(&adapter->cmdq_done.lock); memset(&adapter->cmdqmem, 0, sizeof(struct slic_cmdqmem)); adapter->slic_handle_ix = 1; for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) { @@ -1394,11 +1389,10 @@ static void slic_cmdq_reset(struct adapter *adapter) struct slic_hostcmd *hcmd; struct sk_buff *skb; u32 outstanding; + unsigned long flags; - spin_lock_irqsave(&adapter->cmdq_free.lock.lock, - adapter->cmdq_free.lock.flags); - spin_lock_irqsave(&adapter->cmdq_done.lock.lock, - adapter->cmdq_done.lock.flags); + spin_lock_irqsave(&adapter->cmdq_free.lock, flags); + spin_lock(&adapter->cmdq_done.lock); outstanding = adapter->cmdq_all.count - adapter->cmdq_done.count; outstanding -= adapter->cmdq_free.count; hcmd = adapter->cmdq_all.head; @@ -1429,40 +1423,40 @@ static void slic_cmdq_reset(struct adapter *adapter) "free_count %d != all count %d\n", adapter->cmdq_free.count, adapter->cmdq_all.count); } - spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock, - adapter->cmdq_done.lock.flags); - spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock, - adapter->cmdq_free.lock.flags); + spin_unlock(&adapter->cmdq_done.lock); + spin_unlock_irqrestore(&adapter->cmdq_free.lock, flags); } static void slic_cmdq_getdone(struct adapter *adapter) { struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done; struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free; + unsigned long flags; - spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags); + spin_lock_irqsave(&done_cmdq->lock, flags); free_cmdq->head = done_cmdq->head; free_cmdq->count = done_cmdq->count; done_cmdq->head = NULL; done_cmdq->tail = NULL; done_cmdq->count = 0; - spin_unlock_irqrestore(&done_cmdq->lock.lock, done_cmdq->lock.flags); + spin_unlock_irqrestore(&done_cmdq->lock, flags); } static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter) { struct slic_cmdqueue *cmdq = &adapter->cmdq_free; struct slic_hostcmd *cmd = NULL; + unsigned long flags; lock_and_retry: - spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags); + spin_lock_irqsave(&cmdq->lock, flags); retry: cmd = cmdq->head; if (cmd) { cmdq->head = cmd->next; cmdq->count--; - spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags); + spin_unlock_irqrestore(&cmdq->lock, flags); } else { slic_cmdq_getdone(adapter); cmd = cmdq->head; @@ -1471,8 +1465,7 @@ retry: } else { u32 *pageaddr; - spin_unlock_irqrestore(&cmdq->lock.lock, - cmdq->lock.flags); + spin_unlock_irqrestore(&cmdq->lock, flags); pageaddr = slic_cmdqmem_addpage(adapter); if (pageaddr) { slic_cmdq_addcmdpage(adapter, pageaddr); @@ -1488,14 +1481,14 @@ static void slic_cmdq_putdone_irq(struct adapter *adapter, { struct slic_cmdqueue *cmdq = &adapter->cmdq_done; - spin_lock(&cmdq->lock.lock); + spin_lock(&cmdq->lock); cmd->busy = 0; cmd->next = cmdq->head; cmdq->head = cmd; cmdq->count++; if ((adapter->xmitq_full) && (cmdq->count > 10)) netif_wake_queue(adapter->netdev); - spin_unlock(&cmdq->lock.lock); + spin_unlock(&cmdq->lock); } static int slic_rcvqueue_fill(struct adapter *adapter) @@ -2250,21 +2243,20 @@ static void slic_adapter_freeresources(struct adapter *adapter) adapter->rcv_unicasts = 0; } -static int slic_adapter_allocresources(struct adapter *adapter) +static int slic_adapter_allocresources(struct adapter *adapter, + unsigned long *flags) { if (!adapter->intrregistered) { int retval; - spin_unlock_irqrestore(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_unlock_irqrestore(&slic_global.driver_lock, *flags); retval = request_irq(adapter->netdev->irq, &slic_interrupt, IRQF_SHARED, adapter->netdev->name, adapter->netdev); - spin_lock_irqsave(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_lock_irqsave(&slic_global.driver_lock, *flags); if (retval) { dev_err(&adapter->netdev->dev, @@ -2283,7 +2275,7 @@ static int slic_adapter_allocresources(struct adapter *adapter) * Perform initialization of our slic interface. * */ -static int slic_if_init(struct adapter *adapter) +static int slic_if_init(struct adapter *adapter, unsigned long *flags) { struct sliccard *card = adapter->card; struct net_device *dev = adapter->netdev; @@ -2311,7 +2303,7 @@ static int slic_if_init(struct adapter *adapter) if (dev->flags & IFF_MULTICAST) adapter->macopts |= MAC_MCAST; } - rc = slic_adapter_allocresources(adapter); + rc = slic_adapter_allocresources(adapter, flags); if (rc) { dev_err(&dev->dev, "slic_adapter_allocresources FAILED %x\n", rc); @@ -2336,11 +2328,11 @@ static int slic_if_init(struct adapter *adapter) mdelay(1); if (!adapter->isp_initialized) { + unsigned long flags; pshmem = (struct slic_shmem *)(unsigned long) adapter->phys_shmem; - spin_lock_irqsave(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); + spin_lock_irqsave(&adapter->bit64reglock, flags); #if BITS_PER_LONG == 64 slic_reg32_write(&slic_regs->slic_addr_upper, @@ -2352,8 +2344,7 @@ static int slic_if_init(struct adapter *adapter) slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH); #endif - spin_unlock_irqrestore(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); + spin_unlock_irqrestore(&adapter->bit64reglock, flags); adapter->isp_initialized = 1; } @@ -2396,18 +2387,18 @@ static int slic_entry_open(struct net_device *dev) { struct adapter *adapter = netdev_priv(dev); struct sliccard *card = adapter->card; + unsigned long flags; int status; netif_stop_queue(adapter->netdev); - spin_lock_irqsave(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_lock_irqsave(&slic_global.driver_lock, flags); if (!adapter->activated) { card->adapters_activated++; slic_global.num_slic_ports_active++; adapter->activated = 1; } - status = slic_if_init(adapter); + status = slic_if_init(adapter, &flags); if (status != 0) { if (adapter->activated) { @@ -2421,8 +2412,7 @@ static int slic_entry_open(struct net_device *dev) card->master = adapter; spin_unlock: - spin_unlock_irqrestore(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_unlock_irqrestore(&slic_global.driver_lock, flags); return status; } @@ -2481,9 +2471,9 @@ static int slic_entry_halt(struct net_device *dev) struct adapter *adapter = netdev_priv(dev); struct sliccard *card = adapter->card; __iomem struct slic_regs *slic_regs = adapter->slic_regs; + unsigned long flags; - spin_lock_irqsave(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_lock_irqsave(&slic_global.driver_lock, flags); netif_stop_queue(adapter->netdev); adapter->state = ADAPT_DOWN; adapter->linkstate = LINK_DOWN; @@ -2512,8 +2502,7 @@ static int slic_entry_halt(struct net_device *dev) slic_card_init(card, adapter); #endif - spin_unlock_irqrestore(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); + spin_unlock_irqrestore(&slic_global.driver_lock, flags); return 0; } @@ -2663,6 +2652,7 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter) unsigned char oemfruformat; struct atk_fru *patkfru; union oemfru *poemfru; + unsigned long flags; /* Reset everything except PCI configuration space */ slic_soft_reset(adapter); @@ -2693,14 +2683,12 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter) pshmem = (struct slic_shmem *)(unsigned long) adapter->phys_shmem; - spin_lock_irqsave(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); + spin_lock_irqsave(&adapter->bit64reglock, flags); slic_reg32_write(&slic_regs->slic_addr_upper, SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH); slic_reg32_write(&slic_regs->slic_isp, SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH); - spin_unlock_irqrestore(&adapter->bit64reglock.lock, - adapter->bit64reglock.flags); + spin_unlock_irqrestore(&adapter->bit64reglock, flags); status = slic_config_get(adapter, phys_configl, phys_configh); if (status) { @@ -2854,7 +2842,7 @@ static void slic_init_driver(void) { if (slic_first_init) { slic_first_init = 0; - spin_lock_init(&slic_global.driver_lock.lock); + spin_lock_init(&slic_global.driver_lock); } } @@ -2880,11 +2868,11 @@ static void slic_init_adapter(struct net_device *netdev, adapter->chipid = chip_idx; adapter->port = 0; /*adapter->functionnumber;*/ adapter->cardindex = adapter->port; - spin_lock_init(&adapter->upr_lock.lock); - spin_lock_init(&adapter->bit64reglock.lock); - spin_lock_init(&adapter->adapter_lock.lock); - spin_lock_init(&adapter->reset_lock.lock); - spin_lock_init(&adapter->handle_lock.lock); + spin_lock_init(&adapter->upr_lock); + spin_lock_init(&adapter->bit64reglock); + spin_lock_init(&adapter->adapter_lock); + spin_lock_init(&adapter->reset_lock); + spin_lock_init(&adapter->handle_lock); adapter->card_size = 1; /* diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig index c40d088a4d3b..ccebc25c2ec1 100644 --- a/drivers/staging/sm750fb/Kconfig +++ b/drivers/staging/sm750fb/Kconfig @@ -1,6 +1,10 @@ config FB_SM750 tristate "Silicon Motion SM750 framebuffer support" depends on FB && PCI + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help Frame buffer driver for the Silicon Motion SM750 chip with 2D accelearion and dual head support. diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO index ce23f3ccc3a4..a3a877d90066 100644 --- a/drivers/staging/sm750fb/TODO +++ b/drivers/staging/sm750fb/TODO @@ -2,6 +2,7 @@ TODO: - lots of checkpatch cleanup - use kernel coding style - refine the code and remove unused code +- Implement hardware acceleration for imageblit if image->depth > 1 - check on hardware effects of removal of USE_HW_I2C and USE_DVICHIP (these two are supposed to be sample code which is given here if someone wants to use those functionalities) diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c index 3cb860ce60cc..8b47c1bfc401 100644 --- a/drivers/staging/sm750fb/ddk750_chip.c +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -616,7 +616,7 @@ unsigned int formatPllReg(pll_value_t *pPLL) | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N) | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M); - return ulPllReg; + return ulPllReg; } diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h index 04cb0d559245..4e030e820cf3 100644 --- a/drivers/staging/sm750fb/ddk750_chip.h +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -10,10 +10,10 @@ /* This is all the chips recognized by this library */ typedef enum _logical_chip_type_t { - SM_UNKNOWN, - SM718, - SM750, - SM750LE, + SM_UNKNOWN, + SM718, + SM750, + SM750LE, } logical_chip_type_t; @@ -30,51 +30,56 @@ clock_type_t; typedef struct _pll_value_t { - clock_type_t clockType; - unsigned long inputFreq; /* Input clock frequency to the PLL */ + clock_type_t clockType; + unsigned long inputFreq; /* Input clock frequency to the PLL */ - /* Use this when clockType = PANEL_PLL */ - unsigned long M; - unsigned long N; - unsigned long OD; - unsigned long POD; + /* Use this when clockType = PANEL_PLL */ + unsigned long M; + unsigned long N; + unsigned long OD; + unsigned long POD; } pll_value_t; /* input struct to initChipParam() function */ typedef struct _initchip_param_t { - unsigned short powerMode; /* Use power mode 0 or 1 */ - unsigned short chipClock; /* Speed of main chip clock in MHz unit - 0 = keep the current clock setting - Others = the new main chip clock - */ - unsigned short memClock; /* Speed of memory clock in MHz unit - 0 = keep the current clock setting - Others = the new memory clock - */ - unsigned short masterClock; /* Speed of master clock in MHz unit - 0 = keep the current clock setting - Others = the new master clock - */ - unsigned short setAllEngOff; /* 0 = leave all engine state untouched. - 1 = make sure they are off: 2D, Overlay, - video alpha, alpha, hardware cursors - */ - unsigned char resetMemory; /* 0 = Do not reset the memory controller - 1 = Reset the memory controller - */ + unsigned short powerMode; /* Use power mode 0 or 1 */ + unsigned short chipClock; /** + * Speed of main chip clock in MHz unit + * 0 = keep the current clock setting + * Others = the new main chip clock + */ + unsigned short memClock; /** + * Speed of memory clock in MHz unit + * 0 = keep the current clock setting + * Others = the new memory clock + */ + unsigned short masterClock; /** + * Speed of master clock in MHz unit + * 0 = keep the current clock setting + * Others = the new master clock + */ + unsigned short setAllEngOff; /** + * 0 = leave all engine state untouched. + * 1 = make sure they are off: 2D, Overlay, + * video alpha, alpha, hardware cursors + */ + unsigned char resetMemory; /** + * 0 = Do not reset the memory controller + * 1 = Reset the memory controller + */ - /* More initialization parameter can be added if needed */ + /* More initialization parameter can be added if needed */ } initchip_param_t; logical_chip_type_t getChipType(void); -unsigned int calcPllValue(unsigned int request,pll_value_t *pll); -unsigned int calcPllValue2(unsigned int,pll_value_t *); +unsigned int calcPllValue(unsigned int request, pll_value_t *pll); +unsigned int calcPllValue2(unsigned int, pll_value_t *); unsigned int formatPllReg(pll_value_t *pPLL); -void ddk750_set_mmio(void __iomem *,unsigned short,char); +void ddk750_set_mmio(void __iomem *, unsigned short, char); unsigned int ddk750_getVMSize(void); int ddk750_initHw(initchip_param_t *); unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL); diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index c84196ac055d..a3e672056ef8 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -4,9 +4,9 @@ #include "ddk750_power.h" #include "ddk750_dvi.h" -#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0,delay) +#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay) -static void setDisplayControl(int ctrl,int dispState) +static void setDisplayControl(int ctrl, int dispState) { /* state != 0 means turn on both timing & plane en_bit */ unsigned long ulDisplayCtrlReg, ulReservedBits; @@ -51,7 +51,7 @@ static void setDisplayControl(int ctrl,int dispState) POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); } while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulDisplayCtrlReg & ~ulReservedBits)); - printk("Set Panel Plane enbit:after tried %d times\n",cnt); + printk("Set Panel Plane enbit:after tried %d times\n", cnt); } else { @@ -106,7 +106,7 @@ static void setDisplayControl(int ctrl,int dispState) POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); } while((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != (ulDisplayCtrlReg & ~ulReservedBits)); - printk("Set Crt Plane enbit:after tried %d times\n",cnt); + printk("Set Crt Plane enbit:after tried %d times\n", cnt); } else { @@ -129,7 +129,7 @@ static void setDisplayControl(int ctrl,int dispState) } -static void waitNextVerticalSync(int ctrl,int delay) +static void waitNextVerticalSync(int ctrl, int delay) { unsigned int status; if(!ctrl){ @@ -201,31 +201,31 @@ static void waitNextVerticalSync(int ctrl,int delay) } } -static void swPanelPowerSequence(int disp,int delay) +static void swPanelPowerSequence(int disp, int delay) { unsigned int reg; /* disp should be 1 to open sequence */ reg = PEEK32(PANEL_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); - POKE32(PANEL_DISPLAY_CTRL,reg); + reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp); + POKE32(PANEL_DISPLAY_CTRL, reg); primaryWaitVerticalSync(delay); reg = PEEK32(PANEL_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,DATA,disp); - POKE32(PANEL_DISPLAY_CTRL,reg); + reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp); + POKE32(PANEL_DISPLAY_CTRL, reg); primaryWaitVerticalSync(delay); reg = PEEK32(PANEL_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,VBIASEN,disp); - POKE32(PANEL_DISPLAY_CTRL,reg); + reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp); + POKE32(PANEL_DISPLAY_CTRL, reg); primaryWaitVerticalSync(delay); reg = PEEK32(PANEL_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); - POKE32(PANEL_DISPLAY_CTRL,reg); + reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp); + POKE32(PANEL_DISPLAY_CTRL, reg); primaryWaitVerticalSync(delay); } @@ -236,33 +236,33 @@ void ddk750_setLogicalDispOut(disp_output_t output) if(output & PNL_2_USAGE){ /* set panel path controller select */ reg = PEEK32(PANEL_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,SELECT,(output & PNL_2_MASK)>>PNL_2_OFFSET); - POKE32(PANEL_DISPLAY_CTRL,reg); + reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET); + POKE32(PANEL_DISPLAY_CTRL, reg); } if(output & CRT_2_USAGE){ /* set crt path controller select */ reg = PEEK32(CRT_DISPLAY_CTRL); - reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,SELECT,(output & CRT_2_MASK)>>CRT_2_OFFSET); + reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET); /*se blank off */ - reg = FIELD_SET(reg,CRT_DISPLAY_CTRL,BLANK,OFF); - POKE32(CRT_DISPLAY_CTRL,reg); + reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF); + POKE32(CRT_DISPLAY_CTRL, reg); } if(output & PRI_TP_USAGE){ /* set primary timing and plane en_bit */ - setDisplayControl(0,(output&PRI_TP_MASK)>>PRI_TP_OFFSET); + setDisplayControl(0, (output&PRI_TP_MASK)>>PRI_TP_OFFSET); } if(output & SEC_TP_USAGE){ /* set secondary timing and plane en_bit*/ - setDisplayControl(1,(output&SEC_TP_MASK)>>SEC_TP_OFFSET); + setDisplayControl(1, (output&SEC_TP_MASK)>>SEC_TP_OFFSET); } if(output & PNL_SEQ_USAGE){ /* set panel sequence */ - swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET,4); + swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET, 4); } if(output & DAC_USAGE) diff --git a/drivers/staging/sm750fb/ddk750_help.c b/drivers/staging/sm750fb/ddk750_help.c index c68ff3b5751a..647004d5690c 100644 --- a/drivers/staging/sm750fb/ddk750_help.c +++ b/drivers/staging/sm750fb/ddk750_help.c @@ -7,7 +7,7 @@ char revId750 = 0; unsigned short devId750 = 0; /* after driver mapped io registers, use this function first */ -void ddk750_set_mmio(void __iomem * addr,unsigned short devId,char revId) +void ddk750_set_mmio(void __iomem * addr, unsigned short devId, char revId) { mmio750 = addr; devId750 = devId; diff --git a/drivers/staging/sm750fb/ddk750_help.h b/drivers/staging/sm750fb/ddk750_help.h index e7e49cebd303..f99f907f0ad9 100644 --- a/drivers/staging/sm750fb/ddk750_help.h +++ b/drivers/staging/sm750fb/ddk750_help.h @@ -13,10 +13,10 @@ /* if 718 big endian turned on,be aware that don't use this driver for general use,only for ppc big-endian */ #warning "big endian on target cpu and enable nature big endian support of 718 capability !" #define PEEK32(addr) __raw_readl(mmio750 + addr) -#define POKE32(addr,data) __raw_writel(data, mmio750 + addr) +#define POKE32(addr, data) __raw_writel(data, mmio750 + addr) #else /* software control endianness */ #define PEEK32(addr) readl(addr + mmio750) -#define POKE32(addr,data) writel(data, addr + mmio750) +#define POKE32(addr, data) writel(data, addr + mmio750) #endif extern void __iomem * mmio750; diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.h b/drivers/staging/sm750fb/ddk750_hwi2c.h index ad311493c9fc..0b830ba65eec 100644 --- a/drivers/staging/sm750fb/ddk750_hwi2c.h +++ b/drivers/staging/sm750fb/ddk750_hwi2c.h @@ -5,6 +5,6 @@ int hwI2CInit(unsigned char busSpeedMode); void hwI2CClose(void); -unsigned char hwI2CReadReg(unsigned char deviceAddress,unsigned char registerIndex); -int hwI2CWriteReg(unsigned char deviceAddress,unsigned char registerIndex,unsigned char data); +unsigned char hwI2CReadReg(unsigned char deviceAddress, unsigned char registerIndex); +int hwI2CWriteReg(unsigned char deviceAddress, unsigned char registerIndex, unsigned char data); #endif diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c index 021d4c3b2b10..a05474793ad4 100644 --- a/drivers/staging/sm750fb/ddk750_mode.c +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -75,15 +75,15 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, /* only timing related registers will be programed */ -static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) +static int programModeRegisters(mode_parameter_t * pModeParam, pll_value_t * pll) { int ret = 0; int cnt = 0; - unsigned int ulTmpValue,ulReg; + unsigned int ulTmpValue, ulReg; if(pll->clockType == SECONDARY_PLL) { /* programe secondary pixel clock */ - POKE32(CRT_PLL_CTRL,formatPllReg(pll)); + POKE32(CRT_PLL_CTRL, formatPllReg(pll)); POKE32(CRT_HORIZONTAL_TOTAL, FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); @@ -101,29 +101,29 @@ static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); - ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| - FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| - FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| - FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); + ulTmpValue = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)| + FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)| + FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE); if(getChipType() == SM750LE){ - displayControlAdjust_SM750LE(pModeParam,ulTmpValue); + displayControlAdjust_SM750LE(pModeParam, ulTmpValue); }else{ ulReg = PEEK32(CRT_DISPLAY_CTRL) - & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) - & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) - & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) - & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); + & FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE); - POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); + POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg); } } else if(pll->clockType == PRIMARY_PLL) { unsigned int ulReservedBits; - POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); + POKE32(PANEL_PLL_CTRL, formatPllReg(pll)); POKE32(PANEL_HORIZONTAL_TOTAL, FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) @@ -141,16 +141,16 @@ static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); - ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| - FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| - FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| - FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| - FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); + ulTmpValue = FIELD_VALUE(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)| + FIELD_VALUE(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, pModeParam->clock_phase_polarity)| + FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)| + FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE); ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| - FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); + FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC, ACTIVE_LOW); ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) @@ -168,14 +168,14 @@ static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) * next vertical sync to turn on/off the plane. */ - POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); + POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg); #if 1 while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) { cnt++; if(cnt > 1000) break; - POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); + POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg); } #endif } @@ -185,20 +185,20 @@ static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) return ret; } -int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) +int ddk750_setModeTiming(mode_parameter_t * parm, clock_type_t clock) { pll_value_t pll; unsigned int uiActualPixelClk; pll.inputFreq = DEFAULT_INPUT_CLOCK; pll.clockType = clock; - uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); + uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll); if(getChipType() == SM750LE){ /* set graphic mode via IO method */ - outb_p(0x88,0x3d4); - outb_p(0x06,0x3d5); + outb_p(0x88, 0x3d4); + outb_p(0x06, 0x3d5); } - programModeRegisters(parm,&pll); + programModeRegisters(parm, &pll); return 0; } diff --git a/drivers/staging/sm750fb/ddk750_mode.h b/drivers/staging/sm750fb/ddk750_mode.h index 6f8df96a8b02..4e8fab3f17e4 100644 --- a/drivers/staging/sm750fb/ddk750_mode.h +++ b/drivers/staging/sm750fb/ddk750_mode.h @@ -37,7 +37,7 @@ typedef struct _mode_parameter_t } mode_parameter_t; -int ddk750_setModeTiming(mode_parameter_t *,clock_type_t); +int ddk750_setModeTiming(mode_parameter_t *, clock_type_t); #endif diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c index cbb97676b33c..1e5f398aed10 100644 --- a/drivers/staging/sm750fb/ddk750_power.c +++ b/drivers/staging/sm750fb/ddk750_power.c @@ -7,10 +7,10 @@ void ddk750_setDPMS(DPMS_t state) unsigned int value; if(getChipType() == SM750LE){ value = PEEK32(CRT_DISPLAY_CTRL); - POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(value,CRT_DISPLAY_CTRL,DPMS,state)); + POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(value, CRT_DISPLAY_CTRL, DPMS, state)); }else{ value = PEEK32(SYSTEM_CTRL); - value= FIELD_VALUE(value,SYSTEM_CTRL,DPMS,state); + value= FIELD_VALUE(value, SYSTEM_CTRL, DPMS, state); POKE32(SYSTEM_CTRL, value); } } diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h index 71dc7f980069..4e00955a07dd 100644 --- a/drivers/staging/sm750fb/ddk750_power.h +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -12,7 +12,7 @@ DPMS_t; #define setDAC(off) \ { \ - POKE32(MISC_CTRL,FIELD_VALUE(PEEK32(MISC_CTRL), \ + POKE32(MISC_CTRL, FIELD_VALUE(PEEK32(MISC_CTRL), \ MISC_CTRL, \ DAC_POWER, \ off)); \ diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c index 901b3737f1ed..fc8f5a51e43c 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -96,7 +96,7 @@ static void swI2CWait(void) it's more reliable than counter loop .. write 0x61 to 0x3ce and read from 0x3cf */ - while(peekIO(0x3ce,0x61) & 0x10); + while(peekIO(0x3ce, 0x61) & 0x10); #else int i, Temp; diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 77310ff325b2..6b642d75b9b5 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -16,9 +16,6 @@ #include<linux/vmalloc.h> #include<linux/pagemap.h> #include <linux/console.h> -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif #include <asm/fb.h> #include "sm750.h" #include "sm750_hw.h" @@ -47,9 +44,7 @@ typedef int (*PROC_SPEC_INITHW)(struct lynx_share*, struct pci_dev*); /* common var for all device */ static int g_hwcursor = 1; static int g_noaccel; -#ifdef CONFIG_MTRR static int g_nomtrr; -#endif static const char *g_fbmode[] = {NULL, NULL}; static const char *g_def_fbmode = "800x600-16@60"; static char *g_settings = NULL; @@ -93,9 +88,6 @@ static const struct fb_videomode lynx750_ext[] = { FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, - {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3, - FB_SYNC_HOR_HIGH_ACT|FB_VMODE_NONINTERLACED}, - /* 1360 x 768 [1.77083:1] */ {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, @@ -279,7 +271,10 @@ static void lynxfb_ops_imageblit(struct fb_info *info, } goto _do_work; } + /* TODO: Implement hardware acceleration for image->depth > 1 */ + cfb_imageblit(info, image); return; + _do_work: /* * If not use spin_lock, system will die if user load driver @@ -979,7 +974,7 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index) ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret < 0) { - pr_err("Could not allcate memory for cmap.\n"); + pr_err("Could not allocate memory for cmap.\n"); goto exit; } @@ -1126,11 +1121,8 @@ static int lynxfb_pci_probe(struct pci_dev *pdev, pr_info("share->revid = %02x\n", share->revid); share->pdev = pdev; -#ifdef CONFIG_MTRR share->mtrr_off = g_nomtrr; share->mtrr.vram = 0; - share->mtrr.vram_added = 0; -#endif share->accel_off = g_noaccel; share->dual = g_dualview; spin_lock_init(&share->slock); @@ -1158,22 +1150,9 @@ static int lynxfb_pci_probe(struct pci_dev *pdev, goto err_map; } -#ifdef CONFIG_MTRR - if (!share->mtrr_off) { - pr_info("enable mtrr\n"); - share->mtrr.vram = mtrr_add(share->vidmem_start, - share->vidmem_size, - MTRR_TYPE_WRCOMB, 1); - - if (share->mtrr.vram < 0) { - /* don't block driver with the failure of MTRR */ - pr_err("Unable to setup MTRR.\n"); - } else { - share->mtrr.vram_added = 1; - pr_info("MTRR added successfully\n"); - } - } -#endif + if (!share->mtrr_off) + share->mtrr.vram = arch_phys_wc_add(share->vidmem_start, + share->vidmem_size); memset_io(share->pvMem, 0, share->vidmem_size); @@ -1250,7 +1229,7 @@ err_enable: return -ENODEV; } -static void __exit lynxfb_pci_remove(struct pci_dev *pdev) +static void lynxfb_pci_remove(struct pci_dev *pdev) { struct fb_info *info; struct lynx_share *share; @@ -1274,12 +1253,7 @@ static void __exit lynxfb_pci_remove(struct pci_dev *pdev) /* release frame buffer */ framebuffer_release(info); } -#ifdef CONFIG_MTRR - if (share->mtrr.vram_added) - mtrr_del(share->mtrr.vram, - share->vidmem_start, - share->vidmem_size); -#endif + arch_phys_wc_del(share->mtrr.vram); iounmap(share->pvReg); iounmap(share->pvMem); @@ -1321,10 +1295,8 @@ static int __init lynxfb_setup(char *options) /* options that mean for any lynx chips are configured here */ if (!strncmp(opt, "noaccel", strlen("noaccel"))) g_noaccel = 1; -#ifdef CONFIG_MTRR else if (!strncmp(opt, "nomtrr", strlen("nomtrr"))) g_nomtrr = 1; -#endif else if (!strncmp(opt, "dual", strlen("dual"))) g_dualview = 1; else { diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index 0847d2bd95c8..30aa31239125 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -12,7 +12,7 @@ #define MB(x) ((x)<<20) #define MHZ(x) ((x) * 1000000) /* align should be 2,4,8,16 */ -#define PADDING(align,data) (((data)+(align)-1)&(~((align) -1))) +#define PADDING(align, data) (((data)+(align)-1)&(~((align) -1))) extern int smi_indent; @@ -27,15 +27,16 @@ struct lynx_accel{ int (*de_wait)(void);/* see if hardware ready to work */ - int (*de_fillrect)(struct lynx_accel *,u32,u32,u32, - u32,u32,u32,u32,u32,u32); + int (*de_fillrect)(struct lynx_accel *, u32, u32, u32, u32, + u32, u32, u32, u32, u32); - int (*de_copyarea)(struct lynx_accel *,u32,u32,u32,u32, - u32,u32,u32,u32, - u32,u32,u32,u32); + int (*de_copyarea)(struct lynx_accel *, u32, u32, u32, u32, + u32, u32, u32, u32, + u32, u32, u32, u32); - int (*de_imageblit)(struct lynx_accel *,const char *,u32,u32,u32, - u32,u32,u32,u32,u32,u32,u32,u32,u32); + int (*de_imageblit)(struct lynx_accel *, const char *, u32, u32, u32, u32, + u32, u32, u32, u32, + u32, u32, u32, u32); }; @@ -51,13 +52,10 @@ struct lynx_share{ struct lynx_accel accel; int accel_off; int dual; -#ifdef CONFIG_MTRR int mtrr_off; struct{ int vram; - int vram_added; }mtrr; -#endif /* all smi graphic adaptor got below attributes */ unsigned long vidmem_start; unsigned long vidreg_start; @@ -90,10 +88,10 @@ struct lynx_cursor{ /* proc_routines */ void (*enable)(struct lynx_cursor *); void (*disable)(struct lynx_cursor *); - void (*setSize)(struct lynx_cursor *,int,int); - void (*setPos)(struct lynx_cursor *,int,int); - void (*setColor)(struct lynx_cursor *,u32,u32); - void (*setData)(struct lynx_cursor *,u16,const u8*,const u8*); + void (*setSize)(struct lynx_cursor *, int, int); + void (*setPos)(struct lynx_cursor *, int, int); + void (*setColor)(struct lynx_cursor *, u32, u32); + void (*setData)(struct lynx_cursor *, u16, const u8*, const u8*); }; struct lynxfb_crtc{ @@ -116,8 +114,8 @@ struct lynxfb_crtc{ struct fb_var_screeninfo*, struct fb_fix_screeninfo*); - int(*proc_checkMode)(struct lynxfb_crtc*,struct fb_var_screeninfo*); - int(*proc_setColReg)(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); + int(*proc_checkMode)(struct lynxfb_crtc*, struct fb_var_screeninfo*); + int(*proc_setColReg)(struct lynxfb_crtc*, ushort, ushort, ushort, ushort); void (*clear)(struct lynxfb_crtc*); /* pan display */ int (*proc_panDisplay)(struct lynxfb_crtc *, @@ -148,8 +146,8 @@ struct lynxfb_output{ struct fb_var_screeninfo*, struct fb_fix_screeninfo*); - int(*proc_checkMode)(struct lynxfb_output*,struct fb_var_screeninfo*); - int(*proc_setBLANK)(struct lynxfb_output*,int); + int(*proc_checkMode)(struct lynxfb_output*, struct fb_var_screeninfo*); + int(*proc_setBLANK)(struct lynxfb_output*, int); void (*clear)(struct lynxfb_output*); }; @@ -171,7 +169,7 @@ struct lynxfb_par{ #define PS_TO_HZ(ps) \ ({ \ unsigned long long hz = 1000*1000*1000*1000ULL; \ - do_div(hz,ps); \ + do_div(hz, ps); \ (unsigned long)hz;}) static inline unsigned long ps_to_hz(unsigned int psvalue) diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c index 6a04ef86eb13..001e98031056 100644 --- a/drivers/staging/sm750fb/sm750_accel.c +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -18,81 +18,81 @@ #include "sm750.h" #include "sm750_accel.h" #include "sm750_help.h" -static inline void write_dpr(struct lynx_accel * accel,int offset,u32 regValue) +static inline void write_dpr(struct lynx_accel * accel, int offset, u32 regValue) { - writel(regValue,accel->dprBase + offset); + writel(regValue, accel->dprBase + offset); } -static inline u32 read_dpr(struct lynx_accel * accel,int offset) +static inline u32 read_dpr(struct lynx_accel * accel, int offset) { return readl(accel->dprBase + offset); } -static inline void write_dpPort(struct lynx_accel * accel,u32 data) +static inline void write_dpPort(struct lynx_accel * accel, u32 data) { - writel(data,accel->dpPortBase); + writel(data, accel->dpPortBase); } void hw_de_init(struct lynx_accel * accel) { /* setup 2d engine registers */ - u32 reg,clr; + u32 reg, clr; - write_dpr(accel,DE_MASKS,0xFFFFFFFF); + write_dpr(accel, DE_MASKS, 0xFFFFFFFF); /* dpr1c */ - reg = FIELD_SET(0,DE_STRETCH_FORMAT,PATTERN_XY,NORMAL)| - FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_Y,0)| - FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_X,0)| - FIELD_SET(0,DE_STRETCH_FORMAT,ADDRESSING,XY)| - FIELD_VALUE(0,DE_STRETCH_FORMAT,SOURCE_HEIGHT,3); - - clr = FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_XY)& - FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_Y)& - FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_X)& - FIELD_CLEAR(DE_STRETCH_FORMAT,ADDRESSING)& - FIELD_CLEAR(DE_STRETCH_FORMAT,SOURCE_HEIGHT); + reg = FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL)| + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0)| + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0)| + FIELD_SET(0, DE_STRETCH_FORMAT, ADDRESSING, XY)| + FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3); + + clr = FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_XY)& + FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_Y)& + FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_X)& + FIELD_CLEAR(DE_STRETCH_FORMAT, ADDRESSING)& + FIELD_CLEAR(DE_STRETCH_FORMAT, SOURCE_HEIGHT); /* DE_STRETCH bpp format need be initilized in setMode routine */ - write_dpr(accel,DE_STRETCH_FORMAT,(read_dpr(accel,DE_STRETCH_FORMAT) & clr) | reg); + write_dpr(accel, DE_STRETCH_FORMAT, (read_dpr(accel, DE_STRETCH_FORMAT) & clr) | reg); /* disable clipping and transparent */ - write_dpr(accel,DE_CLIP_TL,0);//dpr2c - write_dpr(accel,DE_CLIP_BR,0);//dpr30 + write_dpr(accel, DE_CLIP_TL, 0);//dpr2c + write_dpr(accel, DE_CLIP_BR, 0);//dpr30 - write_dpr(accel,DE_COLOR_COMPARE_MASK,0);//dpr24 - write_dpr(accel,DE_COLOR_COMPARE,0); + write_dpr(accel, DE_COLOR_COMPARE_MASK, 0);//dpr24 + write_dpr(accel, DE_COLOR_COMPARE, 0); - reg = FIELD_SET(0,DE_CONTROL,TRANSPARENCY,DISABLE)| - FIELD_SET(0,DE_CONTROL,TRANSPARENCY_MATCH,OPAQUE)| - FIELD_SET(0,DE_CONTROL,TRANSPARENCY_SELECT,SOURCE); + reg = FIELD_SET(0, DE_CONTROL, TRANSPARENCY, DISABLE)| + FIELD_SET(0, DE_CONTROL, TRANSPARENCY_MATCH, OPAQUE)| + FIELD_SET(0, DE_CONTROL, TRANSPARENCY_SELECT, SOURCE); - clr = FIELD_CLEAR(DE_CONTROL,TRANSPARENCY)& - FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_MATCH)& - FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_SELECT); + clr = FIELD_CLEAR(DE_CONTROL, TRANSPARENCY)& + FIELD_CLEAR(DE_CONTROL, TRANSPARENCY_MATCH)& + FIELD_CLEAR(DE_CONTROL, TRANSPARENCY_SELECT); /* dpr0c */ - write_dpr(accel,DE_CONTROL,(read_dpr(accel,DE_CONTROL)&clr)|reg); + write_dpr(accel, DE_CONTROL, (read_dpr(accel, DE_CONTROL)&clr)|reg); } /* set2dformat only be called from setmode functions * but if you need dual framebuffer driver,need call set2dformat * every time you use 2d function */ -void hw_set2dformat(struct lynx_accel * accel,int fmt) +void hw_set2dformat(struct lynx_accel * accel, int fmt) { u32 reg; /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */ - reg = read_dpr(accel,DE_STRETCH_FORMAT); - reg = FIELD_VALUE(reg,DE_STRETCH_FORMAT,PIXEL_FORMAT,fmt); - write_dpr(accel,DE_STRETCH_FORMAT,reg); + reg = read_dpr(accel, DE_STRETCH_FORMAT); + reg = FIELD_VALUE(reg, DE_STRETCH_FORMAT, PIXEL_FORMAT, fmt); + write_dpr(accel, DE_STRETCH_FORMAT, reg); } int hw_fillrect(struct lynx_accel * accel, - u32 base,u32 pitch,u32 Bpp, - u32 x,u32 y,u32 width,u32 height, - u32 color,u32 rop) + u32 base, u32 pitch, u32 Bpp, + u32 x, u32 y, u32 width, u32 height, + u32 color, u32 rop) { u32 deCtrl; @@ -100,39 +100,39 @@ int hw_fillrect(struct lynx_accel * accel, { /* int time wait and always busy,seems hardware * got something error */ - pr_debug("%s:De engine always bussy\n",__func__); + pr_debug("%s:De engine always bussy\n", __func__); return -1; } - write_dpr(accel,DE_WINDOW_DESTINATION_BASE,base);//dpr40 - write_dpr(accel,DE_PITCH, - FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch/Bpp)| - FIELD_VALUE(0,DE_PITCH,SOURCE,pitch/Bpp));//dpr10 + write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base);//dpr40 + write_dpr(accel, DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, pitch/Bpp)| + FIELD_VALUE(0, DE_PITCH, SOURCE, pitch/Bpp));//dpr10 - write_dpr(accel,DE_WINDOW_WIDTH, - FIELD_VALUE(0,DE_WINDOW_WIDTH,DESTINATION,pitch/Bpp)| - FIELD_VALUE(0,DE_WINDOW_WIDTH,SOURCE,pitch/Bpp));//dpr44 + write_dpr(accel, DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, pitch/Bpp)| + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, pitch/Bpp));//dpr44 - write_dpr(accel,DE_FOREGROUND,color);//DPR14 + write_dpr(accel, DE_FOREGROUND, color);//DPR14 - write_dpr(accel,DE_DESTINATION, - FIELD_SET(0,DE_DESTINATION,WRAP,DISABLE)| - FIELD_VALUE(0,DE_DESTINATION,X,x)| - FIELD_VALUE(0,DE_DESTINATION,Y,y));//dpr4 + write_dpr(accel, DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE)| + FIELD_VALUE(0, DE_DESTINATION, X, x)| + FIELD_VALUE(0, DE_DESTINATION, Y, y));//dpr4 - write_dpr(accel,DE_DIMENSION, - FIELD_VALUE(0,DE_DIMENSION,X,width)| - FIELD_VALUE(0,DE_DIMENSION,Y_ET,height));//dpr8 + write_dpr(accel, DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width)| + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr8 deCtrl = - FIELD_SET(0,DE_CONTROL,STATUS,START)| - FIELD_SET(0,DE_CONTROL,DIRECTION,LEFT_TO_RIGHT)| - FIELD_SET(0,DE_CONTROL,LAST_PIXEL,ON)| - FIELD_SET(0,DE_CONTROL,COMMAND,RECTANGLE_FILL)| - FIELD_SET(0,DE_CONTROL,ROP_SELECT,ROP2)| - FIELD_VALUE(0,DE_CONTROL,ROP,rop);//dpr0xc - - write_dpr(accel,DE_CONTROL,deCtrl); + FIELD_SET(0, DE_CONTROL, STATUS, START)| + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)| + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, ON)| + FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL)| + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2)| + FIELD_VALUE(0, DE_CONTROL, ROP, rop);//dpr0xc + + write_dpr(accel, DE_CONTROL, deCtrl); return 0; } @@ -236,12 +236,12 @@ unsigned int rop2) /* ROP value */ /* 2D Source Base. It is an address offset (128 bit aligned) from the beginning of frame buffer. */ - write_dpr(accel,DE_WINDOW_SOURCE_BASE, sBase);//dpr40 + write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase);//dpr40 /* 2D Destination Base. It is an address offset (128 bit aligned) from the beginning of frame buffer. */ - write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase);//dpr44 + write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);//dpr44 #if 0 /* Program pitch (distance between the 1st points of two adjacent lines). @@ -252,14 +252,14 @@ unsigned int rop2) /* ROP value */ sx *= 3; dx *= 3; width *= 3; - write_dpr(accel,DE_PITCH, + write_dpr(accel, DE_PITCH, FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | FIELD_VALUE(0, DE_PITCH, SOURCE, sPitch));//dpr10 } else #endif { - write_dpr(accel,DE_PITCH, + write_dpr(accel, DE_PITCH, FIELD_VALUE(0, DE_PITCH, DESTINATION, (dPitch/Bpp)) | FIELD_VALUE(0, DE_PITCH, SOURCE, (sPitch/Bpp)));//dpr10 } @@ -267,7 +267,7 @@ unsigned int rop2) /* ROP value */ /* Screen Window width in Pixels. 2D engine uses this value to calculate the linear address in frame buffer for a given point. */ - write_dpr(accel,DE_WINDOW_WIDTH, + write_dpr(accel, DE_WINDOW_WIDTH, FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/Bpp)) | FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (sPitch/Bpp)));//dpr3c @@ -277,15 +277,15 @@ unsigned int rop2) /* ROP value */ { - write_dpr(accel,DE_SOURCE, + write_dpr(accel, DE_SOURCE, FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | FIELD_VALUE(0, DE_SOURCE, X_K1, sx) | FIELD_VALUE(0, DE_SOURCE, Y_K2, sy));//dpr0 - write_dpr(accel,DE_DESTINATION, + write_dpr(accel, DE_DESTINATION, FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, dx) | FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 - write_dpr(accel,DE_DIMENSION, + write_dpr(accel, DE_DIMENSION, FIELD_VALUE(0, DE_DIMENSION, X, width) | FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 @@ -297,7 +297,7 @@ unsigned int rop2) /* ROP value */ FIELD_SET(0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) : FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, STATUS, START); - write_dpr(accel,DE_CONTROL,de_ctrl);//dpr0c + write_dpr(accel, DE_CONTROL, de_ctrl);//dpr0c } return 0; @@ -307,7 +307,7 @@ static unsigned int deGetTransparency(struct lynx_accel * accel) { unsigned int de_ctrl; - de_ctrl = read_dpr(accel,DE_CONTROL); + de_ctrl = read_dpr(accel, DE_CONTROL); de_ctrl &= FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | @@ -353,12 +353,12 @@ int hw_imageblit(struct lynx_accel *accel, /* 2D Source Base. Use 0 for HOST Blt. */ - write_dpr(accel,DE_WINDOW_SOURCE_BASE, 0); + write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0); /* 2D Destination Base. It is an address offset (128 bit aligned) from the beginning of frame buffer. */ - write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase); + write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); #if 0 /* Program pitch (distance between the 1st points of two adjacent lines). Note that input pitch is BYTE value, but the 2D Pitch register uses @@ -368,7 +368,7 @@ int hw_imageblit(struct lynx_accel *accel, dx *= 3; width *= 3; startBit *= 3; - write_dpr(accel,DE_PITCH, + write_dpr(accel, DE_PITCH, FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch));//dpr10 @@ -376,7 +376,7 @@ int hw_imageblit(struct lynx_accel *accel, else #endif { - write_dpr(accel,DE_PITCH, + write_dpr(accel, DE_PITCH, FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch/bytePerPixel) | FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch/bytePerPixel));//dpr10 } @@ -384,27 +384,27 @@ int hw_imageblit(struct lynx_accel *accel, /* Screen Window width in Pixels. 2D engine uses this value to calculate the linear address in frame buffer for a given point. */ - write_dpr(accel,DE_WINDOW_WIDTH, + write_dpr(accel, DE_WINDOW_WIDTH, FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/bytePerPixel)) | FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (dPitch/bytePerPixel))); /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, and Y_K2 field is not used. For mono bitmap, use startBit for X_K1. */ - write_dpr(accel,DE_SOURCE, + write_dpr(accel, DE_SOURCE, FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | FIELD_VALUE(0, DE_SOURCE, X_K1_MONO, startBit));//dpr00 - write_dpr(accel,DE_DESTINATION, + write_dpr(accel, DE_DESTINATION, FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, dx) | FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 - write_dpr(accel,DE_DIMENSION, + write_dpr(accel, DE_DIMENSION, FIELD_VALUE(0, DE_DIMENSION, X, width) | FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 - write_dpr(accel,DE_FOREGROUND, fColor); - write_dpr(accel,DE_BACKGROUND, bColor); + write_dpr(accel, DE_FOREGROUND, fColor); + write_dpr(accel, DE_BACKGROUND, bColor); de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | @@ -412,7 +412,7 @@ int hw_imageblit(struct lynx_accel *accel, FIELD_SET(0, DE_CONTROL, HOST, MONO) | FIELD_SET(0, DE_CONTROL, STATUS, START); - write_dpr(accel,DE_CONTROL, de_ctrl | deGetTransparency(accel)); + write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel)); /* Write MONO data (line by line) to 2D Engine data port */ for (i=0; i<height; i++) diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h index 3ee0bd89257b..e9d217b88a50 100644 --- a/drivers/staging/sm750fb/sm750_accel.h +++ b/drivers/staging/sm750fb/sm750_accel.h @@ -234,14 +234,14 @@ #define BOTTOM_TO_TOP 1 #define RIGHT_TO_LEFT 1 -void hw_set2dformat(struct lynx_accel * accel,int fmt); +void hw_set2dformat(struct lynx_accel * accel, int fmt); void hw_de_init(struct lynx_accel * accel); int hw_fillrect(struct lynx_accel * accel, - u32 base,u32 pitch,u32 Bpp, - u32 x,u32 y,u32 width,u32 height, - u32 color,u32 rop); + u32 base, u32 pitch, u32 Bpp, + u32 x, u32 y, u32 width, u32 height, + u32 color, u32 rop); int hw_copyarea( struct lynx_accel * accel, diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index 68d5cbc3e513..b14528574d59 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -23,8 +23,8 @@ #define PEEK32(addr) \ readl(cursor->mmio + (addr)) -#define POKE32(addr,data) \ -writel((data),cursor->mmio + (addr)) +#define POKE32(addr, data) \ +writel((data), cursor->mmio + (addr)) /* cursor control for voyager and 718/750*/ #define HWC_ADDRESS 0x0 @@ -61,42 +61,42 @@ writel((data),cursor->mmio + (addr)) void hw_cursor_enable(struct lynx_cursor * cursor) { u32 reg; - reg = FIELD_VALUE(0,HWC_ADDRESS,ADDRESS,cursor->offset)| - FIELD_SET(0,HWC_ADDRESS,EXT,LOCAL)| - FIELD_SET(0,HWC_ADDRESS,ENABLE,ENABLE); - POKE32(HWC_ADDRESS,reg); + reg = FIELD_VALUE(0, HWC_ADDRESS, ADDRESS, cursor->offset)| + FIELD_SET(0, HWC_ADDRESS, EXT, LOCAL)| + FIELD_SET(0, HWC_ADDRESS, ENABLE, ENABLE); + POKE32(HWC_ADDRESS, reg); } void hw_cursor_disable(struct lynx_cursor * cursor) { - POKE32(HWC_ADDRESS,0); + POKE32(HWC_ADDRESS, 0); } void hw_cursor_setSize(struct lynx_cursor * cursor, - int w,int h) + int w, int h) { cursor->w = w; cursor->h = h; } void hw_cursor_setPos(struct lynx_cursor * cursor, - int x,int y) + int x, int y) { u32 reg; - reg = FIELD_VALUE(0,HWC_LOCATION,Y,y)| - FIELD_VALUE(0,HWC_LOCATION,X,x); - POKE32(HWC_LOCATION,reg); + reg = FIELD_VALUE(0, HWC_LOCATION, Y, y)| + FIELD_VALUE(0, HWC_LOCATION, X, x); + POKE32(HWC_LOCATION, reg); } void hw_cursor_setColor(struct lynx_cursor * cursor, - u32 fg,u32 bg) + u32 fg, u32 bg) { - POKE32(HWC_COLOR_12,(fg<<16)|(bg&0xffff)); - POKE32(HWC_COLOR_3,0xffe0); + POKE32(HWC_COLOR_12, (fg<<16)|(bg&0xffff)); + POKE32(HWC_COLOR_3, 0xffe0); } void hw_cursor_setData(struct lynx_cursor * cursor, - u16 rop,const u8* pcol,const u8* pmsk) + u16 rop, const u8* pcol, const u8* pmsk) { - int i,j,count,pitch,offset; - u8 color,mask,opr; + int i, j, count, pitch, offset; + u8 color, mask, opr; u16 data; void __iomem *pbuffer, *pstart; @@ -184,9 +184,9 @@ void hw_cursor_setData(struct lynx_cursor * cursor, void hw_cursor_setData2(struct lynx_cursor * cursor, - u16 rop,const u8* pcol,const u8* pmsk) + u16 rop, const u8* pcol, const u8* pmsk) { - int i,j,count,pitch,offset; + int i, j, count, pitch, offset; u8 color, mask; u16 data; void __iomem *pbuffer, *pstart; diff --git a/drivers/staging/sm750fb/sm750_cursor.h b/drivers/staging/sm750fb/sm750_cursor.h index 8cede0721332..be588687a81d 100644 --- a/drivers/staging/sm750fb/sm750_cursor.h +++ b/drivers/staging/sm750fb/sm750_cursor.h @@ -5,13 +5,13 @@ void hw_cursor_enable(struct lynx_cursor * cursor); void hw_cursor_disable(struct lynx_cursor * cursor); void hw_cursor_setSize(struct lynx_cursor * cursor, - int w,int h); + int w, int h); void hw_cursor_setPos(struct lynx_cursor * cursor, - int x,int y); + int x, int y); void hw_cursor_setColor(struct lynx_cursor * cursor, - u32 fg,u32 bg); + u32 fg, u32 bg); void hw_cursor_setData(struct lynx_cursor * cursor, - u16 rop,const u8* data,const u8* mask); + u16 rop, const u8* data, const u8* mask); void hw_cursor_setData2(struct lynx_cursor * cursor, - u16 rop,const u8* data,const u8* mask); + u16 rop, const u8* data, const u8* mask); #endif diff --git a/drivers/staging/sm750fb/sm750_help.h b/drivers/staging/sm750fb/sm750_help.h index e0128d2a9ead..ebc946cfe81b 100644 --- a/drivers/staging/sm750fb/sm750_help.h +++ b/drivers/staging/sm750fb/sm750_help.h @@ -10,11 +10,11 @@ #define RAW_MASK(f) (0xFFFFFFFF >> (32 - _COUNT(f))) #define GET_MASK(f) (RAW_MASK(f) << _LSB(f)) -#define GET_FIELD(d,f) (((d) >> _LSB(f)) & RAW_MASK(f)) -#define TEST_FIELD(d,f,v) (GET_FIELD(d,f) == f ## _ ## v) -#define SET_FIELD(d,f,v) (((d) & ~GET_MASK(f)) | \ +#define GET_FIELD(d, f) (((d) >> _LSB(f)) & RAW_MASK(f)) +#define TEST_FIELD(d, f, v) (GET_FIELD(d, f) == f ## _ ## v) +#define SET_FIELD(d, f, v) (((d) & ~GET_MASK(f)) | \ (((f ## _ ## v) & RAW_MASK(f)) << _LSB(f))) -#define SET_FIELDV(d,f,v) (((d) & ~GET_MASK(f)) | \ +#define SET_FIELDV(d, f, v) (((d) & ~GET_MASK(f)) | \ (((v) & RAW_MASK(f)) << _LSB(f))) @@ -91,7 +91,7 @@ (unsigned short) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3)) \ ) -static inline unsigned int absDiff(unsigned int a,unsigned int b) +static inline unsigned int absDiff(unsigned int a, unsigned int b) { if(a<b) return b-a; @@ -100,7 +100,7 @@ static inline unsigned int absDiff(unsigned int a,unsigned int b) } /* n / d + 1 / 2 = (2n + d) / 2d */ -#define roundedDiv(num,denom) ((2 * (num) + (denom)) / (2 * (denom))) +#define roundedDiv(num, denom) ((2 * (num) + (denom)) / (2 * (denom))) #define MB(x) ((x)<<20) #define KB(x) ((x)<<10) #define MHz(x) ((x) * 1000000) diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index 9f0d06da12fb..131125ca5737 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -30,7 +30,7 @@ int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev) struct sm750_share * spec_share; - spec_share = container_of(share, struct sm750_share,share); + spec_share = container_of(share, struct sm750_share, share); ret = 0; share->vidreg_start = pci_resource_start(pdev, 1); @@ -64,7 +64,7 @@ int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev) share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1; share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1; - ddk750_set_mmio(share->pvReg,share->devid, share->revid); + ddk750_set_mmio(share->pvReg, share->devid, share->revid); share->vidmem_start = pci_resource_start(pdev, 0); /* don't use pdev_resource[x].end - resource[x].start to @@ -78,15 +78,14 @@ int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev) /* reserve the vidmem space of smi adaptor */ #if 0 - if((ret = pci_request_region(pdev,0,_moduleName_))) + if((ret = pci_request_region(pdev, 0, _moduleName_))) { pr_err("Can not request PCI regions.\n"); goto exit; } #endif - share->pvMem = ioremap(share->vidmem_start, - share->vidmem_size); + share->pvMem = ioremap_wc(share->vidmem_start, share->vidmem_size); if(!share->pvMem){ pr_err("Map video memory failed\n"); @@ -106,7 +105,7 @@ int hw_sm750_inithw(struct lynx_share* share, struct pci_dev * pdev) struct sm750_share * spec_share; struct init_status * parm; - spec_share = container_of(share, struct sm750_share,share); + spec_share = container_of(share, struct sm750_share, share); parm = &spec_share->state.initParm; if(parm->chip_clk == 0) parm->chip_clk = (getChipType() == SM750LE)? @@ -172,7 +171,7 @@ int hw_sm750_inithw(struct lynx_share* share, struct pci_dev * pdev) /* Set up GPIO for software I2C to program DVI chip in the Xilinx SP605 board, in order to have video signal. */ - swI2CInit(0,1); + swI2CInit(0, 1); /* Customer may NOT use CH7301 DVI chip, which has to be @@ -270,7 +269,7 @@ int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc, struct fb_var_screeninfo* struct lynx_share * share; - share = container_of(crtc, struct lynxfb_par,crtc)->share; + share = container_of(crtc, struct lynxfb_par, crtc)->share; switch (var->bits_per_pixel){ case 8: @@ -298,7 +297,7 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc, struct fb_var_screeninfo* var, struct fb_fix_screeninfo* fix) { - int ret,fmt; + int ret, fmt; u32 reg; mode_parameter_t modparm; clock_type_t clock; @@ -365,7 +364,7 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc, reg = var->xres * (var->bits_per_pixel >> 3); /* crtc->channel is not equal to par->index on numeric,be aware of that */ - reg = PADDING(crtc->line_pad,reg); + reg = PADDING(crtc->line_pad, reg); POKE32(PANEL_FB_WIDTH, FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, reg)| @@ -383,7 +382,7 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc, POKE32(PANEL_PLANE_BR, FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, var->yres - 1)| - FIELD_VALUE(0, PANEL_PLANE_BR,RIGHT, var->xres - 1)); + FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT, var->xres - 1)); /* set pixel format */ reg = PEEK32(PANEL_DISPLAY_CTRL); @@ -424,17 +423,17 @@ void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc) int hw_sm750_setColReg(struct lynxfb_crtc* crtc, ushort index, ushort red, ushort green, ushort blue) { - static unsigned int add[]={PANEL_PALETTE_RAM,CRT_PALETTE_RAM}; + static unsigned int add[]={PANEL_PALETTE_RAM, CRT_PALETTE_RAM}; POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue); return 0; } int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){ - int dpms,crtdb; + int dpms, crtdb; switch(blank) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_UNBLANK: #else case VESA_NO_BLANKING: @@ -442,13 +441,13 @@ int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){ dpms = CRT_DISPLAY_CTRL_DPMS_0; crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_NORMAL: dpms = CRT_DISPLAY_CTRL_DPMS_0; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_VSYNC_SUSPEND: #else case VESA_VSYNC_SUSPEND: @@ -456,7 +455,7 @@ int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){ dpms = CRT_DISPLAY_CTRL_DPMS_2; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_HSYNC_SUSPEND: #else case VESA_HSYNC_SUSPEND: @@ -464,7 +463,7 @@ int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){ dpms = CRT_DISPLAY_CTRL_DPMS_1; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_POWERDOWN: #else case VESA_POWERDOWN: @@ -483,7 +482,7 @@ int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){ return 0; } -int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) +int hw_sm750_setBLANK(struct lynxfb_output* output, int blank) { unsigned int dpms, pps, crtdb; @@ -491,7 +490,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) switch (blank) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_UNBLANK: #else case VESA_NO_BLANKING: @@ -501,7 +500,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) pps = PANEL_DISPLAY_CTRL_DATA_ENABLE; crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_NORMAL: pr_info("flag = FB_BLANK_NORMAL \n"); dpms = SYSTEM_CTRL_DPMS_VPHP; @@ -509,7 +508,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_VSYNC_SUSPEND: #else case VESA_VSYNC_SUSPEND: @@ -518,7 +517,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_HSYNC_SUSPEND: #else case VESA_HSYNC_SUSPEND: @@ -527,7 +526,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) case FB_BLANK_POWERDOWN: #else case VESA_POWERDOWN: @@ -540,8 +539,8 @@ int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) if(output->paths & sm750_crt){ - POKE32(SYSTEM_CTRL,FIELD_VALUE(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, DPMS, dpms)); - POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL,BLANK, crtdb)); + POKE32(SYSTEM_CTRL, FIELD_VALUE(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, DPMS, dpms)); + POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, BLANK, crtdb)); } if(output->paths & sm750_panel){ @@ -559,21 +558,21 @@ void hw_sm750_initAccel(struct lynx_share * share) if(getChipType() == SM750LE){ reg = PEEK32(DE_STATE1); - reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,ON); - POKE32(DE_STATE1,reg); + reg = FIELD_SET(reg, DE_STATE1, DE_ABORT, ON); + POKE32(DE_STATE1, reg); reg = PEEK32(DE_STATE1); - reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,OFF); + reg = FIELD_SET(reg, DE_STATE1, DE_ABORT, OFF); POKE32(DE_STATE1, reg); }else{ /* engine reset */ reg = PEEK32(SYSTEM_CTRL); - reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,ON); + reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT, ON); POKE32(SYSTEM_CTRL, reg); reg = PEEK32(SYSTEM_CTRL); - reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,OFF); + reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT, OFF); POKE32(SYSTEM_CTRL, reg); } @@ -603,9 +602,9 @@ int hw_sm750_deWait(void) int i=0x10000000; while(i--){ unsigned int dwVal = PEEK32(SYSTEM_CTRL); - if((FIELD_GET(dwVal,SYSTEM_CTRL,DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) && - (FIELD_GET(dwVal,SYSTEM_CTRL,DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) && - (FIELD_GET(dwVal,SYSTEM_CTRL,DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) + if((FIELD_GET(dwVal, SYSTEM_CTRL, DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) && + (FIELD_GET(dwVal, SYSTEM_CTRL, DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal, SYSTEM_CTRL, DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) { return 0; } diff --git a/drivers/staging/sm750fb/sm750_hw.h b/drivers/staging/sm750fb/sm750_hw.h index c607d9b81cd8..4fee28d22b58 100644 --- a/drivers/staging/sm750fb/sm750_hw.h +++ b/drivers/staging/sm750fb/sm750_hw.h @@ -81,20 +81,20 @@ struct sm750_share{ */ }; -int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev); -int hw_sm750_inithw(struct lynx_share*,struct pci_dev *); +int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev); +int hw_sm750_inithw(struct lynx_share*, struct pci_dev *); void hw_sm750_initAccel(struct lynx_share *); int hw_sm750_deWait(void); int hw_sm750le_deWait(void); resource_size_t hw_sm750_getVMSize(struct lynx_share *); -int hw_sm750_output_checkMode(struct lynxfb_output*,struct fb_var_screeninfo*); -int hw_sm750_output_setMode(struct lynxfb_output*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); -int hw_sm750_crtc_checkMode(struct lynxfb_crtc*,struct fb_var_screeninfo*); -int hw_sm750_crtc_setMode(struct lynxfb_crtc*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); -int hw_sm750_setColReg(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); -int hw_sm750_setBLANK(struct lynxfb_output*,int); -int hw_sm750le_setBLANK(struct lynxfb_output*,int); +int hw_sm750_output_checkMode(struct lynxfb_output*, struct fb_var_screeninfo*); +int hw_sm750_output_setMode(struct lynxfb_output*, struct fb_var_screeninfo*, struct fb_fix_screeninfo*); +int hw_sm750_crtc_checkMode(struct lynxfb_crtc*, struct fb_var_screeninfo*); +int hw_sm750_crtc_setMode(struct lynxfb_crtc*, struct fb_var_screeninfo*, struct fb_fix_screeninfo*); +int hw_sm750_setColReg(struct lynxfb_crtc*, ushort, ushort, ushort, ushort); +int hw_sm750_setBLANK(struct lynxfb_output*, int); +int hw_sm750le_setBLANK(struct lynxfb_output*, int); void hw_sm750_crtc_clear(struct lynxfb_crtc*); void hw_sm750_output_clear(struct lynxfb_output*); int hw_sm750_pan_display(struct lynxfb_crtc *crtc, diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h deleted file mode 100644 index 33d9caf337c8..000000000000 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* - * Module Name: - * controlframework.h - * - * Abstract: This file defines common structures in the unmanaged - * Ultravisor (mostly EFI) space. - * - */ - -#ifndef _CONTROL_FRAMEWORK_H_ -#define _CONTROL_FRAMEWORK_H_ - -#include <linux/types.h> -#include "channel.h" - -struct spar_segment_state { - u16 enabled:1; /* Bit 0: May enter other states */ - u16 active:1; /* Bit 1: Assigned to active partition */ - u16 alive:1; /* Bit 2: Configure message sent to - * service/server */ - u16 revoked:1; /* Bit 3: similar to partition state - * ShuttingDown */ - u16 allocated:1; /* Bit 4: memory (device/port number) - * has been selected by Command */ - u16 known:1; /* Bit 5: has been introduced to the - * service/guest partition */ - u16 ready:1; /* Bit 6: service/Guest partition has - * responded to introduction */ - u16 operating:1; /* Bit 7: resource is configured and - * operating */ - /* Note: don't use high bit unless we need to switch to ushort - * which is non-compliant */ -}; - -static const struct spar_segment_state segment_state_running = { - 1, 1, 1, 0, 1, 1, 1, 1 -}; - -static const struct spar_segment_state segment_state_paused = { - 1, 1, 1, 0, 1, 1, 1, 0 -}; - -static const struct spar_segment_state segment_state_standby = { - 1, 1, 0, 0, 1, 1, 1, 0 -}; - -#endif /* _CONTROL_FRAMEWORK_H_ not defined */ diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h deleted file mode 100644 index e8fb8678a8e2..000000000000 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ /dev/null @@ -1,427 +0,0 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/*++ - * - * Module Name: - * - * diagchannel.h - * - * Abstract: - * - * This file defines the DiagChannel protocol. This protocol is used to aid in - * preserving event data sent by external applications. This protocol provides - * a region for event data to reside in. This data will eventually be sent to - * the Boot Partition where it will be committed to memory and/or disk. This - * file contains platform-independent data that can be built using any - * Supervisor build environment (Windows, Linux, EFI). - * -*/ - -#ifndef _DIAG_CHANNEL_H_ -#define _DIAG_CHANNEL_H_ - -#include <linux/uuid.h> -#include "channel.h" - -/* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */ -#define SPAR_DIAG_CHANNEL_PROTOCOL_UUID \ - UUID_LE(0xeea7a573, 0xdb82, 0x447c, \ - 0x87, 0x16, 0xef, 0xbe, 0xaa, 0xae, 0x48, 0x58) - -static const uuid_le spar_diag_channel_protocol_uuid = - SPAR_DIAG_CHANNEL_PROTOCOL_UUID; - -/* {E850F968-3263-4484-8CA5-2A35D087A5A8} */ -#define ULTRA_DIAG_ROOT_CHANNEL_PROTOCOL_GUID \ - UUID_LE(0xe850f968, 0x3263, 0x4484, \ - 0x8c, 0xa5, 0x2a, 0x35, 0xd0, 0x87, 0xa5, 0xa8) - -#define ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE - -/* Must increment this whenever you insert or delete fields within this channel -* struct. Also increment whenever you change the meaning of fields within this -* channel struct so as to break pre-existing software. Note that you can -* usually add fields to the END of the channel struct withOUT needing to -* increment this. */ -#define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2 - -#define SPAR_DIAG_CHANNEL_OK_CLIENT(ch)\ - (spar_check_channel_client(ch,\ - spar_diag_channel_protocol_uuid,\ - "diag",\ - sizeof(struct spar_diag_channel_protocol),\ - ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ - ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) - -#define SPAR_DIAG_CHANNEL_OK_SERVER(bytes)\ - (spar_check_channel_server(spar_diag_channel_protocol_uuid,\ - "diag",\ - sizeof(struct spar_diag_channel_protocol),\ - bytes)) - -#define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ -#define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info - * accompanying event... */ -#define MAX_SUBSYSTEMS 64 /* Maximum number of subsystems allowed in - * DiagChannel... */ -#define LOW_SUBSYSTEMS 32 /* Half of MAX_SUBSYSTEMS to allow 64-bit - * math */ -#define SUBSYSTEM_DEBUG 0 /* Standard subsystem for debug events */ -#define SUBSYSTEM_DEFAULT 1 /* Default subsystem for legacy calls to - * ReportEvent */ - -/* few useful subsystem mask values */ -#define SUBSYSTEM_MASK_DEBUG 0x01 /* Standard subsystem for debug - * events */ -#define SUBSYSTEM_MASK_DEFAULT 0x02 /* Default subsystem for legacy calls to - * ReportEvents */ - -/* Event parameter "Severity" is overloaded with Cause in byte 2 and Severity in - * byte 0, bytes 1 and 3 are reserved */ -#define SEVERITY_MASK 0x0FF /* mask out all but the Severity in byte 0 */ -#define CAUSE_MASK 0x0FF0000 /* mask out all but the cause in byte 2 */ -#define CAUSE_SHIFT_AMT 16 /* shift 2 bytes to place it in byte 2 */ - -/* SubsystemSeverityFilter */ -#define SEVERITY_FILTER_MASK 0x0F /* mask out the Cause half, SeverityFilter is - * in the lower nibble */ -#define CAUSE_FILTER_MASK 0xF0 /* mask out the Severity half, CauseFilter is in - * the upper nibble */ -#define CAUSE_FILTER_SHIFT_AMT 4 /* shift amount to place it in lower or upper - * nibble */ - -/* Copied from EFI's EFI_TIME struct in efidef.h. EFI headers are not allowed -* in some of the Supervisor areas, such as Monitor, so it has been "ported" here -* for use in diagnostic event timestamps... */ -struct diag_efi_time { - u16 year; /* 1998 - 20XX */ - u8 month; /* 1 - 12 */ - u8 day; /* 1 - 31 */ - u8 hour; /* 0 - 23 */ - u8 minute; /* 0 - 59 */ - u8 second; /* 0 - 59 */ - u8 pad1; - u32 nanosecond; /* 0 - 999, 999, 999 */ - s16 timezone; /* -1440 to 1440 or 2047 */ - u8 daylight; - u8 pad2; -}; - -enum spar_component_types { - ULTRA_COMPONENT_GUEST = 0, - ULTRA_COMPONENT_MONITOR = 0x01, - ULTRA_COMPONENT_CCM = 0x02, /* Common Control module */ - /* RESERVED 0x03 - 0x7 */ - - /* Ultravisor Components */ - ULTRA_COMPONENT_BOOT = 0x08, - ULTRA_COMPONENT_IDLE = 0x09, - ULTRA_COMPONENT_CONTROL = 0x0A, - ULTRA_COMPONENT_LOGGER = 0x0B, - ULTRA_COMPONENT_ACPI = 0X0C, - /* RESERVED 0x0D - 0x0F */ - - /* sPAR Components */ - ULTRA_COMPONENT_COMMAND = 0x10, - ULTRA_COMPONENT_IODRIVER = 0x11, - ULTRA_COMPONENT_CONSOLE = 0x12, - ULTRA_COMPONENT_OPERATIONS = 0x13, - ULTRA_COMPONENT_MANAGEMENT = 0x14, - ULTRA_COMPONENT_DIAG = 0x15, - ULTRA_COMPONENT_HWDIAG = 0x16, - ULTRA_COMPONENT_PSERVICES = 0x17, - ULTRA_COMPONENT_PDIAG = 0x18 - /* RESERVED 0x18 - 0x1F */ -}; - -/* Structure: diag_channel_event Purpose: Contains attributes that make up an - * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of - * the diagnostic event to write to memory. Severity: Severity of the event - * (Error, Info, etc). ModuleName: Module/file name where event originated. - * LineNumber: Line number in module name where event originated. Timestamp: - * Date/time when event was received by ReportEvent, and written to DiagChannel. - * Reserved: Padding to align structure on a 64-byte cache line boundary. - * AdditionalInfo: Array of characters for additional event info (may be - * empty). */ -struct diag_channel_event { - u32 event_id; - u32 severity; - u8 module_name[MAX_MODULE_NAME_SIZE]; - u32 line_number; - struct diag_efi_time timestamp; /* Size = 16 bytes */ - u32 partition_number; /* Filled in by Diag Switch as pool blocks are - * filled */ - u16 vcpu_number; - u16 lcpu_number; - u8 component_type; /* ULTRA_COMPONENT_TYPES */ - u8 subsystem; - u16 reserved0; /* pad to u64 alignment */ - u32 block_no; /* filled in by DiagSwitch as pool blocks are - * filled */ - u32 block_no_high; - u32 event_no; /* filled in by DiagSwitch as pool blocks are - * filled */ - u32 event_no_high; - - /* The block_no and event_no fields are set only by DiagSwitch - * and referenced only by WinDiagDisplay formatting tool as - * additional diagnostic information. Other tools including - * WinDiagDisplay currently ignore these 'Reserved' bytes. */ - u8 reserved[8]; - u8 additional_info[MAX_ADDITIONAL_INFO_SIZE]; - - /* NOTE: Changes to diag_channel_event generally need to be reflected in - * existing copies * - * - for AppOS at - * GuestLinux/visordiag_early/supervisor_diagchannel.h * - * - for WinDiagDisplay at - * EFI/Ultra/Tools/WinDiagDisplay/WinDiagDisplay/diagstruct.h */ -}; - -/* Levels of severity for diagnostic events, in order from lowest severity to -* highest (i.e. fatal errors are the most severe, and should always be logged, -* but info events rarely need to be logged except during debugging). The values -* DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid severity -* values. They exist merely to dilineate the list, so that future additions -* won't require changes to the driver (i.e. when checking for out-of-range -* severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE and -* DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events but -* they are valid for controlling the amount of event data. This enum is also -* defined in DotNet\sParFramework\ControlFramework\ControlFramework.cs. If a -* change is made to this enum, they should also be reflected in that file. */ -enum diag_severity { - DIAG_SEVERITY_ENUM_BEGIN = 0, - DIAG_SEVERITY_OVERRIDE = DIAG_SEVERITY_ENUM_BEGIN, - DIAG_SEVERITY_VERBOSE = DIAG_SEVERITY_OVERRIDE, /* 0 */ - DIAG_SEVERITY_INFO = DIAG_SEVERITY_VERBOSE + 1, /* 1 */ - DIAG_SEVERITY_WARNING = DIAG_SEVERITY_INFO + 1, /* 2 */ - DIAG_SEVERITY_ERR = DIAG_SEVERITY_WARNING + 1, /* 3 */ - DIAG_SEVERITY_PRINT = DIAG_SEVERITY_ERR + 1, /* 4 */ - DIAG_SEVERITY_SHUTOFF = DIAG_SEVERITY_PRINT + 1, /* 5 */ - DIAG_SEVERITY_ENUM_END = DIAG_SEVERITY_SHUTOFF, /* 5 */ - DIAG_SEVERITY_NONFATAL_ERR = DIAG_SEVERITY_ERR, - DIAG_SEVERITY_FATAL_ERR = DIAG_SEVERITY_PRINT -}; - -/* Event Cause enums -* -* Levels of cause for diagnostic events, in order from least to greatest cause -* Internal errors are most urgent since ideally they should never exist -* Invalid requests are preventable by avoiding invalid inputs -* Operations errors depend on environmental factors which may impact which -* requests are possible -* Manifest provides intermediate value to capture firmware and configuration -* version information -* Trace provides suplimental debug information in release firmware -* Unknown Log captures unclasified LogEvent calls. -* Debug is the least urgent since it provides suplimental debug information only -* in debug firmware -* Unknown Debug captures unclassified DebugEvent calls. -* This enum is also defined in -* DotNet\sParFramework\ControlFramework\ControlFramework.cs. -* If a change is made to this enum, they should also be reflected in that -* file. */ - -/* A cause value "DIAG_CAUSE_FILE_XFER" together with a severity value of -* "DIAG_SEVERITY_PRINT" (=4), is used for transferring text or binary file to -* the Diag partition. This cause-severity combination will be used by Logger -* DiagSwitch to segregate events into block types. The files are transferred in -* 256 byte chunks maximum, in the AdditionalInfo field of the diag_channel_event -* structure. In the file transfer mode, some event fields will have different -* meaning: EventId specifies the file offset, severity specifies the block type, -* ModuleName specifies the filename, LineNumber specifies the number of valid -* data bytes in an event and AdditionalInfo contains up to 256 bytes of data. */ - -/* The Diag DiagWriter appends event blocks to events.raw as today, and for data - * blocks uses diag_channel_event - * PartitionNumber to extract and append 'AdditionalInfo' to filename (specified - * by ModuleName). */ - -/* The Dell PDiag uses this new mechanism to stash DSET .zip onto the - * 'diagnostic' virtual disk. */ -enum diag_cause { - DIAG_CAUSE_UNKNOWN = 0, - DIAG_CAUSE_UNKNOWN_DEBUG = DIAG_CAUSE_UNKNOWN + 1, /* 1 */ - DIAG_CAUSE_DEBUG = DIAG_CAUSE_UNKNOWN_DEBUG + 1, /* 2 */ - DIAG_CAUSE_UNKNOWN_LOG = DIAG_CAUSE_DEBUG + 1, /* 3 */ - DIAG_CAUSE_TRACE = DIAG_CAUSE_UNKNOWN_LOG + 1, /* 4 */ - DIAG_CAUSE_MANIFEST = DIAG_CAUSE_TRACE + 1, /* 5 */ - DIAG_CAUSE_OPERATIONS_ERROR = DIAG_CAUSE_MANIFEST + 1, /* 6 */ - DIAG_CAUSE_INVALID_REQUEST = DIAG_CAUSE_OPERATIONS_ERROR + 1, /* 7 */ - DIAG_CAUSE_INTERNAL_ERROR = DIAG_CAUSE_INVALID_REQUEST + 1, /* 8 */ - DIAG_CAUSE_FILE_XFER = DIAG_CAUSE_INTERNAL_ERROR + 1, /* 9 */ - DIAG_CAUSE_ENUM_END = DIAG_CAUSE_FILE_XFER /* 9 */ -}; - -/* Event Cause category defined into the byte 2 of Severity */ -#define CAUSE_DEBUG (DIAG_CAUSE_DEBUG << CAUSE_SHIFT_AMT) -#define CAUSE_TRACE (DIAG_CAUSE_TRACE << CAUSE_SHIFT_AMT) -#define CAUSE_MANIFEST (DIAG_CAUSE_MANIFEST << CAUSE_SHIFT_AMT) -#define CAUSE_OPERATIONS_ERROR (DIAG_CAUSE_OPERATIONS_ERROR << CAUSE_SHIFT_AMT) -#define CAUSE_INVALID_REQUEST (DIAG_CAUSE_INVALID_REQUEST << CAUSE_SHIFT_AMT) -#define CAUSE_INTERNAL_ERROR (DIAG_CAUSE_INTERNAL_ERROR << CAUSE_SHIFT_AMT) -#define CAUSE_FILE_XFER (DIAG_CAUSE_FILE_XFER << CAUSE_SHIFT_AMT) -#define CAUSE_ENUM_END CAUSE_FILE_XFER - -/* Combine Cause and Severity categories into one */ -#define CAUSE_DEBUG_SEVERITY_VERBOSE \ - (CAUSE_DEBUG | DIAG_SEVERITY_VERBOSE) -#define CAUSE_TRACE_SEVERITY_VERBOSE \ - (CAUSE_TRACE | DIAG_SEVERITY_VERBOSE) -#define CAUSE_MANIFEST_SEVERITY_VERBOSE\ - (CAUSE_MANIFEST | DIAG_SEVERITY_VERBOSE) -#define CAUSE_OPERATIONS_SEVERITY_VERBOSE \ - (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_VERBOSE) -#define CAUSE_INVALID_SEVERITY_VERBOSE \ - (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_VERBOSE) -#define CAUSE_INTERNAL_SEVERITY_VERBOSE \ - (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_VERBOSE) - -#define CAUSE_DEBUG_SEVERITY_INFO \ - (CAUSE_DEBUG | DIAG_SEVERITY_INFO) -#define CAUSE_TRACE_SEVERITY_INFO \ - (CAUSE_TRACE | DIAG_SEVERITY_INFO) -#define CAUSE_MANIFEST_SEVERITY_INFO \ - (CAUSE_MANIFEST | DIAG_SEVERITY_INFO) -#define CAUSE_OPERATIONS_SEVERITY_INFO \ - (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_INFO) -#define CAUSE_INVALID_SEVERITY_INFO \ - (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_INFO) -#define CAUSE_INTERNAL_SEVERITY_INFO \ - (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_INFO) - -#define CAUSE_DEBUG_SEVERITY_WARN \ - (CAUSE_DEBUG | DIAG_SEVERITY_WARNING) -#define CAUSE_TRACE_SEVERITY_WARN \ - (CAUSE_TRACE | DIAG_SEVERITY_WARNING) -#define CAUSE_MANIFEST_SEVERITY_WARN \ - (CAUSE_MANIFEST | DIAG_SEVERITY_WARNING) -#define CAUSE_OPERATIONS_SEVERITY_WARN \ - (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_WARNING) -#define CAUSE_INVALID_SEVERITY_WARN \ - (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_WARNING) -#define CAUSE_INTERNAL_SEVERITY_WARN \ - (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_WARNING) - -#define CAUSE_DEBUG_SEVERITY_ERR \ - (CAUSE_DEBUG | DIAG_SEVERITY_ERR) -#define CAUSE_TRACE_SEVERITY_ERR \ - (CAUSE_TRACE | DIAG_SEVERITY_ERR) -#define CAUSE_MANIFEST_SEVERITY_ERR \ - (CAUSE_MANIFEST | DIAG_SEVERITY_ERR) -#define CAUSE_OPERATIONS_SEVERITY_ERR \ - (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_ERR) -#define CAUSE_INVALID_SEVERITY_ERR \ - (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_ERR) -#define CAUSE_INTERNAL_SEVERITY_ERR \ - (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_ERR) - -#define CAUSE_DEBUG_SEVERITY_PRINT \ - (CAUSE_DEBUG | DIAG_SEVERITY_PRINT) -#define CAUSE_TRACE_SEVERITY_PRINT \ - (CAUSE_TRACE | DIAG_SEVERITY_PRINT) -#define CAUSE_MANIFEST_SEVERITY_PRINT \ - (CAUSE_MANIFEST | DIAG_SEVERITY_PRINT) -#define CAUSE_OPERATIONS_SEVERITY_PRINT \ - (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_PRINT) -#define CAUSE_INVALID_SEVERITY_PRINT \ - (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_PRINT) -#define CAUSE_INTERNAL_SEVERITY_PRINT \ - (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_PRINT) -#define CAUSE_FILE_XFER_SEVERITY_PRINT \ - (CAUSE_FILE_XFER | DIAG_SEVERITY_PRINT) - -/* Structure: diag_channel_protocol_header - * - * Purpose: Contains attributes that make up the header specific to the - * DIAG_CHANNEL area. - * - * Attributes: - * - * DiagLock: Diag Channel spinlock. - * - *IsChannelInitialized: 1 iff SignalInit was called for this channel; otherwise - * 0, and assume the channel is not ready for use yet. - * - * Reserved: Padding to align the fields in this structure. - * - *SubsystemSeverityFilter: Level of severity on a subsystem basis that controls - * whether events are logged. Any event's severity for a - * particular subsystem below this level will be discarded. - */ -struct diag_channel_protocol_header { - u32 diag_lock; - u8 channel_initialized; - u8 reserved[3]; - u8 subsystem_severity_filter[64]; -}; - -/* The Diagram for the Diagnostic Channel: */ -/* ----------------------- */ -/* | Channel Header | Defined by ULTRA_CHANNEL_PROTOCOL */ -/* ----------------------- */ -/* | Signal Queue Header | Defined by SIGNAL_QUEUE_HEADER */ -/* ----------------------- */ -/* | DiagChannel Header | Defined by diag_channel_protocol_header */ -/* ----------------------- */ -/* | Channel Event Info | Defined by diag_channel_event*MAX_EVENTS */ -/* ----------------------- */ -/* | Reserved | Reserved (pad out to 4MB) */ -/* ----------------------- */ - -/* Offsets/sizes for diagnostic channel attributes... */ -#define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(struct channel_header)) -#define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(struct signal_queue_header)) -#define DIAG_CH_PROTOCOL_HEADER_OFFSET \ - (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE) -#define DIAG_CH_PROTOCOL_HEADER_SIZE \ - (sizeof(struct diag_channel_protocol_header)) -#define DIAG_CH_EVENT_OFFSET \ - (DIAG_CH_PROTOCOL_HEADER_OFFSET + DIAG_CH_PROTOCOL_HEADER_SIZE) -#define DIAG_CH_SIZE (4096 * 1024) - -/* For Control and Idle Partitions with larger (8 MB) diagnostic(root) - * channels */ -#define DIAG_CH_LRG_SIZE (2 * DIAG_CH_SIZE) /* 8 MB */ - -/* - * Structure: spar_diag_channel_protocol - * - * Purpose: Contains attributes that make up the DIAG_CHANNEL memory. - * - * Attributes: - * - * CommonChannelHeader: Header info common to all channels. - * - * QueueHeader: Queue header common to all channels - used to determine where to - * store event. - * - * DiagChannelHeader: Diagnostic channel header info (see - * diag_channel_protocol_header comments). - * - * Events: Area where diagnostic events (up to MAX_EVENTS) are written. - * - *Reserved: Reserved area to allow for correct channel size padding. -*/ -struct spar_diag_channel_protocol { - struct channel_header common_channel_header; - struct signal_queue_header queue_header; - struct diag_channel_protocol_header diag_channel_header; - struct diag_channel_event events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / - sizeof(struct diag_channel_event)]; -}; - -#endif diff --git a/drivers/staging/unisys/common-spar/include/diagnostics/appos_subsystems.h b/drivers/staging/unisys/common-spar/include/diagnostics/appos_subsystems.h deleted file mode 100644 index 18cc9ed2748b..000000000000 --- a/drivers/staging/unisys/common-spar/include/diagnostics/appos_subsystems.h +++ /dev/null @@ -1,310 +0,0 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* Please note that this file is to be used ONLY for defining diagnostic - * subsystem values for the appos (sPAR Linux service partitions) component. - */ -#ifndef __APPOS_SUBSYSTEMS_H__ -#define __APPOS_SUBSYSTEMS_H__ - -#ifdef __KERNEL__ -#include <linux/kernel.h> -#include <linux/string.h> -#else -#include <stdio.h> -#include <string.h> -#endif - -static inline char * -subsys_unknown_to_s(int subsys, char *s, int n) -{ - snprintf(s, n, "SUBSYS-%-2.2d", subsys); - s[n - 1] = '\0'; - return s; -} - -#define SUBSYS_TO_MASK(subsys) (1ULL << (subsys)) - -/* The first SUBSYS_APPOS_MAX subsystems are the same for each AppOS type - * (IOVM, SMS, etc.) The rest have unique values for each AppOS type. - */ -#define SUBSYS_APPOS_MAX 16 - -#define SUBSYS_APPOS_DEFAULT 1 /* or "other" */ -#define SUBSYS_APPOS_CHIPSET 2 /* controlvm and other */ - /* low-level sPAR activity */ -#define SUBSYS_APPOS_BUS 3 /* sPAR bus */ -/* DAK #define SUBSYS_APPOS_DIAG 4 // diagnostics and dump */ -#define SUBSYS_APPOS_CHANNELACCESS 5 /* generic channel access */ -#define SUBSYS_APPOS_NICCLIENT 6 /* virtual NIC client */ -#define SUBSYS_APPOS_HBACLIENT 7 /* virtual HBA client */ -#define SUBSYS_APPOS_CONSOLESERIAL 8 /* sPAR virtual serial console */ -#define SUBSYS_APPOS_UISLIB 9 /* */ -#define SUBSYS_APPOS_VRTCUPDD 10 /* */ -#define SUBSYS_APPOS_WATCHDOG 11 /* watchdog timer and healthcheck */ -#define SUBSYS_APPOS_13 13 /* available */ -#define SUBSYS_APPOS_14 14 /* available */ -#define SUBSYS_APPOS_15 15 /* available */ -#define SUBSYS_APPOS_16 16 /* available */ -static inline char * -subsys_generic_to_s(int subsys, char *s, int n) -{ - switch (subsys) { - case SUBSYS_APPOS_DEFAULT: - strncpy(s, "APPOS_DEFAULT", n); - break; - case SUBSYS_APPOS_CHIPSET: - strncpy(s, "APPOS_CHIPSET", n); - break; - case SUBSYS_APPOS_BUS: - strncpy(s, "APPOS_BUS", n); - break; - case SUBSYS_APPOS_CHANNELACCESS: - strncpy(s, "APPOS_CHANNELACCESS", n); - break; - case SUBSYS_APPOS_NICCLIENT: - strncpy(s, "APPOS_NICCLIENT", n); - break; - case SUBSYS_APPOS_HBACLIENT: - strncpy(s, "APPOS_HBACLIENT", n); - break; - case SUBSYS_APPOS_CONSOLESERIAL: - strncpy(s, "APPOS_CONSOLESERIAL", n); - break; - case SUBSYS_APPOS_UISLIB: - strncpy(s, "APPOS_UISLIB", n); - break; - case SUBSYS_APPOS_VRTCUPDD: - strncpy(s, "APPOS_VRTCUPDD", n); - break; - case SUBSYS_APPOS_WATCHDOG: - strncpy(s, "APPOS_WATCHDOG", n); - break; - case SUBSYS_APPOS_13: - strncpy(s, "APPOS_13", n); - break; - case SUBSYS_APPOS_14: - strncpy(s, "APPOS_14", n); - break; - case SUBSYS_APPOS_15: - strncpy(s, "APPOS_15", n); - break; - case SUBSYS_APPOS_16: - strncpy(s, "APPOS_16", n); - break; - default: - subsys_unknown_to_s(subsys, s, n); - break; - } - s[n - 1] = '\0'; - return s; -} - -/* CONSOLE */ - -#define SUBSYS_CONSOLE_VIDEO (SUBSYS_APPOS_MAX + 1) /* 17 */ -#define SUBSYS_CONSOLE_KBDMOU (SUBSYS_APPOS_MAX + 2) /* 18 */ -#define SUBSYS_CONSOLE_04 (SUBSYS_APPOS_MAX + 4) -#define SUBSYS_CONSOLE_05 (SUBSYS_APPOS_MAX + 5) -#define SUBSYS_CONSOLE_06 (SUBSYS_APPOS_MAX + 6) -#define SUBSYS_CONSOLE_07 (SUBSYS_APPOS_MAX + 7) -#define SUBSYS_CONSOLE_08 (SUBSYS_APPOS_MAX + 8) -#define SUBSYS_CONSOLE_09 (SUBSYS_APPOS_MAX + 9) -#define SUBSYS_CONSOLE_10 (SUBSYS_APPOS_MAX + 10) -#define SUBSYS_CONSOLE_11 (SUBSYS_APPOS_MAX + 11) -#define SUBSYS_CONSOLE_12 (SUBSYS_APPOS_MAX + 12) -#define SUBSYS_CONSOLE_13 (SUBSYS_APPOS_MAX + 13) -#define SUBSYS_CONSOLE_14 (SUBSYS_APPOS_MAX + 14) -#define SUBSYS_CONSOLE_15 (SUBSYS_APPOS_MAX + 15) -#define SUBSYS_CONSOLE_16 (SUBSYS_APPOS_MAX + 16) -#define SUBSYS_CONSOLE_17 (SUBSYS_APPOS_MAX + 17) -#define SUBSYS_CONSOLE_18 (SUBSYS_APPOS_MAX + 18) -#define SUBSYS_CONSOLE_19 (SUBSYS_APPOS_MAX + 19) -#define SUBSYS_CONSOLE_20 (SUBSYS_APPOS_MAX + 20) -#define SUBSYS_CONSOLE_21 (SUBSYS_APPOS_MAX + 21) -#define SUBSYS_CONSOLE_22 (SUBSYS_APPOS_MAX + 22) -#define SUBSYS_CONSOLE_23 (SUBSYS_APPOS_MAX + 23) -#define SUBSYS_CONSOLE_24 (SUBSYS_APPOS_MAX + 24) -#define SUBSYS_CONSOLE_25 (SUBSYS_APPOS_MAX + 25) -#define SUBSYS_CONSOLE_26 (SUBSYS_APPOS_MAX + 26) -#define SUBSYS_CONSOLE_27 (SUBSYS_APPOS_MAX + 27) -#define SUBSYS_CONSOLE_28 (SUBSYS_APPOS_MAX + 28) -#define SUBSYS_CONSOLE_29 (SUBSYS_APPOS_MAX + 29) -#define SUBSYS_CONSOLE_30 (SUBSYS_APPOS_MAX + 30) -#define SUBSYS_CONSOLE_31 (SUBSYS_APPOS_MAX + 31) -#define SUBSYS_CONSOLE_32 (SUBSYS_APPOS_MAX + 32) -#define SUBSYS_CONSOLE_33 (SUBSYS_APPOS_MAX + 33) -#define SUBSYS_CONSOLE_34 (SUBSYS_APPOS_MAX + 34) -#define SUBSYS_CONSOLE_35 (SUBSYS_APPOS_MAX + 35) -#define SUBSYS_CONSOLE_36 (SUBSYS_APPOS_MAX + 36) -#define SUBSYS_CONSOLE_37 (SUBSYS_APPOS_MAX + 37) -#define SUBSYS_CONSOLE_38 (SUBSYS_APPOS_MAX + 38) -#define SUBSYS_CONSOLE_39 (SUBSYS_APPOS_MAX + 39) -#define SUBSYS_CONSOLE_40 (SUBSYS_APPOS_MAX + 40) -#define SUBSYS_CONSOLE_41 (SUBSYS_APPOS_MAX + 41) -#define SUBSYS_CONSOLE_42 (SUBSYS_APPOS_MAX + 42) -#define SUBSYS_CONSOLE_43 (SUBSYS_APPOS_MAX + 43) -#define SUBSYS_CONSOLE_44 (SUBSYS_APPOS_MAX + 44) -#define SUBSYS_CONSOLE_45 (SUBSYS_APPOS_MAX + 45) -#define SUBSYS_CONSOLE_46 (SUBSYS_APPOS_MAX + 46) - -static inline char * -subsys_console_to_s(int subsys, char *s, int n) -{ - switch (subsys) { - case SUBSYS_CONSOLE_VIDEO: - strncpy(s, "CONSOLE_VIDEO", n); - break; - case SUBSYS_CONSOLE_KBDMOU: - strncpy(s, "CONSOLE_KBDMOU", n); - break; - case SUBSYS_CONSOLE_04: - strncpy(s, "CONSOLE_04", n); - break; - case SUBSYS_CONSOLE_05: - strncpy(s, "CONSOLE_05", n); - break; - case SUBSYS_CONSOLE_06: - strncpy(s, "CONSOLE_06", n); - break; - case SUBSYS_CONSOLE_07: - strncpy(s, "CONSOLE_07", n); - break; - case SUBSYS_CONSOLE_08: - strncpy(s, "CONSOLE_08", n); - break; - case SUBSYS_CONSOLE_09: - strncpy(s, "CONSOLE_09", n); - break; - case SUBSYS_CONSOLE_10: - strncpy(s, "CONSOLE_10", n); - break; - case SUBSYS_CONSOLE_11: - strncpy(s, "CONSOLE_11", n); - break; - case SUBSYS_CONSOLE_12: - strncpy(s, "CONSOLE_12", n); - break; - case SUBSYS_CONSOLE_13: - strncpy(s, "CONSOLE_13", n); - break; - case SUBSYS_CONSOLE_14: - strncpy(s, "CONSOLE_14", n); - break; - case SUBSYS_CONSOLE_15: - strncpy(s, "CONSOLE_15", n); - break; - case SUBSYS_CONSOLE_16: - strncpy(s, "CONSOLE_16", n); - break; - case SUBSYS_CONSOLE_17: - strncpy(s, "CONSOLE_17", n); - break; - case SUBSYS_CONSOLE_18: - strncpy(s, "CONSOLE_18", n); - break; - case SUBSYS_CONSOLE_19: - strncpy(s, "CONSOLE_19", n); - break; - case SUBSYS_CONSOLE_20: - strncpy(s, "CONSOLE_20", n); - break; - case SUBSYS_CONSOLE_21: - strncpy(s, "CONSOLE_21", n); - break; - case SUBSYS_CONSOLE_22: - strncpy(s, "CONSOLE_22", n); - break; - case SUBSYS_CONSOLE_23: - strncpy(s, "CONSOLE_23", n); - break; - case SUBSYS_CONSOLE_24: - strncpy(s, "CONSOLE_24", n); - break; - case SUBSYS_CONSOLE_25: - strncpy(s, "CONSOLE_25", n); - break; - case SUBSYS_CONSOLE_26: - strncpy(s, "CONSOLE_26", n); - break; - case SUBSYS_CONSOLE_27: - strncpy(s, "CONSOLE_27", n); - break; - case SUBSYS_CONSOLE_28: - strncpy(s, "CONSOLE_28", n); - break; - case SUBSYS_CONSOLE_29: - strncpy(s, "CONSOLE_29", n); - break; - case SUBSYS_CONSOLE_30: - strncpy(s, "CONSOLE_30", n); - break; - case SUBSYS_CONSOLE_31: - strncpy(s, "CONSOLE_31", n); - break; - case SUBSYS_CONSOLE_32: - strncpy(s, "CONSOLE_32", n); - break; - case SUBSYS_CONSOLE_33: - strncpy(s, "CONSOLE_33", n); - break; - case SUBSYS_CONSOLE_34: - strncpy(s, "CONSOLE_34", n); - break; - case SUBSYS_CONSOLE_35: - strncpy(s, "CONSOLE_35", n); - break; - case SUBSYS_CONSOLE_36: - strncpy(s, "CONSOLE_36", n); - break; - case SUBSYS_CONSOLE_37: - strncpy(s, "CONSOLE_37", n); - break; - case SUBSYS_CONSOLE_38: - strncpy(s, "CONSOLE_38", n); - break; - case SUBSYS_CONSOLE_39: - strncpy(s, "CONSOLE_39", n); - break; - case SUBSYS_CONSOLE_40: - strncpy(s, "CONSOLE_40", n); - break; - case SUBSYS_CONSOLE_41: - strncpy(s, "CONSOLE_41", n); - break; - case SUBSYS_CONSOLE_42: - strncpy(s, "CONSOLE_42", n); - break; - case SUBSYS_CONSOLE_43: - strncpy(s, "CONSOLE_43", n); - break; - case SUBSYS_CONSOLE_44: - strncpy(s, "CONSOLE_44", n); - break; - case SUBSYS_CONSOLE_45: - strncpy(s, "CONSOLE_45", n); - break; - case SUBSYS_CONSOLE_46: - strncpy(s, "CONSOLE_46", n); - break; - default: - subsys_unknown_to_s(subsys, s, n); - break; - } - s[n - 1] = '\0'; - return s; -} - -#endif diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/include/channel.h index 6fb6e5b3ddaf..da0b5387f884 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -114,41 +114,6 @@ ULTRA_CHANNELCLI_STRING(u32 v) (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ ? (1) : (0)) -#define SPAR_CHANNEL_CLIENT_CHK_TRANSITION(old, new, id, log, \ - file, line) \ - do { \ - if (!ULTRA_VALID_CHANNELCLI_TRANSITION(old, new)) \ - pr_info("%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - id, "CliState<x>", \ - ULTRA_CHANNELCLI_STRING(old), \ - old, \ - ULTRA_CHANNELCLI_STRING(new), \ - new, \ - pathname_last_n_nodes((u8 *)file, 4), \ - line); \ - } while (0) - -#define SPAR_CHANNEL_CLIENT_TRANSITION(ch, id, newstate, log) \ - do { \ - SPAR_CHANNEL_CLIENT_CHK_TRANSITION( \ - readl(&(((struct channel_header __iomem *)\ - (ch))->cli_state_os)), \ - newstate, id, log, __FILE__, __LINE__); \ - pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - id, "CliStateOS", \ - ULTRA_CHANNELCLI_STRING( \ - readl(&((struct channel_header __iomem *)\ - (ch))->cli_state_os)), \ - readl(&((struct channel_header __iomem *)\ - (ch))->cli_state_os), \ - ULTRA_CHANNELCLI_STRING(newstate), \ - newstate, \ - pathname_last_n_nodes(__FILE__, 4), __LINE__); \ - writel(newstate, &((struct channel_header __iomem *)\ - (ch))->cli_state_os); \ - mb(); /* required for channel synch */ \ - } while (0) - /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */ /* throttling invalid boot channel statetransition error due to client * disabled */ diff --git a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h b/drivers/staging/unisys/include/channel_guid.h index 706363fc3e9a..706363fc3e9a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h +++ b/drivers/staging/unisys/include/channel_guid.h diff --git a/drivers/staging/unisys/include/diagchannel.h b/drivers/staging/unisys/include/diagchannel.h new file mode 100644 index 000000000000..d2d35685d69f --- /dev/null +++ b/drivers/staging/unisys/include/diagchannel.h @@ -0,0 +1,43 @@ +/* Copyright (C) 2010 - 2013 UNISYS CORPORATION + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + +#ifndef _DIAG_CHANNEL_H_ +#define _DIAG_CHANNEL_H_ + +#define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ +#define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional + * info accompanying event... + */ + +/* Levels of severity for diagnostic events, in order from lowest severity to + * highest (i.e. fatal errors are the most severe, and should always be logged, + * but info events rarely need to be logged except during debugging). The + * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid + * severity values. They exist merely to dilineate the list, so that future + * additions won't require changes to the driver (i.e. when checking for + * out-of-range severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE + * and DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events + * but they are valid for controlling the amount of event data. Changes made + * to the enum, need to be reflected in s-Par. + */ +enum diag_severity { + DIAG_SEVERITY_VERBOSE = 0, + DIAG_SEVERITY_INFO = 1, + DIAG_SEVERITY_WARNING = 2, + DIAG_SEVERITY_ERR = 3, + DIAG_SEVERITY_PRINT = 4, +}; + +#endif diff --git a/drivers/staging/unisys/include/guestlinuxdebug.h b/drivers/staging/unisys/include/guestlinuxdebug.h index 98150aa5bd01..82ee565395ba 100644 --- a/drivers/staging/unisys/include/guestlinuxdebug.h +++ b/drivers/staging/unisys/include/guestlinuxdebug.h @@ -22,7 +22,6 @@ * ISSUE_IO_VMCALL_POSTCODE_SEVERITY */ /******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/ -#include "vmcallinterface.h" enum driver_pc { /* POSTCODE driver identifier tuples */ /* visorchipset driver files */ VISOR_CHIPSET_PC = 0xA0, diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/include/iochannel.h index cbb58757e76a..cbb58757e76a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h diff --git a/drivers/staging/unisys/include/sparstop.h b/drivers/staging/unisys/include/sparstop.h deleted file mode 100644 index 6150d2d58d69..000000000000 --- a/drivers/staging/unisys/include/sparstop.h +++ /dev/null @@ -1,29 +0,0 @@ -/* sparstop.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __SPARSTOP_H__ -#define __SPARSTOP_H__ - -#include "version.h" -#include <linux/ctype.h> - -typedef void (*SPARSTOP_COMPLETE_FUNC) (void *context, int status); - -int sp_stop(void *context, SPARSTOP_COMPLETE_FUNC get_complete_func); -void test_remove_stop_device(void); - -#endif diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h deleted file mode 100644 index 08ba16ea840e..000000000000 --- a/drivers/staging/unisys/include/uisqueue.h +++ /dev/null @@ -1,396 +0,0 @@ -/* uisqueue.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* - * Unisys IO Virtualization header NOTE: This file contains only Linux - * specific structs. All OS-independent structs are in iochannel.h.xx - */ - -#ifndef __UISQUEUE_H__ -#define __UISQUEUE_H__ - -#include "linux/version.h" -#include "iochannel.h" -#include <linux/atomic.h> -#include <linux/semaphore.h> -#include <linux/uuid.h> - -#include "controlvmchannel.h" -#include "controlvmcompletionstatus.h" - -struct uisqueue_info { - struct channel_header __iomem *chan; - /* channel containing queues in which scsi commands & - * responses are queued - */ - u64 packets_sent; - u64 packets_received; - u64 interrupts_sent; - u64 interrupts_received; - u64 max_not_empty_cnt; - u64 total_wakeup_cnt; - u64 non_empty_wakeup_cnt; - - struct { - struct signal_queue_header reserved1; /* */ - struct signal_queue_header reserved2; /* */ - } safe_uis_queue; - unsigned int (*send_int_if_needed)(struct uisqueue_info *info, - unsigned int whichcqueue, - unsigned char issue_irq_if_empty, - u64 irq_handle, - unsigned char io_termination); -}; - -/* uisqueue_put_cmdrsp_with_lock_client queues a commmand or response - * to the specified queue, at the tail if the queue is full but - * oktowait == 0, then it return 0 indicating failure. otherwise it - * wait for the queue to become non-full. If command is queued, return - * 1 for success. - */ -#define DONT_ISSUE_INTERRUPT 0 -#define ISSUE_INTERRUPT 1 - -#define DONT_WAIT 0 -#define OK_TO_WAIT 1 -#define UISLIB_LOCK_PREFIX \ - ".section .smp_locks,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661f\n" /* address */ \ - ".previous\n" \ - "661:\n\tlock; " - -unsigned long long uisqueue_interlocked_or(unsigned long long __iomem *tgt, - unsigned long long set); -unsigned long long uisqueue_interlocked_and(unsigned long long __iomem *tgt, - unsigned long long set); - -int uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo, - struct uiscmdrsp *cmdrsp, - unsigned int queue, - void *insertlock, - unsigned char issue_irq_if_empty, - u64 irq_handle, - char oktowait, - u8 *channel_id); - -/* uisqueue_get_cmdrsp gets the cmdrsp entry at the head of the queue - * and copies it to the area pointed by cmdrsp param. - * returns 0 if queue is empty, 1 otherwise - */ -int - -uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo, void *cmdrsp, - unsigned int queue); - -#define MAX_NAME_SIZE_UISQUEUE 64 - -struct extport_info { - u8 valid:1; - /* if 1, indicates this extport slot is occupied - * if 0, indicates that extport slot is unoccupied */ - - u32 num_devs_using; - /* When extport is added, this is set to 0. For exports - * located in NETWORK switches: - * Each time a VNIC, i.e., intport, is added to the switch this - * is used to assign a pref_pnic for the VNIC and when assigned - * to a VNIC this counter is incremented. When a VNIC is - * deleted, the extport corresponding to the VNIC's pref_pnic - * is located and its num_devs_using is decremented. For VNICs, - * num_devs_using is basically used to load-balance transmit - * traffic from VNICs. - */ - - struct switch_info *swtch; - struct pci_id pci_id; - char name[MAX_NAME_SIZE_UISQUEUE]; - union { - struct vhba_wwnn wwnn; - unsigned char macaddr[MAX_MACADDR_LEN]; - }; -}; - -struct device_info { - void __iomem *chanptr; - u64 channel_addr; - u64 channel_bytes; - uuid_le channel_uuid; - uuid_le instance_uuid; - struct irq_info intr; - struct switch_info *swtch; - char devid[30]; /* "vbus<busno>:dev<devno>" */ - u16 polling; - struct semaphore interrupt_callback_lock; - u32 bus_no; - u32 dev_no; - int (*interrupt)(void *); - void *interrupt_context; - void *private_data; - struct list_head list_polling_device_channels; - unsigned long long moved_to_tail_cnt; - unsigned long long first_busy_cnt; - unsigned long long last_on_list_cnt; -}; - -enum switch_type { - RECOVERY_LAN = 1, - IB_LAN = 2 -}; - -struct bus_info { - u32 bus_no, device_count; - struct device_info **device; - u64 guest_handle, recv_bus_irq_handle; - uuid_le bus_inst_uuid; - struct ultra_vbus_channel_protocol __iomem *bus_channel; - int bus_channel_bytes; - struct proc_dir_entry *proc_dir; /* proc/uislib/vbus/<x> */ - struct proc_dir_entry *proc_info; /* proc/uislib/vbus/<x>/info */ - char name[25]; - char partition_name[99]; - struct bus_info *next; - u8 local_vnic; /* 1 if local vnic created internally - * by IOVM; 0 otherwise... */ -}; - -struct sn_list_entry { - struct uisscsi_dest pdest; /* scsi bus, target, lun for - * phys disk */ - u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical - * disk.. The length is always - * MAX_SERIAL_NUM, padded with - * spaces */ - struct sn_list_entry *next; -}; - -/* - * IO messages sent to UisnicControlChanFunc & UissdControlChanFunc by - * code that processes the ControlVm channel messages. - */ - -enum iopart_msg_type { - IOPART_ADD_VNIC, - IOPART_DEL_VNIC, - IOPART_DEL_ALL_VNICS, - IOPART_ADD_VHBA, - IOPART_ADD_VDISK, - IOPART_DEL_VHBA, - IOPART_DEL_VDISK, - IOPART_DEL_ALL_VDISKS_FOR_VHBA, - IOPART_DEL_ALL_VHBAS, - IOPART_ATTACH_PHBA, - IOPART_DETACH_PHBA, /* 10 */ - IOPART_ATTACH_PNIC, - IOPART_DETACH_PNIC, - IOPART_DETACH_VHBA, - IOPART_DETACH_VNIC, - IOPART_PAUSE_VDISK, - IOPART_RESUME_VDISK, - IOPART_ADD_DEVICE, /* add generic device */ - IOPART_DEL_DEVICE, /* del generic device */ -}; - -struct add_virt_iopart { - void *chanptr; /* pointer to data channel */ - u64 guest_handle; /* used to convert guest physical - * address to real physical address - * for DMA, for ex. */ - u64 recv_bus_irq_handle; /* used to register to receive - * bus level interrupts. */ - struct irq_info intr; /* contains recv & send - * interrupt info */ - /* recvInterruptHandle is used to register to receive - * interrupts on the data channel. Used by GuestLinux/Windows - * IO drivers to connect to interrupt. sendInterruptHandle is - * used by IOPart drivers as parameter to - * Issue_VMCALL_IO_QUEUE_TRANSITION to interrupt thread in - * guest linux/windows IO drivers when data channel queue for - * vhba/vnic goes from EMPTY to NON-EMPTY. */ - struct switch_info *swtch; /* pointer to the virtual - * switch to which the vnic is - * connected */ - - u8 use_g2g_copy; /* Used to determine if a virtual HBA - * needs to use G2G copy. */ - u8 filler[7]; - - u32 bus_no; - u32 dev_no; - char *params; - ulong params_bytes; - -}; - -struct add_vdisk_iopart { - void *chanptr; /* pointer to data channel */ - int implicit; - struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ - struct uisscsi_dest pdest; /* scsi bus, target, lun for phys disk */ - u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */ - u32 serlen; /* length of serial num */ -}; - -struct del_vdisk_iopart { - void *chanptr; /* pointer to data channel */ - struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ -}; - -struct del_virt_iopart { - void *chanptr; /* pointer to data channel */ -}; - -struct det_virt_iopart { /* detach internal port */ - void *chanptr; /* pointer to data channel */ - struct switch_info *swtch; -}; - -struct paures_vdisk_iopart { - void *chanptr; /* pointer to data channel */ - struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ -}; - -struct add_switch_iopart { /* add switch */ - struct switch_info *swtch; - char *params; - ulong params_bytes; -}; - -struct del_switch_iopart { /* destroy switch */ - struct switch_info *swtch; -}; - -struct io_msgs { - enum iopart_msg_type msgtype; - - /* additional params needed by some messages */ - union { - struct add_virt_iopart add_vhba; - struct add_virt_iopart add_vnic; - struct add_vdisk_iopart add_vdisk; - struct del_virt_iopart del_vhba; - struct del_virt_iopart del_vnic; - struct det_virt_iopart det_vhba; - struct det_virt_iopart det_vnic; - struct del_vdisk_iopart del_vdisk; - struct del_virt_iopart del_all_vdisks_for_vhba; - struct add_virt_iopart add_device; - struct del_virt_iopart del_device; - struct det_virt_iopart det_intport; - struct add_switch_iopart add_switch; - struct del_switch_iopart del_switch; - struct extport_info *ext_port; /* for attach or detach - * pnic/generic delete all - * vhbas/allvnics need no - * parameters */ - struct paures_vdisk_iopart paures_vdisk; - }; -}; - -/* -* Guest messages sent to VirtControlChanFunc by code that processes -* the ControlVm channel messages. -*/ - -enum guestpart_msg_type { - GUEST_ADD_VBUS, - GUEST_ADD_VHBA, - GUEST_ADD_VNIC, - GUEST_DEL_VBUS, - GUEST_DEL_VHBA, - GUEST_DEL_VNIC, - GUEST_DEL_ALL_VHBAS, - GUEST_DEL_ALL_VNICS, - GUEST_DEL_ALL_VBUSES, /* deletes all vhbas & vnics on all - * buses and deletes all buses */ - GUEST_PAUSE_VHBA, - GUEST_PAUSE_VNIC, - GUEST_RESUME_VHBA, - GUEST_RESUME_VNIC -}; - -struct add_vbus_guestpart { - void __iomem *chanptr; /* pointer to data channel for bus - - * NOT YET USED */ - u32 bus_no; /* bus number to be created/deleted */ - u32 dev_count; /* max num of devices on bus */ - uuid_le bus_uuid; /* indicates type of bus */ - uuid_le instance_uuid; /* instance guid for device */ -}; - -struct del_vbus_guestpart { - u32 bus_no; /* bus number to be deleted */ - /* once we start using the bus's channel, add can dump busNo - * into the channel header and then delete will need only one - * parameter, chanptr. */ -}; - -struct add_virt_guestpart { - void __iomem *chanptr; /* pointer to data channel */ - u32 bus_no; /* bus number for the operation */ - u32 device_no; /* number of device on the bus */ - uuid_le instance_uuid; /* instance guid for device */ - struct irq_info intr; /* recv/send interrupt info */ - /* recvInterruptHandle contains info needed in order to - * register to receive interrupts on the data channel. - * sendInterruptHandle contains handle which is provided to - * monitor VMCALL that will cause an interrupt to be generated - * for the other end. - */ -}; - -struct pause_virt_guestpart { - void __iomem *chanptr; /* pointer to data channel */ -}; - -struct resume_virt_guestpart { - void __iomem *chanptr; /* pointer to data channel */ -}; - -struct del_virt_guestpart { - void __iomem *chanptr; /* pointer to data channel */ -}; - -struct init_chipset_guestpart { - u32 bus_count; /* indicates the max number of busses */ - u32 switch_count; /* indicates the max number of switches */ -}; - -struct guest_msgs { - enum guestpart_msg_type msgtype; - - /* additional params needed by messages */ - union { - struct add_vbus_guestpart add_vbus; - struct add_virt_guestpart add_vhba; - struct add_virt_guestpart add_vnic; - struct pause_virt_guestpart pause_vhba; - struct pause_virt_guestpart pause_vnic; - struct resume_virt_guestpart resume_vhba; - struct resume_virt_guestpart resume_vnic; - struct del_vbus_guestpart del_vbus; - struct del_virt_guestpart del_vhba; - struct del_virt_guestpart del_vnic; - struct del_vbus_guestpart del_all_vhbas; - struct del_vbus_guestpart del_all_vnics; - /* del_all_vbuses needs no parameters */ - }; - struct init_chipset_guestpart init_chipset; - -}; - -#endif /* __UISQUEUE_H__ */ diff --git a/drivers/staging/unisys/include/uisthread.h b/drivers/staging/unisys/include/uisthread.h deleted file mode 100644 index 52c3eb4ded2c..000000000000 --- a/drivers/staging/unisys/include/uisthread.h +++ /dev/null @@ -1,42 +0,0 @@ -/* uisthread.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/*****************************************************************************/ -/* Unisys thread utilities header */ -/*****************************************************************************/ - -#ifndef __UISTHREAD_H__ -#define __UISTHREAD_H__ - -#include "linux/completion.h" - -struct uisthread_info { - struct task_struct *task; - int id; - struct completion has_stopped; -}; - -/* returns 0 for failure, 1 for success */ -int uisthread_start( - struct uisthread_info *thrinfo, - int (*threadfn)(void *), - void *thrcontext, - char *name); - -void uisthread_stop(struct uisthread_info *thrinfo); - -#endif /* __UISTHREAD_H__ */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h deleted file mode 100644 index 4514772323ac..000000000000 --- a/drivers/staging/unisys/include/uisutils.h +++ /dev/null @@ -1,294 +0,0 @@ -/* uisutils.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* - * Unisys Virtual HBA utilities header - */ - -#ifndef __UISUTILS__H__ -#define __UISUTILS__H__ -#include <linux/string.h> -#include <linux/io.h> -#include <linux/sched.h> -#include <linux/gfp.h> -#include <linux/uuid.h> -#include <linux/if_ether.h> - -#include "vmcallinterface.h" -#include "channel.h" -#include "uisthread.h" -#include "uisqueue.h" -#include "diagnostics/appos_subsystems.h" -#include "vbusdeviceinfo.h" -#include <linux/atomic.h> - -/* This is the MAGIC number stuffed by virthba in host->this_id. Used to - * identify virtual hbas. - */ -#define UIS_MAGIC_VHBA 707 - -/* global function pointers that act as callback functions into - * uisnicmod, uissdmod, and virtpcimod - */ -extern int (*uisnic_control_chan_func)(struct io_msgs *); -extern int (*uissd_control_chan_func)(struct io_msgs *); -extern int (*virt_control_chan_func)(struct guest_msgs *); - -/* Return values of above callback functions: */ -#define CCF_ERROR 0 /* completed and failed */ -#define CCF_OK 1 /* completed successfully */ -#define CCF_PENDING 2 /* operation still pending */ -extern atomic_t uisutils_registered_services; - -struct req_handler_info { - uuid_le switch_uuid; - int (*controlfunc)(struct io_msgs *); - unsigned long min_channel_bytes; - int (*server_channel_ok)(unsigned long channel_bytes); - int (*server_channel_init)(void *x, unsigned char *client_str, - u32 client_str_len, u64 bytes); - char switch_type_name[99]; - struct list_head list_link; /* links into ReqHandlerInfo_list */ -}; - -struct req_handler_info *req_handler_find(uuid_le switch_uuid); - -#define uislib_ioremap_cache(addr, size) \ - dbg_ioremap_cache(addr, size, __FILE__, __LINE__) - -static inline void __iomem * -dbg_ioremap_cache(u64 addr, unsigned long size, char *file, int line) -{ - void __iomem *new; - - new = ioremap_cache(addr, size); - return new; -} - -#define uislib_ioremap(addr, size) dbg_ioremap(addr, size, __FILE__, __LINE__) - -static inline void * -dbg_ioremap(u64 addr, unsigned long size, char *file, int line) -{ - void *new; - - new = ioremap(addr, size); - return new; -} - -#define uislib_iounmap(addr) dbg_iounmap(addr, __FILE__, __LINE__) - -static inline void -dbg_iounmap(void __iomem *addr, char *file, int line) -{ - iounmap(addr); -} - -#define PROC_READ_BUFFER_SIZE 131072 /* size of the buffer to allocate to - * hold all of /proc/XXX/info */ -int uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, - char *format, ...); - -int uisctrl_register_req_handler(int type, void *fptr, - struct ultra_vbus_deviceinfo *chipset_driver_info); - -unsigned char *util_map_virt(struct phys_info *sg); -void util_unmap_virt(struct phys_info *sg); -unsigned char *util_map_virt_atomic(struct phys_info *sg); -void util_unmap_virt_atomic(void *buf); -int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, - u64 channel_addr, ulong n_channel_bytes); -int uislib_client_inject_del_bus(u32 bus_no); - -int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, - u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le inst_uuid, - struct irq_info *intr); -int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, - u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le inst_uuid, - struct irq_info *intr); -int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); -int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no); -int uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no); -#ifdef STORAGE_CHANNEL -u64 uislib_storage_channel(int client_id); -#endif -int uislib_get_owned_pdest(struct uisscsi_dest *pdest); - -int uislib_send_event(enum controlvm_id id, - struct controlvm_message_packet *event); - -/* structure used by vhba & vnic to keep track of queue & thread info */ -struct chaninfo { - struct uisqueue_info *queueinfo; - /* this specifies the queue structures for a channel */ - /* ALLOCATED BY THE OTHER END - WE JUST GET A POINTER TO THE MEMORY */ - spinlock_t insertlock; - /* currently used only in virtnic when sending data to uisnic */ - /* to synchronize the inserts into the signal queue */ - struct uisthread_info threadinfo; - /* this specifies the thread structures used by the thread that */ - /* handles this channel */ -}; - -/* this is the wait code for all the threads - it is used to get -* something from a queue choices: wait_for_completion_interruptible, -* _timeout, interruptible_timeout -*/ -#define UIS_THREAD_WAIT_MSEC(x) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - schedule_timeout(msecs_to_jiffies(x)); \ -} - -#define UIS_THREAD_WAIT_USEC(x) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - schedule_timeout(usecs_to_jiffies(x)); \ -} - -#define UIS_THREAD_WAIT UIS_THREAD_WAIT_MSEC(5) - -#define UIS_THREAD_WAIT_SEC(x) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - schedule_timeout((x)*HZ); \ -} - -/* This is a hack until we fix IOVM to initialize the channel header - * correctly at DEVICE_CREATE time, INSTEAD OF waiting until - * DEVICE_CONFIGURE time. - */ -static inline void -wait_for_valid_guid(uuid_le __iomem *guid) -{ - uuid_le tmpguid; - - while (1) { - memcpy_fromio((void *)&tmpguid, - (void __iomem *)guid, sizeof(uuid_le)); - if (uuid_le_cmp(tmpguid, NULL_UUID_LE) != 0) - break; - UIS_THREAD_WAIT_SEC(5); - } -} - -static inline unsigned int -issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) -{ - struct vmcall_io_controlvm_addr_params params; - int result = VMCALL_SUCCESS; - u64 physaddr; - - physaddr = virt_to_phys(¶ms); - ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR, physaddr, result); - if (VMCALL_SUCCESSFUL(result)) { - *control_addr = params.address; - *control_bytes = params.channel_bytes; - } - return result; -} - -static inline unsigned int issue_vmcall_io_diag_addr(u64 *diag_channel_addr) -{ - struct vmcall_io_diag_addr_params params; - int result = VMCALL_SUCCESS; - u64 physaddr; - - physaddr = virt_to_phys(¶ms); - ISSUE_IO_VMCALL(VMCALL_IO_DIAG_ADDR, physaddr, result); - if (VMCALL_SUCCESSFUL(result)) - *diag_channel_addr = params.address; - return result; -} - -static inline unsigned int issue_vmcall_io_visorserial_addr(u64 *channel_addr) -{ - struct vmcall_io_visorserial_addr_params params; - int result = VMCALL_SUCCESS; - u64 physaddr; - - physaddr = virt_to_phys(¶ms); - ISSUE_IO_VMCALL(VMCALL_IO_VISORSERIAL_ADDR, physaddr, result); - if (VMCALL_SUCCESSFUL(result)) - *channel_addr = params.address; - return result; -} - -static inline s64 issue_vmcall_query_guest_virtual_time_offset(void) -{ - u64 result = VMCALL_SUCCESS; - u64 physaddr = 0; - - ISSUE_IO_VMCALL(VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET, physaddr, - result); - return result; -} - -struct log_info_t { - unsigned long long last_cycles; - unsigned long long delta_sum[64]; - unsigned long long delta_cnt[64]; - unsigned long long max_delta[64]; - unsigned long long min_delta[64]; -}; - -static inline int issue_vmcall_update_physical_time(u64 adjustment) -{ - int result = VMCALL_SUCCESS; - - ISSUE_IO_VMCALL(VMCALL_UPDATE_PHYSICAL_TIME, adjustment, result); - return result; -} - -static inline unsigned int issue_vmcall_channel_mismatch(const char *chname, - const char *item_name, u32 line_no, - const char *path_n_fn) -{ - struct vmcall_channel_version_mismatch_params params; - int result = VMCALL_SUCCESS; - u64 physaddr; - char *last_slash = NULL; - - strlcpy(params.chname, chname, sizeof(params.chname)); - strlcpy(params.item_name, item_name, sizeof(params.item_name)); - params.line_no = line_no; - - last_slash = strrchr(path_n_fn, '/'); - if (last_slash != NULL) { - last_slash++; - strlcpy(params.file_name, last_slash, sizeof(params.file_name)); - } else - strlcpy(params.file_name, - "Cannot determine source filename", - sizeof(params.file_name)); - - physaddr = virt_to_phys(¶ms); - ISSUE_IO_VMCALL(VMCALL_CHANNEL_VERSION_MISMATCH, physaddr, result); - return result; -} - -#define UIS_DAEMONIZE(nam) - -void uislib_enable_channel_interrupts(u32 bus_no, u32 dev_no, - int (*interrupt)(void *), - void *interrupt_context); -void uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no); -void uislib_force_channel_interrupt(u32 bus_no, u32 dev_no); - -#endif /* __UISUTILS__H__ */ diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h index 84abe5f99f54..f272975b2920 100644 --- a/drivers/staging/unisys/include/vbushelper.h +++ b/drivers/staging/unisys/include/vbushelper.h @@ -18,8 +18,6 @@ #ifndef __VBUSHELPER_H__ #define __VBUSHELPER_H__ -#include "vbusdeviceinfo.h" - /* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the * command line */ diff --git a/drivers/staging/unisys/common-spar/include/version.h b/drivers/staging/unisys/include/version.h index 83d1da7a2f81..83d1da7a2f81 100644 --- a/drivers/staging/unisys/common-spar/include/version.h +++ b/drivers/staging/unisys/include/version.h diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index d54282222f65..e4a21e42e868 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -40,9 +40,18 @@ struct visor_driver; struct visor_device; +extern struct bus_type visorbus_type; typedef void (*visorbus_state_complete_func) (struct visor_device *dev, int status); +struct visorchipset_state { + u32 created:1; + u32 attached:1; + u32 configured:1; + u32 running:1; + /* Add new fields above. */ + /* Remaining bits in this 32-bit word are unused. */ +}; /** This struct describes a specific Supervisor channel, by providing its * GUID, name, and sizes. @@ -50,8 +59,6 @@ typedef void (*visorbus_state_complete_func) (struct visor_device *dev, struct visor_channeltype_descriptor { const uuid_le guid; const char *name; - unsigned long min_size; - unsigned long max_size; }; /** Information provided by each visor driver when it registers with the @@ -128,7 +135,6 @@ struct visor_device { struct periodic_work *periodic_work; bool being_removed; bool responded_to_device_create; - struct kobject kobjchannel; /* visorbus<x>/dev<y>/channel/ */ struct kobject kobjdevmajorminor; /* visorbus<x>/dev<y>/devmajorminor/*/ struct { int major, minor; @@ -140,8 +146,18 @@ struct visor_device { struct semaphore visordriver_callback_lock; bool pausing; bool resuming; - unsigned long chipset_bus_no; - unsigned long chipset_dev_no; + u32 chipset_bus_no; + u32 chipset_dev_no; + struct visorchipset_state state; + uuid_le type; + uuid_le inst; + u8 *name; + u8 *description; + struct controlvm_message_header *pending_msg_hdr; + void *vbus_hdr_info; + u32 switch_no; + u32 internal_port_no; + uuid_le partition_uuid; }; #define to_visor_device(x) container_of(x, struct visor_device, device) @@ -192,10 +208,15 @@ ulong visorchannel_get_nbytes(struct visorchannel *channel); char *visorchannel_id(struct visorchannel *channel, char *s); char *visorchannel_zoneid(struct visorchannel *channel, char *s); u64 visorchannel_get_clientpartition(struct visorchannel *channel); +int visorchannel_set_clientpartition(struct visorchannel *channel, + u64 partition_handle); uuid_le visorchannel_get_uuid(struct visorchannel *channel); char *visorchannel_uuid_id(uuid_le *guid, char *s); void visorchannel_debug(struct visorchannel *channel, int num_queues, struct seq_file *seq, u32 off); void __iomem *visorchannel_get_header(struct visorchannel *channel); +#define BUS_ROOT_DEVICE UINT_MAX +struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, + struct visor_device *from); #endif diff --git a/drivers/staging/unisys/visorbus/Makefile b/drivers/staging/unisys/visorbus/Makefile index 72d4d4429684..fa27ee5f336c 100644 --- a/drivers/staging/unisys/visorbus/Makefile +++ b/drivers/staging/unisys/visorbus/Makefile @@ -10,6 +10,4 @@ visorbus-y += visorchipset.o visorbus-y += periodic_work.o ccflags-y += -Idrivers/staging/unisys/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels ccflags-y += -Idrivers/staging/unisys/visorutil diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h index f1c86fbc126c..a50d9cf4bed7 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/visorbus/controlvmchannel.h @@ -18,7 +18,6 @@ #include <linux/uuid.h> #include "channel.h" -#include "controlframework.h" /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ #define SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID \ @@ -56,6 +55,37 @@ /* Max num of messages stored during IOVM creation to be reused after crash */ #define CONTROLVM_CRASHMSG_MAX 2 +struct spar_segment_state { + u16 enabled:1; /* Bit 0: May enter other states */ + u16 active:1; /* Bit 1: Assigned to active partition */ + u16 alive:1; /* Bit 2: Configure message sent to + * service/server */ + u16 revoked:1; /* Bit 3: similar to partition state + * ShuttingDown */ + u16 allocated:1; /* Bit 4: memory (device/port number) + * has been selected by Command */ + u16 known:1; /* Bit 5: has been introduced to the + * service/guest partition */ + u16 ready:1; /* Bit 6: service/Guest partition has + * responded to introduction */ + u16 operating:1; /* Bit 7: resource is configured and + * operating */ + /* Note: don't use high bit unless we need to switch to ushort + * which is non-compliant */ +}; + +static const struct spar_segment_state segment_state_running = { + 1, 1, 1, 0, 1, 1, 1, 1 +}; + +static const struct spar_segment_state segment_state_paused = { + 1, 1, 1, 0, 1, 1, 1, 0 +}; + +static const struct spar_segment_state segment_state_standby = { + 1, 1, 0, 0, 1, 1, 1, 0 +}; + /* Ids for commands that may appear in either queue of a ControlVm channel. * * Commands that are initiated by the command partition (CP), by an IO or diff --git a/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h b/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h index f74f5d8c2820..f74f5d8c2820 100644 --- a/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h +++ b/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h diff --git a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h b/drivers/staging/unisys/visorbus/iovmcall_gnuc.h index 57dd93e0cc83..57dd93e0cc83 100644 --- a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h +++ b/drivers/staging/unisys/visorbus/iovmcall_gnuc.h diff --git a/drivers/staging/unisys/visorbus/periodic_work.c b/drivers/staging/unisys/visorbus/periodic_work.c index 3562e8b2824b..5e56088cf855 100644 --- a/drivers/staging/unisys/visorbus/periodic_work.c +++ b/drivers/staging/unisys/visorbus/periodic_work.c @@ -192,8 +192,7 @@ bool visor_periodic_work_stop(struct periodic_work *pw) } if (pw->is_scheduled) { write_unlock(&pw->lock); - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(10); + schedule_timeout_interruptible(msecs_to_jiffies(10)); write_lock(&pw->lock); } else { pw->want_to_stop = false; diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index 5ed83a3f1428..5ed83a3f1428 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/visorbus/vbusdeviceinfo.h index 9b6d3e69355c..9b6d3e69355c 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/visorbus/vbusdeviceinfo.h diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 77afa9dbbdc8..dcce1f02d54d 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -23,63 +23,17 @@ #include "periodic_work.h" #include "vbuschannel.h" #include "guestlinuxdebug.h" -#include "vbusdeviceinfo.h" +#include "vmcallinterface.h" #define MYDRVNAME "visorbus" /* module parameters */ -int visorbus_debug; -int visorbus_forcematch; -int visorbus_forcenomatch; -#define MAXDEVICETEST 4 -int visorbus_devicetest; -int visorbus_debugref; +static int visorbus_debug; +static int visorbus_forcematch; +static int visorbus_forcenomatch; +static int visorbus_debugref; #define SERIALLOOPBACKCHANADDR (100 * 1024 * 1024) -/** This is the private data that we store for each bus device instance. - */ -struct visorbus_devdata { - int devno; /* this is the chipset busNo */ - struct list_head list_all; - struct device *dev; - struct kobject kobj; - struct visorchannel *chan; /* channel area for bus itself */ - bool vbus_valid; - struct spar_vbus_headerinfo vbus_hdr_info; -}; - -/* These forward declarations are required since our drivers are out-of-tree. - * The structures referenced are kernel-private and are not in the headers, but - * it is impossible to make a functioning bus driver without them. - */ -struct subsys_private { - struct kset subsys; - struct kset *devices_kset; - - struct kset *drivers_kset; - struct klist klist_devices; - struct klist klist_drivers; - struct blocking_notifier_head bus_notifier; - unsigned int drivers_autoprobe:1; - struct bus_type *bus; - - struct list_head class_interfaces; - struct kset glue_dirs; - struct mutex class_mutex; /* ignore */ - struct class *class; -}; - -struct bus_type_private { - struct kset subsys; - struct kset *drivers_kset; - struct kset *devices_kset; - struct klist klist_devices; - struct klist klist_drivers; - struct blocking_notifier_head bus_notifier; - unsigned int drivers_autoprobe:1; - struct bus_type *bus; -}; - #define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c #define POLLJIFFIES_TESTWORK 100 #define POLLJIFFIES_NORMALCHANNEL 10 @@ -88,13 +42,43 @@ static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env); static int visorbus_match(struct device *xdev, struct device_driver *xdrv); static void fix_vbus_dev_info(struct visor_device *visordev); +/* BUS type attributes + * + * define & implement display of bus attributes under + * /sys/bus/visorbus. + * + */ + +static ssize_t version_show(struct bus_type *bus, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", VERSION); +} + +static BUS_ATTR_RO(version); + +static struct attribute *visorbus_bus_attrs[] = { + &bus_attr_version.attr, + NULL, +}; + +static const struct attribute_group visorbus_bus_group = { + .attrs = visorbus_bus_attrs, +}; + +static const struct attribute_group *visorbus_bus_groups[] = { + &visorbus_bus_group, + NULL, +}; + + /** This describes the TYPE of bus. * (Don't confuse this with an INSTANCE of the bus.) */ -static struct bus_type visorbus_type = { +struct bus_type visorbus_type = { .name = "visorbus", .match = visorbus_match, .uevent = visorbus_uevent, + .bus_groups = visorbus_bus_groups, }; static struct delayed_work periodic_work; @@ -107,15 +91,14 @@ static struct delayed_work periodic_work; static struct workqueue_struct *periodic_test_workqueue; static struct workqueue_struct *periodic_dev_workqueue; static long long bus_count; /** number of bus instances */ -static long long total_devices_created; /** ever-increasing */ -static void chipset_bus_create(u32 bus_no); -static void chipset_bus_destroy(u32 bus_no); -static void chipset_device_create(u32 bus_no, u32 dev_no); -static void chipset_device_destroy(u32 bus_no, u32 dev_no); -static void chipset_device_pause(u32 bus_no, u32 dev_no); -static void chipset_device_resume(u32 bus_no, u32 dev_no); +static void chipset_bus_create(struct visor_device *bus_info); +static void chipset_bus_destroy(struct visor_device *bus_info); +static void chipset_device_create(struct visor_device *dev_info); +static void chipset_device_destroy(struct visor_device *dev_info); +static void chipset_device_pause(struct visor_device *dev_info); +static void chipset_device_resume(struct visor_device *dev_info); /** These functions are implemented herein, and are called by the chipset * driver to notify us about specific events. @@ -139,7 +122,7 @@ static struct ultra_vbus_deviceinfo chipset_driverinfo; /* filled in with info about this driver, wrt it servicing client busses */ static struct ultra_vbus_deviceinfo clientbus_driverinfo; -/** list of visorbus_devdata structs, linked via .list_all */ +/** list of visor_device structs, linked via .list_all */ static LIST_HEAD(list_all_bus_instances); /** list of visor_device structs, linked via .list_all */ static LIST_HEAD(list_all_device_instances); @@ -197,11 +180,10 @@ away: static void visorbus_release_busdevice(struct device *xdev) { - struct visorbus_devdata *devdata = dev_get_drvdata(xdev); + struct visor_device *dev = dev_get_drvdata(xdev); dev_set_drvdata(xdev, NULL); - kfree(devdata); - kfree(xdev); + kfree(dev); } /** This is called when device_unregister() is called for each child @@ -284,7 +266,7 @@ devmajorminor_attr_store(struct kobject *kobj, static int register_devmajorminor_attributes(struct visor_device *dev); -int +static int devmajorminor_create_file(struct visor_device *dev, const char *name, int major, int minor) { @@ -329,7 +311,7 @@ away: return rc; } -void +static void devmajorminor_remove_file(struct visor_device *dev, int slot) { int maxdevnodes = ARRAY_SIZE(dev->devnodes) / sizeof(dev->devnodes[0]); @@ -338,7 +320,7 @@ devmajorminor_remove_file(struct visor_device *dev, int slot) if (slot < 0 || slot >= maxdevnodes) return; myattr = (struct devmajorminor_attribute *)(dev->devnodes[slot].attr); - if (myattr) + if (!myattr) return; sysfs_remove_file(&dev->kobjdevmajorminor, &myattr->attr); kobject_uevent(&dev->device.kobj, KOBJ_OFFLINE); @@ -346,7 +328,7 @@ devmajorminor_remove_file(struct visor_device *dev, int slot) kfree(myattr); } -void +static void devmajorminor_remove_all_files(struct visor_device *dev) { int i = 0; @@ -386,7 +368,7 @@ away: return rc; } -void +static void unregister_devmajorminor_attributes(struct visor_device *dev) { if (!dev->kobjdevmajorminor.parent) @@ -398,370 +380,111 @@ unregister_devmajorminor_attributes(struct visor_device *dev) dev->kobjdevmajorminor.parent = NULL; } -/* Implement publishing of channel attributes under: - * - * /sys/bus/visorbus<x>/dev<y>/channel - * - */ - -#define to_channel_attr(_attr) \ - container_of(_attr, struct channel_attribute, attr) -#define to_visor_device_from_kobjchannel(obj) \ - container_of(obj, struct visor_device, kobjchannel) - -struct channel_attribute { - struct attribute attr; - ssize_t (*show)(struct visor_device*, char *buf); - ssize_t (*store)(struct visor_device*, const char *buf, size_t count); -}; - /* begin implementation of specific channel attributes to appear under * /sys/bus/visorbus<x>/dev<y>/channel */ -static ssize_t devicechannel_attr_physaddr(struct visor_device *dev, char *buf) +static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr, + char *buf) { - if (!dev->visorchannel) + struct visor_device *vdev = to_visor_device(dev); + + if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "0x%Lx\n", - visorchannel_get_physaddr(dev->visorchannel)); + visorchannel_get_physaddr(vdev->visorchannel)); } -static ssize_t devicechannel_attr_nbytes(struct visor_device *dev, char *buf) +static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr, + char *buf) { - if (!dev->visorchannel) + struct visor_device *vdev = to_visor_device(dev); + + if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "0x%lx\n", - visorchannel_get_nbytes(dev->visorchannel)); + visorchannel_get_nbytes(vdev->visorchannel)); } -static ssize_t devicechannel_attr_clientpartition(struct visor_device *dev, - char *buf) { - if (!dev->visorchannel) +static ssize_t clientpartition_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct visor_device *vdev = to_visor_device(dev); + + if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "0x%Lx\n", - visorchannel_get_clientpartition(dev->visorchannel)); + visorchannel_get_clientpartition(vdev->visorchannel)); } -static ssize_t devicechannel_attr_typeguid(struct visor_device *dev, char *buf) +static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); char s[99]; - if (!dev->visorchannel) + if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_id(dev->visorchannel, s)); + visorchannel_id(vdev->visorchannel, s)); } -static ssize_t devicechannel_attr_zoneguid(struct visor_device *dev, char *buf) +static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); char s[99]; - if (!dev->visorchannel) + if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_zoneid(dev->visorchannel, s)); + visorchannel_zoneid(vdev->visorchannel, s)); } -static ssize_t devicechannel_attr_typename(struct visor_device *dev, char *buf) +static ssize_t typename_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); int i = 0; - struct bus_type *xbus = dev->device.bus; - struct device_driver *xdrv = dev->device.driver; + struct bus_type *xbus = dev->bus; + struct device_driver *xdrv = dev->driver; struct visor_driver *drv = NULL; - if (!dev->visorchannel || !xbus || !xdrv) + if (!vdev->visorchannel || !xbus || !xdrv) return 0; - i = xbus->match(&dev->device, xdrv); + i = xbus->match(dev, xdrv); if (!i) return 0; drv = to_visor_driver(xdrv); return snprintf(buf, PAGE_SIZE, "%s\n", drv->channel_types[i - 1].name); } -static ssize_t devicechannel_attr_dump(struct visor_device *dev, char *buf) -{ - int count = 0; -/* TODO: replace this with debugfs code - struct seq_file *m = NULL; - if (dev->visorchannel == NULL) - return 0; - m = visor_seq_file_new_buffer(buf, PAGE_SIZE - 1); - if (m == NULL) - return 0; - visorchannel_debug(dev->visorchannel, 1, m, 0); - count = m->count; - visor_seq_file_done_buffer(m); - m = NULL; -*/ - return count; -} - -static struct channel_attribute all_channel_attrs[] = { - __ATTR(physaddr, S_IRUGO, - devicechannel_attr_physaddr, NULL), - __ATTR(nbytes, S_IRUGO, - devicechannel_attr_nbytes, NULL), - __ATTR(clientpartition, S_IRUGO, - devicechannel_attr_clientpartition, NULL), - __ATTR(typeguid, S_IRUGO, - devicechannel_attr_typeguid, NULL), - __ATTR(zoneguid, S_IRUGO, - devicechannel_attr_zoneguid, NULL), - __ATTR(typename, S_IRUGO, - devicechannel_attr_typename, NULL), - __ATTR(dump, S_IRUGO, - devicechannel_attr_dump, NULL), +static DEVICE_ATTR_RO(physaddr); +static DEVICE_ATTR_RO(nbytes); +static DEVICE_ATTR_RO(clientpartition); +static DEVICE_ATTR_RO(typeguid); +static DEVICE_ATTR_RO(zoneguid); +static DEVICE_ATTR_RO(typename); + +static struct attribute *channel_attrs[] = { + &dev_attr_physaddr.attr, + &dev_attr_nbytes.attr, + &dev_attr_clientpartition.attr, + &dev_attr_typeguid.attr, + &dev_attr_zoneguid.attr, + &dev_attr_typename.attr, }; -/* end implementation of specific channel attributes */ - -static ssize_t channel_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct channel_attribute *channel_attr = to_channel_attr(attr); - struct visor_device *dev = to_visor_device_from_kobjchannel(kobj); - ssize_t ret = 0; - - if (channel_attr->show) - ret = channel_attr->show(dev, buf); - return ret; -} - -static ssize_t channel_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct channel_attribute *channel_attr = to_channel_attr(attr); - struct visor_device *dev = to_visor_device_from_kobjchannel(kobj); - ssize_t ret = 0; - - if (channel_attr->store) - ret = channel_attr->store(dev, buf, count); - return ret; -} - -static int channel_create_file(struct visor_device *dev, - struct channel_attribute *attr) -{ - return sysfs_create_file(&dev->kobjchannel, &attr->attr); -} - -static void channel_remove_file(struct visor_device *dev, - struct channel_attribute *attr) -{ - sysfs_remove_file(&dev->kobjchannel, &attr->attr); -} - -static const struct sysfs_ops channel_sysfs_ops = { - .show = channel_attr_show, - .store = channel_attr_store, +static struct attribute_group channel_attr_grp = { + .name = "channel", + .attrs = channel_attrs, }; -static struct kobj_type channel_kobj_type = { - .sysfs_ops = &channel_sysfs_ops +static const struct attribute_group *visorbus_dev_groups[] = { + &channel_attr_grp, + NULL }; -int register_channel_attributes(struct visor_device *dev) -{ - int rc = 0, i = 0, x = 0; - - if (dev->kobjchannel.parent) - goto away; /* already registered */ - x = kobject_init_and_add(&dev->kobjchannel, &channel_kobj_type, - &dev->device.kobj, "channel"); - if (x < 0) { - rc = x; - goto away; - } - - kobject_uevent(&dev->kobjchannel, KOBJ_ADD); - - for (i = 0; - i < sizeof(all_channel_attrs) / sizeof(struct channel_attribute); - i++) - x = channel_create_file(dev, &all_channel_attrs[i]); - if (x < 0) { - while (--i >= 0) - channel_remove_file(dev, &all_channel_attrs[i]); - kobject_del(&dev->kobjchannel); - kobject_put(&dev->kobjchannel); - rc = x; - goto away; - } -away: - return rc; -} - -void unregister_channel_attributes(struct visor_device *dev) -{ - int i = 0; - - if (!dev->kobjchannel.parent) - return; /* already unregistered */ - for (i = 0; - i < sizeof(all_channel_attrs) / sizeof(struct channel_attribute); - i++) - channel_remove_file(dev, &all_channel_attrs[i]); - - kobject_del(&dev->kobjchannel); - kobject_put(&dev->kobjchannel); - dev->kobjchannel.parent = NULL; -} -/* This is actually something they forgot to put in the kernel. - * struct bus_type in the kernel SHOULD have a "busses" member, which - * should be treated similarly to the "devices" and "drivers" members. - * There SHOULD be: - * - a "businst_attribute" analogous to the existing "bus_attribute" - * - a "businst_create_file" and "businst_remove_file" analogous to the - * existing "bus_create_file" and "bus_remove_file". - * That's what I created businst.c and businst.h to do. - * - * We want to add the "busses" sub-tree in sysfs, where we will house the - * names and properties of each bus instance: - * - * /sys/bus/<bustypename>/ - * version - * devices - * <devname1> --> /sys/devices/<businstancename><devname1> - * <devname2> --> /sys/devices/<businstancename><devname2> - * drivers - * <driverinstancename1> - * <driverinstance1property1> - * <driverinstance1property2> - * ... - * <driverinstancename2> - * <driverinstance2property1> - * <driverinstance2property2> - * ... - * >> busses - * >> <businstancename1> - * >> <businstance1property1> - * >> <businstance1property2> - * >> ... - * >> <businstancename2> - * >> <businstance2property1> - * >> <businstance2property2> - * >> ... - * - * I considered adding bus instance properties under - * /sys/devices/<businstancename>. But I thought there may be existing - * notions that ONLY device sub-trees should live under - * /sys/devices/<businstancename>. So I stayed out of there. - * - */ - -struct businst_attribute { - struct attribute attr; - ssize_t (*show)(struct visorbus_devdata*, char *buf); - ssize_t (*store)(struct visorbus_devdata*, const char *buf, - size_t count); -}; - -#define to_businst_attr(_attr) \ - container_of(_attr, struct businst_attribute, attr) -#define to_visorbus_devdata(obj) \ - container_of(obj, struct visorbus_devdata, kobj) - -static ssize_t -businst_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct businst_attribute *businst_attr = to_businst_attr(attr); - struct visorbus_devdata *bus = to_visorbus_devdata(kobj); - ssize_t ret = 0; - - if (businst_attr->show) - ret = businst_attr->show(bus, buf); - return ret; -} - -static ssize_t -businst_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct businst_attribute *businst_attr = to_businst_attr(attr); - struct visorbus_devdata *bus = to_visorbus_devdata(kobj); - ssize_t ret = 0; - - if (businst_attr->store) - ret = businst_attr->store(bus, buf, count); - return ret; -} - -static int -businst_create_file(struct visorbus_devdata *bus, - struct businst_attribute *attr) -{ - return sysfs_create_file(&bus->kobj, &attr->attr); -} - -static void -businst_remove_file(struct visorbus_devdata *bus, - struct businst_attribute *attr) -{ - sysfs_remove_file(&bus->kobj, &attr->attr); -} - -static const struct sysfs_ops businst_sysfs_ops = { - .show = businst_attr_show, - .store = businst_attr_store, -}; - -static struct kobj_type businst_kobj_type = { - .sysfs_ops = &businst_sysfs_ops -}; - -static struct kset businstances = { /* should actually be a member of - * bus_type */ -}; - -/* BUS type attributes - * - * define & implement display of bus attributes under - * /sys/bus/visorbus. - * - */ - -static ssize_t -BUSTYPE_ATTR_version(struct bus_type *bus, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", VERSION); -} - -static struct bus_attribute bustype_attr_version = -__ATTR(version, S_IRUGO, BUSTYPE_ATTR_version, NULL); - -static int -register_bustype_attributes(void) -{ - int rc = 0; - - rc = bus_create_file(&visorbus_type, &bustype_attr_version); - if (rc < 0) - goto away; - - /* Here we make up for the fact that bus_type does not yet have a - * member to keep track of multiple bus instances for a given bus - * type. This is useful for stashing properties for each bus - * instance. - */ - kobject_set_name(&businstances.kobj, "busses"); - businstances.kobj.ktype = &businst_kobj_type; - businstances.kobj.parent = &visorbus_type.p->subsys.kobj; - rc = kset_register(&businstances); - if (rc < 0) - goto away; - - rc = 0; -away: - return rc; -} - -static void -unregister_bustype_attributes(void) -{ - bus_remove_file(&visorbus_type, &bustype_attr_version); - kset_unregister(&businstances); -} +/* end implementation of specific channel attributes */ /* BUS instance attributes * @@ -774,78 +497,69 @@ unregister_bustype_attributes(void) * */ -static ssize_t businst_attr_partition_handle(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; - int len = 0; +static ssize_t partition_handle_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); + u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); - if (businst && visorchipset_get_bus_info(businst->devno, &bus_info)) - len = snprintf(buf, PAGE_SIZE, - "0x%Lx\n", - (unsigned long long)bus_info.partition_handle); - return len; + return snprintf(buf, PAGE_SIZE, "0x%Lx\n", handle); } -static ssize_t businst_attr_partition_guid(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; - int len = 0; +static ssize_t partition_guid_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); - if (businst && visorchipset_get_bus_info(businst->devno, &bus_info)) - len = snprintf(buf, PAGE_SIZE, "{%pUb}\n", - &bus_info.partition_uuid); - return len; + return snprintf(buf, PAGE_SIZE, "{%pUb}\n", &vdev->partition_uuid); } -static ssize_t businst_attr_partition_name(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; - int len = 0; +static ssize_t partition_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); - if (businst && - visorchipset_get_bus_info(businst->devno, &bus_info) && - bus_info.name) - len = snprintf(buf, PAGE_SIZE, "%s\n", bus_info.name); - return len; + return snprintf(buf, PAGE_SIZE, "%s\n", vdev->name); } -static ssize_t businst_attr_channel_addr(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; - int len = 0; +static ssize_t channel_addr_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); + u64 addr = visorchannel_get_physaddr(vdev->visorchannel); - if (businst && visorchipset_get_bus_info(businst->devno, &bus_info)) - len = snprintf(buf, PAGE_SIZE, "0x%Lx\n", (unsigned long long) - bus_info.chan_info.channel_addr); - return len; + return snprintf(buf, PAGE_SIZE, "0x%Lx\n", addr); } -static ssize_t businst_attr_nchannel_bytes(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; - int len = 0; +static ssize_t channel_bytes_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); + u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); - if (businst && visorchipset_get_bus_info(businst->devno, &bus_info)) - len = snprintf(buf, PAGE_SIZE, "0x%Lx\n", (unsigned long long) - bus_info.chan_info.n_channel_bytes); - return len; + return snprintf(buf, PAGE_SIZE, "0x%Lx\n", nbytes); } -static ssize_t businst_attr_channel_id(struct visorbus_devdata *businst, - char *buf) { +static ssize_t channel_id_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); int len = 0; - if (businst && businst->chan) { - visorchannel_id(businst->chan, buf); + if (vdev->visorchannel) { + visorchannel_id(vdev->visorchannel, buf); len = strlen(buf); buf[len++] = '\n'; } return len; } -static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst, - char *buf) { - struct visorchipset_bus_info bus_info; +static ssize_t client_bus_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct visor_device *vdev = to_visor_device(dev); + struct visorchannel *channel = vdev->visorchannel; + int i, x, remain = PAGE_SIZE; unsigned long off; char *p = buf; @@ -853,16 +567,15 @@ static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst, struct ultra_vbus_deviceinfo dev_info; partition_name = ""; - if (businst && businst->chan) { - if (visorchipset_get_bus_info(businst->devno, &bus_info) && - bus_info.name) - partition_name = bus_info.name; + if (channel) { + if (vdev->name) + partition_name = vdev->name; x = snprintf(p, remain, "Client device / client driver info for %s partition (vbus #%d):\n", - partition_name, businst->devno); + partition_name, vdev->chipset_dev_no); p += x; remain -= x; - x = visorchannel_read(businst->chan, + x = visorchannel_read(channel, offsetof(struct spar_vbus_channel_protocol, chp_info), @@ -873,7 +586,7 @@ static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst, p += x; remain -= x; } - x = visorchannel_read(businst->chan, + x = visorchannel_read(channel, offsetof(struct spar_vbus_channel_protocol, bus_info), @@ -887,8 +600,8 @@ static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst, off = offsetof(struct spar_vbus_channel_protocol, dev_info); i = 0; while (off + sizeof(dev_info) <= - visorchannel_get_nbytes(businst->chan)) { - x = visorchannel_read(businst->chan, + visorchannel_get_nbytes(channel)) { + x = visorchannel_read(channel, off, &dev_info, sizeof(dev_info)); if (x >= 0) { x = vbuschannel_devinfo_to_string @@ -903,79 +616,33 @@ static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst, return PAGE_SIZE - remain; } -static struct businst_attribute ba_partition_handle = - __ATTR(partition_handle, S_IRUGO, businst_attr_partition_handle, NULL); -static struct businst_attribute ba_partition_guid = - __ATTR(partition_guid, S_IRUGO, businst_attr_partition_guid, NULL); -static struct businst_attribute ba_partition_name = - __ATTR(partition_name, S_IRUGO, businst_attr_partition_name, NULL); -static struct businst_attribute ba_channel_addr = - __ATTR(channel_addr, S_IRUGO, businst_attr_channel_addr, NULL); -static struct businst_attribute ba_nchannel_bytes = - __ATTR(nchannel_bytes, S_IRUGO, businst_attr_nchannel_bytes, NULL); -static struct businst_attribute ba_channel_id = - __ATTR(channel_id, S_IRUGO, businst_attr_channel_id, NULL); -static struct businst_attribute ba_client_bus_info = - __ATTR(client_bus_info, S_IRUGO, businst_attr_client_bus_info, NULL); - -static int -register_businst_attributes(struct visorbus_devdata *businst) -{ - int rc = 0; - - businst->kobj.kset = &businstances; /* identify parent sysfs dir */ - rc = kobject_init_and_add(&businst->kobj, &businst_kobj_type, - NULL, "visorbus%d", businst->devno); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_partition_handle); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_partition_guid); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_partition_name); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_channel_addr); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_nchannel_bytes); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_channel_id); - if (rc < 0) - goto away; - - rc = businst_create_file(businst, &ba_client_bus_info); - if (rc < 0) - goto away; - - kobject_uevent(&businst->kobj, KOBJ_ADD); +static DEVICE_ATTR_RO(partition_handle); +static DEVICE_ATTR_RO(partition_guid); +static DEVICE_ATTR_RO(partition_name); +static DEVICE_ATTR_RO(channel_addr); +static DEVICE_ATTR_RO(channel_bytes); +static DEVICE_ATTR_RO(channel_id); +static DEVICE_ATTR_RO(client_bus_info); + +static struct attribute *dev_attrs[] = { + &dev_attr_partition_handle.attr, + &dev_attr_partition_guid.attr, + &dev_attr_partition_name.attr, + &dev_attr_channel_addr.attr, + &dev_attr_channel_bytes.attr, + &dev_attr_channel_id.attr, + &dev_attr_client_bus_info.attr, + NULL +}; - rc = 0; -away: - return rc; -} +static struct attribute_group dev_attr_grp = { + .attrs = dev_attrs, +}; -static void -unregister_businst_attributes(struct visorbus_devdata *businst) -{ - businst_remove_file(businst, &ba_partition_handle); - businst_remove_file(businst, &ba_partition_guid); - businst_remove_file(businst, &ba_partition_name); - businst_remove_file(businst, &ba_channel_addr); - businst_remove_file(businst, &ba_nchannel_bytes); - businst_remove_file(businst, &ba_channel_id); - businst_remove_file(businst, &ba_client_bus_info); - kobject_put(&businst->kobj); -} +static const struct attribute_group *visorbus_groups[] = { + &dev_attr_grp, + NULL +}; /* DRIVER attributes * @@ -1009,25 +676,6 @@ unregister_driver_attributes(struct visor_driver *drv) driver_remove_file(&drv->driver, &drv->version_attr); } -/* DEVICE attributes - * - * define & implement display of device attributes under - * /sys/bus/visorbus/devices/<devicename>. - * - */ - -#define DEVATTR(nam, func) { \ - .attr = { .name = __stringify(nam), \ - .mode = 0444, \ - .owner = THIS_MODULE }, \ - .show = func, \ -} - -static struct device_attribute visor_device_attrs[] = { - /* DEVATTR(channel_nbytes, DEVICE_ATTR_channel_nbytes), */ - __ATTR_NULL -}; - static void dev_periodic_work(void *xdev) { @@ -1105,11 +753,10 @@ away: * initialized. */ if (!dev->responded_to_device_create) { + dev->responded_to_device_create = true; if (chipset_responders.device_create) - (*chipset_responders.device_create)(dev->chipset_bus_no, - dev->chipset_dev_no, - rc); + (*chipset_responders.device_create)(dev, rc); } return rc; } @@ -1294,49 +941,22 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); * device. */ static int -create_visor_device(struct visorbus_devdata *devdata, - unsigned long chipset_bus_no, unsigned long chipset_dev_no, - struct visorchipset_channel_info chan_info, - u64 partition_handle) +create_visor_device(struct visor_device *dev) { int rc = -1; - struct visorchannel *visorchannel = NULL; - struct visor_device *dev = NULL; - bool gotten = false, registered1 = false, registered2 = false; + u32 chipset_bus_no = dev->chipset_bus_no; + u32 chipset_dev_no = dev->chipset_dev_no; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no, POSTCODE_SEVERITY_INFO); - /* prepare chan_hdr (abstraction to read/write channel memory) */ - visorchannel = visorchannel_create(chan_info.channel_addr, - chan_info.n_channel_bytes, - GFP_KERNEL, - chan_info.channel_type_uuid); - if (!visorchannel) { - POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, chipset_dev_no, - DIAG_SEVERITY_ERR); - goto away; - } - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, chipset_dev_no, - DIAG_SEVERITY_ERR); - goto away; - } - memset(dev, 0, sizeof(struct visor_device)); - dev->visorchannel = visorchannel; - dev->channel_type_guid = chan_info.channel_type_uuid; - dev->channel_bytes = chan_info.n_channel_bytes; - dev->chipset_bus_no = chipset_bus_no; - dev->chipset_dev_no = chipset_dev_no; - dev->device.parent = devdata->dev; sema_init(&dev->visordriver_callback_lock, 1); /* unlocked */ dev->device.bus = &visorbus_type; + dev->device.groups = visorbus_dev_groups; device_initialize(&dev->device); dev->device.release = visorbus_release_device; /* keep a reference just for us (now 2) */ get_device(&dev->device); - gotten = true; dev->periodic_work = visor_periodic_work_create(POLLJIFFIES_NORMALCHANNEL, periodic_dev_workqueue, @@ -1352,7 +972,7 @@ create_visor_device(struct visorbus_devdata *devdata, * (NOT bus instance). That's why we need to include the bus * number within the name. */ - dev_set_name(&dev->device, "vbus%lu:dev%lu", + dev_set_name(&dev->device, "vbus%u:dev%u", chipset_bus_no, chipset_dev_no); /* device_add does this: @@ -1378,41 +998,20 @@ create_visor_device(struct visorbus_devdata *devdata, goto away; } - /* note: device_register is simply device_initialize + device_add */ - rc = register_channel_attributes(dev); - if (rc < 0) { - POSTCODE_LINUX_3(DEVICE_REGISTER_FAILURE_PC, chipset_dev_no, - DIAG_SEVERITY_ERR); - goto away; - } - - registered1 = true; - rc = register_devmajorminor_attributes(dev); if (rc < 0) { POSTCODE_LINUX_3(DEVICE_REGISTER_FAILURE_PC, chipset_dev_no, DIAG_SEVERITY_ERR); - goto away; + goto away_register; } - registered2 = true; - rc = 0; + list_add_tail(&dev->list_all, &list_all_device_instances); + return 0; +away_register: + device_unregister(&dev->device); away: - if (rc < 0) { - if (registered2) - unregister_devmajorminor_attributes(dev); - if (registered1) - unregister_channel_attributes(dev); - if (gotten) - put_device(&dev->device); - if (visorchannel) - visorchannel_destroy(visorchannel); - kfree(dev); - } else { - total_devices_created++; - list_add_tail(&dev->list_all, &list_all_device_instances); - } + put_device(&dev->device); return rc; } @@ -1421,75 +1020,10 @@ remove_visor_device(struct visor_device *dev) { list_del(&dev->list_all); unregister_devmajorminor_attributes(dev); - unregister_channel_attributes(dev); put_device(&dev->device); device_unregister(&dev->device); } -static struct visor_device * -find_visor_device_by_channel(u64 channel_physaddr) -{ - struct list_head *listentry, *listtmp; - - list_for_each_safe(listentry, listtmp, &list_all_device_instances) { - struct visor_device *dev = list_entry(listentry, - struct visor_device, - list_all); - if (visorchannel_get_physaddr(dev->visorchannel) == - channel_physaddr) - return dev; - } - return NULL; -} - -static int -init_vbus_channel(struct visorchannel *chan) -{ - int rc = -1; - unsigned long allocated_bytes = visorchannel_get_nbytes(chan); - struct spar_vbus_channel_protocol *x = - kmalloc(sizeof(struct spar_vbus_channel_protocol), - GFP_KERNEL); - - POSTCODE_LINUX_3(VBUS_CHANNEL_ENTRY_PC, rc, POSTCODE_SEVERITY_INFO); - - if (x) { - POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR); - goto away; - } - if (visorchannel_clear(chan, 0, 0, allocated_bytes) < 0) { - POSTCODE_LINUX_2(VBUS_CHANNEL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - goto away; - } - if (visorchannel_read - (chan, 0, x, sizeof(struct spar_vbus_channel_protocol)) < 0) { - POSTCODE_LINUX_2(VBUS_CHANNEL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - goto away; - } - if (!SPAR_VBUS_CHANNEL_OK_SERVER(allocated_bytes)) { - POSTCODE_LINUX_2(VBUS_CHANNEL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - goto away; - } - - if (visorchannel_write - (chan, 0, x, sizeof(struct spar_vbus_channel_protocol)) < 0) { - POSTCODE_LINUX_3(VBUS_CHANNEL_FAILURE_PC, chan, - POSTCODE_SEVERITY_ERR); - goto away; - } - - POSTCODE_LINUX_3(VBUS_CHANNEL_EXIT_PC, chan, POSTCODE_SEVERITY_INFO); - rc = 0; - -away: - kfree(x); - x = NULL; - return rc; -} - static int get_vbus_header_info(struct visorchannel *chan, struct spar_vbus_headerinfo *hdr_info) @@ -1578,27 +1112,26 @@ static void fix_vbus_dev_info(struct visor_device *visordev) { int i; - struct visorchipset_bus_info bus_info; - struct visorbus_devdata *devdata = NULL; + struct visor_device *bdev; struct visor_driver *visordrv; int bus_no = visordev->chipset_bus_no; int dev_no = visordev->chipset_dev_no; struct ultra_vbus_deviceinfo dev_info; const char *chan_type_name = NULL; + struct spar_vbus_headerinfo *hdr_info; if (!visordev->device.driver) return; - visordrv = to_visor_driver(visordev->device.driver); - if (!visorchipset_get_bus_info(bus_no, &bus_info)) - return; + hdr_info = (struct spar_vbus_headerinfo *)visordev->vbus_hdr_info; + if (!hdr_info) + return; - devdata = (struct visorbus_devdata *)(bus_info.bus_driver_context); - if (!devdata) - return; + bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); + if (!bdev) + return; - if (!devdata->vbus_valid) - return; + visordrv = to_visor_driver(visordev->device.driver); /* Within the list of device types (by GUID) that the driver * says it supports, find out which one of those types matches @@ -1617,98 +1150,61 @@ fix_vbus_dev_info(struct visor_device *visordev) bus_device_info_init(&dev_info, chan_type_name, visordrv->name, visordrv->version, visordrv->vertag); - write_vbus_dev_info(devdata->chan, - &devdata->vbus_hdr_info, &dev_info, dev_no); + write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no); /* Re-write bus+chipset info, because it is possible that this * was previously written by our evil counterpart, virtpci. */ - write_vbus_chp_info(devdata->chan, &devdata->vbus_hdr_info, - &chipset_driverinfo); - write_vbus_bus_info(devdata->chan, &devdata->vbus_hdr_info, + write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo); + write_vbus_bus_info(bdev->visorchannel, hdr_info, &clientbus_driverinfo); } /** Create a device instance for the visor bus itself. */ -static struct visorbus_devdata * -create_bus_instance(int id) +static int +create_bus_instance(struct visor_device *dev) { - struct visorbus_devdata *rc = NULL; - struct visorbus_devdata *devdata = NULL; - struct device *dev; - struct visorchipset_bus_info bus_info; + int rc; + int id = dev->chipset_bus_no; + struct spar_vbus_headerinfo *hdr_info; POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR); - rc = NULL; + + hdr_info = kzalloc(sizeof(*hdr_info), GFP_KERNEL); + if (!hdr_info) { + rc = -1; goto away; } - memset(dev, 0, sizeof(struct device)); - dev_set_name(dev, "visorbus%d", id); - dev->release = visorbus_release_busdevice; - if (device_register(dev) < 0) { + + dev_set_name(&dev->device, "visorbus%d", id); + dev->device.bus = &visorbus_type; + dev->device.groups = visorbus_groups; + dev->device.release = visorbus_release_busdevice; + + if (device_register(&dev->device) < 0) { POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, id, POSTCODE_SEVERITY_ERR); - rc = NULL; - goto away; - } - devdata = kmalloc(sizeof(*devdata), GFP_KERNEL); - if (!devdata) { - POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR); - rc = NULL; - goto away; + rc = -1; + goto away_mem; } - memset(devdata, 0, sizeof(struct visorbus_devdata)); - devdata->devno = id; - devdata->dev = dev; - if ((visorchipset_get_bus_info(id, &bus_info)) && - (bus_info.chan_info.channel_addr > 0) && - (bus_info.chan_info.n_channel_bytes > 0)) { - u64 channel_addr = bus_info.chan_info.channel_addr; - unsigned long n_channel_bytes = - (unsigned long) - bus_info.chan_info.n_channel_bytes; - uuid_le channel_type_guid = - bus_info.chan_info.channel_type_uuid; - - devdata->chan = visorchannel_create(channel_addr, - n_channel_bytes, - GFP_KERNEL, - channel_type_guid); - if (!devdata->chan) { - POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, channel_addr, - POSTCODE_SEVERITY_ERR); - } else { - if (bus_info.flags.server) { - init_vbus_channel(devdata->chan); - } else { - if (get_vbus_header_info(devdata->chan, - &devdata-> - vbus_hdr_info) >= 0) { - devdata->vbus_valid = true; - write_vbus_chp_info(devdata->chan, - &devdata-> - vbus_hdr_info, - &chipset_driverinfo - ); - write_vbus_bus_info(devdata->chan, - &devdata-> - vbus_hdr_info, - &clientbus_driverinfo); - } - } - } + + if (get_vbus_header_info(dev->visorchannel, hdr_info) >= 0) { + dev->vbus_hdr_info = (void *)hdr_info; + write_vbus_chp_info(dev->visorchannel, hdr_info, + &chipset_driverinfo); + write_vbus_bus_info(dev->visorchannel, hdr_info, + &clientbus_driverinfo); + } else { + kfree(hdr_info); } - register_businst_attributes(devdata); bus_count++; - list_add_tail(&devdata->list_all, &list_all_bus_instances); - if (id == 0) - devdata = devdata; /* for testing ONLY */ - dev_set_drvdata(dev, devdata); - rc = devdata; + list_add_tail(&dev->list_all, &list_all_bus_instances); + dev_set_drvdata(&dev->device, dev); + return 0; + +away_mem: + kfree(hdr_info); away: return rc; } @@ -1716,23 +1212,23 @@ away: /** Remove a device instance for the visor bus itself. */ static void -remove_bus_instance(struct visorbus_devdata *devdata) +remove_bus_instance(struct visor_device *dev) { /* Note that this will result in the release method for - * devdata->dev being called, which will call + * dev->dev being called, which will call * visorbus_release_busdevice(). This has something to do with * the put_device() done in device_unregister(), but I have never * successfully been able to trace thru the code to see where/how * release() gets called. But I know it does. */ - unregister_businst_attributes(devdata); bus_count--; - if (devdata->chan) { - visorchannel_destroy(devdata->chan); - devdata->chan = NULL; + if (dev->visorchannel) { + visorchannel_destroy(dev->visorchannel); + dev->visorchannel = NULL; } - list_del(&devdata->list_all); - device_unregister(devdata->dev); + kfree(dev->vbus_hdr_info); + list_del(&dev->list_all); + device_unregister(&dev->device); } /** Create and register the one-and-only one instance of @@ -1743,12 +1239,7 @@ create_bus_type(void) { int rc = 0; - visorbus_type.dev_attrs = visor_device_attrs; rc = bus_register(&visorbus_type); - if (rc < 0) - return rc; - - rc = register_bustype_attributes(); return rc; } @@ -1757,7 +1248,6 @@ create_bus_type(void) static void remove_bus_type(void) { - unregister_bustype_attributes(); bus_unregister(&visorbus_type); } @@ -1776,128 +1266,64 @@ remove_all_visor_devices(void) } } -static bool entered_testing_mode; -static struct visorchipset_channel_info test_channel_infos[MAXDEVICETEST]; -static unsigned long test_bus_nos[MAXDEVICETEST]; -static unsigned long test_dev_nos[MAXDEVICETEST]; - static void -chipset_bus_create(u32 bus_no) +chipset_bus_create(struct visor_device *dev) { - struct visorchipset_bus_info bus_info; - struct visorbus_devdata *devdata; - int rc = -1; + int rc; + u32 bus_no = dev->chipset_bus_no; POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); - if (!visorchipset_get_bus_info(bus_no, &bus_info)) - goto away; - devdata = create_bus_instance(bus_no); - if (!devdata) - goto away; - if (!visorchipset_set_bus_context(bus_no, devdata)) - goto away; + rc = create_bus_instance(dev); POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); - rc = 0; -away: - if (rc < 0) { + + if (rc < 0) POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); - return; - } - POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no, - POSTCODE_SEVERITY_INFO); + else + POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no, + POSTCODE_SEVERITY_INFO); + if (chipset_responders.bus_create) - (*chipset_responders.bus_create) (bus_no, rc); + (*chipset_responders.bus_create) (dev, rc); } static void -chipset_bus_destroy(u32 bus_no) +chipset_bus_destroy(struct visor_device *dev) { - struct visorchipset_bus_info bus_info; - struct visorbus_devdata *devdata; - int rc = -1; - - if (!visorchipset_get_bus_info(bus_no, &bus_info)) - goto away; - devdata = (struct visorbus_devdata *)(bus_info.bus_driver_context); - if (!devdata) - goto away; - remove_bus_instance(devdata); - if (!visorchipset_set_bus_context(bus_no, NULL)) - goto away; - rc = 0; -away: - if (rc < 0) - return; + remove_bus_instance(dev); if (chipset_responders.bus_destroy) - (*chipset_responders.bus_destroy)(bus_no, rc); + (*chipset_responders.bus_destroy)(dev, 0); } static void -chipset_device_create(u32 bus_no, u32 dev_no) +chipset_device_create(struct visor_device *dev_info) { - struct visorchipset_device_info dev_info; - struct visorchipset_bus_info bus_info; - struct visorbus_devdata *devdata = NULL; int rc = -1; + u32 bus_no = dev_info->chipset_bus_no; + u32 dev_no = dev_info->chipset_dev_no; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); - if (entered_testing_mode) - return; - if (!visorchipset_get_device_info(bus_no, dev_no, &dev_info)) - goto away; - if (!visorchipset_get_bus_info(bus_no, &bus_info)) - goto away; - if (visorbus_devicetest) - if (total_devices_created < MAXDEVICETEST) { - test_channel_infos[total_devices_created] = - dev_info.chan_info; - test_bus_nos[total_devices_created] = bus_no; - test_dev_nos[total_devices_created] = dev_no; - } - POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); - rc = 0; -away: + rc = create_visor_device(dev_info); if (rc < 0) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); - return; + if (chipset_responders.device_create) + (*chipset_responders.device_create)(dev_info, rc); } - devdata = (struct visorbus_devdata *)(bus_info.bus_driver_context); - rc = create_visor_device(devdata, bus_no, dev_no, - dev_info.chan_info, bus_info.partition_handle); + POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); - if (rc < 0) - if (chipset_responders.device_create) - (*chipset_responders.device_create)(bus_no, dev_no, rc); } static void -chipset_device_destroy(u32 bus_no, u32 dev_no) +chipset_device_destroy(struct visor_device *dev_info) { - struct visorchipset_device_info dev_info; - struct visor_device *dev; - int rc = -1; - - if (entered_testing_mode) - return; - if (!visorchipset_get_device_info(bus_no, dev_no, &dev_info)) - goto away; - dev = find_visor_device_by_channel(dev_info.chan_info.channel_addr); - if (!dev) - goto away; - rc = 0; -away: - if (rc < 0) - return; + remove_visor_device(dev_info); if (chipset_responders.device_destroy) - (*chipset_responders.device_destroy) (bus_no, dev_no, rc); - remove_visor_device(dev); + (*chipset_responders.device_destroy) (dev_info, 0); } /* This is the callback function specified for a function driver, to @@ -1917,8 +1343,7 @@ pause_state_change_complete(struct visor_device *dev, int status) /* Notify the chipset driver that the pause is complete, which * will presumably want to send some sort of response to the * initiator. */ - (*chipset_responders.device_pause) (dev->chipset_bus_no, - dev->chipset_dev_no, status); + (*chipset_responders.device_pause) (dev, status); } /* This is the callback function specified for a function driver, to @@ -1938,8 +1363,7 @@ resume_state_change_complete(struct visor_device *dev, int status) /* Notify the chipset driver that the resume is complete, * which will presumably want to send some sort of response to * the initiator. */ - (*chipset_responders.device_resume) (dev->chipset_bus_no, - dev->chipset_dev_no, status); + (*chipset_responders.device_resume) (dev, status); } /* Tell the subordinate function driver for a specific device to pause @@ -1947,13 +1371,11 @@ resume_state_change_complete(struct visor_device *dev, int status) * callback function. */ static void -initiate_chipset_device_pause_resume(u32 bus_no, u32 dev_no, bool is_pause) +initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause) { - struct visorchipset_device_info dev_info; - struct visor_device *dev = NULL; int rc = -1, x; struct visor_driver *drv = NULL; - void (*notify_func)(u32 bus_no, u32 dev_no, int response) = NULL; + void (*notify_func)(struct visor_device *dev, int response) = NULL; if (is_pause) notify_func = chipset_responders.device_pause; @@ -1962,13 +1384,6 @@ initiate_chipset_device_pause_resume(u32 bus_no, u32 dev_no, bool is_pause) if (!notify_func) goto away; - if (!visorchipset_get_device_info(bus_no, dev_no, &dev_info)) - goto away; - - dev = find_visor_device_by_channel(dev_info.chan_info.channel_addr); - if (!dev) - goto away; - drv = to_visor_driver(dev->device.driver); if (!drv) goto away; @@ -2013,20 +1428,20 @@ initiate_chipset_device_pause_resume(u32 bus_no, u32 dev_no, bool is_pause) away: if (rc < 0) { if (notify_func) - (*notify_func)(bus_no, dev_no, rc); + (*notify_func)(dev, rc); } } static void -chipset_device_pause(u32 bus_no, u32 dev_no) +chipset_device_pause(struct visor_device *dev_info) { - initiate_chipset_device_pause_resume(bus_no, dev_no, true); + initiate_chipset_device_pause_resume(dev_info, true); } static void -chipset_device_resume(u32 bus_no, u32 dev_no) +chipset_device_resume(struct visor_device *dev_info) { - initiate_chipset_device_pause_resume(bus_no, dev_no, false); + initiate_chipset_device_pause_resume(dev_info, false); } struct channel_size_info { @@ -2045,11 +1460,6 @@ visorbus_init(void) "clientbus", "visorbus", VERSION, NULL); - /* process module options */ - - if (visorbus_devicetest > MAXDEVICETEST) - visorbus_devicetest = MAXDEVICETEST; - rc = create_bus_type(); if (rc < 0) { POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, DIAG_SEVERITY_ERR); @@ -2099,39 +1509,25 @@ visorbus_exit(void) } list_for_each_safe(listentry, listtmp, &list_all_bus_instances) { - struct visorbus_devdata *devdata = list_entry(listentry, + struct visor_device *dev = list_entry(listentry, struct - visorbus_devdata, + visor_device, list_all); - remove_bus_instance(devdata); + remove_bus_instance(dev); } remove_bus_type(); } module_param_named(debug, visorbus_debug, int, S_IRUGO); MODULE_PARM_DESC(visorbus_debug, "1 to debug"); -int visorbus_debug = 0; module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcematch, "1 to force a successful dev <--> drv match"); -int visorbus_forcematch = 0; module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcenomatch, "1 to force an UNsuccessful dev <--> drv match"); -int visorbus_forcenomatch = 0; - -module_param_named(devicetest, visorbus_devicetest, int, S_IRUGO); -MODULE_PARM_DESC(visorbus_devicetest, - "non-0 to just test device creation and destruction"); -int visorbus_devicetest = 0; module_param_named(debugref, visorbus_debugref, int, S_IRUGO); MODULE_PARM_DESC(visorbus_debugref, "1 to debug reference counting"); -int visorbus_debugref = 0; - -MODULE_AUTHOR("Unisys"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Supervisor bus driver for service partition: ver " VERSION); -MODULE_VERSION(VERSION); diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index 8326e4da56c1..2f12483e38ab 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -20,105 +20,21 @@ #include <linux/uuid.h> -#include "channel.h" #include "controlvmchannel.h" #include "vbusdeviceinfo.h" #include "vbushelper.h" -struct visorchannel; - -struct visorchipset_state { - u32 created:1; - u32 attached:1; - u32 configured:1; - u32 running:1; - /* Add new fields above. */ - /* Remaining bits in this 32-bit word are unused. */ -}; - -enum visorchipset_addresstype { - /** address is guest physical, but outside of the physical memory - * region that is controlled by the running OS (this is the normal - * address type for Supervisor channels) - */ - ADDRTYPE_LOCALPHYSICAL, - - /** address is guest physical, and withIN the confines of the - * physical memory controlled by the running OS. - */ - ADDRTYPE_LOCALTEST, -}; - -/** Attributes for a particular Supervisor channel. - */ -struct visorchipset_channel_info { - enum visorchipset_addresstype addr_type; - u64 channel_addr; - struct irq_info intr; - u64 n_channel_bytes; - uuid_le channel_type_uuid; - uuid_le channel_inst_uuid; -}; - -/** Attributes for a particular Supervisor device. - * Any visorchipset client can query these attributes using - * visorchipset_get_client_device_info() or - * visorchipset_get_server_device_info(). - */ -struct visorchipset_device_info { - struct list_head entry; - u32 bus_no; - u32 dev_no; - uuid_le dev_inst_uuid; - struct visorchipset_state state; - struct visorchipset_channel_info chan_info; - u32 reserved1; /* control_vm_id */ - u64 reserved2; - u32 switch_no; /* when devState.attached==1 */ - u32 internal_port_no; /* when devState.attached==1 */ - struct controlvm_message_header pending_msg_hdr;/* CONTROLVM_MESSAGE */ - /** For private use by the bus driver */ - void *bus_driver_context; -}; - -/** Attributes for a particular Supervisor bus. - * (For a service partition acting as the server for buses/devices, there - * is a 1-to-1 relationship between busses and guest partitions.) - * Any visorchipset client can query these attributes using - * visorchipset_get_client_bus_info() or visorchipset_get_bus_info(). - */ -struct visorchipset_bus_info { - struct list_head entry; - u32 bus_no; - struct visorchipset_state state; - struct visorchipset_channel_info chan_info; - uuid_le partition_uuid; - u64 partition_handle; - u8 *name; /* UTF8 */ - u8 *description; /* UTF8 */ - u64 reserved1; - u32 reserved2; - struct { - u32 server:1; - /* Add new fields above. */ - /* Remaining bits in this 32-bit word are unused. */ - } flags; - struct controlvm_message_header pending_msg_hdr;/* CONTROLVM MsgHdr */ - /** For private use by the bus driver */ - void *bus_driver_context; -}; - /* These functions will be called from within visorchipset when certain * events happen. (The implementation of these functions is outside of * visorchipset.) */ struct visorchipset_busdev_notifiers { - void (*bus_create)(u32 bus_no); - void (*bus_destroy)(u32 bus_no); - void (*device_create)(u32 bus_no, u32 dev_no); - void (*device_destroy)(u32 bus_no, u32 dev_no); - void (*device_pause)(u32 bus_no, u32 dev_no); - void (*device_resume)(u32 bus_no, u32 dev_no); + void (*bus_create)(struct visor_device *bus_info); + void (*bus_destroy)(struct visor_device *bus_info); + void (*device_create)(struct visor_device *bus_info); + void (*device_destroy)(struct visor_device *bus_info); + void (*device_pause)(struct visor_device *bus_info); + void (*device_resume)(struct visor_device *bus_info); }; /* These functions live inside visorchipset, and will be called to indicate @@ -128,12 +44,12 @@ struct visorchipset_busdev_notifiers { * -1 = it failed */ struct visorchipset_busdev_responders { - void (*bus_create)(u32 bus_no, int response); - void (*bus_destroy)(u32 bus_no, int response); - void (*device_create)(u32 bus_no, u32 dev_no, int response); - void (*device_destroy)(u32 bus_no, u32 dev_no, int response); - void (*device_pause)(u32 bus_no, u32 dev_no, int response); - void (*device_resume)(u32 bus_no, u32 dev_no, int response); + void (*bus_create)(struct visor_device *p, int response); + void (*bus_destroy)(struct visor_device *p, int response); + void (*device_create)(struct visor_device *p, int response); + void (*device_destroy)(struct visor_device *p, int response); + void (*device_pause)(struct visor_device *p, int response); + void (*device_resume)(struct visor_device *p, int response); }; /** Register functions (in the bus driver) to get called by visorchipset @@ -147,12 +63,6 @@ visorchipset_register_busdev( struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driver_info); -bool visorchipset_get_bus_info(u32 bus_no, - struct visorchipset_bus_info *bus_info); -bool visorchipset_get_device_info(u32 bus_no, u32 dev_no, - struct visorchipset_device_info *dev_info); -bool visorchipset_set_bus_context(u32 bus_no, void *context); - /* visorbus init and exit functions */ int visorbus_init(void); void visorbus_exit(void); diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 2d3e4d6defea..e0dfaa9c955d 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -23,6 +23,7 @@ #include "version.h" #include "visorbus.h" #include <linux/uuid.h> +#include "controlvmchannel.h" #define MYDRVNAME "visorchannel" @@ -44,6 +45,8 @@ struct visorchannel { struct signal_queue_header event_queue; struct signal_queue_header ack_queue; } safe_uis_queue; + uuid_le type; + uuid_le inst; }; /* Creates the struct visorchannel abstraction for a data area in memory, @@ -58,6 +61,9 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, int err; size_t size = sizeof(struct channel_header); + if (physaddr == 0) + return NULL; + channel = kzalloc(sizeof(*channel), gfp); if (!channel) goto cleanup; @@ -186,6 +192,15 @@ visorchannel_get_clientpartition(struct visorchannel *channel) } EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition); +int +visorchannel_set_clientpartition(struct visorchannel *channel, + u64 partition_handle) +{ + channel->chan_hdr.partition_handle = partition_handle; + return 0; +} +EXPORT_SYMBOL_GPL(visorchannel_set_clientpartition); + uuid_le visorchannel_get_uuid(struct visorchannel *channel) { diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index ca22f49f386b..cf35d9d3a9bc 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -26,14 +26,15 @@ #include <linux/uuid.h> #include <linux/crash_dump.h> +#include "channel_guid.h" #include "controlvmchannel.h" #include "controlvmcompletionstatus.h" #include "guestlinuxdebug.h" #include "periodic_work.h" -#include "uisutils.h" #include "version.h" #include "visorbus.h" #include "visorbus_private.h" +#include "vmcallinterface.h" #define CURRENT_FILE_PC VISOR_CHIPSET_PC_visorchipset_main_c @@ -109,17 +110,8 @@ static DEFINE_SEMAPHORE(notifier_lock); static struct cdev file_cdev; static struct visorchannel **file_controlvm_channel; static struct controlvm_message_header g_chipset_msg_hdr; -static const uuid_le spar_diag_pool_channel_protocol_uuid = - SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID; -/* 0xffffff is an invalid Bus/Device number */ -static u32 g_diagpool_bus_no = 0xffffff; -static u32 g_diagpool_dev_no = 0xffffff; static struct controlvm_message_packet g_devicechangestate_packet; -#define is_diagpool_channel(channel_type_guid) \ - (uuid_le_cmp(channel_type_guid,\ - spar_diag_pool_channel_protocol_uuid) == 0) - static LIST_HEAD(bus_info_list); static LIST_HEAD(dev_info_list); @@ -135,22 +127,6 @@ struct visor_controlvm_payload_info { static struct visor_controlvm_payload_info controlvm_payload_info; -/* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE / - * CONTROLVM_DUMP_GETTEXTDUMP / CONTROLVM_DUMP_COMPLETE conversation. - */ -struct visor_livedump_info { - struct controlvm_message_header dumpcapture_header; - struct controlvm_message_header gettextdump_header; - struct controlvm_message_header dumpcomplete_header; - bool gettextdump_outstanding; - u32 crc32; - unsigned long length; - atomic_t buffers_in_use; - unsigned long destination; -}; - -static struct visor_livedump_info livedump_info; - /* The following globals are used to handle the scenario where we are unable to * offload the payload from a controlvm message due to memory requirements. In * this scenario, we simply stash the controlvm message, then attempt to @@ -243,13 +219,13 @@ static void parahotplug_process_list(void); */ static struct visorchipset_busdev_notifiers busdev_notifiers; -static void bus_create_response(u32 bus_no, int response); -static void bus_destroy_response(u32 bus_no, int response); -static void device_create_response(u32 bus_no, u32 dev_no, int response); -static void device_destroy_response(u32 bus_no, u32 dev_no, int response); -static void device_resume_response(u32 bus_no, u32 dev_no, int response); +static void bus_create_response(struct visor_device *p, int response); +static void bus_destroy_response(struct visor_device *p, int response); +static void device_create_response(struct visor_device *p, int response); +static void device_destroy_response(struct visor_device *p, int response); +static void device_resume_response(struct visor_device *p, int response); -static void visorchipset_device_pause_response(u32 bus_no, u32 dev_no, +static void visorchipset_device_pause_response(struct visor_device *p, int response); static struct visorchipset_busdev_responders busdev_responders = { @@ -355,11 +331,16 @@ static const struct attribute_group *visorchipset_dev_groups[] = { NULL }; +static void visorchipset_dev_release(struct device *dev) +{ +} + /* /sys/devices/platform/visorchipset */ static struct platform_device visorchipset_platform_device = { .name = "visorchipset", .id = -1, .dev.groups = visorchipset_dev_groups, + .dev.release = visorchipset_dev_release, }; /* Function prototypes */ @@ -707,62 +688,44 @@ static ssize_t remaining_steps_store(struct device *dev, return count; } -static void -bus_info_clear(void *v) -{ - struct visorchipset_bus_info *p = (struct visorchipset_bus_info *) v; - - kfree(p->name); - kfree(p->description); - memset(p, 0, sizeof(struct visorchipset_bus_info)); -} - -static void -dev_info_clear(void *v) -{ - struct visorchipset_device_info *p = - (struct visorchipset_device_info *) v; - - memset(p, 0, sizeof(struct visorchipset_device_info)); -} - -static struct visorchipset_bus_info * -bus_find(struct list_head *list, u32 bus_no) -{ - struct visorchipset_bus_info *p; - - list_for_each_entry(p, list, entry) { - if (p->bus_no == bus_no) - return p; - } - - return NULL; -} +struct visor_busdev { + u32 bus_no; + u32 dev_no; +}; -static struct visorchipset_device_info * -device_find(struct list_head *list, u32 bus_no, u32 dev_no) +static int match_visorbus_dev_by_id(struct device *dev, void *data) { - struct visorchipset_device_info *p; + struct visor_device *vdev = to_visor_device(dev); + struct visor_busdev *id = (struct visor_busdev *)data; + u32 bus_no = id->bus_no; + u32 dev_no = id->dev_no; - list_for_each_entry(p, list, entry) { - if (p->bus_no == bus_no && p->dev_no == dev_no) - return p; - } + if ((vdev->chipset_bus_no == bus_no) && + (vdev->chipset_dev_no == dev_no)) + return 1; - return NULL; + return 0; } - -static void busdevices_del(struct list_head *list, u32 bus_no) +struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, + struct visor_device *from) { - struct visorchipset_device_info *p, *tmp; + struct device *dev; + struct device *dev_start = NULL; + struct visor_device *vdev = NULL; + struct visor_busdev id = { + .bus_no = bus_no, + .dev_no = dev_no + }; - list_for_each_entry_safe(p, tmp, list, entry) { - if (p->bus_no == bus_no) { - list_del(&p->entry); - kfree(p); - } - } + if (from) + dev_start = &from->device; + dev = bus_find_device(&visorbus_type, dev_start, (void *)&id, + match_visorbus_dev_by_id); + if (dev) + vdev = to_visor_device(dev); + return vdev; } +EXPORT_SYMBOL(visorbus_get_device_by_id); static u8 check_chipset_events(void) @@ -810,25 +773,6 @@ visorchipset_register_busdev( EXPORT_SYMBOL_GPL(visorchipset_register_busdev); static void -cleanup_controlvm_structures(void) -{ - struct visorchipset_bus_info *bi, *tmp_bi; - struct visorchipset_device_info *di, *tmp_di; - - list_for_each_entry_safe(bi, tmp_bi, &bus_info_list, entry) { - bus_info_clear(bi); - list_del(&bi->entry); - kfree(bi); - } - - list_for_each_entry_safe(di, tmp_di, &dev_info_list, entry) { - dev_info_clear(di); - list_del(&di->entry); - kfree(di); - } -} - -static void chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; @@ -854,8 +798,6 @@ chipset_init(struct controlvm_message *inmsg) features |= ULTRA_CHIPSET_FEATURE_REPLY; cleanup: - if (rc < 0) - cleanup_controlvm_structures(); if (inmsg->hdr.flags.response_expected) controlvm_respond_chipset_init(&inmsg->hdr, rc, features); } @@ -881,14 +823,6 @@ controlvm_respond(struct controlvm_message_header *msg_hdr, int response) struct controlvm_message outmsg; controlvm_init_response(&outmsg, msg_hdr, response); - /* For DiagPool channel DEVICE_CHANGESTATE, we need to send - * back the deviceChangeState structure in the packet. */ - if (msg_hdr->id == CONTROLVM_DEVICE_CHANGESTATE && - g_devicechangestate_packet.device_change_state.bus_no == - g_diagpool_bus_no && - g_devicechangestate_packet.device_change_state.dev_no == - g_diagpool_dev_no) - outmsg.cmd = g_devicechangestate_packet; if (outmsg.hdr.flags.test_message == 1) return; @@ -933,113 +867,35 @@ enum crash_obj_type { CRASH_BUS, }; -void -visorchipset_save_message(struct controlvm_message *msg, - enum crash_obj_type type) -{ - u32 crash_msg_offset; - u16 crash_msg_count; - - /* get saved message count */ - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_count), - &crash_msg_count, sizeof(u16)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; - } - - if (crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, - crash_msg_count, - POSTCODE_SEVERITY_ERR); - return; - } - - /* get saved crash message offset */ - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_offset), - &crash_msg_offset, sizeof(u32)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; - } - - if (type == CRASH_BUS) { - if (visorchannel_write(controlvm_channel, - crash_msg_offset, - msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; - } - } else { /* CRASH_DEV */ - if (visorchannel_write(controlvm_channel, - crash_msg_offset + - sizeof(struct controlvm_message), msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; - } - } -} -EXPORT_SYMBOL_GPL(visorchipset_save_message); - static void -bus_responder(enum controlvm_id cmd_id, u32 bus_no, int response) +bus_responder(enum controlvm_id cmd_id, + struct controlvm_message_header *pending_msg_hdr, + int response) { - struct visorchipset_bus_info *p; - bool need_clear = false; + if (pending_msg_hdr == NULL) + return; /* no controlvm response needed */ - p = bus_find(&bus_info_list, bus_no); - if (!p) + if (pending_msg_hdr->id != (u32)cmd_id) return; - if (response < 0) { - if ((cmd_id == CONTROLVM_BUS_CREATE) && - (response != (-CONTROLVM_RESP_ERROR_ALREADY_DONE))) - /* undo the row we just created... */ - busdevices_del(&dev_info_list, bus_no); - } else { - if (cmd_id == CONTROLVM_BUS_CREATE) - p->state.created = 1; - if (cmd_id == CONTROLVM_BUS_DESTROY) - need_clear = true; - } - - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) - return; /* no controlvm response needed */ - if (p->pending_msg_hdr.id != (u32)cmd_id) - return; - controlvm_respond(&p->pending_msg_hdr, response); - p->pending_msg_hdr.id = CONTROLVM_INVALID; - if (need_clear) { - bus_info_clear(p); - busdevices_del(&dev_info_list, bus_no); - } + controlvm_respond(pending_msg_hdr, response); } static void device_changestate_responder(enum controlvm_id cmd_id, - u32 bus_no, u32 dev_no, int response, + struct visor_device *p, int response, struct spar_segment_state response_state) { - struct visorchipset_device_info *p; struct controlvm_message outmsg; + u32 bus_no = p->chipset_bus_no; + u32 dev_no = p->chipset_dev_no; - p = device_find(&dev_info_list, bus_no, dev_no); - if (!p) - return; - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) + if (p->pending_msg_hdr == NULL) return; /* no controlvm response needed */ - if (p->pending_msg_hdr.id != cmd_id) + if (p->pending_msg_hdr->id != cmd_id) return; - controlvm_init_response(&outmsg, &p->pending_msg_hdr, response); + controlvm_init_response(&outmsg, p->pending_msg_hdr, response); outmsg.cmd.device_change_state.bus_no = bus_no; outmsg.cmd.device_change_state.dev_no = dev_no; @@ -1048,56 +904,54 @@ device_changestate_responder(enum controlvm_id cmd_id, if (!visorchannel_signalinsert(controlvm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) return; - - p->pending_msg_hdr.id = CONTROLVM_INVALID; } static void -device_responder(enum controlvm_id cmd_id, u32 bus_no, u32 dev_no, int response) +device_responder(enum controlvm_id cmd_id, + struct controlvm_message_header *pending_msg_hdr, + int response) { - struct visorchipset_device_info *p; - bool need_clear = false; - - p = device_find(&dev_info_list, bus_no, dev_no); - if (!p) - return; - if (response >= 0) { - if (cmd_id == CONTROLVM_DEVICE_CREATE) - p->state.created = 1; - if (cmd_id == CONTROLVM_DEVICE_DESTROY) - need_clear = true; - } - - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) + if (pending_msg_hdr == NULL) return; /* no controlvm response needed */ - if (p->pending_msg_hdr.id != (u32)cmd_id) + if (pending_msg_hdr->id != (u32)cmd_id) return; - controlvm_respond(&p->pending_msg_hdr, response); - p->pending_msg_hdr.id = CONTROLVM_INVALID; - if (need_clear) - dev_info_clear(p); + controlvm_respond(pending_msg_hdr, response); } static void -bus_epilog(u32 bus_no, +bus_epilog(struct visor_device *bus_info, u32 cmd, struct controlvm_message_header *msg_hdr, int response, bool need_response) { - struct visorchipset_bus_info *bus_info; bool notified = false; + struct controlvm_message_header *pmsg_hdr = NULL; - bus_info = bus_find(&bus_info_list, bus_no); + if (!bus_info) { + /* relying on a valid passed in response code */ + /* be lazy and re-use msg_hdr for this failure, is this ok?? */ + pmsg_hdr = msg_hdr; + goto away; + } - if (!bus_info) - return; + if (bus_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + pmsg_hdr = bus_info->pending_msg_hdr; + goto away; + } if (need_response) { - memcpy(&bus_info->pending_msg_hdr, msg_hdr, + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + goto away; + } + + memcpy(pmsg_hdr, msg_hdr, sizeof(struct controlvm_message_header)); - } else { - bus_info->pending_msg_hdr.id = CONTROLVM_INVALID; + bus_info->pending_msg_hdr = pmsg_hdr; } down(¬ifier_lock); @@ -1105,18 +959,19 @@ bus_epilog(u32 bus_no, switch (cmd) { case CONTROLVM_BUS_CREATE: if (busdev_notifiers.bus_create) { - (*busdev_notifiers.bus_create) (bus_no); + (*busdev_notifiers.bus_create) (bus_info); notified = true; } break; case CONTROLVM_BUS_DESTROY: if (busdev_notifiers.bus_destroy) { - (*busdev_notifiers.bus_destroy) (bus_no); + (*busdev_notifiers.bus_destroy) (bus_info); notified = true; } break; } } +away: if (notified) /* The callback function just called above is responsible * for calling the appropriate visorchipset_busdev_responders @@ -1124,35 +979,51 @@ bus_epilog(u32 bus_no, */ ; else - bus_responder(cmd, bus_no, response); + /* + * Do not kfree(pmsg_hdr) as this is the failure path. + * The success path ('notified') will call the responder + * directly and kfree() there. + */ + bus_responder(cmd, pmsg_hdr, response); up(¬ifier_lock); } static void -device_epilog(u32 bus_no, u32 dev_no, struct spar_segment_state state, u32 cmd, +device_epilog(struct visor_device *dev_info, + struct spar_segment_state state, u32 cmd, struct controlvm_message_header *msg_hdr, int response, bool need_response, bool for_visorbus) { struct visorchipset_busdev_notifiers *notifiers; bool notified = false; + struct controlvm_message_header *pmsg_hdr = NULL; - struct visorchipset_device_info *dev_info = - device_find(&dev_info_list, bus_no, dev_no); - char *envp[] = { - "SPARSP_DIAGPOOL_PAUSED_STATE = 1", - NULL - }; + notifiers = &busdev_notifiers; - if (!dev_info) - return; + if (!dev_info) { + /* relying on a valid passed in response code */ + /* be lazy and re-use msg_hdr for this failure, is this ok?? */ + pmsg_hdr = msg_hdr; + goto away; + } - notifiers = &busdev_notifiers; + if (dev_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + pmsg_hdr = dev_info->pending_msg_hdr; + goto away; + } if (need_response) { - memcpy(&dev_info->pending_msg_hdr, msg_hdr, + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + goto away; + } + + memcpy(pmsg_hdr, msg_hdr, sizeof(struct controlvm_message_header)); - } else { - dev_info->pending_msg_hdr.id = CONTROLVM_INVALID; + dev_info->pending_msg_hdr = pmsg_hdr; } down(¬ifier_lock); @@ -1160,7 +1031,7 @@ device_epilog(u32 bus_no, u32 dev_no, struct spar_segment_state state, u32 cmd, switch (cmd) { case CONTROLVM_DEVICE_CREATE: if (notifiers->device_create) { - (*notifiers->device_create) (bus_no, dev_no); + (*notifiers->device_create) (dev_info); notified = true; } break; @@ -1170,8 +1041,7 @@ device_epilog(u32 bus_no, u32 dev_no, struct spar_segment_state state, u32 cmd, state.operating == segment_state_running.operating) { if (notifiers->device_resume) { - (*notifiers->device_resume) (bus_no, - dev_no); + (*notifiers->device_resume) (dev_info); notified = true; } } @@ -1183,35 +1053,20 @@ device_epilog(u32 bus_no, u32 dev_no, struct spar_segment_state state, u32 cmd, * where server is lost */ if (notifiers->device_pause) { - (*notifiers->device_pause) (bus_no, - dev_no); + (*notifiers->device_pause) (dev_info); notified = true; } - } else if (state.alive == segment_state_paused.alive && - state.operating == - segment_state_paused.operating) { - /* this is lite pause where channel is - * still valid just 'pause' of it - */ - if (bus_no == g_diagpool_bus_no && - dev_no == g_diagpool_dev_no) { - /* this will trigger the - * diag_shutdown.sh script in - * the visorchipset hotplug */ - kobject_uevent_env - (&visorchipset_platform_device.dev. - kobj, KOBJ_ONLINE, envp); - } } break; case CONTROLVM_DEVICE_DESTROY: if (notifiers->device_destroy) { - (*notifiers->device_destroy) (bus_no, dev_no); + (*notifiers->device_destroy) (dev_info); notified = true; } break; } } +away: if (notified) /* The callback function just called above is responsible * for calling the appropriate visorchipset_busdev_responders @@ -1219,7 +1074,12 @@ device_epilog(u32 bus_no, u32 dev_no, struct spar_segment_state state, u32 cmd, */ ; else - device_responder(cmd, bus_no, dev_no, response); + /* + * Do not kfree(pmsg_hdr) as this is the failure path. + * The success path ('notified') will call the responder + * directly and kfree() there. + */ + device_responder(cmd, pmsg_hdr, response); up(¬ifier_lock); } @@ -1229,9 +1089,10 @@ bus_create(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no = cmd->create_bus.bus_no; int rc = CONTROLVM_RESP_SUCCESS; - struct visorchipset_bus_info *bus_info; + struct visor_device *bus_info; + struct visorchannel *visorchannel; - bus_info = bus_find(&bus_info_list, bus_no); + bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); @@ -1246,29 +1107,31 @@ bus_create(struct controlvm_message *inmsg) goto cleanup; } - INIT_LIST_HEAD(&bus_info->entry); - bus_info->bus_no = bus_no; + INIT_LIST_HEAD(&bus_info->list_all); + bus_info->chipset_bus_no = bus_no; + bus_info->chipset_dev_no = BUS_ROOT_DEVICE; POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.flags.test_message == 1) - bus_info->chan_info.addr_type = ADDRTYPE_LOCALTEST; - else - bus_info->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; - - bus_info->flags.server = inmsg->hdr.flags.server; - bus_info->chan_info.channel_addr = cmd->create_bus.channel_addr; - bus_info->chan_info.n_channel_bytes = cmd->create_bus.channel_bytes; - bus_info->chan_info.channel_type_uuid = - cmd->create_bus.bus_data_type_uuid; - bus_info->chan_info.channel_inst_uuid = cmd->create_bus.bus_inst_uuid; + visorchannel = visorchannel_create(cmd->create_bus.channel_addr, + cmd->create_bus.channel_bytes, + GFP_KERNEL, + cmd->create_bus.bus_data_type_uuid); - list_add(&bus_info->entry, &bus_info_list); + if (!visorchannel) { + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, + POSTCODE_SEVERITY_ERR); + rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + kfree(bus_info); + bus_info = NULL; + goto cleanup; + } + bus_info->visorchannel = visorchannel; POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); cleanup: - bus_epilog(bus_no, CONTROLVM_BUS_CREATE, &inmsg->hdr, + bus_epilog(bus_info, CONTROLVM_BUS_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1); } @@ -1277,17 +1140,19 @@ bus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no = cmd->destroy_bus.bus_no; - struct visorchipset_bus_info *bus_info; + struct visor_device *bus_info; int rc = CONTROLVM_RESP_SUCCESS; - bus_info = bus_find(&bus_info_list, bus_no); + bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; else if (bus_info->state.created == 0) rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - bus_epilog(bus_no, CONTROLVM_BUS_DESTROY, &inmsg->hdr, + bus_epilog(bus_info, CONTROLVM_BUS_DESTROY, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1); + + /* bus_info is freed as part of the busdevice_release function */ } static void @@ -1296,15 +1161,14 @@ bus_configure(struct controlvm_message *inmsg, { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; - struct visorchipset_bus_info *bus_info; + struct visor_device *bus_info; int rc = CONTROLVM_RESP_SUCCESS; - char s[99]; bus_no = cmd->configure_bus.bus_no; POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); - bus_info = bus_find(&bus_info_list, bus_no); + bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); @@ -1313,21 +1177,21 @@ bus_configure(struct controlvm_message *inmsg, POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - } else if (bus_info->pending_msg_hdr.id != CONTROLVM_INVALID) { + } else if (bus_info->pending_msg_hdr != NULL) { POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; } else { - bus_info->partition_handle = cmd->configure_bus.guest_handle; + visorchannel_set_clientpartition(bus_info->visorchannel, + cmd->configure_bus.guest_handle); bus_info->partition_uuid = parser_id_get(parser_ctx); parser_param_start(parser_ctx, PARSERSTRING_NAME); bus_info->name = parser_string_get(parser_ctx); - visorchannel_uuid_id(&bus_info->partition_uuid, s); POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); } - bus_epilog(bus_no, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, + bus_epilog(bus_info, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1); } @@ -1337,30 +1201,34 @@ my_device_create(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no = cmd->create_device.bus_no; u32 dev_no = cmd->create_device.dev_no; - struct visorchipset_device_info *dev_info; - struct visorchipset_bus_info *bus_info; + struct visor_device *dev_info = NULL; + struct visor_device *bus_info; + struct visorchannel *visorchannel; int rc = CONTROLVM_RESP_SUCCESS; - dev_info = device_find(&dev_info_list, bus_no, dev_no); - if (dev_info && (dev_info->state.created == 1)) { + bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); + if (!bus_info) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto cleanup; } - bus_info = bus_find(&bus_info_list, bus_no); - if (!bus_info) { + + if (bus_info->state.created == 0) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto cleanup; } - if (bus_info->state.created == 0) { + + dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); + if (dev_info && (dev_info->state.created == 1)) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; + rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto cleanup; } + dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1369,33 +1237,35 @@ my_device_create(struct controlvm_message *inmsg) goto cleanup; } - INIT_LIST_HEAD(&dev_info->entry); - dev_info->bus_no = bus_no; - dev_info->dev_no = dev_no; - dev_info->dev_inst_uuid = cmd->create_device.dev_inst_uuid; + dev_info->chipset_bus_no = bus_no; + dev_info->chipset_dev_no = dev_no; + dev_info->inst = cmd->create_device.dev_inst_uuid; + + /* not sure where the best place to set the 'parent' */ + dev_info->device.parent = &bus_info->device; + POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.flags.test_message == 1) - dev_info->chan_info.addr_type = ADDRTYPE_LOCALTEST; - else - dev_info->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; - dev_info->chan_info.channel_addr = cmd->create_device.channel_addr; - dev_info->chan_info.n_channel_bytes = cmd->create_device.channel_bytes; - dev_info->chan_info.channel_type_uuid = - cmd->create_device.data_type_uuid; - dev_info->chan_info.intr = cmd->create_device.intr; - list_add(&dev_info->entry, &dev_info_list); + visorchannel = visorchannel_create(cmd->create_device.channel_addr, + cmd->create_device.channel_bytes, + GFP_KERNEL, + cmd->create_device.data_type_uuid); + + if (!visorchannel) { + POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + POSTCODE_SEVERITY_ERR); + rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + kfree(dev_info); + dev_info = NULL; + goto cleanup; + } + dev_info->visorchannel = visorchannel; + dev_info->channel_type_guid = cmd->create_device.data_type_uuid; POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); cleanup: - /* get the bus and devNo for DiagPool channel */ - if (dev_info && - is_diagpool_channel(dev_info->chan_info.channel_type_uuid)) { - g_diagpool_bus_no = bus_no; - g_diagpool_dev_no = dev_no; - } - device_epilog(bus_no, dev_no, segment_state_running, + device_epilog(dev_info, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, 1); } @@ -1407,10 +1277,10 @@ my_device_changestate(struct controlvm_message *inmsg) u32 bus_no = cmd->device_change_state.bus_no; u32 dev_no = cmd->device_change_state.dev_no; struct spar_segment_state state = cmd->device_change_state.state; - struct visorchipset_device_info *dev_info; + struct visor_device *dev_info; int rc = CONTROLVM_RESP_SUCCESS; - dev_info = device_find(&dev_info_list, bus_no, dev_no); + dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -1421,7 +1291,7 @@ my_device_changestate(struct controlvm_message *inmsg) rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; } if ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(bus_no, dev_no, state, + device_epilog(dev_info, state, CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, 1); } @@ -1432,17 +1302,17 @@ my_device_destroy(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no = cmd->destroy_device.bus_no; u32 dev_no = cmd->destroy_device.dev_no; - struct visorchipset_device_info *dev_info; + struct visor_device *dev_info; int rc = CONTROLVM_RESP_SUCCESS; - dev_info = device_find(&dev_info_list, bus_no, dev_no); + dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; else if (dev_info->state.created == 0) rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; if ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(bus_no, dev_no, segment_state_running, + device_epilog(dev_info, segment_state_running, CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, 1); } @@ -1530,15 +1400,14 @@ initialize_controlvm_payload(void) /* Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. * Returns CONTROLVM_RESP_xxx code. */ -int +static int visorchipset_chipset_ready(void) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_ONLINE); return CONTROLVM_RESP_SUCCESS; } -EXPORT_SYMBOL_GPL(visorchipset_chipset_ready); -int +static int visorchipset_chipset_selftest(void) { char env_selftest[20]; @@ -1549,18 +1418,16 @@ visorchipset_chipset_selftest(void) envp); return CONTROLVM_RESP_SUCCESS; } -EXPORT_SYMBOL_GPL(visorchipset_chipset_selftest); /* Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset. * Returns CONTROLVM_RESP_xxx code. */ -int +static int visorchipset_chipset_notready(void) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE); return CONTROLVM_RESP_SUCCESS; } -EXPORT_SYMBOL_GPL(visorchipset_chipset_notready); static void chipset_ready(struct controlvm_message_header *msg_hdr) @@ -1931,6 +1798,22 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) return true; } +static inline unsigned int +issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) +{ + struct vmcall_io_controlvm_addr_params params; + int result = VMCALL_SUCCESS; + u64 physaddr; + + physaddr = virt_to_phys(¶ms); + ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR, physaddr, result); + if (VMCALL_SUCCESSFUL(result)) { + *control_addr = params.address; + *control_bytes = params.channel_bytes; + } + return result; +} + static u64 controlvm_get_channel_address(void) { u64 addr = 0; @@ -2132,96 +2015,73 @@ cleanup: } static void -bus_create_response(u32 bus_no, int response) +bus_create_response(struct visor_device *bus_info, int response) { - bus_responder(CONTROLVM_BUS_CREATE, bus_no, response); -} + if (response >= 0) { + bus_info->state.created = 1; + } -static void -bus_destroy_response(u32 bus_no, int response) -{ - bus_responder(CONTROLVM_BUS_DESTROY, bus_no, response); -} + bus_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr, + response); -static void -device_create_response(u32 bus_no, u32 dev_no, int response) -{ - device_responder(CONTROLVM_DEVICE_CREATE, bus_no, dev_no, response); + kfree(bus_info->pending_msg_hdr); + bus_info->pending_msg_hdr = NULL; } static void -device_destroy_response(u32 bus_no, u32 dev_no, int response) +bus_destroy_response(struct visor_device *bus_info, int response) { - device_responder(CONTROLVM_DEVICE_DESTROY, bus_no, dev_no, response); -} + bus_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr, + response); -void -visorchipset_device_pause_response(u32 bus_no, u32 dev_no, int response) -{ - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - bus_no, dev_no, response, - segment_state_standby); + kfree(bus_info->pending_msg_hdr); + bus_info->pending_msg_hdr = NULL; } -EXPORT_SYMBOL_GPL(visorchipset_device_pause_response); static void -device_resume_response(u32 bus_no, u32 dev_no, int response) +device_create_response(struct visor_device *dev_info, int response) { - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - bus_no, dev_no, response, - segment_state_running); -} + if (response >= 0) + dev_info->state.created = 1; -bool -visorchipset_get_bus_info(u32 bus_no, struct visorchipset_bus_info *bus_info) -{ - void *p = bus_find(&bus_info_list, bus_no); + device_responder(CONTROLVM_DEVICE_CREATE, dev_info->pending_msg_hdr, + response); - if (!p) - return false; - memcpy(bus_info, p, sizeof(struct visorchipset_bus_info)); - return true; + kfree(dev_info->pending_msg_hdr); } -EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); -bool -visorchipset_set_bus_context(u32 bus_no, void *context) +static void +device_destroy_response(struct visor_device *dev_info, int response) { - struct visorchipset_bus_info *p = bus_find(&bus_info_list, bus_no); + device_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr, + response); - if (!p) - return false; - p->bus_driver_context = context; - return true; + kfree(dev_info->pending_msg_hdr); + dev_info->pending_msg_hdr = NULL; } -EXPORT_SYMBOL_GPL(visorchipset_set_bus_context); -bool -visorchipset_get_device_info(u32 bus_no, u32 dev_no, - struct visorchipset_device_info *dev_info) +static void +visorchipset_device_pause_response(struct visor_device *dev_info, + int response) { - void *p = device_find(&dev_info_list, bus_no, dev_no); + device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, + dev_info, response, + segment_state_standby); - if (!p) - return false; - memcpy(dev_info, p, sizeof(struct visorchipset_device_info)); - return true; + kfree(dev_info->pending_msg_hdr); + dev_info->pending_msg_hdr = NULL; } -EXPORT_SYMBOL_GPL(visorchipset_get_device_info); -bool -visorchipset_set_device_context(u32 bus_no, u32 dev_no, void *context) +static void +device_resume_response(struct visor_device *dev_info, int response) { - struct visorchipset_device_info *p; - - p = device_find(&dev_info_list, bus_no, dev_no); + device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, + dev_info, response, + segment_state_running); - if (!p) - return false; - p->bus_driver_context = context; - return true; + kfree(dev_info->pending_msg_hdr); + dev_info->pending_msg_hdr = NULL; } -EXPORT_SYMBOL_GPL(visorchipset_set_device_context); static ssize_t chipsetready_store(struct device *dev, struct device_attribute *attr, @@ -2315,6 +2175,24 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +static inline s64 issue_vmcall_query_guest_virtual_time_offset(void) +{ + u64 result = VMCALL_SUCCESS; + u64 physaddr = 0; + + ISSUE_IO_VMCALL(VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET, physaddr, + result); + return result; +} + +static inline int issue_vmcall_update_physical_time(u64 adjustment) +{ + int result = VMCALL_SUCCESS; + + ISSUE_IO_VMCALL(VMCALL_UPDATE_PHYSICAL_TIME, adjustment, result); + return result; +} + static long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -2351,7 +2229,7 @@ static const struct file_operations visorchipset_fops = { .mmap = visorchipset_mmap, }; -int +static int visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) { int rc = 0; @@ -2383,28 +2261,24 @@ visorchipset_init(struct acpi_device *acpi_device) { int rc = 0; u64 addr; + int tmp_sz = sizeof(struct spar_controlvm_channel_protocol); + uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; + + addr = controlvm_get_channel_address(); + if (!addr) + return -ENODEV; memset(&busdev_notifiers, 0, sizeof(busdev_notifiers)); memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info)); - memset(&livedump_info, 0, sizeof(livedump_info)); - atomic_set(&livedump_info.buffers_in_use, 0); - addr = controlvm_get_channel_address(); - if (addr) { - int tmp_sz = sizeof(struct spar_controlvm_channel_protocol); - uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; - controlvm_channel = - visorchannel_create_with_lock(addr, tmp_sz, - GFP_KERNEL, uuid); - if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) { - initialize_controlvm_payload(); - } else { - visorchannel_destroy(controlvm_channel); - controlvm_channel = NULL; - return -ENODEV; - } + controlvm_channel = visorchannel_create_with_lock(addr, tmp_sz, + GFP_KERNEL, uuid); + if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( + visorchannel_get_header(controlvm_channel))) { + initialize_controlvm_payload(); } else { + visorchannel_destroy(controlvm_channel); + controlvm_channel = NULL; return -ENODEV; } @@ -2460,7 +2334,7 @@ cleanup: return rc; } -void +static void visorchipset_file_cleanup(dev_t major_dev) { if (file_cdev.ops) @@ -2482,13 +2356,12 @@ visorchipset_exit(struct acpi_device *acpi_device) periodic_controlvm_workqueue = NULL; destroy_controlvm_payload_info(&controlvm_payload_info); - cleanup_controlvm_structures(); - memset(&g_chipset_msg_hdr, 0, sizeof(struct controlvm_message_header)); visorchannel_destroy(controlvm_channel); visorchipset_file_cleanup(visorchipset_platform_device.dev.devt); + platform_device_unregister(&visorchipset_platform_device); POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); return 0; diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h index 59a7459eb962..dc09caf7d075 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/visorbus/vmcallinterface.h @@ -85,10 +85,8 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently * not used much */ #define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \ -do { \ ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \ - MDS_APPOS, postcode); \ -} while (0) + MDS_APPOS, postcode) #endif /* Structures for IO VMCALLs */ diff --git a/drivers/staging/unisys/visorchannel/Kconfig b/drivers/staging/unisys/visorchannel/Kconfig index 8d31bebf039a..3148f6b2a2e9 100644 --- a/drivers/staging/unisys/visorchannel/Kconfig +++ b/drivers/staging/unisys/visorchannel/Kconfig @@ -4,7 +4,6 @@ config UNISYS_VISORCHANNEL tristate "Unisys visorchannel driver" - select UNISYS_VISORUTIL ---help--- If you say Y here, you will enable the Unisys visorchannel driver. diff --git a/drivers/staging/unisys/visorchannel/Makefile b/drivers/staging/unisys/visorchannel/Makefile index e079c96b1cdf..0c0cacbd8843 100644 --- a/drivers/staging/unisys/visorchannel/Makefile +++ b/drivers/staging/unisys/visorchannel/Makefile @@ -7,6 +7,4 @@ obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel.o visorchannel-y := visorchannel_main.o visorchannel_funcs.o ccflags-y += -Idrivers/staging/unisys/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels ccflags-y += -Idrivers/staging/unisys/visorutil diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 115b951bf0d9..d55c3baade53 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -11,7 +11,6 @@ vt6655_stage-y += device_main.o \ dpc.o \ power.o \ srom.o \ - mib.o \ key.o \ rf.o diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 1cdcf49b2445..e00c0605d154 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -362,12 +362,16 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, u8 bb_type) * Return Value: none */ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, - u64 qwBSSTimestamp, u64 qwLocalTSF) + u64 qwBSSTimestamp) { + u64 local_tsf; u64 qwTSFOffset = 0; - if (qwBSSTimestamp != qwLocalTSF) { - qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); + CARDbGetCurrentTSF(pDevice, &local_tsf); + + if (qwBSSTimestamp != local_tsf) { + qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, + local_tsf); /* adjust TSF, HW's TSF add TSF Offset reg */ VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 2dfc41952271..16cca49e680a 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -83,7 +83,7 @@ bool CARDbRadioPowerOff(struct vnt_private *); bool CARDbRadioPowerOn(struct vnt_private *); bool CARDbSetPhyParameter(struct vnt_private *, u8); bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate, - u64 qwBSSTimestamp, u64 qwLocalTSF); + u64 qwBSSTimestamp); bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval); #endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 440537e47121..5cf1b337cba7 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -68,7 +68,6 @@ #include "device_cfg.h" #include "card.h" -#include "mib.h" #include "srom.h" #include "desc.h" #include "key.h" @@ -239,7 +238,6 @@ struct vnt_private { CHIP_TYPE chip_id; void __iomem *PortOffset; - unsigned long dwIsr; u32 memaddr; u32 ioaddr; u32 io_size; @@ -286,11 +284,6 @@ struct vnt_private { unsigned char abyCurrentNetAddr[ETH_ALEN]; __aligned(2) bool bLinkPass; /* link status: OK or fail */ - /* Adapter statistics */ - SStatCounter scStatistic; - /* 802.11 counter */ - SDot11Counters s802_11Counter; - unsigned int uCurrRSSI; unsigned char byCurrSQ; @@ -410,6 +403,10 @@ struct vnt_private { unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ unsigned short wBeaconInterval; + + struct work_struct interrupt_work; + + struct ieee80211_low_level_stats low_stats; }; static inline PDEVICE_RD_INFO alloc_rd_info(void) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 5b3de43bde99..8dbde24eb154 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -32,7 +32,6 @@ * device_free_info - device structure resource free function * device_get_pci_info - get allocated pci io/mem resource * device_print_info - print out resource - * device_intr - interrupt handle function * device_rx_srv - rx service function * device_alloc_rx_buf - rx buffer pre-allocated function * device_free_tx_buf - free tx buffer function @@ -148,7 +147,6 @@ static void vt6655_init_info(struct pci_dev *pcid, static void device_free_info(struct vnt_private *pDevice); static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid); static void device_print_info(struct vnt_private *pDevice); -static irqreturn_t device_intr(int irq, void *dev_instance); #ifdef CONFIG_PM static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); @@ -807,6 +805,10 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) pRD = pRD->next) { if (works++ > 15) break; + + if (!pRD->pRDInfo->skb) + break; + if (vnt_receive_frame(pDevice, pRD)) { if (!device_alloc_rx_buf(pDevice, pRD)) { dev_err(&pDevice->pcid->dev, @@ -912,7 +914,11 @@ static int vnt_int_report_rate(struct vnt_private *priv, if (!(tsr1 & TSR1_TERR)) { info->status.rates[0].idx = idx; - info->flags |= IEEE80211_TX_STAT_ACK; + + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + else + info->flags |= IEEE80211_TX_STAT_ACK; } return 0; @@ -937,9 +943,6 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) /* Only the status of first TD in the chain is correct */ if (pTD->m_td1TD1.byTCR & TCR_STP) { if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { - - vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); - if (!(byTsr1 & TSR1_TERR)) { if (byTsr0 != 0) { pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n", @@ -958,6 +961,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) (int)uIdx, byTsr1, byTsr0); } } + + vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); + device_free_tx_buf(pDevice, pTD); pDevice->iTDUsed[uIdx]--; } @@ -989,10 +995,8 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) skb->len, DMA_TO_DEVICE); } - if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) + if (skb) ieee80211_tx_status_irqsafe(pDevice->hw, skb); - else - dev_kfree_skb_irq(skb); pTDInfo->skb_dma = 0; pTDInfo->skb = NULL; @@ -1051,124 +1055,135 @@ static void vnt_check_bb_vga(struct vnt_private *priv) } } -static irqreturn_t device_intr(int irq, void *dev_instance) +static void vnt_interrupt_process(struct vnt_private *priv) { - struct vnt_private *pDevice = dev_instance; + struct ieee80211_low_level_stats *low_stats = &priv->low_stats; int max_count = 0; - unsigned long dwMIBCounter = 0; - unsigned char byOrgPageSel = 0; - int handled = 0; + u32 mib_counter; + u32 isr; unsigned long flags; - MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); + MACvReadISR(priv->PortOffset, &isr); - if (pDevice->dwIsr == 0) - return IRQ_RETVAL(handled); + if (isr == 0) + return; - if (pDevice->dwIsr == 0xffffffff) { - pr_debug("dwIsr = 0xffff\n"); - return IRQ_RETVAL(handled); + if (isr == 0xffffffff) { + pr_debug("isr = 0xffff\n"); + return; } - handled = 1; - MACvIntDisable(pDevice->PortOffset); + MACvIntDisable(priv->PortOffset); - spin_lock_irqsave(&pDevice->lock, flags); + spin_lock_irqsave(&priv->lock, flags); - /* Make sure current page is 0 */ - VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel); - if (byOrgPageSel == 1) - MACvSelectPage0(pDevice->PortOffset); - else - byOrgPageSel = 0; + /* Read low level stats */ + MACvReadMIBCounter(priv->PortOffset, &mib_counter); + + low_stats->dot11RTSSuccessCount += mib_counter & 0xff; + low_stats->dot11RTSFailureCount += (mib_counter >> 8) & 0xff; + low_stats->dot11ACKFailureCount += (mib_counter >> 16) & 0xff; + low_stats->dot11FCSErrorCount += (mib_counter >> 24) & 0xff; - MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter); /* * TBD.... * Must do this after doing rx/tx, cause ISR bit is slow * than RD/TD write back * update ISR counter */ - STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter); - while (pDevice->dwIsr && pDevice->vif) { - STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); - MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); + while (isr && priv->vif) { + MACvWriteISR(priv->PortOffset, isr); - if (pDevice->dwIsr & ISR_FETALERR) { + if (isr & ISR_FETALERR) { pr_debug(" ISR_FETALERR\n"); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); - device_error(pDevice, pDevice->dwIsr); + VNSvOutPortB(priv->PortOffset + MAC_REG_SOFTPWRCTL, 0); + VNSvOutPortW(priv->PortOffset + + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); + device_error(priv, isr); } - if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) - vnt_check_bb_vga(pDevice); + if (isr & ISR_TBTT) { + if (priv->op_mode != NL80211_IFTYPE_ADHOC) + vnt_check_bb_vga(priv); - pDevice->bBeaconSent = false; - if (pDevice->bEnablePSMode) - PSbIsNextTBTTWakeUp((void *)pDevice); + priv->bBeaconSent = false; + if (priv->bEnablePSMode) + PSbIsNextTBTTWakeUp((void *)priv); - if ((pDevice->op_mode == NL80211_IFTYPE_AP || - pDevice->op_mode == NL80211_IFTYPE_ADHOC) && - pDevice->vif->bss_conf.enable_beacon) { - MACvOneShotTimer1MicroSec(pDevice->PortOffset, - (pDevice->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10); + if ((priv->op_mode == NL80211_IFTYPE_AP || + priv->op_mode == NL80211_IFTYPE_ADHOC) && + priv->vif->bss_conf.enable_beacon) { + MACvOneShotTimer1MicroSec(priv->PortOffset, + (priv->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10); } /* TODO: adhoc PS mode */ } - if (pDevice->dwIsr & ISR_BNTX) { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - pDevice->bIsBeaconBufReadySet = false; - pDevice->cbBeaconBufReadySetCnt = 0; + if (isr & ISR_BNTX) { + if (priv->op_mode == NL80211_IFTYPE_ADHOC) { + priv->bIsBeaconBufReadySet = false; + priv->cbBeaconBufReadySetCnt = 0; } - pDevice->bBeaconSent = true; + priv->bBeaconSent = true; } - if (pDevice->dwIsr & ISR_RXDMA0) - max_count += device_rx_srv(pDevice, TYPE_RXDMA0); + if (isr & ISR_RXDMA0) + max_count += device_rx_srv(priv, TYPE_RXDMA0); - if (pDevice->dwIsr & ISR_RXDMA1) - max_count += device_rx_srv(pDevice, TYPE_RXDMA1); + if (isr & ISR_RXDMA1) + max_count += device_rx_srv(priv, TYPE_RXDMA1); - if (pDevice->dwIsr & ISR_TXDMA0) - max_count += device_tx_srv(pDevice, TYPE_TXDMA0); + if (isr & ISR_TXDMA0) + max_count += device_tx_srv(priv, TYPE_TXDMA0); - if (pDevice->dwIsr & ISR_AC0DMA) - max_count += device_tx_srv(pDevice, TYPE_AC0DMA); + if (isr & ISR_AC0DMA) + max_count += device_tx_srv(priv, TYPE_AC0DMA); - if (pDevice->dwIsr & ISR_SOFTTIMER1) { - if (pDevice->vif->bss_conf.enable_beacon) - vnt_beacon_make(pDevice, pDevice->vif); + if (isr & ISR_SOFTTIMER1) { + if (priv->vif->bss_conf.enable_beacon) + vnt_beacon_make(priv, priv->vif); } /* If both buffers available wake the queue */ - if (AVAIL_TD(pDevice, TYPE_TXDMA0) && - AVAIL_TD(pDevice, TYPE_AC0DMA) && - ieee80211_queue_stopped(pDevice->hw, 0)) - ieee80211_wake_queues(pDevice->hw); + if (AVAIL_TD(priv, TYPE_TXDMA0) && + AVAIL_TD(priv, TYPE_AC0DMA) && + ieee80211_queue_stopped(priv->hw, 0)) + ieee80211_wake_queues(priv->hw); - MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); + MACvReadISR(priv->PortOffset, &isr); - MACvReceive0(pDevice->PortOffset); - MACvReceive1(pDevice->PortOffset); + MACvReceive0(priv->PortOffset); + MACvReceive1(priv->PortOffset); - if (max_count > pDevice->sOpts.int_works) + if (max_count > priv->sOpts.int_works) break; } - if (byOrgPageSel == 1) - MACvSelectPage1(pDevice->PortOffset); + spin_unlock_irqrestore(&priv->lock, flags); - spin_unlock_irqrestore(&pDevice->lock, flags); + MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE); +} - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); +static void vnt_interrupt_work(struct work_struct *work) +{ + struct vnt_private *priv = + container_of(work, struct vnt_private, interrupt_work); - return IRQ_RETVAL(handled); + if (priv->vif) + vnt_interrupt_process(priv); +} + +static irqreturn_t vnt_interrupt(int irq, void *arg) +{ + struct vnt_private *priv = arg; + + if (priv->vif) + schedule_work(&priv->interrupt_work); + + return IRQ_HANDLED; } static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) @@ -1199,14 +1214,6 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) if (dma_idx == TYPE_AC0DMA) head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; - priv->iTDUsed[dma_idx]++; - - /* Take ownership */ - wmb(); - head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; - - /* get Next */ - wmb(); priv->apCurrTD[dma_idx] = head_td->next; spin_unlock_irqrestore(&priv->lock, flags); @@ -1227,11 +1234,18 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); + /* Poll Transmit the adapter */ + wmb(); + head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); /* second memory barrier */ + if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) MACvTransmitAC0(priv->PortOffset); else MACvTransmit0(priv->PortOffset); + priv->iTDUsed[dma_idx]++; + spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -1261,7 +1275,7 @@ static int vnt_start(struct ieee80211_hw *hw) if (!device_init_rings(priv)) return -ENOMEM; - ret = request_irq(priv->pcid->irq, &device_intr, + ret = request_irq(priv->pcid->irq, &vnt_interrupt, IRQF_SHARED, "vt6655", priv); if (ret) { dev_dbg(&priv->pcid->dev, "failed to start irq\n"); @@ -1290,6 +1304,8 @@ static void vnt_stop(struct ieee80211_hw *hw) ieee80211_stop_queues(hw); + cancel_work_sync(&priv->interrupt_work); + MACbShutdown(priv->PortOffset); MACbSoftwareReset(priv->PortOffset); CARDbRadioPowerOff(priv); @@ -1411,9 +1427,16 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, priv->current_aid = conf->aid; - if (changed & BSS_CHANGED_BSSID) + if (changed & BSS_CHANGED_BSSID) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid); + spin_unlock_irqrestore(&priv->lock, flags); + } + if (changed & BSS_CHANGED_BASIC_RATES) { priv->basic_rates = conf->basic_rates; @@ -1472,7 +1495,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) { if (conf->assoc) { CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, - conf->sync_device_ts, conf->sync_tsf); + conf->sync_tsf); CARDbSetBeaconPeriod(priv, conf->beacon_int); @@ -1596,6 +1619,16 @@ static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return 0; } +static int vnt_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct vnt_private *priv = hw->priv; + + memcpy(stats, &priv->low_stats, sizeof(*stats)); + + return 0; +} + static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct vnt_private *priv = hw->priv; @@ -1633,6 +1666,7 @@ static const struct ieee80211_ops vnt_mac_ops = { .prepare_multicast = vnt_prepare_multicast, .configure_filter = vnt_configure, .set_key = vnt_set_key, + .get_stats = vnt_get_stats, .get_tsf = vnt_get_tsf, .set_tsf = vnt_set_tsf, .reset_tsf = vnt_reset_tsf, @@ -1758,6 +1792,8 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) return -ENODEV; } + INIT_WORK(&priv->interrupt_work, vnt_interrupt_work); + /* do reset */ if (!MACbSoftwareReset(priv->PortOffset)) { dev_err(&pcid->dev, ": Failed to access MAC hardware..\n"); diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c deleted file mode 100644 index d55c762027ed..000000000000 --- a/drivers/staging/vt6655/mib.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: mib.c - * - * Purpose: Implement MIB Data Structure - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * STAvUpdateIstStatCounter - Update ISR statistic counter - * STAvUpdate802_11Counter - Update 802.11 mib counter - * - * Revision History: - * - */ - -#include "mac.h" -#include "mib.h" - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Update Isr Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * wisr - Interrupt status - * Out: - * none - * - * Return Value: none - * - */ -void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr) -{ - /**********************/ - /* ABNORMAL interrupt */ - /**********************/ - /* not any IMR bit invoke irq */ - - if (dwIsr == 0) { - pStatistic->ISRStat.dwIsrUnknown++; - return; - } - -/* Added by Kyle */ - if (dwIsr & ISR_TXDMA0) /* ISR, bit0 */ - pStatistic->ISRStat.dwIsrTx0OK++; /* TXDMA0 successful */ - - if (dwIsr & ISR_AC0DMA) /* ISR, bit1 */ - pStatistic->ISRStat.dwIsrAC0TxOK++; /* AC0DMA successful */ - - if (dwIsr & ISR_BNTX) /* ISR, bit2 */ - pStatistic->ISRStat.dwIsrBeaconTxOK++; /* BeaconTx successful */ - - if (dwIsr & ISR_RXDMA0) /* ISR, bit3 */ - pStatistic->ISRStat.dwIsrRx0OK++; /* Rx0 successful */ - - if (dwIsr & ISR_TBTT) /* ISR, bit4 */ - pStatistic->ISRStat.dwIsrTBTTInt++; /* TBTT successful */ - - if (dwIsr & ISR_SOFTTIMER) /* ISR, bit6 */ - pStatistic->ISRStat.dwIsrSTIMERInt++; - - if (dwIsr & ISR_WATCHDOG) /* ISR, bit7 */ - pStatistic->ISRStat.dwIsrWatchDog++; - - if (dwIsr & ISR_FETALERR) /* ISR, bit8 */ - pStatistic->ISRStat.dwIsrUnrecoverableError++; - - if (dwIsr & ISR_SOFTINT) /* ISR, bit9 */ - pStatistic->ISRStat.dwIsrSoftInterrupt++; /* software interrupt */ - - if (dwIsr & ISR_MIBNEARFULL) /* ISR, bit10 */ - pStatistic->ISRStat.dwIsrMIBNearfull++; - - if (dwIsr & ISR_RXNOBUF) /* ISR, bit11 */ - pStatistic->ISRStat.dwIsrRxNoBuf++; /* Rx No Buff */ - - if (dwIsr & ISR_RXDMA1) /* ISR, bit12 */ - pStatistic->ISRStat.dwIsrRx1OK++; /* Rx1 successful */ - - if (dwIsr & ISR_SOFTTIMER1) /* ISR, bit21 */ - pStatistic->ISRStat.dwIsrSTIMER1Int++; -} - -/* - * Description: Update 802.11 mib counter - * - * Parameters: - * In: - * p802_11Counter - Pointer to 802.11 mib counter - * pStatistic - Pointer to Statistic Counter Data Structure - * dwCounter - hardware counter for 802.11 mib - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdate802_11Counter( - PSDot11Counters p802_11Counter, - PSStatCounter pStatistic, - unsigned long dwCounter -) -{ - p802_11Counter->RTSSuccessCount += (unsigned long long) (dwCounter & 0x000000ff); - p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8); - p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16); - p802_11Counter->FCSErrorCount += (unsigned long long) ((dwCounter & 0xff000000) >> 24); -} diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h deleted file mode 100644 index 5cb59b8a1c7c..000000000000 --- a/drivers/staging/vt6655/mib.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: mib.h - * - * Purpose: Implement MIB Data Structure - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __MIB_H__ -#define __MIB_H__ - -#include "desc.h" - -// -// 802.11 counter -// - -typedef struct tagSDot11Counters { - unsigned long long RTSSuccessCount; - unsigned long long RTSFailureCount; - unsigned long long ACKFailureCount; - unsigned long long FCSErrorCount; -} SDot11Counters, *PSDot11Counters; - -// -// Custom counter -// -typedef struct tagSISRCounters { - unsigned long dwIsrTx0OK; - unsigned long dwIsrAC0TxOK; - unsigned long dwIsrBeaconTxOK; - unsigned long dwIsrRx0OK; - unsigned long dwIsrTBTTInt; - unsigned long dwIsrSTIMERInt; - unsigned long dwIsrWatchDog; - unsigned long dwIsrUnrecoverableError; - unsigned long dwIsrSoftInterrupt; - unsigned long dwIsrMIBNearfull; - unsigned long dwIsrRxNoBuf; - - unsigned long dwIsrUnknown; - - unsigned long dwIsrRx1OK; - unsigned long dwIsrSTIMER1Int; -} SISRCounters, *PSISRCounters; - -// -// statistic counter -// -typedef struct tagSStatCounter { - SISRCounters ISRStat; -} SStatCounter, *PSStatCounter; - -void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr); - -void STAvUpdate802_11Counter( - PSDot11Counters p802_11Counter, - PSStatCounter pStatistic, - unsigned long dwCounter -); - -#endif // __MIB_H__ diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index f71d59fa3b21..635d931de409 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -364,7 +364,7 @@ struct vnt_private { /* Power save */ u16 current_aid; - /* Beacon releated */ + /* Beacon related */ u16 seq_counter; enum vnt_cmd_state command_state; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index f6c2cf8590c4..5c589962a1e8 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -805,10 +805,18 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) vnt_schedule_command(priv, WLAN_CMD_SETPOWER); } - if (current_rate > RATE_11M) - pkt_type = priv->packet_type; - else + if (current_rate > RATE_11M) { + if (info->band == IEEE80211_BAND_5GHZ) { + pkt_type = PK_TYPE_11A; + } else { + if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) + pkt_type = PK_TYPE_11GB; + else + pkt_type = PK_TYPE_11GA; + } + } else { pkt_type = PK_TYPE_11B; + } spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig new file mode 100644 index 000000000000..c246b0d904df --- /dev/null +++ b/drivers/staging/wilc1000/Kconfig @@ -0,0 +1,58 @@ +config WILC1000 + tristate "WILC1000 support (WiFi only)" + depends on !S390 + depends on CFG80211 && WEXT_CORE && INET + depends on MMC || SPI + ---help--- + This module only support IEEE 802.11n WiFi. + +choice + prompt "Memory Allocation" + depends on WILC1000 + default WILC1000_PREALLOCATE_AT_LOADING_DRIVER + +config WILC1000_PREALLOCATE_AT_LOADING_DRIVER + bool "Preallocate memory at loading driver" + ---help--- + This choice supports static allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + during initial time. The driver will also free the buffer + by calling network device stop. + +config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY + bool "Dynamically allocate memory in real time" + ---help--- + This choice supports dynamic allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + when it is required. +endchoice + +choice + prompt "Bus Type" + depends on WILC1000 + default WILC1000_SDIO + + config WILC1000_SDIO + bool "SDIO support" + depends on MMC + ---help--- + This module adds support for the SDIO interface + of adapters using WILC chipset. Select this if + your platform is using the SDIO bus. + + config WILC1000_SPI + depends on SPI + bool "SPI support" + ---help--- + This module adds support for the SPI interface + of adapters using WILC chipset. Select this if + your platform is using the SPI bus. +endchoice + +config WILC1000_HW_OOB_INTR + bool "Use out of band interrupt" + depends on WILC1000 && WILC1000_SDIO + default n + ---help--- + If your platform don't recognize SDIO IRQ, connect chipset external IRQ pin + and check this option. Or, Use this to get all interrupts including SDIO interrupts. diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile new file mode 100644 index 000000000000..a78c4d529a58 --- /dev/null +++ b/drivers/staging/wilc1000/Makefile @@ -0,0 +1,34 @@ +obj-$(CONFIG_WILC1000) += wilc1000.o +obj-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += wilc_exported_buf.o + + +ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT +ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO +ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI + +ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ + -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ + -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" + +ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \ + -DPLL_WORKAROUND -DCONNECT_DIRECT -DAGING_ALG \ + -DWILC_PARSE_SCAN_IN_HOST -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP \ + -Wno-unused-function -DUSE_WIRELESS -DWILC_DEBUGFS +#ccflags-y += -DTCP_ACK_FILTER + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_BOOT + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_INSMOD + +ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC + + +wilc1000-objs := wilc_wfi_netdevice.o wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ + wilc_memory.o wilc_msgqueue.o wilc_sleep.o wilc_strutils.o \ + wilc_timer.o coreconfigurator.o host_interface.o \ + fifo_buffer.o wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o + +wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o +wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o diff --git a/drivers/staging/wilc1000/TODO b/drivers/staging/wilc1000/TODO new file mode 100644 index 000000000000..95199d80a3e4 --- /dev/null +++ b/drivers/staging/wilc1000/TODO @@ -0,0 +1,14 @@ +TODO: +- remove the defined feature as kernel versions +- remove OS wrapper functions +- remove custom debug and tracing functions +- rework comments and function headers(also coding style) +- replace all semaphores with mutexes or completions +- make spi and sdio components coexist in one build +- turn compile-time platform configuration (BEAGLE_BOARD, + PANDA_BOARD, PLAT_WMS8304, PLAT_RKXXXX, CUSTOMER_PLATFORM, ...) + into run-time options that are read from DT +- support soft-ap and p2p mode +- support resume/suspend function +- replace SIOCDEVPRIVATE commands with generic API functions +- use wext-core handling instead of private SIOCSIWPRIV implementation diff --git a/drivers/staging/wilc1000/coreconfigsimulator.h b/drivers/staging/wilc1000/coreconfigsimulator.h new file mode 100644 index 000000000000..6c3f431314fa --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigsimulator.h @@ -0,0 +1,20 @@ + +/*! + * @file coreconfigsimulator.h + * @brief + * @author + * @sa coreconfigsimulator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGSIMULATOR_H +#define CORECONFIGSIMULATOR_H + + +extern WILC_Sint32 CoreConfigSimulatorInit (void); +extern WILC_Sint32 CoreConfigSimulatorDeInit (void); + + +#endif
\ No newline at end of file diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c new file mode 100644 index 000000000000..3a6c5baf0abb --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -0,0 +1,2187 @@ + +/*! + * @file coreconfigurator.c + * @brief + * @author + * @sa coreconfigurator.h + * @date 1 Mar 2012 + * @version 1.0 + */ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include "itypes.h" +#include "coreconfigurator.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +#define INLINE static __inline +#define PHY_802_11n +#define MAX_CFG_PKTLEN 1450 +#define MSG_HEADER_LEN 4 +#define QUERY_MSG_TYPE 'Q' +#define WRITE_MSG_TYPE 'W' +#define RESP_MSG_TYPE 'R' +#define WRITE_RESP_SUCCESS 1 +#define INVALID 255 +#define MAC_ADDR_LEN 6 +#define TAG_PARAM_OFFSET (MAC_HDR_LEN + TIME_STAMP_LEN + \ + BEACON_INTERVAL_LEN + CAP_INFO_LEN) + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/* Basic Frame Type Codes (2-bit) */ +typedef enum { + FRAME_TYPE_CONTROL = 0x04, + FRAME_TYPE_DATA = 0x08, + FRAME_TYPE_MANAGEMENT = 0x00, + FRAME_TYPE_RESERVED = 0x0C, + FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuBasicFrmType; + +/* Frame Type and Subtype Codes (6-bit) */ +typedef enum { + ASSOC_REQ = 0x00, + ASSOC_RSP = 0x10, + REASSOC_REQ = 0x20, + REASSOC_RSP = 0x30, + PROBE_REQ = 0x40, + PROBE_RSP = 0x50, + BEACON = 0x80, + ATIM = 0x90, + DISASOC = 0xA0, + AUTH = 0xB0, + DEAUTH = 0xC0, + ACTION = 0xD0, + PS_POLL = 0xA4, + RTS = 0xB4, + CTS = 0xC4, + ACK = 0xD4, + CFEND = 0xE4, + CFEND_ACK = 0xF4, + DATA = 0x08, + DATA_ACK = 0x18, + DATA_POLL = 0x28, + DATA_POLL_ACK = 0x38, + NULL_FRAME = 0x48, + CFACK = 0x58, + CFPOLL = 0x68, + CFPOLL_ACK = 0x78, + QOS_DATA = 0x88, + QOS_DATA_ACK = 0x98, + QOS_DATA_POLL = 0xA8, + QOS_DATA_POLL_ACK = 0xB8, + QOS_NULL_FRAME = 0xC8, + QOS_CFPOLL = 0xE8, + QOS_CFPOLL_ACK = 0xF8, + BLOCKACK_REQ = 0x84, + BLOCKACK = 0x94, + FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuFrmSubtype; + +/* Basic Frame Classes */ +typedef enum { + CLASS1_FRAME_TYPE = 0x00, + CLASS2_FRAME_TYPE = 0x01, + CLASS3_FRAME_TYPE = 0x02, + FRAME_CLASS_FORCE_32BIT = 0xFFFFFFFF +} tenuFrameClass; + +/* Element ID of various Information Elements */ +typedef enum { + ISSID = 0, /* Service Set Identifier */ + ISUPRATES = 1, /* Supported Rates */ + IFHPARMS = 2, /* FH parameter set */ + IDSPARMS = 3, /* DS parameter set */ + ICFPARMS = 4, /* CF parameter set */ + ITIM = 5, /* Traffic Information Map */ + IIBPARMS = 6, /* IBSS parameter set */ + ICOUNTRY = 7, /* Country element */ + IEDCAPARAMS = 12, /* EDCA parameter set */ + ITSPEC = 13, /* Traffic Specification */ + ITCLAS = 14, /* Traffic Classification */ + ISCHED = 15, /* Schedule */ + ICTEXT = 16, /* Challenge Text */ + IPOWERCONSTRAINT = 32, /* Power Constraint */ + IPOWERCAPABILITY = 33, /* Power Capability */ + ITPCREQUEST = 34, /* TPC Request */ + ITPCREPORT = 35, /* TPC Report */ + ISUPCHANNEL = 36, /* Supported channel list */ + ICHSWANNOUNC = 37, /* Channel Switch Announcement */ + IMEASUREMENTREQUEST = 38, /* Measurement request */ + IMEASUREMENTREPORT = 39, /* Measurement report */ + IQUIET = 40, /* Quiet element Info */ + IIBSSDFS = 41, /* IBSS DFS */ + IERPINFO = 42, /* ERP Information */ + ITSDELAY = 43, /* TS Delay */ + ITCLASPROCESS = 44, /* TCLAS Processing */ + IHTCAP = 45, /* HT Capabilities */ + IQOSCAP = 46, /* QoS Capability */ + IRSNELEMENT = 48, /* RSN Information Element */ + IEXSUPRATES = 50, /* Extended Supported Rates */ + IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/ + IHTOPERATION = 61, /* HT Information */ + ISECCHOFF = 62, /* Secondary Channel Offeset */ + I2040COEX = 72, /* 20/40 Coexistence IE */ + I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/ + IOBSSSCAN = 74, /* OBSS Scan parameters */ + IEXTCAP = 127, /* Extended capability */ + IWMM = 221, /* WMM parameters */ + IWPAELEMENT = 221, /* WPA Information Element */ + INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF +} tenuInfoElemID; + + +typedef struct { + WILC_Char *pcRespBuffer; + WILC_Sint32 s32MaxRespBuffLen; + WILC_Sint32 s32BytesRead; + WILC_Bool bRespRequired; +} tstrConfigPktInfo; + + + +/*****************************************************************************/ +/* Extern Variable Declarations */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Extern Function Declarations */ +/*****************************************************************************/ +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *ps8Packet, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); +extern void GnrlAsyncInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); +extern void host_int_ScanCompleteReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); +/*****************************************************************************/ +/* Global Variables */ +/*****************************************************************************/ +static struct semaphore SemHandleSendPkt; +static struct semaphore SemHandlePktResp; + +static WILC_Sint8 *gps8ConfigPacket; + +static tstrConfigPktInfo gstrConfigPktInfo; + +static u8 g_seqno; + +static WILC_Sint16 g_wid_num = -1; + +static WILC_Uint16 Res_Len; + +static u8 g_oper_mode = SET_CFG; + +/* WID Switches */ +static tstrWID gastrWIDs[] = { + {WID_FIRMWARE_VERSION, WID_STR}, + {WID_PHY_VERSION, WID_STR}, + {WID_HARDWARE_VERSION, WID_STR}, + {WID_BSS_TYPE, WID_CHAR}, + {WID_QOS_ENABLE, WID_CHAR}, + {WID_11I_MODE, WID_CHAR}, + {WID_CURRENT_TX_RATE, WID_CHAR}, + {WID_LINKSPEED, WID_CHAR}, + {WID_RTS_THRESHOLD, WID_SHORT}, + {WID_FRAG_THRESHOLD, WID_SHORT}, + {WID_SSID, WID_STR}, + {WID_BSSID, WID_ADR}, + {WID_BEACON_INTERVAL, WID_SHORT}, + {WID_POWER_MANAGEMENT, WID_CHAR}, + {WID_LISTEN_INTERVAL, WID_CHAR}, + {WID_DTIM_PERIOD, WID_CHAR}, + {WID_CURRENT_CHANNEL, WID_CHAR}, + {WID_TX_POWER_LEVEL_11A, WID_CHAR}, + {WID_TX_POWER_LEVEL_11B, WID_CHAR}, + {WID_PREAMBLE, WID_CHAR}, + {WID_11G_OPERATING_MODE, WID_CHAR}, + {WID_MAC_ADDR, WID_ADR}, + {WID_IP_ADDRESS, WID_ADR}, + {WID_ACK_POLICY, WID_CHAR}, + {WID_PHY_ACTIVE_REG, WID_CHAR}, + {WID_AUTH_TYPE, WID_CHAR}, + {WID_REKEY_POLICY, WID_CHAR}, + {WID_REKEY_PERIOD, WID_INT}, + {WID_REKEY_PACKET_COUNT, WID_INT}, +#if 0 + {WID_WEP_KEY_VALUE0, WID_STR}, +#endif + {WID_11I_PSK, WID_STR}, + {WID_1X_KEY, WID_STR}, + {WID_1X_SERV_ADDR, WID_IP}, + {WID_SUPP_USERNAME, WID_STR}, + {WID_SUPP_PASSWORD, WID_STR}, + {WID_USER_CONTROL_ON_TX_POWER, WID_CHAR}, + {WID_MEMORY_ADDRESS, WID_INT}, + {WID_MEMORY_ACCESS_32BIT, WID_INT}, + {WID_MEMORY_ACCESS_16BIT, WID_SHORT}, + {WID_MEMORY_ACCESS_8BIT, WID_CHAR}, + {WID_SITE_SURVEY_RESULTS, WID_STR}, + {WID_PMKID_INFO, WID_STR}, + {WID_ASSOC_RES_INFO, WID_STR}, + {WID_MANUFACTURER, WID_STR}, /* 4 Wids added for the CAPI tool*/ + {WID_MODEL_NAME, WID_STR}, + {WID_MODEL_NUM, WID_STR}, + {WID_DEVICE_NAME, WID_STR}, + {WID_SSID_PROBE_REQ, WID_STR}, + +#ifdef MAC_802_11N + {WID_11N_ENABLE, WID_CHAR}, + {WID_11N_CURRENT_TX_MCS, WID_CHAR}, + {WID_TX_POWER_LEVEL_11N, WID_CHAR}, + {WID_11N_OPERATING_MODE, WID_CHAR}, + {WID_11N_SMPS_MODE, WID_CHAR}, + {WID_11N_PROT_MECH, WID_CHAR}, + {WID_11N_ERP_PROT_TYPE, WID_CHAR}, + {WID_11N_HT_PROT_TYPE, WID_CHAR}, + {WID_11N_PHY_ACTIVE_REG_VAL, WID_INT}, + {WID_11N_PRINT_STATS, WID_CHAR}, + {WID_11N_AUTORATE_TABLE, WID_BIN_DATA}, + {WID_HOST_CONFIG_IF_TYPE, WID_CHAR}, + {WID_HOST_DATA_IF_TYPE, WID_CHAR}, + {WID_11N_SIG_QUAL_VAL, WID_SHORT}, + {WID_11N_IMMEDIATE_BA_ENABLED, WID_CHAR}, + {WID_11N_TXOP_PROT_DISABLE, WID_CHAR}, + {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR}, + {WID_SHORT_SLOT_ALLOWED, WID_CHAR}, + {WID_11W_ENABLE, WID_CHAR}, + {WID_11W_MGMT_PROT_REQ, WID_CHAR}, + {WID_2040_ENABLE, WID_CHAR}, + {WID_2040_COEXISTENCE, WID_CHAR}, + {WID_USER_SEC_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_CURR_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_40MHZ_INTOLERANT, WID_CHAR}, + {WID_HUT_RESTART, WID_CHAR}, + {WID_HUT_NUM_TX_PKTS, WID_INT}, + {WID_HUT_FRAME_LEN, WID_SHORT}, + {WID_HUT_TX_FORMAT, WID_CHAR}, + {WID_HUT_BANDWIDTH, WID_CHAR}, + {WID_HUT_OP_BAND, WID_CHAR}, + {WID_HUT_STBC, WID_CHAR}, + {WID_HUT_ESS, WID_CHAR}, + {WID_HUT_ANTSET, WID_CHAR}, + {WID_HUT_HT_OP_MODE, WID_CHAR}, + {WID_HUT_RIFS_MODE, WID_CHAR}, + {WID_HUT_SMOOTHING_REC, WID_CHAR}, + {WID_HUT_SOUNDING_PKT, WID_CHAR}, + {WID_HUT_HT_CODING, WID_CHAR}, + {WID_HUT_TEST_DIR, WID_CHAR}, + {WID_HUT_TXOP_LIMIT, WID_SHORT}, + {WID_HUT_DEST_ADDR, WID_ADR}, + {WID_HUT_TX_PATTERN, WID_BIN_DATA}, + {WID_HUT_TX_TIME_TAKEN, WID_INT}, + {WID_HUT_PHY_TEST_MODE, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_HI, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_LO, WID_CHAR}, + {WID_HUT_TX_TEST_TIME, WID_INT}, + {WID_HUT_LOG_INTERVAL, WID_INT}, + {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR}, + {WID_HUT_TEST_ID, WID_STR}, + {WID_HUT_KEY_ORIGIN, WID_CHAR}, + {WID_HUT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_GROUP_CIPHER_TYPE, WID_CHAR}, + {WID_HUT_STATS, WID_BIN_DATA}, + {WID_HUT_TSF_TEST_MODE, WID_CHAR}, + {WID_HUT_SIG_QUAL_AVG, WID_SHORT}, + {WID_HUT_SIG_QUAL_AVG_CNT, WID_SHORT}, + {WID_HUT_TSSI_VALUE, WID_CHAR}, + {WID_HUT_MGMT_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_ALLOW_HT, WID_CHAR}, + {WID_HUT_UC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_BC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_UC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_BC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_11W_MFP_REQUIRED_TX, WID_CHAR}, + {WID_HUT_11W_MFP_PEER_CAPABLE, WID_CHAR}, + {WID_HUT_11W_TX_IGTK_ID, WID_CHAR}, + {WID_HUT_FC_TXOP_MOD, WID_CHAR}, + {WID_HUT_FC_PROT_TYPE, WID_CHAR}, + {WID_HUT_SEC_CCA_ASSERT, WID_CHAR}, +#endif /* MAC_802_11N */ +}; + +WILC_Uint16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID)); +/*****************************************************************************/ +/* Static Function Declarations */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ +INLINE u8 ascii_hex_to_dec(u8 num) +{ + if ((num >= '0') && (num <= '9')) + return (num - '0'); + else if ((num >= 'A') && (num <= 'F')) + return (10 + (num - 'A')); + else if ((num >= 'a') && (num <= 'f')) + return (10 + (num - 'a')); + + return INVALID; +} + +INLINE u8 get_hex_char(u8 inp) +{ + u8 *d2htab = "0123456789ABCDEF"; + + return d2htab[inp & 0xF]; +} + +/* This function extracts the MAC address held in a string in standard format */ +/* into another buffer as integers. */ +INLINE WILC_Uint16 extract_mac_addr(WILC_Char *str, u8 *buff) +{ + *buff = 0; + while (*str != '\0') { + if ((*str == ':') || (*str == '-')) + *(++buff) = 0; + else + *buff = (*buff << 4) + ascii_hex_to_dec(*str); + + str++; + } + + return MAC_ADDR_LEN; +} + +/* This function creates MAC address in standard format from a buffer of */ +/* integers. */ +INLINE void create_mac_addr(u8 *str, u8 *buff) +{ + WILC_Uint32 i = 0; + WILC_Uint32 j = 0; + + for (i = 0; i < MAC_ADDR_LEN; i++) { + str[j++] = get_hex_char((u8)((buff[i] >> 4) & 0x0F)); + str[j++] = get_hex_char((u8)(buff[i] & 0x0F)); + str[j++] = ':'; + } + str[--j] = '\0'; +} + +/* This function converts the IP address string in dotted decimal format to */ +/* unsigned integer. This functionality is similar to the library function */ +/* inet_addr() but is reimplemented here since I could not confirm that */ +/* inet_addr is platform independent. */ +/* ips=>IP Address String in dotted decimal format */ +/* ipn=>Pointer to IP Address in integer format */ +INLINE u8 conv_ip_to_int(u8 *ips, WILC_Uint32 *ipn) +{ + u8 i = 0; + u8 ipb = 0; + *ipn = 0; + /* Integer to string for each component */ + while (ips[i] != '\0') { + if (ips[i] == '.') { + *ipn = ((*ipn) << 8) | ipb; + ipb = 0; + } else { + ipb = ipb * 10 + ascii_hex_to_dec(ips[i]); + } + + i++; + } + + /* The last byte of the IP address is read in here */ + *ipn = ((*ipn) << 8) | ipb; + + return 0; +} + +/* This function converts the IP address from integer format to dotted */ +/* decimal string format. Alternative to std library fn inet_ntoa(). */ +/* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B) */ +/* ipn=>IP Address in integer format */ +INLINE u8 conv_int_to_ip(u8 *ips, WILC_Uint32 ipn) +{ + u8 i = 0; + u8 ipb = 0; + u8 cnt = 0; + u8 ipbsize = 0; + + for (cnt = 4; cnt > 0; cnt--) { + ipb = (ipn >> (8 * (cnt - 1))) & 0xFF; + + if (ipb >= 100) + ipbsize = 2; + else if (ipb >= 10) + ipbsize = 1; + else + ipbsize = 0; + + switch (ipbsize) { + case 2: + ips[i++] = get_hex_char(ipb / 100); + ipb %= 100; + + case 1: + ips[i++] = get_hex_char(ipb / 10); + ipb %= 10; + + default: + ips[i++] = get_hex_char(ipb); + } + + if (cnt > 1) + ips[i++] = '.'; + } + + ips[i] = '\0'; + + return i; +} + +INLINE tenuWIDtype get_wid_type(WILC_Uint32 wid_num) +{ + /* Check for iconfig specific WID types first */ + if ((wid_num == WID_BSSID) || + (wid_num == WID_MAC_ADDR) || + (wid_num == WID_IP_ADDRESS) || + (wid_num == WID_HUT_DEST_ADDR)) { + return WID_ADR; + } + + if ((WID_1X_SERV_ADDR == wid_num) || + (WID_STACK_IP_ADDR == wid_num) || + (WID_STACK_NETMASK_ADDR == wid_num)) { + return WID_IP; + } + + /* Next check for standard WID types */ + if (wid_num < 0x1000) + return WID_CHAR; + else if (wid_num < 0x2000) + return WID_SHORT; + else if (wid_num < 0x3000) + return WID_INT; + else if (wid_num < 0x4000) + return WID_STR; + else if (wid_num < 0x5000) + return WID_BIN_DATA; + + return WID_UNDEF; +} + + +/* This function extracts the beacon period field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_beacon_period(u8 *data) +{ + WILC_Uint16 bcn_per = 0; + + bcn_per = data[0]; + bcn_per |= (data[1] << 8); + + return bcn_per; +} + +INLINE WILC_Uint32 get_beacon_timestamp_lo(u8 *data) +{ + WILC_Uint32 time_stamp = 0; + WILC_Uint32 index = MAC_HDR_LEN; + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +INLINE UWORD32 get_beacon_timestamp_hi(UWORD8 *data) +{ + UWORD32 time_stamp = 0; + UWORD32 index = (MAC_HDR_LEN + 4); + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +/* This function extracts the 'frame type' bits from the MAC header of the */ +/* input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuBasicFrmType get_type(u8 *header) +{ + return ((tenuBasicFrmType)(header[0] & 0x0C)); +} + +/* This function extracts the 'frame type and sub type' bits from the MAC */ +/* header of the input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuFrmSubtype get_sub_type(u8 *header) +{ + return ((tenuFrmSubtype)(header[0] & 0xFC)); +} + +/* This function extracts the 'to ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE u8 get_to_ds(u8 *header) +{ + return (header[1] & 0x01); +} + +/* This function extracts the 'from ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE u8 get_from_ds(u8 *header) +{ + return ((header[1] & 0x02) >> 1); +} + +/* This function extracts the MAC Address in 'address1' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address1(u8 *pu8msa, u8 *addr) +{ + WILC_memcpy(addr, pu8msa + 4, 6); +} + +/* This function extracts the MAC Address in 'address2' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address2(u8 *pu8msa, u8 *addr) +{ + WILC_memcpy(addr, pu8msa + 10, 6); +} + +/* This function extracts the MAC Address in 'address3' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address3(u8 *pu8msa, u8 *addr) +{ + WILC_memcpy(addr, pu8msa + 16, 6); +} + +/* This function extracts the BSSID from the incoming WLAN packet based on */ +/* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */ +/* variable. */ +INLINE void get_BSSID(u8 *data, u8 *bssid) +{ + if (get_from_ds(data) == 1) + get_address2(data, bssid); + else if (get_to_ds(data) == 1) + get_address1(data, bssid); + else + get_address3(data, bssid); +} + +/* This function extracts the SSID from a beacon/probe response frame */ +INLINE void get_ssid(u8 *data, u8 *ssid, u8 *p_ssid_len) +{ + u8 len = 0; + u8 i = 0; + u8 j = 0; + + len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 1]; + j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 2; + + /* If the SSID length field is set wrongly to a value greater than the */ + /* allowed maximum SSID length limit, reset the length to 0 */ + if (len >= MAX_SSID_LEN) + len = 0; + + for (i = 0; i < len; i++, j++) + ssid[i] = data[j]; + + ssid[len] = '\0'; + + *p_ssid_len = len; +} + +/* This function extracts the capability info field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_cap_info(u8 *data) +{ + WILC_Uint16 cap_info = 0; + WILC_Uint16 index = MAC_HDR_LEN; + tenuFrmSubtype st = BEACON; + + st = get_sub_type(data); + + /* Location of the Capability field is different for Beacon and */ + /* Association frames. */ + if ((st == BEACON) || (st == PROBE_RSP)) + index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN; + + cap_info = data[index]; + cap_info |= (data[index + 1] << 8); + + return cap_info; +} + +/* This function extracts the capability info field from the Association */ +/* response frame. */ +INLINE WILC_Uint16 get_assoc_resp_cap_info(u8 *data) +{ + WILC_Uint16 cap_info = 0; + + cap_info = data[0]; + cap_info |= (data[1] << 8); + + return cap_info; +} + +/* This funcion extracts the association status code from the incoming */ +/* association response frame and returns association status code */ +INLINE WILC_Uint16 get_asoc_status(u8 *data) +{ + WILC_Uint16 asoc_status = 0; + + asoc_status = data[3]; + asoc_status = (asoc_status << 8) | data[2]; + + return asoc_status; +} + +/* This function extracts association ID from the incoming association */ +/* response frame */ +INLINE WILC_Uint16 get_asoc_id(u8 *data) +{ + WILC_Uint16 asoc_id = 0; + + asoc_id = data[4]; + asoc_id |= (data[5] << 8); + + return asoc_id; +} + +/** + * @brief initializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n"); + + sema_init(&SemHandleSendPkt, 1); + sema_init(&SemHandlePktResp, 0); + + gps8ConfigPacket = (WILC_Sint8 *)WILC_MALLOC(MAX_PACKET_BUFF_SIZE); + if (gps8ConfigPacket == NULL) { + PRINT_ER("failed in gps8ConfigPacket allocation\n"); + s32Error = WILC_NO_MEM; + goto _fail_; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); +_fail_: + return s32Error; +} + +u8 *get_tim_elm(u8 *pu8msa, WILC_Uint16 u16RxLen, WILC_Uint16 u16TagParamOffset) +{ + WILC_Uint16 u16index = 0; + + /*************************************************************************/ + /* Beacon Frame - Frame Body */ + /* --------------------------------------------------------------------- */ + /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */ + /* --------------------------------------------------------------------- */ + /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */ + /* --------------------------------------------------------------------- */ + /* */ + /*************************************************************************/ + + u16index = u16TagParamOffset; + + /* Search for the TIM Element Field and return if the element is found */ + while (u16index < (u16RxLen - FCS_LEN)) { + if (pu8msa[u16index] == ITIM) { + return &pu8msa[u16index]; + } else { + u16index += (IE_HDR_LEN + pu8msa[u16index + 1]); + } + } + + return 0; +} + +/* This function gets the current channel information from + * the 802.11n beacon/probe response frame */ +u8 get_current_channel_802_11n(u8 *pu8msa, WILC_Uint16 u16RxLen) +{ + WILC_Uint16 index; + + index = TAG_PARAM_OFFSET; + while (index < (u16RxLen - FCS_LEN)) { + if (pu8msa[index] == IDSPARMS) + return pu8msa[index + 2]; + else + /* Increment index by length information and header */ + index += pu8msa[index + 1] + IE_HDR_LEN; + } + + /* Return current channel information from the MIB, if beacon/probe */ + /* response frame does not contain the DS parameter set IE */ + /* return (mget_CurrentChannel() + 1); */ + return 0; /* no MIB here */ +} + +u8 get_current_channel(u8 *pu8msa, WILC_Uint16 u16RxLen) +{ +#ifdef PHY_802_11n +#ifdef FIVE_GHZ_BAND + /* Get the current channel as its not set in */ + /* 802.11a beacons/probe response */ + return (get_rf_channel() + 1); +#else /* FIVE_GHZ_BAND */ + /* Extract current channel information from */ + /* the beacon/probe response frame */ + return get_current_channel_802_11n(pu8msa, u16RxLen); +#endif /* FIVE_GHZ_BAND */ +#else + return 0; +#endif /* PHY_802_11n */ +} + +/** + * @brief parses the received 'N' message + * @details + * @param[in] pu8MsgBuffer The message to be parsed + * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = NULL; + u8 u8MsgType = 0; + u8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + WILC_Uint16 u16WidLen = 0; + u8 *pu8WidVal = 0; + + u8MsgType = pu8MsgBuffer[0]; + + /* Check whether the received message type is 'N' */ + if ('N' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pu8MsgBuffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); + + /* Extract WID ID */ + u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); + + /* Extract WID Length */ + u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); + + /* Assign a pointer to the WID value */ + pu8WidVal = &pu8MsgBuffer[8]; + + /* parse the WID value of the WID "WID_NEWORK_INFO" */ + { + u8 *pu8msa = 0; + WILC_Uint16 u16RxLen = 0; + u8 *pu8TimElm = 0; + u8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + u8 u8index = 0; + WILC_Uint32 u32Tsf_Lo; + WILC_Uint32 u32Tsf_Hi; + + pstrNetworkInfo = (tstrNetworkInfo *)WILC_MALLOC(sizeof(tstrNetworkInfo)); + WILC_memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo)); + + pstrNetworkInfo->s8rssi = pu8WidVal[0]; + + /* Assign a pointer to msa "Mac Header Start Address" */ + pu8msa = &pu8WidVal[1]; + + u16RxLen = u16WidLen - 1; + + /* parse msa*/ + + /* Get the cap_info */ + pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); + #ifdef WILC_P2P + /* Get time-stamp [Low only 32 bit] */ + pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); + PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); + #endif + + /* Get full time-stamp [Low and High 64 bit] */ + u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); + u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); + + pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((WILC_Uint64)u32Tsf_Hi << 32); + + /* Get SSID */ + get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen)); + + /* Get BSSID */ + get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); + + /* Get the current channel */ + pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN)); + + /* Get beacon period */ + u8index = (MAC_HDR_LEN + TIME_STAMP_LEN); + + pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); + + u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; + + /* Get DTIM Period */ + pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index); + if (pu8TimElm != 0) { + pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; + } + pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; + u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); + + if (u16IEsLen > 0) { + pstrNetworkInfo->pu8IEs = (u8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen); + + WILC_memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen); + } + pstrNetworkInfo->u16IEsLen = u16IEsLen; + + } + + *ppstrNetworkInfo = pstrNetworkInfo; + +ERRORHANDLER: + return s32Error; +} + +/** + * @brief Deallocates the parsed Network Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrNetworkInfo != NULL) { + if (pstrNetworkInfo->pu8IEs != NULL) { + WILC_FREE(pstrNetworkInfo->pu8IEs); + pstrNetworkInfo->pu8IEs = NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrNetworkInfo); + pstrNetworkInfo = NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +/** + * @brief parses the received Association Response frame + * @details + * @param[in] pu8Buffer The Association Response frame to be parsed + * @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 ParseAssocRespInfo(u8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectRespInfo *pstrConnectRespInfo = NULL; + WILC_Uint16 u16AssocRespLen = 0; + u8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + + pstrConnectRespInfo = (tstrConnectRespInfo *)WILC_MALLOC(sizeof(tstrConnectRespInfo)); + WILC_memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo)); + + /* u16AssocRespLen = pu8Buffer[0]; */ + u16AssocRespLen = (WILC_Uint16)u32BufferLen; + + /* get the status code */ + pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer); + if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + + /* get the capability */ + pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer); + + /* get the Association ID */ + pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer); + + /* get the Information Elements */ + pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN]; + u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN); + + pstrConnectRespInfo->pu8RespIEs = (u8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen); + + WILC_memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen); + pstrConnectRespInfo->u16RespIEsLen = u16IEsLen; + } + + *ppstrConnectRespInfo = pstrConnectRespInfo; + + + return s32Error; +} + +/** + * @brief Deallocates the parsed Association Response Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrConnectRespInfo != NULL) { + if (pstrConnectRespInfo->pu8RespIEs != NULL) { + WILC_FREE(pstrConnectRespInfo->pu8RespIEs); + pstrConnectRespInfo->pu8RespIEs = NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrConnectRespInfo); + pstrConnectRespInfo = NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +#ifndef CONNECT_DIRECT +WILC_Sint32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, + WILC_Uint32 *pu32SurveyResultsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + wid_site_survey_reslts_s *pstrSurveyResults = NULL; + WILC_Uint32 u32SurveyResultsCount = 0; + WILC_Uint32 u32SurveyBytesLength = 0; + u8 *pu8BufferPtr; + WILC_Uint32 u32RcvdSurveyResultsNum = 2; + u8 u8ReadSurveyResFragNum; + WILC_Uint32 i; + WILC_Uint32 j; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0]; + + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + u32SurveyResultsCount++; + } + } + + pstrSurveyResults = (wid_site_survey_reslts_s *)WILC_MALLOC(u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + if (pstrSurveyResults == NULL) { + u32SurveyResultsCount = 0; + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + WILC_memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + + u32SurveyResultsCount = 0; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + pu8BufferPtr = ppu8RcvdSiteSurveyResults[i]; + + u32SurveyBytesLength = pu8BufferPtr[0]; + + /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */ + u8ReadSurveyResFragNum = pu8BufferPtr[1]; + + pu8BufferPtr += 2; + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + WILC_memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH); + pu8BufferPtr += SURVEY_RESULT_LENGTH; + u32SurveyResultsCount++; + } + } + +ERRORHANDLER: + *ppstrSurveyResults = pstrSurveyResults; + *pu32SurveyResultsCount = u32SurveyResultsCount; + + return s32Error; +} + + +WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrSurveyResults != NULL) { + WILC_FREE(pstrSurveyResults); + } + + return s32Error; +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessCharWid */ +/* */ +/* Description : This function processes a WID of type WID_CHAR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessCharWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + u8 *pu8val = (u8 *)ps8WidVal; + u8 u8val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid >> 8) & 0xFF; + if (g_oper_mode == SET_CFG) { + u8val = *pu8val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(u8); + + + /* Value */ + pcPacket[s32PktLen++] = u8val; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessShortWid */ +/* */ +/* Description : This function processes a WID of type WID_SHORT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessShortWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint16 *pu16val = (WILC_Uint16 *)ps8WidVal; + WILC_Uint16 u16val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u16val = *pu16val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint16); + + /* Value */ + pcPacket[s32PktLen++] = (u8)(u16val & 0xFF); + pcPacket[s32PktLen++] = (u8)((u16val >> 8) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIntWid */ +/* */ +/* Description : This function processes a WID of type WID_INT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIntWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint32 *pu32val = (WILC_Uint32 *)ps8WidVal; + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u32val = *pu32val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Value */ + pcPacket[s32PktLen++] = (u8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIPwid */ +/* */ +/* Description : This function processes a WID of type WID_IP and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIPwid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, u8 *pu8ip) +{ + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Convert the IP Address String to Integer */ + conv_ip_to_int(pu8ip, &u32val); + + /* Value */ + pcPacket[s32PktLen++] = (u8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessStrWid */ +/* */ +/* Description : This function processes a WID of type WID_STR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessStrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, u8 *pu8val, WILC_Sint32 s32ValueSize) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + /* u16MsgLen = WILC_strlen(pu8val); */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + pcPacket[s32PktLen++] = (u8)u16MsgLen; + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessAdrWid */ +/* */ +/* Description : This function processes a WID of type WID_ADR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessAdrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, u8 *pu8val) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = MAC_ADDR_LEN; + + /* Length */ + pcPacket[s32PktLen++] = (u8)u16MsgLen; + + /* Value */ + extract_mac_addr(pu8val, pcPacket + s32PktLen); + s32PktLen += u16MsgLen; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessBinWid */ +/* */ +/* Description : This function processes a WID of type WID_BIN_DATA and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Name of file containing the binary data in text mode */ +/* */ +/* Globals : */ +/* */ +/* Processing : The binary data is expected to be supplied through a */ +/* file in text mode. This file is expected to be in the */ +/* finject format. It is parsed, converted to binary format */ +/* and copied into g_cfg_pkt for further processing. This */ +/* is obviously a round-about way of processing involving */ +/* multiple (re)conversions between bin & ascii formats. */ +/* But it is done nevertheless to retain uniformity and for */ +/* ease of debugging. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ + +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessBinWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, u8 *pu8val, WILC_Sint32 s32ValueSize) +{ + /* WILC_ERROR("processing Binary WIDs is not supported\n"); */ + + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + u8 u8checksum = 0; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + /* pcPacket[s32PktLen++] = (u8)u16MsgLen; */ + pcPacket[s32PktLen++] = (u8)(u16MsgLen & 0xFF); + pcPacket[s32PktLen++] = (u8)((u16MsgLen >> 8) & 0xFF); + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + + /* checksum */ + for (idx = 0; idx < u16MsgLen; idx++) + u8checksum += pcPacket[MSG_HEADER_LEN + idx + 4]; + + pcPacket[s32PktLen++] = u8checksum; + } + *ps32PktLen = s32PktLen; +} + + +/*****************************************************************************/ +/* */ +/* Function Name : further_process_response */ +/* */ +/* Description : This function parses the response frame got from the */ +/* device. */ +/* */ +/* Inputs : 1) The received response frame */ +/* 2) WID */ +/* 3) WID Length */ +/* 4) Output file handle */ +/* 5) Process Wid Number(i.e wid from --widn switch) */ +/* 6) Index the array in the Global Wid Structure. */ +/* */ +/* Globals : g_wid_num, gastrWIDs */ +/* */ +/* Processing : This function parses the response of the device depending*/ +/* WID type and writes it to the output file in Hex or */ +/* decimal notation depending on the --getx or --get switch.*/ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -2 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2009 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 further_process_response(u8 *resp, + WILC_Uint16 u16WIDid, + WILC_Uint16 cfg_len, + WILC_Bool process_wid_num, + WILC_Uint32 cnt, + tstrWID *pstrWIDresult) +{ + WILC_Uint32 retval = 0; + WILC_Uint32 idx = 0; + u8 cfg_chr = 0; + WILC_Uint16 cfg_sht = 0; + WILC_Uint32 cfg_int = 0; + u8 cfg_str[256] = {0}; + tenuWIDtype enuWIDtype = WID_UNDEF; + + if (process_wid_num) { + enuWIDtype = get_wid_type(g_wid_num); + } else { + enuWIDtype = gastrWIDs[cnt].enuWIDtype; + } + + + switch (enuWIDtype) { + case WID_CHAR: + cfg_chr = resp[idx]; + /*Set local copy of WID*/ + *(pstrWIDresult->ps8WidVal) = cfg_chr; + break; + + case WID_SHORT: + { + WILC_Uint16 *pu16val = (WILC_Uint16 *)(pstrWIDresult->ps8WidVal); + cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)(WILC_Sint32)cfg_sht; */ + *pu16val = cfg_sht; + break; + } + + case WID_INT: + { + WILC_Uint32 *pu32val = (WILC_Uint32 *)(pstrWIDresult->ps8WidVal); + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)cfg_int; */ + *pu32val = cfg_int; + break; + } + + case WID_STR: + WILC_memcpy(cfg_str, resp + idx, cfg_len); + /* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */ + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); /* mostafa: no need currently for the extra NULL byte */ + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("allocated WID buffer length is smaller than the received WID Length\n"); + retval = -2; + } + + break; + + case WID_ADR: + create_mac_addr(cfg_str, resp + idx); + + WILC_strncpy(pstrWIDresult->ps8WidVal, cfg_str, WILC_strlen(cfg_str)); + pstrWIDresult->ps8WidVal[WILC_strlen(cfg_str)] = '\0'; + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_IP: + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + conv_int_to_ip(cfg_str, cfg_int); + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_BIN_DATA: + #if 0 + /* FILE *fp_bin = NULL; */ + u8 first_bin_wid = 1; + if (first_bin_wid) { + /* fp_bin = fopen("wid_response.bin","wb"); */ + first_bin_wid = 0; + } else { + /* fp_bin = fopen("wid_response.bin","ab"); */ + } + + if (/*fp_bin == NULL*/ 0) { + PRINT_ER("Error: Could not open wid_response.bin for write\n"); + return -2; + } + + /* fwrite(resp + idx, cfg_len, 1, fp_bin); */ + + /* fclose(fp_bin); */ + #endif + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len); + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n", retval); + retval = -2; + } + break; + + default: + PRINT_ER("ERROR: Check config database: Error(%d)\n", retval); + retval = -2; + break; + } + + return retval; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ParseResponse */ +/* */ +/* Description : This function parses the command-line options and */ +/* creates the config packets which can be sent to the WLAN */ +/* station. */ +/* */ +/* Inputs : 1) The received response frame */ +/* */ +/* Globals : g_opt_list, gastrWIDs */ +/* */ +/* Processing : This function parses the options and creates different */ +/* types of packets depending upon the WID-type */ +/* corresponding to the option. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -1 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 ParseResponse(u8 *resp, tstrWID *pstrWIDcfgResult) +{ + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDid = 0; + WILC_Uint16 cfg_len = 0; + tenuWIDtype enuWIDtype = WID_UNDEF; + WILC_Bool num_wid_processed = WILC_FALSE; + WILC_Uint32 cnt = 0; + WILC_Uint32 idx = 0; + WILC_Uint32 ResCnt = 0; + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != resp[0]) { + PRINT_INFO(CORECONFIG_DBG, "Received Message format incorrect.\n"); + return -1; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(resp[2], resp[3]); + Res_Len = u16RespLen; + + for (idx = MSG_HEADER_LEN; idx < u16RespLen; ) { + u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]); + cfg_len = resp[idx + 2]; + /* Incase of Bin Type Wid, the length is given by two byte field */ + enuWIDtype = get_wid_type(u16WIDid); + if (WID_BIN_DATA == enuWIDtype) { + cfg_len |= ((WILC_Uint16)resp[idx + 3] << 8) & 0xFF00; + idx++; + } + idx += 3; + if ((u16WIDid == g_wid_num) && (num_wid_processed == WILC_FALSE)) { + num_wid_processed = WILC_TRUE; + + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_TRUE, 0, &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } else { + for (cnt = 0; cnt < g_num_total_switches; cnt++) { + if (gastrWIDs[cnt].u16WIDid == u16WIDid) { + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_FALSE, cnt, + &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } + } + } + idx += cfg_len; + /* In case if BIN type Wid, The last byte of the Cfg packet is the */ + /* Checksum. The WID Length field does not accounts for the checksum. */ + /* The Checksum is discarded. */ + if (WID_BIN_DATA == enuWIDtype) { + idx++; + } + } + + return 0; +} + +/** + * @brief parses the write response [just detects its status: success or failure] + * @details + * @param[in] pu8RespBuffer The Response to be parsed + * @return Error code indicating Write Operation status: + * WRITE_RESP_SUCCESS (1) => Write Success. + * WILC_FAIL (-100) => Write Failure. + * @note + * @author Ittiam + * @date 11 Aug 2009 + * @version 1.0 + */ + +WILC_Sint32 ParseWriteResponse(u8 *pu8RespBuffer) +{ + WILC_Sint32 s32Error = WILC_FAIL; + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDtype = (WILC_Uint16)WID_NIL; + + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != pu8RespBuffer[0]) { + PRINT_ER("Received Message format incorrect.\n"); + return WILC_FAIL; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(pu8RespBuffer[2], pu8RespBuffer[3]); + + u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]); + + /* Check for WID_STATUS ID and then check the length and status value */ + if ((u16WIDtype == WID_STATUS) && + (pu8RespBuffer[6] == 1) && + (pu8RespBuffer[7] == WRITE_RESP_SUCCESS)) { + s32Error = WRITE_RESP_SUCCESS; + return s32Error; + } + + /* If the length or status are not as expected return failure */ + s32Error = WILC_FAIL; + return s32Error; + +} + +/** + * @brief creates the header of the Configuration Packet + * @details + * @param[in,out] pcpacket The Configuration Packet + * @param[in,out] ps32PacketLength Length of the Configuration Packet + * @return Error code indicating success/failure + * @note + * @author aismail + * @date 18 Feb 2012 + * @version 1.0 + */ + +WILC_Sint32 CreatePacketHeader(WILC_Char *pcpacket, WILC_Sint32 *ps32PacketLength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16MsgLen = (WILC_Uint16)(*ps32PacketLength); + WILC_Uint16 u16MsgInd = 0; + + /* The format of the message is: */ + /* +-------------------------------------------------------------------+ */ + /* | Message Type | Message ID | Message Length |Message body | */ + /* +-------------------------------------------------------------------+ */ + /* | 1 Byte | 1 Byte | 2 Bytes | Message Length - 4 | */ + /* +-------------------------------------------------------------------+ */ + + /* The format of a message body of a message type 'W' is: */ + /* +-------------------------------------------------------------------+ */ + /* | WID0 | WID0 Length | WID0 Value | ......................... | */ + /* +-------------------------------------------------------------------+ */ + /* | 2 Bytes | 1 Byte | WID0 Length | ......................... | */ + /* +-------------------------------------------------------------------+ */ + + + + /* Message Type */ + if (g_oper_mode == SET_CFG) + pcpacket[u16MsgInd++] = WRITE_MSG_TYPE; + else + pcpacket[u16MsgInd++] = QUERY_MSG_TYPE; + + /* Sequence Number */ + pcpacket[u16MsgInd++] = g_seqno++; + + /* Message Length */ + pcpacket[u16MsgInd++] = (u8)(u16MsgLen & 0xFF); + pcpacket[u16MsgInd++] = (u8)((u16MsgLen >> 8) & 0xFF); + + *ps32PacketLength = u16MsgLen; + + return s32Error; +} + +/** + * @brief creates Configuration packet based on the Input WIDs + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] ps8packet The created Configuration Packet + * @param[out] ps32PacketLength Length of the created Configuration Packet + * @return Error code indicating success/failure + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CreateConfigPacket(WILC_Sint8 *ps8packet, WILC_Sint32 *ps32PacketLength, + tstrWID *pstrWIDs, WILC_Uint32 u32WIDsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint32 u32idx = 0; + *ps32PacketLength = MSG_HEADER_LEN; + for (u32idx = 0; u32idx < u32WIDsCount; u32idx++) { + switch (pstrWIDs[u32idx].enuWIDtype) { + case WID_CHAR: + ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_SHORT: + ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_INT: + ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_STR: + ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + #if 0 + case WID_ADR: + ProcessAdrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + #endif + case WID_IP: + ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_BIN_DATA: + ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + default: + PRINT_ER("ERROR: Check Config database\n"); + } + } + + CreatePacketHeader(ps8packet, ps32PacketLength); + + return s32Error; +} + +WILC_Sint32 ConfigWaitResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32MaxRespBuffLen, WILC_Sint32 *ps32BytesRead, + WILC_Bool bRespRequired) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + /*bug 3878*/ + /*removed to caller function*/ + /*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer; + * gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen; + * gstrConfigPktInfo.bRespRequired = bRespRequired;*/ + + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + down(&SemHandlePktResp); + + *ps32BytesRead = gstrConfigPktInfo.s32BytesRead; + } + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); + + return s32Error; +} + +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * and retrieves the packet response pu8RxResp + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +#ifdef SIMULATION +WILC_Sint32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Sint32 err = WILC_SUCCESS; + WILC_Sint32 s32ConfigPacketLen = 0; + WILC_Sint32 s32RcvdRespLen = 0; + + down(&SemHandleSendPkt); + + /*set the packet mode*/ + g_oper_mode = u8Mode; + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + if (CreateConfigPacket(gps8ConfigPacket, &s32ConfigPacketLen, pstrWIDs, u32WIDsCount) != WILC_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } + /*bug 3878*/ + gstrConfigPktInfo.pcRespBuffer = gps8ConfigPacket; + gstrConfigPktInfo.s32MaxRespBuffLen = MAX_PACKET_BUFF_SIZE; + PRINT_INFO(CORECONFIG_DBG, "GLOBAL =bRespRequired =%d\n", bRespRequired); + gstrConfigPktInfo.bRespRequired = bRespRequired; + + s32Error = SendRawPacket(gps8ConfigPacket, s32ConfigPacketLen); + if (s32Error != WILC_SUCCESS) { + goto End_ConfigPkt; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + ConfigWaitResponse(gps8ConfigPacket, MAX_PACKET_BUFF_SIZE, &s32RcvdRespLen, bRespRequired); + + + if (bRespRequired == WILC_TRUE) { + /* If the operating Mode is GET, then we expect a response frame from */ + /* the driver. Hence start listening to the port for response */ + if (g_oper_mode == GET_CFG) { + #if 1 + err = ParseResponse(gps8ConfigPacket, pstrWIDs); + if (err != 0) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + #endif + } else { + err = ParseWriteResponse(gps8ConfigPacket); + if (err != WRITE_RESP_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + } + + + } + + +End_ConfigPkt: + up(&SemHandleSendPkt); + + return s32Error; +} +#endif +WILC_Sint32 ConfigProvideResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32RespLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen); + gstrConfigPktInfo.s32BytesRead = s32RespLen; + } else { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen); + gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen; + PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size\n"); + } + + up(&SemHandlePktResp); + } + + return s32Error; +} + +/** + * @brief writes the received packet pu8RxPacket in the global Rx FIFO buffer + * @details + * @param[in] pu8RxPacket The received packet + * @param[in] s32RxPacketLen Length of the received packet + * @return Error code indicating success/failure + * @note + * + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 ConfigPktReceived(u8 *pu8RxPacket, WILC_Sint32 s32RxPacketLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 u8MsgType = 0; + + u8MsgType = pu8RxPacket[0]; + + switch (u8MsgType) { + case 'R': + ConfigProvideResponse(pu8RxPacket, s32RxPacketLen); + + break; + + case 'N': + PRINT_INFO(CORECONFIG_DBG, "NetworkInfo packet received\n"); + NetworkInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'I': + GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'S': + host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen); + break; + + default: + PRINT_ER("ConfigPktReceived(): invalid received msg type at the Core Configurator\n"); + break; + } + + return s32Error; +} + +/** + * @brief Deinitializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorDeInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit()\n"); + + if (gps8ConfigPacket != NULL) { + + WILC_FREE(gps8ConfigPacket); + gps8ConfigPacket = NULL; + } + + return s32Error; +} + + +#ifndef SIMULATION +/*Using the global handle of the driver*/ +extern wilc_wlan_oup_t *gpstrWlanOps; +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * using driver config layer + * + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 counter = 0, ret = 0; + if (gpstrWlanOps == NULL) { + PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n"); + } + if (gpstrWlanOps->wlan_cfg_set == NULL || + gpstrWlanOps->wlan_cfg_get == NULL) { + PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "SET is initialized\n"); + } + if (u8Mode == GET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter, + (counter == u32WIDsCount - 1)); + if (!gpstrWlanOps->wlan_cfg_get(!counter, + pstrWIDs[counter].u16WIDid, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Get Timed out\n"); + break; + } + } + /** + * get the value + **/ + /* WILC_Sleep(1000); */ + counter = 0; + for (counter = 0; counter < u32WIDsCount; counter++) { + pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value( + pstrWIDs[counter].u16WIDid, + pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize); + + } + } else if (u8Mode == SET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid); + if (!gpstrWlanOps->wlan_cfg_set(!counter, + pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal, + pstrWIDs[counter].s32ValueSize, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Set Timed out\n"); + break; + } + } + } + + return ret; +} +#endif diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h new file mode 100644 index 000000000000..b8e52414ebcc --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -0,0 +1,498 @@ + +/*! + * @file coreconfigurator.h + * @brief + * @author + * @sa coreconfigurator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGURATOR_H +#define CORECONFIGURATOR_H + +#include "wilc_oswrapper.h" +#include "wilc_wlan_if.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +/* Number of WID Options Supported */ +#define NUM_BASIC_SWITCHES 45 +#define NUM_FHSS_SWITCHES 0 + +#define NUM_RSSI 5 + +#ifdef MAC_802_11N +#define NUM_11N_BASIC_SWITCHES 25 +#define NUM_11N_HUT_SWITCHES 47 +#else /* MAC_802_11N */ +#define NUM_11N_BASIC_SWITCHES 0 +#define NUM_11N_HUT_SWITCHES 0 +#endif /* MAC_802_11N */ + +extern WILC_Uint16 g_num_total_switches; + +#define MAC_HDR_LEN 24 /* No Address4 - non-ESS */ +#define MAX_SSID_LEN 33 +#define FCS_LEN 4 +#define TIME_STAMP_LEN 8 +#define BEACON_INTERVAL_LEN 2 +#define CAP_INFO_LEN 2 +#define STATUS_CODE_LEN 2 +#define AID_LEN 2 +#define IE_HDR_LEN 2 + + +/* Operating Mode: SET */ +#define SET_CFG 0 +/* Operating Mode: GET */ +#define GET_CFG 1 + +#define MAX_PACKET_BUFF_SIZE 1596 + +#define MAX_STRING_LEN 256 +#define MAX_SURVEY_RESULT_FRAG_SIZE MAX_STRING_LEN +#define SURVEY_RESULT_LENGTH 44 +#define MAX_ASSOC_RESP_FRAME_SIZE MAX_STRING_LEN + +#define STATUS_MSG_LEN 12 +#define MAC_CONNECTED 1 +#define MAC_DISCONNECTED 0 + + + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +#define MAKE_WORD16(lsb, msb) ((((WILC_Uint16)(msb) << 8) & 0xFF00) | (lsb)) +#define MAKE_WORD32(lsw, msw) ((((WILC_Uint32)(msw) << 16) & 0xFFFF0000) | (lsw)) + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ +/* WID Data Types */ +#if 0 +typedef enum { + WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7, + WID_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuWIDtype; + +/* WLAN Identifiers */ +typedef enum { + WID_NIL = -1, + /* EMAC Character WID list */ + WID_BSS_TYPE = 0x0000, + WID_CURRENT_TX_RATE = 0x0001, + WID_CURRENT_CHANNEL = 0x0002, + WID_PREAMBLE = 0x0003, + WID_11G_OPERATING_MODE = 0x0004, + WID_STATUS = 0x0005, + WID_11G_PROT_MECH = 0x0006, + WID_SCAN_TYPE = 0x0007, + WID_PRIVACY_INVOKED = 0x0008, + WID_KEY_ID = 0x0009, + WID_QOS_ENABLE = 0x000A, + WID_POWER_MANAGEMENT = 0x000B, + WID_11I_MODE = 0x000C, + WID_AUTH_TYPE = 0x000D, + WID_SITE_SURVEY = 0x000E, + WID_LISTEN_INTERVAL = 0x000F, + WID_DTIM_PERIOD = 0x0010, + WID_ACK_POLICY = 0x0011, + WID_RESET = 0x0012, + WID_PCF_MODE = 0x0013, + WID_CFP_PERIOD = 0x0014, + WID_BCAST_SSID = 0x0015, + WID_PHY_TEST_PATTERN = 0x0016, + WID_DISCONNECT = 0x0016, + WID_READ_ADDR_SDRAM = 0x0017, + WID_TX_POWER_LEVEL_11A = 0x0018, + WID_REKEY_POLICY = 0x0019, + WID_SHORT_SLOT_ALLOWED = 0x001A, + WID_PHY_ACTIVE_REG = 0x001B, + WID_PHY_ACTIVE_REG_VAL = 0x001C, + WID_TX_POWER_LEVEL_11B = 0x001D, + WID_START_SCAN_REQ = 0x001E, + WID_RSSI = 0x001F, + WID_JOIN_REQ = 0x0020, + WID_ANTENNA_SELECTION = 0x0021, + WID_USER_CONTROL_ON_TX_POWER = 0x0027, + WID_MEMORY_ACCESS_8BIT = 0x0029, + WID_UAPSD_SUPPORT_AP = 0x002A, + WID_CURRENT_MAC_STATUS = 0x0031, + WID_AUTO_RX_SENSITIVITY = 0x0032, + WID_DATAFLOW_CONTROL = 0x0033, + WID_SCAN_FILTER = 0x0036, + WID_LINK_LOSS_THRESHOLD = 0x0037, + WID_AUTORATE_TYPE = 0x0038, + WID_CCA_THRESHOLD = 0x0039, + WID_802_11H_DFS_MODE = 0x003B, + WID_802_11H_TPC_MODE = 0x003C, + WID_DEVICE_READY = 0x003D, + WID_PM_NULL_FRAME_INTERVAL = 0x003E, + WID_PM_ACTIVITY_TIMER = 0x003F, + WID_PM_NULL_FRAME_WAIT_ENABLE = 0x0040, + WID_SCAN_WAIT_TIME = 0x0041, + WID_WSC_IE_EN = 0x0042, + WID_WPS_START = 0x0043, + WID_WPS_DEV_MODE = 0x0044, + WID_BT_COEXISTENCE = 0x0050, + WID_TRACKING_ROAMING = 0x0070, + WID_NUM_PKTS_FOR_RSSI_AVG = 0x0071, + WID_FHSS_SCAN_CHAN_INDEX = 0x0072, + WID_FHSS_SCAN_STEP_INDEX = 0x0073, + + /* NMAC Character WID list */ + WID_11N_PROT_MECH = 0x0080, + WID_11N_ERP_PROT_TYPE = 0x0081, + WID_11N_ENABLE = 0x0082, + WID_11N_OPERATING_MODE = 0x0083, + WID_11N_OBSS_NONHT_DETECTION = 0x0084, + WID_11N_HT_PROT_TYPE = 0x0085, + WID_11N_RIFS_PROT_ENABLE = 0x0086, + WID_11N_SMPS_MODE = 0x0087, + WID_11N_CURRENT_TX_MCS = 0x0088, + WID_11N_PRINT_STATS = 0x0089, + WID_HUT_FCS_CORRUPT_MODE = 0x008A, + WID_HUT_RESTART = 0x008B, + WID_HUT_TX_FORMAT = 0x008C, + WID_11N_SHORT_GI_20MHZ_ENABLE = 0x008D, + WID_HUT_BANDWIDTH = 0x008E, + WID_HUT_OP_BAND = 0x008F, + WID_HUT_STBC = 0x0090, + WID_HUT_ESS = 0x0091, + WID_HUT_ANTSET = 0x0092, + WID_HUT_HT_OP_MODE = 0x0093, + WID_HUT_RIFS_MODE = 0x0094, + WID_HUT_SMOOTHING_REC = 0x0095, + WID_HUT_SOUNDING_PKT = 0x0096, + WID_HUT_HT_CODING = 0x0097, + WID_HUT_TEST_DIR = 0x0098, + WID_HUT_CAPTURE_MODE = 0x0099, + WID_HUT_PHY_TEST_MODE = 0x009A, + WID_HUT_PHY_TEST_RATE_HI = 0x009B, + WID_HUT_PHY_TEST_RATE_LO = 0x009C, + WID_HUT_DISABLE_RXQ_REPLENISH = 0x009D, + WID_HUT_KEY_ORIGIN = 0x009E, + WID_HUT_BCST_PERCENT = 0x009F, + WID_HUT_GROUP_CIPHER_TYPE = 0x00A0, + WID_TX_ABORT_CONFIG = 0x00A1, + WID_HOST_DATA_IF_TYPE = 0x00A2, + WID_HOST_CONFIG_IF_TYPE = 0x00A3, + WID_HUT_TSF_TEST_MODE = 0x00A4, + WID_HUT_TSSI_VALUE = 0x00A5, + WID_HUT_PKT_TSSI_VALUE = 0x00A5, + WID_REG_TSSI_11B_VALUE = 0x00A6, + WID_REG_TSSI_11G_VALUE = 0x00A7, + WID_REG_TSSI_11N_VALUE = 0x00A8, + WID_TX_CALIBRATION = 0x00A9, + WID_DSCR_TSSI_11B_VALUE = 0x00AA, + WID_DSCR_TSSI_11G_VALUE = 0x00AB, + WID_DSCR_TSSI_11N_VALUE = 0x00AC, + WID_HUT_RSSI_EX = 0x00AD, + WID_HUT_ADJ_RSSI_EX = 0x00AE, + WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF, + WID_11N_TXOP_PROT_DISABLE = 0x00B0, + WID_TX_POWER_LEVEL_11N = 0x00B1, + WID_HUT_MGMT_PERCENT = 0x00B3, + WID_HUT_MGMT_BCST_PERCENT = 0x00B4, + WID_HUT_MGMT_ALLOW_HT = 0x00B5, + WID_HUT_UC_MGMT_TYPE = 0x00B6, + WID_HUT_BC_MGMT_TYPE = 0x00B7, + WID_HUT_11W_MFP_REQUIRED_TX = 0x00B8, + WID_HUT_11W_MFP_PEER_CAPABLE = 0x00B9, + WID_HUT_11W_TX_IGTK_ID = 0x00BA, + WID_11W_ENABLE = 0x00BB, + WID_11W_MGMT_PROT_REQ = 0x00BC, + WID_USER_SEC_CHANNEL_OFFSET = 0x00C0, + WID_2040_COEXISTENCE = 0x00C1, + WID_HUT_FC_TXOP_MOD = 0x00C2, + WID_HUT_FC_PROT_TYPE = 0x00C3, + WID_HUT_SEC_CCA_ASSERT = 0x00C4, + WID_2040_ENABLE = 0x00C5, + WID_2040_CURR_CHANNEL_OFFSET = 0x00C6, + WID_2040_40MHZ_INTOLERANT = 0x00C7, + + + /* Custom Character WID list */ + WID_POWER_SAVE = 0x0100, + WID_WAKE_STATUS = 0x0101, + WID_WAKE_CONTROL = 0x0102, + WID_CCA_BUSY_START = 0x0103, + + /* EMAC Short WID list */ + WID_RTS_THRESHOLD = 0x1000, + WID_FRAG_THRESHOLD = 0x1001, + WID_SHORT_RETRY_LIMIT = 0x1002, + WID_LONG_RETRY_LIMIT = 0x1003, + WID_CFP_MAX_DUR = 0x1004, + WID_PHY_TEST_FRAME_LEN = 0x1005, + WID_BEACON_INTERVAL = 0x1006, + WID_MEMORY_ACCESS_16BIT = 0x1008, + WID_RX_SENSE = 0x100B, + WID_ACTIVE_SCAN_TIME = 0x100C, + WID_PASSIVE_SCAN_TIME = 0x100D, + WID_SITE_SURVEY_SCAN_TIME = 0x100E, + WID_JOIN_START_TIMEOUT = 0x100F, + WID_AUTH_TIMEOUT = 0x1010, + WID_ASOC_TIMEOUT = 0x1011, + WID_11I_PROTOCOL_TIMEOUT = 0x1012, + WID_EAPOL_RESPONSE_TIMEOUT = 0x1013, + WID_WPS_PASS_ID = 0x1017, + WID_WPS_CONFIG_METHOD = 0x1018, + WID_FHSS_INIT_SCAN_TIME = 0x1070, + WID_FHSS_ROAM_SCAN_TIME = 0x1071, + + /* NMAC Short WID list */ + WID_11N_RF_REG_VAL = 0x1080, + WID_HUT_FRAME_LEN = 0x1081, + WID_HUT_TXOP_LIMIT = 0x1082, + WID_HUT_SIG_QUAL_AVG = 0x1083, + WID_HUT_SIG_QUAL_AVG_CNT = 0x1084, + WID_11N_SIG_QUAL_VAL = 0x1085, + WID_HUT_RSSI_EX_COUNT = 0x1086, + WID_HUT_UC_MGMT_FRAME_LEN = 0x1088, + WID_HUT_BC_MGMT_FRAME_LEN = 0x1089, + + /* Custom Short WID list */ + + WID_CCA_BUSY_STATUS = 0x1100, + + /* EMAC Integer WID list */ + WID_FAILED_COUNT = 0x2000, + WID_RETRY_COUNT = 0x2001, + WID_MULTIPLE_RETRY_COUNT = 0x2002, + WID_FRAME_DUPLICATE_COUNT = 0x2003, + WID_ACK_FAILURE_COUNT = 0x2004, + WID_RECEIVED_FRAGMENT_COUNT = 0x2005, + WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006, + WID_FCS_ERROR_COUNT = 0x2007, + WID_SUCCESS_FRAME_COUNT = 0x2008, + WID_PHY_TEST_PKT_CNT = 0x2009, + WID_HUT_TX_COUNT = 0x200A, + WID_TX_FRAGMENT_COUNT = 0x200B, + WID_TX_MULTICAST_FRAME_COUNT = 0x200C, + WID_RTS_SUCCESS_COUNT = 0x200D, + WID_RTS_FAILURE_COUNT = 0x200E, + WID_WEP_UNDECRYPTABLE_COUNT = 0x200F, + WID_REKEY_PERIOD = 0x2010, + WID_REKEY_PACKET_COUNT = 0x2011, + WID_1X_SERV_ADDR = 0x2012, + WID_STACK_IP_ADDR = 0x2013, + WID_STACK_NETMASK_ADDR = 0x2014, + WID_HW_RX_COUNT = 0x2015, + WID_MEMORY_ADDRESS = 0x201E, + WID_MEMORY_ACCESS_32BIT = 0x201F, + WID_RF_REG_VAL = 0x2021, + WID_FIRMWARE_INFO = 0x2023, + WID_DEV_OS_VERSION = 0x2025, + WID_ROAM_RSSI_THESHOLDS = 0x2070, + WID_TRACK_INTERVAL_SEC = 0x2071, + WID_FHSS_HOPPING_PARAMS = 0x2072, + WID_FHSS_HOP_DWELL_TIME = 0x2073, + + /* NMAC Integer WID list */ + WID_11N_PHY_ACTIVE_REG_VAL = 0x2080, + WID_HUT_NUM_TX_PKTS = 0x2081, + WID_HUT_TX_TIME_TAKEN = 0x2082, + WID_HUT_TX_TEST_TIME = 0x2083, + WID_HUT_LOG_INTERVAL = 0x2084, + + /* EMAC String WID list */ + WID_SSID = 0x3000, + WID_FIRMWARE_VERSION = 0x3001, + WID_OPERATIONAL_RATE_SET = 0x3002, + WID_BSSID = 0x3003, + #if 0 + WID_WEP_KEY_VALUE0 = 0x3004, + #endif + WID_11I_PSK = 0x3008, + WID_11E_P_ACTION_REQ = 0x3009, + WID_1X_KEY = 0x300A, + WID_HARDWARE_VERSION = 0x300B, + WID_MAC_ADDR = 0x300C, + WID_HUT_DEST_ADDR = 0x300D, + /*WID_HUT_STATS = 0x300E,*/ + WID_PHY_VERSION = 0x300F, + WID_SUPP_USERNAME = 0x3010, + WID_SUPP_PASSWORD = 0x3011, + WID_SITE_SURVEY_RESULTS = 0x3012, + WID_RX_POWER_LEVEL = 0x3013, + WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */ + WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */ + WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */ + WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */ + + WID_ASSOC_RES_INFO = 0x3020, + + /* NMAC String WID list */ + WID_11N_P_ACTION_REQ = 0x3080, + WID_HUT_TEST_ID = 0x3081, + WID_PMKID_INFO = 0x3082, + + /* Custom String WID list */ + WID_FLASH_DATA = 0x3100, + WID_EEPROM_DATA = 0x3101, + WID_SERIAL_NUMBER = 0x3102, + + /* EMAC Binary WID list */ + WID_UAPSD_CONFIG = 0x4001, + WID_UAPSD_STATUS = 0x4002, + WID_AC_PARAMS_AP = 0x4003, + WID_AC_PARAMS_STA = 0x4004, + WID_NEWORK_INFO = 0x4005, + WID_WPS_CRED_LIST = 0x4006, + WID_PRIM_DEV_TYPE = 0x4007, + WID_STA_JOIN_INFO = 0x4008, + WID_CONNECTED_STA_LIST = 0x4009, + + /* NMAC Binary WID list */ + WID_11N_AUTORATE_TABLE = 0x4080, + WID_HUT_TX_PATTERN = 0x4081, + WID_HUT_STATS = 0x4082, + WID_HUT_LOG_STATS = 0x4083, + + /*BugID_3746 WID to add IE to be added in next probe request*/ + WID_INFO_ELEMENT_PROBE = 0x4085, + /*BugID_3746 WID to add IE to be added in next associate request*/ + WID_INFO_ELEMENT_ASSOCIATE = 0x4086, + + /* Miscellaneous WIDs */ + WID_ALL = 0x7FFE, + WID_MAX = 0xFFFF +} tenuWIDid; +#endif + +/* Status Codes for Authentication and Association Frames */ +typedef enum { + SUCCESSFUL_STATUSCODE = 0, + UNSPEC_FAIL = 1, + UNSUP_CAP = 10, + REASOC_NO_ASOC = 11, + FAIL_OTHER = 12, + UNSUPT_ALG = 13, + AUTH_SEQ_FAIL = 14, + CHLNG_FAIL = 15, + AUTH_TIMEOUT = 16, + AP_FULL = 17, + UNSUP_RATE = 18, + SHORT_PREAMBLE_UNSUP = 19, + PBCC_UNSUP = 20, + CHANNEL_AGIL_UNSUP = 21, + SHORT_SLOT_UNSUP = 25, + OFDM_DSSS_UNSUP = 26, + CONNECT_STS_FORCE_16_BIT = 0xFFFF +} tenuConnectSts; + +typedef struct { + WILC_Uint16 u16WIDid; + tenuWIDtype enuWIDtype; + WILC_Sint32 s32ValueSize; + WILC_Sint8 *ps8WidVal; + +} tstrWID; + +typedef struct { + u8 u8Full; + u8 u8Index; + WILC_Sint8 as8RSSI[NUM_RSSI]; +} tstrRSSI; +/* This structure is used to support parsing of the received 'N' message */ +typedef struct { + WILC_Sint8 s8rssi; + WILC_Uint16 u16CapInfo; + u8 au8ssid[MAX_SSID_LEN]; + u8 u8SsidLen; + u8 au8bssid[6]; + WILC_Uint16 u16BeaconPeriod; + u8 u8DtimPeriod; + u8 u8channel; + unsigned long u32TimeRcvdInScanCached; /* of type unsigned long to be accepted by the linux kernel macro time_after() */ + unsigned long u32TimeRcvdInScan; + WILC_Bool bNewNetwork; +#ifdef AGING_ALG + u8 u8Found; +#endif +#ifdef WILC_P2P + WILC_Uint32 u32Tsf; /* time-stamp [Low only 32 bit] */ +#endif + u8 *pu8IEs; + WILC_Uint16 u16IEsLen; + void *pJoinParams; + tstrRSSI strRssi; + WILC_Uint64 u64Tsf; /* time-stamp [Low and High 64 bit] */ +} tstrNetworkInfo; + +/* This structure is used to support parsing of the received Association Response frame */ +typedef struct { + WILC_Uint16 u16capability; + WILC_Uint16 u16ConnectStatus; + WILC_Uint16 u16AssocID; + u8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; +} tstrConnectRespInfo; + + +typedef struct { + u8 au8bssid[6]; + u8 *pu8ReqIEs; + size_t ReqIEsLen; + u8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; + WILC_Uint16 u16ConnectStatus; +} tstrConnectInfo; + + + +typedef struct { + WILC_Uint16 u16reason; + u8 *ie; + size_t ie_len; +} tstrDisconnectNotifInfo; + +#ifndef CONNECT_DIRECT +typedef struct wid_site_survey_reslts { + WILC_Char SSID[MAX_SSID_LEN]; + u8 BssType; + u8 Channel; + u8 SecurityStatus; + u8 BSSID[6]; + WILC_Char RxPower; + u8 Reserved; + +} wid_site_survey_reslts_s; +#endif + +extern WILC_Sint32 CoreConfiguratorInit(void); +extern WILC_Sint32 CoreConfiguratorDeInit(void); + +extern WILC_Sint32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler); +extern WILC_Sint32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); +extern WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo); + +extern WILC_Sint32 ParseAssocRespInfo(u8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo); +extern WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo); + +#ifndef CONNECT_DIRECT +extern WILC_Sint32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, WILC_Uint32 *pu32SurveyResultsCount); +extern WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults); +#endif + +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *pspacket, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); +void GnrlAsyncInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); +void host_int_ScanCompleteReceived(u8 *pu8Buffer, WILC_Uint32 u32Length); + +#endif diff --git a/drivers/staging/wilc1000/fifo_buffer.c b/drivers/staging/wilc1000/fifo_buffer.c new file mode 100644 index 000000000000..f807bfb72539 --- /dev/null +++ b/drivers/staging/wilc1000/fifo_buffer.c @@ -0,0 +1,134 @@ + + +#include "wilc_oswrapper.h" +#include "fifo_buffer.h" + + + +WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, WILC_Uint32 u32BufferLength) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = WILC_MALLOC (sizeof (tstrFifoHandler)); + if (pstrFifoHandler) { + WILC_memset (pstrFifoHandler, 0, sizeof (tstrFifoHandler)); + pstrFifoHandler->pu8Buffer = WILC_MALLOC (u32BufferLength); + if (pstrFifoHandler->pu8Buffer) { + pstrFifoHandler->u32BufferLength = u32BufferLength; + WILC_memset (pstrFifoHandler->pu8Buffer, 0, u32BufferLength); + /* create semaphore */ + sema_init(&pstrFifoHandler->SemBuffer, 1); + *hBuffer = pstrFifoHandler; + } else { + *hBuffer = NULL; + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} +WILC_Uint32 FIFO_DeInit(tHANDLE hFifo) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (pstrFifoHandler->pu8Buffer) { + WILC_FREE (pstrFifoHandler->pu8Buffer); + } else { + u32Error = 1; + } + + WILC_FREE (pstrFifoHandler); + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, u8 *pu8Buffer, WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler && pu32BytesRead) { + if (pstrFifoHandler->u32TotalBytes) { + down(&pstrFifoHandler->SemBuffer); + + if (u32BytesToRead > pstrFifoHandler->u32TotalBytes) { + *pu32BytesRead = pstrFifoHandler->u32TotalBytes; + } else { + *pu32BytesRead = u32BytesToRead; + } + if ((pstrFifoHandler->u32ReadOffset + u32BytesToRead) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + *pu32BytesRead); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset += u32BytesToRead; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32ReadOffset; + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + u32FirstPart); + WILC_memcpy(pu8Buffer + u32FirstPart, pstrFifoHandler->pu8Buffer, + u32BytesToRead - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset = u32BytesToRead - u32FirstPart; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + } + up(&pstrFifoHandler->SemBuffer); + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, u8 *pu8Buffer, WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (u32BytesToWrite < pstrFifoHandler->u32BufferLength) { + if ((pstrFifoHandler->u32TotalBytes + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength || + bForceOverWrite) { + down(&pstrFifoHandler->SemBuffer); + if ((pstrFifoHandler->u32WriteOffset + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32BytesToWrite); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset += u32BytesToWrite; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32WriteOffset; + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32FirstPart); + WILC_memcpy(pstrFifoHandler->pu8Buffer, pu8Buffer + u32FirstPart, + u32BytesToWrite - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset = u32BytesToWrite - u32FirstPart; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + } + /* if data overwriten */ + if (pstrFifoHandler->u32TotalBytes > pstrFifoHandler->u32BufferLength) { + /* adjust read offset to the oldest data available */ + pstrFifoHandler->u32ReadOffset = pstrFifoHandler->u32WriteOffset; + /* data availabe is the buffer length */ + pstrFifoHandler->u32TotalBytes = pstrFifoHandler->u32BufferLength; + } + up(&pstrFifoHandler->SemBuffer); + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} diff --git a/drivers/staging/wilc1000/fifo_buffer.h b/drivers/staging/wilc1000/fifo_buffer.h new file mode 100644 index 000000000000..4d120503c4b2 --- /dev/null +++ b/drivers/staging/wilc1000/fifo_buffer.h @@ -0,0 +1,23 @@ + +#include "wilc_oswrapper.h" + + +#define tHANDLE void * + +typedef struct { + u8 *pu8Buffer; + WILC_Uint32 u32BufferLength; + WILC_Uint32 u32WriteOffset; + WILC_Uint32 u32ReadOffset; + WILC_Uint32 u32TotalBytes; + struct semaphore SemBuffer; +} tstrFifoHandler; + + +extern WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, + WILC_Uint32 u32BufferLength); +extern WILC_Uint32 FIFO_DeInit(tHANDLE hFifo); +extern WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, u8 *pu8Buffer, + WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead); +extern WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, u8 *pu8Buffer, + WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite); diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c new file mode 100644 index 000000000000..1ecb37341780 --- /dev/null +++ b/drivers/staging/wilc1000/host_interface.c @@ -0,0 +1,8043 @@ +#include "host_interface.h" +#include "wilc_oswrapper.h" +#include "itypes.h" +#include "coreconfigurator.h" + +extern WILC_Sint32 TransportInit(void); +extern WILC_Sint32 TransportDeInit(void); +extern u8 connecting; + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_TimerHandle hDuringIpTimer; +#endif + +extern WILC_Bool bEnablePS; +/*BugID_5137*/ +extern u8 g_wilc_initialized; +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ + +/* Message types of the Host IF Message Queue*/ +#define HOST_IF_MSG_SCAN ((WILC_Uint16)0) +#define HOST_IF_MSG_CONNECT ((WILC_Uint16)1) +#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO ((WILC_Uint16)2) +#define HOST_IF_MSG_KEY ((WILC_Uint16)3) +#define HOST_IF_MSG_RCVD_NTWRK_INFO ((WILC_Uint16)4) +#define HOST_IF_MSG_RCVD_SCAN_COMPLETE ((WILC_Uint16)5) +#define HOST_IF_MSG_CFG_PARAMS ((WILC_Uint16)6) +#define HOST_IF_MSG_SET_CHANNEL ((WILC_Uint16)7) +#define HOST_IF_MSG_DISCONNECT ((WILC_Uint16)8) +#define HOST_IF_MSG_GET_RSSI ((WILC_Uint16)9) +#define HOST_IF_MSG_GET_CHNL ((WILC_Uint16)10) +#define HOST_IF_MSG_ADD_BEACON ((WILC_Uint16)11) +#define HOST_IF_MSG_DEL_BEACON ((WILC_Uint16)12) +#define HOST_IF_MSG_ADD_STATION ((WILC_Uint16)13) +#define HOST_IF_MSG_DEL_STATION ((WILC_Uint16)14) +#define HOST_IF_MSG_EDIT_STATION ((WILC_Uint16)15) +#define HOST_IF_MSG_SCAN_TIMER_FIRED ((WILC_Uint16)16) +#define HOST_IF_MSG_CONNECT_TIMER_FIRED ((WILC_Uint16)17) +#define HOST_IF_MSG_POWER_MGMT ((WILC_Uint16)18) +#define HOST_IF_MSG_GET_INACTIVETIME ((WILC_Uint16)19) +#define HOST_IF_MSG_REMAIN_ON_CHAN ((WILC_Uint16)20) +#define HOST_IF_MSG_REGISTER_FRAME ((WILC_Uint16)21) +#define HOST_IF_MSG_LISTEN_TIMER_FIRED ((WILC_Uint16)22) +#define HOST_IF_MSG_GET_LINKSPEED ((WILC_Uint16)23) +#define HOST_IF_MSG_SET_WFIDRV_HANDLER ((WILC_Uint16)24) +#define HOST_IF_MSG_SET_MAC_ADDRESS ((WILC_Uint16)25) +#define HOST_IF_MSG_GET_MAC_ADDRESS ((WILC_Uint16)26) +#define HOST_IF_MSG_SET_OPERATION_MODE ((WILC_Uint16)27) +#define HOST_IF_MSG_SET_IPADDRESS ((WILC_Uint16)28) +#define HOST_IF_MSG_GET_IPADDRESS ((WILC_Uint16)29) +#define HOST_IF_MSG_FLUSH_CONNECT ((WILC_Uint16)30) +#define HOST_IF_MSG_GET_STATISTICS ((WILC_Uint16)31) +#define HOST_IF_MSG_SET_MULTICAST_FILTER ((WILC_Uint16)32) +#define HOST_IF_MSG_ADD_BA_SESSION ((WILC_Uint16)33) +#define HOST_IF_MSG_DEL_BA_SESSION ((WILC_Uint16)34) +#define HOST_IF_MSG_Q_IDLE ((WILC_Uint16)35) +#define HOST_IF_MSG_DEL_ALL_STA ((WILC_Uint16)36) +#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS ((WILC_Uint16)34) + +#define HOST_IF_MSG_EXIT ((WILC_Uint16)100) + +#define HOST_IF_SCAN_TIMEOUT 4000 +#define HOST_IF_CONNECT_TIMEOUT 9500 + +#define BA_SESSION_DEFAULT_BUFFER_SIZE 16 +#define BA_SESSION_DEFAULT_TIMEOUT 1000 +#define BLOCK_ACK_REQ_SIZE 0x14 +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/*! + * @struct tstrHostIFCfgParamAttr + * @brief Structure to hold Host IF CFG Params Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 02 April 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFCfgParamAttr { + tstrCfgParamVal pstrCfgParamVal; + +} tstrHostIFCfgParamAttr; + +/*! + * @struct tstrHostIFwpaAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwpaAttr { + u8 *pu8key; + const u8 *pu8macaddr; + u8 *pu8seq; + u8 u8seqlen; + u8 u8keyidx; + u8 u8Keylen; + u8 u8Ciphermode; +} tstrHostIFwpaAttr; + + +/*! + * @struct tstrHostIFwepAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwepAttr { + u8 *pu8WepKey; + u8 u8WepKeylen; + u8 u8Wepidx; + u8 u8mode; + AUTHTYPE_T tenuAuth_type; + +} tstrHostIFwepAttr; + +/*! + * @struct tuniHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFkeyAttr { + tstrHostIFwepAttr strHostIFwepAttr; + tstrHostIFwpaAttr strHostIFwpaAttr; + tstrHostIFpmkidAttr strHostIFpmkidAttr; +} tuniHostIFkeyAttr; + +/*! + * @struct tstrHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFkeyAttr { + tenuKeyType enuKeyType; + u8 u8KeyAction; + tuniHostIFkeyAttr uniHostIFkeyAttr; +} tstrHostIFkeyAttr; + + + + +/*! + * @struct tstrHostIFscanAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFscanAttr { + u8 u8ScanSource; + u8 u8ScanType; + u8 *pu8ChnlFreqList; + u8 u8ChnlListLen; + u8 *pu8IEs; + size_t IEsLen; + tWILCpfScanResult pfScanResult; + void *pvUserArg; + /*BugID_4189*/ + tstrHiddenNetwork strHiddenNetwork; + +} tstrHostIFscanAttr; + +/*! + * @struct tstrHostIFconnectAttr + * @brief Structure to hold Host IF Connect Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFconnectAttr { + u8 *pu8bssid; + u8 *pu8ssid; + size_t ssidLen; + u8 *pu8IEs; + size_t IEsLen; + u8 u8security; + tWILCpfConnectResult pfConnectResult; + void *pvUserArg; + AUTHTYPE_T tenuAuth_type; + u8 u8channel; + void *pJoinParams; +} tstrHostIFconnectAttr; + +/*! + * @struct tstrRcvdGnrlAsyncInfo + * @brief Structure to hold Received General Asynchronous info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdGnrlAsyncInfo { + u8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdGnrlAsyncInfo; + +/*! + * @struct tstrHostIFSetChan + * @brief Set Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetChan { + u8 u8SetChan; +} tstrHostIFSetChan; + +/*! + * @struct tstrHostIFSetChan + * @brief Get Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 01 Jule 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFGetChan { + u8 u8GetChan; +} tstrHostIFGetChan; + +/*bug3819: Add Scan acomplete notification to host*/ +/*! + * @struct tstrScanComplete + * @brief hold received Async. Scan Complete message body + * @details + * @todo + * @sa + * @author zsalah + * @date 25 March 2012 + * @version 1.0 + */ +/*typedef struct _tstrScanComplete + * { + * u8* pu8Buffer; + * WILC_Uint32 u32Length; + * } tstrScanComplete;*/ + +/*! + * @struct tstrHostIFSetBeacon + * @brief Set Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetBeacon { + WILC_Uint32 u32Interval; /*!< Beacon Interval. Period between two successive beacons on air */ + WILC_Uint32 u32DTIMPeriod; /*!< DTIM Period. Indicates how many Beacon frames + * (including the current frame) appear before the next DTIM */ + WILC_Uint32 u32HeadLen; /*!< Length of the head buffer in bytes */ + u8 *pu8Head; /*!< Pointer to the beacon's head buffer. Beacon's head is the part + * from the beacon's start till the TIM element, NOT including the TIM */ + WILC_Uint32 u32TailLen; /*!< Length of the tail buffer in bytes */ + u8 *pu8Tail; /*!< Pointer to the beacon's tail buffer. Beacon's tail starts just + * after the TIM inormation element */ +} tstrHostIFSetBeacon; + + + +/*! + * @struct tstrHostIFDelBeacon + * @brief Del Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFDelBeacon { + u8 u8dummy; +} tstrHostIFDelBeacon; + +/*! + * @struct tstrHostIFSetMulti + * @brief set Multicast filter Address + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + WILC_Bool bIsEnabled; + WILC_Uint32 u32count; +} tstrHostIFSetMulti; + +/*! + * @struct tstrHostIFDelAllSta + * @brief Deauth station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 09 April 2014 + * @version 1.0 Description + */ + +typedef struct { + u8 au8Sta_DelAllSta[MAX_NUM_STA][ETH_ALEN]; + u8 u8Num_AssocSta; +} tstrHostIFDelAllSta; + +/*! + * @struct tstrHostIFDelSta + * @brief Delete station message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ + +typedef struct { + u8 au8MacAddr[ETH_ALEN]; +} tstrHostIFDelSta; + +/*! + * @struct tstrTimerCb + * @brief Timer callback message body + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrTimerCb { + void *pvUsrArg; /*!< Private data passed at timer start */ +} tstrTimerCb; + +/*! + * @struct tstrHostIfPowerMgmtParam + * @brief Power management message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 + */ +typedef struct { + + WILC_Bool bIsEnabled; + WILC_Uint32 u32Timeout; +} tstrHostIfPowerMgmtParam; + +/*! + * @struct tstrHostIFSetIPAddr + * @brief set IP Address message body + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + u8 *au8IPAddr; + u8 idx; +} tstrHostIFSetIPAddr; + +/*! + * @struct tstrHostIfStaInactiveT + * @brief Get station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 16 April 2013 + * @version 1.0 + */ +typedef struct { + u8 mac[6]; + +} tstrHostIfStaInactiveT; +/**/ +/*! + * @union tuniHostIFmsgBody + * @brief Message body for the Host Interface message_q + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFmsgBody { + tstrHostIFscanAttr strHostIFscanAttr; /*!< Host IF Scan Request Attributes message body */ + tstrHostIFconnectAttr strHostIFconnectAttr; /*!< Host IF Connect Request Attributes message body */ + tstrRcvdNetworkInfo strRcvdNetworkInfo; /*!< Received Asynchronous Network Info message body */ + tstrRcvdGnrlAsyncInfo strRcvdGnrlAsyncInfo; /*!< Received General Asynchronous Info message body */ + tstrHostIFkeyAttr strHostIFkeyAttr; /*!<>*/ + tstrHostIFCfgParamAttr strHostIFCfgParamAttr; /*! <CFG Parameter message Body> */ + tstrHostIFSetChan strHostIFSetChan; + tstrHostIFGetChan strHostIFGetChan; + tstrHostIFSetBeacon strHostIFSetBeacon; /*!< Set beacon message body */ + tstrHostIFDelBeacon strHostIFDelBeacon; /*!< Del beacon message body */ + tstrWILC_AddStaParam strAddStaParam; /*!< Add station message body */ + tstrHostIFDelSta strDelStaParam; /*!< Del Station message body */ + tstrWILC_AddStaParam strEditStaParam; /*!< Edit station message body */ + /* tstrScanComplete strScanComplete; / *Received Async. Scan Complete message body* / */ + tstrTimerCb strTimerCb; /*!< Timer callback message body */ + tstrHostIfPowerMgmtParam strPowerMgmtparam; /*!< Power Management message body */ + tstrHostIfStaInactiveT strHostIfStaInactiveT; + tstrHostIFSetIPAddr strHostIfSetIP; + tstrHostIfSetDrvHandler strHostIfSetDrvHandler; + tstrHostIFSetMulti strHostIfSetMulti; + tstrHostIfSetOperationMode strHostIfSetOperationMode; + tstrHostIfSetMacAddress strHostIfSetMacAddress; + tstrHostIfGetMacAddress strHostIfGetMacAddress; + tstrHostIfBASessionInfo strHostIfBASessionInfo; + #ifdef WILC_P2P + tstrHostIfRemainOnChan strHostIfRemainOnChan; + tstrHostIfRegisterFrame strHostIfRegisterFrame; + #endif + WILC_Char *pUserData; + tstrHostIFDelAllSta strHostIFDelAllSta; +} tuniHostIFmsgBody; + +/*! + * @struct tstrHostIFmsg + * @brief Host Interface message + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFmsg { + WILC_Uint16 u16MsgId; /*!< Message ID */ + tuniHostIFmsgBody uniHostIFmsgBody; /*!< Message body */ + void *drvHandler; +} tstrHostIFmsg; + +#ifdef CONNECT_DIRECT +typedef struct _tstrWidJoinReqExt { + WILC_Char SSID[MAX_SSID_LEN]; + u8 u8channel; + u8 BSSID[6]; +} tstrWidJoinReqExt; +#endif + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Struct containg joinParam of each AP*/ +typedef struct _tstrJoinBssParam { + BSSTYPE_T bss_type; + u8 dtim_period; + WILC_Uint16 beacon_period; + WILC_Uint16 cap_info; + u8 au8bssid[6]; + WILC_Char ssid[MAX_SSID_LEN]; + u8 ssidLen; + u8 supp_rates[MAX_RATES_SUPPORTED + 1]; + u8 ht_capable; + u8 wmm_cap; + u8 uapsd_cap; + WILC_Bool rsn_found; + u8 rsn_grp_policy; + u8 mode_802_11i; + u8 rsn_pcip_policy[3]; + u8 rsn_auth_policy[3]; + u8 rsn_cap[2]; + struct _tstrJoinParam *nextJoinBss; + #ifdef WILC_P2P + WILC_Uint32 tsf; + u8 u8NoaEnbaled; + u8 u8OppEnable; + u8 u8CtWindow; + u8 u8Count; + u8 u8Index; + u8 au8Duration[4]; + u8 au8Interval[4]; + u8 au8StartTime[4]; + #endif +} tstrJoinBssParam; +/*Bug4218: Parsing Join Param*/ +/*a linked list table containing needed join parameters entries for each AP found in most recent scan*/ +typedef struct _tstrBssTable { + u8 u8noBssEntries; + tstrJoinBssParam *head; + tstrJoinBssParam *tail; +} tstrBssTable; +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +typedef enum { + SCAN_TIMER = 0, + CONNECT_TIMER = 1, + SCAN_CONNECT_TIMER_FORCE_32BIT = 0xFFFFFFFF +} tenuScanConnTimer; + +/*****************************************************************************/ +/* */ +/* Global Variabls */ +/* */ +/*****************************************************************************/ + + +tstrWILC_WFIDrv *terminated_handle = NULL; +tstrWILC_WFIDrv *gWFiDrvHandle = NULL; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +WILC_Bool g_obtainingIP = WILC_FALSE; +#endif +u8 P2P_LISTEN_STATE; +static struct task_struct *HostIFthreadHandler; +static WILC_MsgQueueHandle gMsgQHostIF; +static struct semaphore hSemHostIFthrdEnd; + +struct semaphore hSemDeinitDrvHandle; +static struct semaphore hWaitResponse; +struct semaphore hSemHostIntDeinit; +WILC_TimerHandle g_hPeriodicRSSI; + + + +u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; + +#ifndef CONNECT_DIRECT +static u8 gapu8RcvdSurveyResults[2][MAX_SURVEY_RESULT_FRAG_SIZE]; +#endif + +static u8 gapu8RcvdAssocResp[MAX_ASSOC_RESP_FRAME_SIZE]; + +WILC_Bool gbScanWhileConnected = WILC_FALSE; + +static WILC_Sint8 gs8Rssi; +static WILC_Sint8 gs8lnkspd; +static u8 gu8Chnl; +static u8 gs8SetIP[2][4]; +static u8 gs8GetIP[2][4]; +#ifdef WILC_AP_EXTERNAL_MLME +static WILC_Uint32 gu32InactiveTime; +static u8 gu8DelBcn; +#endif +#ifndef SIMULATION +static WILC_Uint32 gu32WidConnRstHack; +#endif + +/*BugID_5137*/ +u8 *gu8FlushedJoinReq; +u8 *gu8FlushedInfoElemAsoc; +u8 gu8Flushed11iMode; +u8 gu8FlushedAuthType; +WILC_Uint32 gu32FlushedJoinReqSize; +WILC_Uint32 gu32FlushedInfoElemAsocSize; +WILC_Uint32 gu8FlushedJoinReqDrvHandler; +#define REAL_JOIN_REQ 0 +#define FLUSHED_JOIN_REQ 1 +#define FLUSHED_BYTE_POS 79 /* Position the byte indicating flushing in the flushed request */ + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Bug4218: Parsing Join Param*/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +extern void chip_sleep_manually(WILC_Uint32 u32SleepTime); +extern int linux_wlan_get_num_conn_ifcs(void); + +/** + * @brief Handle_SetChannel + * @details Sending config packet to firmware to set channel + * @param[in] tstrHostIFSetChan* pstrHostIFSetChan + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetChannel(void *drvHandler, tstrHostIFSetChan *pstrHostIFSetChan) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Char *)&(pstrHostIFSetChan->u8SetChan); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting channel\n"); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set channel\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +/** + * @brief Handle_SetWfiDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler *pstrHostIfSetDrvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)((pstrHostIfSetDrvHandler->u32Address)); + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_DRV_HANDLER; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetDrvHandler->u32Address); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetDrvHandler->u32Address) == (WILC_Uint32)NULL) { + up(&hSemDeinitDrvHandle); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_SetWfiAPDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetOperationMode(void *drvHandler, tstrHostIfSetOperationMode *pstrHostIfSetOperationMode) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_OPERATION_MODE; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetOperationMode->u32Mode); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + PRINT_INFO(HOSTINF_DBG, "(size_t)pstrWFIDrv= %p \n", pstrWFIDrv); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetOperationMode->u32Mode) == (WILC_Uint32)NULL) { + up(&hSemDeinitDrvHandle); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_set_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, u8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_set_IPAddress(void *drvHandler, u8 *pu8IPAddr, u8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char firmwareIPAddress[4] = {0}; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + if (pu8IPAddr[0] < 192) + pu8IPAddr[0] = 0; + + PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %d.%d.%d.%d \n", idx, pu8IPAddr[0], pu8IPAddr[1], pu8IPAddr[2], pu8IPAddr[3]); + + WILC_memcpy(gs8SetIP[idx], pu8IPAddr, IP_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (u8 *)pu8IPAddr; + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + + host_int_get_ipaddress((WILC_WFIDrvHandle)drvHandler, firmwareIPAddress, idx); + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to set IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address set\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/** + * @brief Handle_get_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, u8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_get_IPAddress(void *drvHandler, u8 *pu8IPAddr, u8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (u8 *)WILC_MALLOC(IP_ALEN); + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", (u8)(strWID.ps8WidVal[0]), (u8)(strWID.ps8WidVal[1]), (u8)(strWID.ps8WidVal[2]), (u8)(strWID.ps8WidVal[3])); + + WILC_memcpy(gs8GetIP[idx], strWID.ps8WidVal, IP_ALEN); + + /*get the value by searching the local copy*/ + WILC_FREE(strWID.ps8WidVal); + + if (WILC_memcmp(gs8GetIP[idx], gs8SetIP[idx], IP_ALEN) != 0) + host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, gs8SetIP[idx], idx); + + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to get IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d \n", idx); + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", gs8GetIP[idx][0], gs8GetIP[idx][1], gs8GetIP[idx][2], gs8GetIP[idx][3]); + PRINT_INFO(HOSTINF_DBG, "\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/*BugId_5077*/ +/** + * @brief Handle_SetMacAddress + * @details Setting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date November 2013 + * @version 7.0 + */ +static WILC_Sint32 Handle_SetMacAddress(void *drvHandler, tstrHostIfSetMacAddress *pstrHostIfSetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + u8 *mac_buf = (u8 *)WILC_MALLOC(ETH_ALEN); + if (mac_buf == NULL) { + PRINT_ER("No buffer to send mac address\n"); + return WILC_FAIL; + } + WILC_memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = mac_buf; + strWID.s32ValueSize = ETH_ALEN; + PRINT_D(GENERIC_DBG, "mac addr = :%x:%x:%x:%x:%x:%x\n", strWID.ps8WidVal[0], strWID.ps8WidVal[1], strWID.ps8WidVal[2], strWID.ps8WidVal[3], strWID.ps8WidVal[4], strWID.ps8WidVal[5]); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_FREE(mac_buf); + return s32Error; +} + + +/*BugID_5213*/ +/** + * @brief Handle_GetMacAddress + * @details Getting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date JAN 2013 + * @version 8.0 + */ +static WILC_Sint32 Handle_GetMacAddress(void *drvHandler, tstrHostIfGetMacAddress *pstrHostIfGetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pstrHostIfGetMacAddress->u8MacAddress; + strWID.s32ValueSize = ETH_ALEN; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to get mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + + } + up(&hWaitResponse); + + return s32Error; +} + + +/** + * @brief Handle_CfgParam + * @details Sending config packet to firmware to set CFG params + * @param[in] tstrHostIFCfgParamAttr* strHostIFCfgParamAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_CfgParam(void *drvHandler, tstrHostIFCfgParamAttr *strHostIFCfgParamAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[32]; + u8 u8WidCnt = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + down(&(pstrWFIDrv->gtOsCfgValuesSem)); + + + PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); + + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BSS_TYPE) { + /*----------------------------------------------------------*/ + /*Input Value: INFRASTRUCTURE = 1, */ + /* INDEPENDENT= 2, */ + /* ANY_BSS= 3 */ + /*----------------------------------------------------------*/ + /* validate input then copy>> need to check value 4 and 5 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.bss_type < 6) { + strWIDList[u8WidCnt].u16WIDid = WID_BSS_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTH_TYPE) { + /*------------------------------------------------------*/ + /*Input Values: OPEN_SYSTEM = 0, */ + /* SHARED_KEY = 1, */ + /* ANY = 2 */ + /*------------------------------------------------------*/ + /*validate Possible values*/ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 1 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 2 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 5) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTHEN_TIMEOUT) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TIMEOUT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & POWER_MANAGEMENT) { + /*-----------------------------------------------------------*/ + /*Input Values: NO_POWERSAVE = 0, */ + /* MIN_FAST_PS = 1, */ + /* MAX_FAST_PS = 2, */ + /* MIN_PSPOLL_PS = 3, */ + /* MAX_PSPOLL_PS = 4 */ + /*----------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode < 5) { + strWIDList[u8WidCnt].u16WIDid = WID_POWER_MANAGEMENT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_SHORT) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_LONG) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_LONG_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & FRAG_THRESHOLD) { + + if (strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold < 7937) { + strWIDList[u8WidCnt].u16WIDid = WID_FRAG_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RTS_THRESHOLD) { + /* range 256 to 65535 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_RTS_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PREAMBLE) { + /*-----------------------------------------------------*/ + /*Input Values: Short= 0, */ + /* Long= 1, */ + /* Auto= 2 */ + /*------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_PREAMBLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.preamble_type = strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SHORT_SLOT_ALLOWED) { + if (strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_SLOT_ALLOWED; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & TXOP_PROT_DISABLE) { + /*Description: used to Disable RTS-CTS protection for TXOP burst*/ + /*transmission when the acknowledgement policy is No-Ack or Block-Ack */ + /* this information is useful for external supplicant */ + /*Input Values: 1 for enable and 0 for disable. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_11N_TXOP_PROT_DISABLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BEACON_INTERVAL) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_BEACON_INTERVAL; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & DTIM_PERIOD) { + /* range is 1 to 255. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period < 256) { + strWIDList[u8WidCnt].u16WIDid = WID_DTIM_PERIOD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.dtim_period = strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY) { + /*----------------------------------------------------------------------*/ + /*Input Values: SITE_SURVEY_1CH = 0, i.e.: currently set channel */ + /* SITE_SURVEY_ALL_CH = 1, */ + /* SITE_SURVEY_OFF = 2 */ + /*----------------------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY_SCAN_TIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & ACTIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_ACTIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PASSIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_PASSIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & CURRENT_TX_RATE) { + CURRENT_TX_RATE_T curr_tx_rate = strHostIFCfgParamAttr->pstrCfgParamVal.curr_tx_rate; + /*----------------------------------------------------------------------*/ + /*Rates: 1 2 5.5 11 6 9 12 18 24 36 48 54 Auto */ + /*InputValues: 1 2 3 4 5 6 7 8 9 10 11 12 0 */ + /*----------------------------------------------------------------------*/ + /* validate rate */ + if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 + || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 + || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 + || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 + || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 + || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { + strWIDList[u8WidCnt].u16WIDid = WID_CURRENT_TX_RATE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&curr_tx_rate; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Error in setting CFG params\n"); + + } + WILC_CATCH(s32Error) + { + } + up(&(pstrWFIDrv->gtOsCfgValuesSem)); + return s32Error; +} + + +/** + * @brief Handle_wait_msg_q_empty + * @details this should be the last msg and then the msg Q becomes idle + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_wait_msg_q_empty(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + g_wilc_initialized = 0; + up(&hWaitResponse); + return s32Error; +} + +/** + * @brief Handle_Scan + * @details Sending config packet to firmware to set the scan params + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Scan(void *drvHandler, tstrHostIFscanAttr *pstrHostIFscanAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + WILC_Uint32 i; + u8 *pu8Buffer; + u8 valuesize = 0; + u8 *pu8HdnNtwrksWidVal = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state \n", pstrWFIDrv->enuHostIFstate); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult; + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg; + + #ifdef WILC_P2P + #if 0 + if (pstrWFIDrv->enuHostIFstate == HOST_IF_P2P_LISTEN || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED && pstrWFIDrv->u8P2PConnect)) { + PRINT_INFO(GENERIC_DBG, "Busy: State: %d\n", pstrWFIDrv->enuHostIFstate); + PRINT_INFO(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + #endif + + if ((pstrWFIDrv->enuHostIFstate >= HOST_IF_SCANNING) && (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTED)) { + /* here we either in HOST_IF_SCANNING, HOST_IF_WAITING_CONN_REQ or HOST_IF_WAITING_CONN_RESP */ + PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", pstrWFIDrv->enuHostIFstate); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount = 0; + + /*BugID_4189*/ + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_SSID_PROBE_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + valuesize += ((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen) + 1); + } + pu8HdnNtwrksWidVal = WILC_MALLOC(valuesize + 1); + strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal; + if (strWIDList[u32WidsCount].ps8WidVal != NULL) { + pu8Buffer = strWIDList[u32WidsCount].ps8WidVal; + + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; + + PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum); + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + WILC_memcpy(pu8Buffer, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen); + pu8Buffer += pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + } + + + + strWIDList[u32WidsCount].s32ValueSize = (WILC_Sint32)(valuesize + 1); + u32WidsCount++; + } + + /*filling cfg param array*/ + + /* if((pstrHostIFscanAttr->pu8IEs != NULL) && (pstrHostIFscanAttr->IEsLen != 0)) */ + { + /* IEs to be inserted in Probe Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_PROBE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8IEs; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->IEsLen; + u32WidsCount++; + } + + /*Scan Type*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanType)); + u32WidsCount++; + + /*list of channels to be scanned*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_CHANNEL_LIST; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + + /* Bug 4648: Convert channel numbers to start from 0 not 1. */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL && pstrHostIFscanAttr->u8ChnlListLen > 0) { + int i; + + for (i = 0; i < pstrHostIFscanAttr->u8ChnlListLen; i++) { + if (pstrHostIFscanAttr->pu8ChnlFreqList[i] > 0) { + pstrHostIFscanAttr->pu8ChnlFreqList[i] = pstrHostIFscanAttr->pu8ChnlFreqList[i] - 1; + } + } + } + + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8ChnlFreqList; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->u8ChnlListLen; + u32WidsCount++; + + /*Scan Request*/ + strWIDList[u32WidsCount].u16WIDid = WID_START_SCAN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanSource)); + u32WidsCount++; + + /*keep the state as is , no need to change it*/ + /* gWFiDrvHandle->enuHostIFstate = HOST_IF_SCANNING; */ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + gbScanWhileConnected = WILC_TRUE; + } else if (pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE) { + gbScanWhileConnected = WILC_FALSE; + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } else { + PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n"); + } + + WILC_CATCH(s32Error) + { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), NULL); + /*if there is an ongoing scan request*/ + Handle_ScanDone(drvHandler, SCAN_EVENT_ABORTED); + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + /* Deallocate pstrHostIFscanAttr->pu8IEs which was previously allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8IEs); + pstrHostIFscanAttr->pu8IEs = NULL; + } + if (pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo != NULL) { + WILC_FREE(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo); + pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo = NULL; + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + if (pu8HdnNtwrksWidVal != NULL) { + WILC_FREE(pu8HdnNtwrksWidVal); + } + + return s32Error; +} + +/** + * @brief Handle_ScanDone + * @details Call scan notification callback function + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ScanDone(void *drvHandler, tenuScanEvent enuEvent) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + u8 u8abort_running_scan; + tstrWID strWID; + + + PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n"); + + /*BugID_4978*/ + /*Ask FW to abort the running scan, if any*/ + if (enuEvent == SCAN_EVENT_ABORTED) { + PRINT_D(GENERIC_DBG, "Abort running scan\n"); + u8abort_running_scan = 1; + strWID.u16WIDid = (WILC_Uint16)WID_ABORT_RUNNING_SCAN; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u8abort_running_scan; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set abort running scan\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + } + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + /*delete current scan request*/ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Connect + * @details Sending config packet to firmware to starting connection + * @param[in] tstrHostIFconnectAttr* pstrHostIFconnectAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +u8 u8ConnectedSSID[6] = {0}; +static WILC_Sint32 Handle_Connect(void *drvHandler, tstrHostIFconnectAttr *pstrHostIFconnectAttr) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[8]; + WILC_Uint32 u32WidsCount = 0, dummyval = 0; + /* char passphrase[] = "12345678"; */ + #ifndef CONNECT_DIRECT + WILC_Sint32 s32Err = WILC_SUCCESS; + WILC_Uint32 i; + u8 u8bssDscListIndex; + wid_site_survey_reslts_s *pstrSurveyResults = NULL; + #else + u8 *pu8CurrByte = NULL; + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + tstrJoinBssParam *ptstrJoinBssParam; + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + #endif + + PRINT_D(GENERIC_DBG, "Handling connect request\n"); + + #ifndef CONNECT_DIRECT + WILC_memset(gapu8RcvdSurveyResults[0], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + WILC_memset(gapu8RcvdSurveyResults[1], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + + + PRINT_D(HOSTINF_DBG, "Getting site survey results\n"); + s32Err = host_int_get_site_survey_results((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdSurveyResults, + MAX_SURVEY_RESULT_FRAG_SIZE); + if (s32Err) { + PRINT_ER("Failed to get site survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } + s32Err = ParseSurveyResults(gapu8RcvdSurveyResults, &pstrSurveyResults, + &pstrWFIDrv->u32SurveyResultsCount); + + + if (s32Err == WILC_SUCCESS) { + /* use the parsed info in pstrSurveyResults, then deallocate it */ + PRINT_D(HOSTINF_DBG, "Copying site survey results in global structure, then deallocate\n"); + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + WILC_memcpy(&pstrWFIDrv->astrSurveyResults[i], &pstrSurveyResults[i], + sizeof(wid_site_survey_reslts_s)); + } + + DeallocateSurveyResults(pstrSurveyResults); + } else { + WILC_ERRORREPORT(s32Error, WILC_FAIL); + PRINT_ER("ParseSurveyResults() Error(%d) \n", s32Err); + } + + + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].SSID, + pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen) == 0) { + PRINT_INFO(HOSTINF_DBG, "Network with required SSID is found %s\n", pstrHostIFconnectAttr->pu8ssid); + if (pstrHostIFconnectAttr->pu8bssid == NULL) { + /* BSSID is not passed from the user, so decision of matching + * is done by SSID only */ + PRINT_INFO(HOSTINF_DBG, "BSSID is not passed from the user\n"); + break; + } else { + /* BSSID is also passed from the user, so decision of matching + * should consider also this passed BSSID */ + + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].BSSID, + pstrHostIFconnectAttr->pu8bssid, + 6) == 0) { + PRINT_INFO(HOSTINF_DBG, "BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if (i < pstrWFIDrv->u32SurveyResultsCount) { + u8bssDscListIndex = i; + + PRINT_INFO(HOSTINF_DBG, "Connecting to network of Bss Idx %d and SSID %s and channel %d \n", + u8bssDscListIndex, pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].SSID, + pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].Channel); + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (u8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (u8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (u8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)&u8bssDscListIndex; + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + + } else { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + + #else + + /* if we try to connect to an already connected AP then discard the request */ + + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + + s32Error = WILC_SUCCESS; + PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); + return s32Error; + } + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + ptstrJoinBssParam = (tstrJoinBssParam *)pstrHostIFconnectAttr->pJoinParams; + if (ptstrJoinBssParam == NULL) { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + +#if 0 + /* if we try to connect to an already connected AP then discard the request */ + PRINT_D(GENERIC_DBG, "Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + PRINT_ER("Discard connect request\n"); + s32Error = WILC_FAIL; + return s32Error; + } +#endif + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (u8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (u8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (u8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + + gu32FlushedInfoElemAsocSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + gu8FlushedInfoElemAsoc = WILC_MALLOC(gu32FlushedInfoElemAsocSize); + memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + gu32FlushedInfoElemAsocSize); + } + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8Flushed11iMode = pstrWFIDrv->strWILC_UsrConnReq.u8security; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8FlushedAuthType = (u8)pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n", + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->u8channel); + + +#ifndef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = MAX_SSID_LEN + 7; + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + if (strWIDList[u32WidsCount].ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + #else + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + /*Sending NoA attributes during connection*/ + strWIDList[u32WidsCount].s32ValueSize = 112; /* 79; */ + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize; + gu8FlushedJoinReq = WILC_MALLOC(gu32FlushedJoinReqSize); + } + if (strWIDList[u32WidsCount].ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + + /* BSS type*/ + *(pu8CurrByte++) = INFRASTRUCTURE; + /* Channel*/ + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + /* Cap Info*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + + /* sa*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* bssid*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* Beacon Period*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + /* DTIM Period*/ + *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period; + PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1))); + /* Supported rates*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1); + pu8CurrByte += (MAX_RATES_SUPPORTED + 1); + + /* wmm cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap; + PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1))); + /* uapsd cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap; + + /* ht cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable; + /* copy this information to the user request */ + pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable; + + /* rsn found*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found; + PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1)); + /* rsn group policy*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy; + PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1))); + /* mode_802_11i*/ + *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i; + PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1))); + /* rsn pcip policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap); + + /*BugID_5137*/ + *(pu8CurrByte++) = REAL_JOIN_REQ; + + #ifdef WILC_P2P + *(pu8CurrByte++) = ptstrJoinBssParam->u8NoaEnbaled; + if (ptstrJoinBssParam->u8NoaEnbaled) { + PRINT_D(HOSTINF_DBG, "NOA present\n"); + + *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Index; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8OppEnable; + + if (ptstrJoinBssParam->u8OppEnable) + *(pu8CurrByte++) = ptstrJoinBssParam->u8CtWindow; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Count; + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Duration, sizeof(ptstrJoinBssParam->au8Duration)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Duration); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Interval, sizeof(ptstrJoinBssParam->au8Interval)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Interval); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof(ptstrJoinBssParam->au8StartTime)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8StartTime); + + } else + PRINT_D(HOSTINF_DBG, "NOA not present\n"); + #endif + + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + #endif /* #ifdef WILC_PARSE_SCAN_IN_HOST*/ + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize); + gu8FlushedJoinReqDrvHandler = (WILC_Uint32)pstrWFIDrv; + } + + PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->pu8bssid, ETH_ALEN); + + PRINT_D(GENERIC_DBG, "save Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "save bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + #endif + + WILC_CATCH(s32Error) + { + tstrConnectInfo strConnectInfo; + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), NULL); + + PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (pstrHostIFconnectAttr->pfConnectResult != NULL) { + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen; + strConnectInfo.pu8ReqIEs = (u8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrHostIFconnectAttr->pfConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrHostIFconnectAttr->pvUserArg); + /*Change state to idle*/ + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* Deallocation */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + } + + PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n"); + /* Deallocate pstrHostIFconnectAttr->pu8bssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8bssid); + pstrHostIFconnectAttr->pu8bssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8ssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8ssid); + pstrHostIFconnectAttr->pu8ssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8IEs which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8IEs); + pstrHostIFconnectAttr->pu8IEs = NULL; + } + + if (pu8CurrByte != NULL) { + WILC_FREE(pu8CurrByte); + } + return s32Error; +} + +/** + * @brief Handle_FlushConnect + * @details Sending config packet to firmware to flush an old connection + * after switching FW from station one to hybrid one + * @param[in] void * drvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +static WILC_Sint32 Handle_FlushConnect(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + u8 *pu8CurrByte = NULL; + + + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = gu8FlushedInfoElemAsoc; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedInfoElemAsocSize; + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(gu8Flushed11iMode)); + u32WidsCount++; + + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&gu8FlushedAuthType); + u32WidsCount++; + + + #ifdef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedJoinReqSize; + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)gu8FlushedJoinReq; + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + pu8CurrByte += FLUSHED_BYTE_POS; + *(pu8CurrByte) = FLUSHED_JOIN_REQ; + + u32WidsCount++; + + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, gu8FlushedJoinReqDrvHandler); + if (s32Error) { + PRINT_ER("Handle_Flush_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_ConnectTimeout + * @details Call connect notification callback function indicating connection failure + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ConnectTimeout(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectInfo strConnectInfo; + tstrWID strWID; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + + /* First, we will notify the upper layer with the Connection failure {through the Connect Callback function}, + * then we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (u8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + /* Deallocation of strConnectInfo.pu8ReqIEs */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + + /* Here we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + } + + /* Deallocation of the Saved Connect Request in the global Handle */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + /*BugID_5213*/ + /*Freeing flushed join request params on connect timeout*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdNtwrkInfo + * @details Handling received network information + * @param[in] tstrRcvdNetworkInfo* pstrRcvdNetworkInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdNtwrkInfo(void *drvHandler, tstrRcvdNetworkInfo *pstrRcvdNetworkInfo) +{ + WILC_Uint32 i; + WILC_Bool bNewNtwrkFound; + + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = NULL; + void *pJoinParams = NULL; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + bNewNtwrkFound = WILC_TRUE; + PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); + + /*if there is a an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); + ParseNetworkInfo(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo); + if ((pstrNetworkInfo == NULL) + || (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult == NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* check whether this network is discovered before */ + for (i = 0; i < pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount; i++) { + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) && + (pstrNetworkInfo->au8bssid != NULL)) { + if (WILC_memcmp(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) { + if (pstrNetworkInfo->s8rssi <= pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) { + /*we have already found this network with better rssi, so keep the old cached one and don't + * send anything to the upper layer */ + PRINT_D(HOSTINF_DBG, "Network previously discovered\n"); + goto done; + } else { + /* here the same already found network is found again but with a better rssi, so just update + * the rssi for this cached network and send this updated network to the upper layer but + * don't add a new record for it */ + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi; + bNewNtwrkFound = WILC_FALSE; + break; + } + } + } + } + + if (bNewNtwrkFound == WILC_TRUE) { + /* here it is confirmed that it is a new discovered network, + * so add its record then call the User CallBack function */ + + PRINT_D(HOSTINF_DBG, "New network found\n"); + + if (pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid != NULL) + && (pstrNetworkInfo->au8bssid != NULL)) { + WILC_memcpy(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid, + pstrNetworkInfo->au8bssid, 6); + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount++; + + pstrNetworkInfo->bNewNetwork = WILC_TRUE; + /*Bug4218: Parsing Join Param*/ + /* add new BSS to JoinBssTable */ + #ifdef WILC_PARSE_SCAN_IN_HOST + pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, + pJoinParams); + + + } + } else { + PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit \n"); + } + } else { + pstrNetworkInfo->bNewNetwork = WILC_FALSE; + /* just call the User CallBack function to send the same discovered network with its updated RSSI */ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + } + } + + + WILC_CATCH(s32Error) + { + + } + +done: + /* Deallocate pstrRcvdNetworkInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdNetworkInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdNetworkInfo->pu8Buffer); + pstrRcvdNetworkInfo->pu8Buffer = NULL; + } + + /*free structure allocated*/ + if (pstrNetworkInfo != NULL) { + DeallocateNetworkInfo(pstrNetworkInfo); + pstrNetworkInfo = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdGnrlAsyncInfo + * @details Handling received asynchrous general network information + * @param[in] tstrRcvdGnrlAsyncInfo* pstrRcvdGnrlAsyncInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdGnrlAsyncInfo(void *drvHandler, tstrRcvdGnrlAsyncInfo *pstrRcvdGnrlAsyncInfo) +{ + /* TODO: mostafa: till now, this function just handles only the received mac status msg, */ + /* which carries only 1 WID which have WID ID = WID_STATUS */ + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 u8MsgType = 0; + u8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + u8 u8WidLen = 0; + u8 u8MacStatus; + u8 u8MacStatusReasonCode; + u8 u8MacStatusAdditionalInfo; + tstrConnectInfo strConnectInfo; + tstrDisconnectNotifInfo strDisconnectNotifInfo; + WILC_Sint32 s32Err = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + } + PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", pstrWFIDrv->enuHostIFstate, + pstrRcvdGnrlAsyncInfo->pu8Buffer[7]); + + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) || + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + if ((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) || + (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + u8MsgType = pstrRcvdGnrlAsyncInfo->pu8Buffer[0]; + + /* Check whether the received message type is 'I' */ + if ('I' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pstrRcvdGnrlAsyncInfo->pu8Buffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[2], pstrRcvdGnrlAsyncInfo->pu8Buffer[3]); + + /* Extract WID ID [expected to be = WID_STATUS] */ + u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[4], pstrRcvdGnrlAsyncInfo->pu8Buffer[5]); + + /* Extract WID Length [expected to be = 1] */ + u8WidLen = pstrRcvdGnrlAsyncInfo->pu8Buffer[6]; + + /* get the WID value [expected to be one of two values: either MAC_CONNECTED = (1) or MAC_DISCONNECTED = (0)] */ + u8MacStatus = pstrRcvdGnrlAsyncInfo->pu8Buffer[7]; + u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->pu8Buffer[8]; + u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->pu8Buffer[9]; + PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + /* our station had sent Association Request frame, so here it will get the Association Response frame then parse it */ + WILC_Uint32 u32RcvdAssocRespInfoLen; + tstrConnectRespInfo *pstrConnectRespInfo = NULL; + + PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (u8MacStatus == MAC_CONNECTED) { + WILC_memset(gapu8RcvdAssocResp, 0, MAX_ASSOC_RESP_FRAME_SIZE); + + host_int_get_assoc_res_info((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdAssocResp, + MAX_ASSOC_RESP_FRAME_SIZE, + &u32RcvdAssocRespInfoLen); + + PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen); + + if (u32RcvdAssocRespInfoLen != 0) { + + PRINT_D(HOSTINF_DBG, "Parsing association response\n"); + s32Err = ParseAssocRespInfo(gapu8RcvdAssocResp, u32RcvdAssocRespInfoLen, + &pstrConnectRespInfo); + if (s32Err) { + PRINT_ER("ParseAssocRespInfo() returned error %d \n", s32Err); + } else { + /* use the necessary parsed Info from the Received Association Response */ + strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus; + + if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n"); + if (pstrConnectRespInfo->pu8RespIEs != NULL) { + strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen; + + + strConnectInfo.pu8RespIEs = (u8 *)WILC_MALLOC(pstrConnectRespInfo->u16RespIEsLen); + WILC_memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs, + pstrConnectRespInfo->u16RespIEsLen); + } + } + + /* deallocate the Assoc. Resp. parsed structure as it is not needed anymore */ + if (pstrConnectRespInfo != NULL) { + DeallocateAssocRespInfo(pstrConnectRespInfo); + pstrConnectRespInfo = NULL; + } + } + } + } + + /* The station has just received mac status and it also received assoc. response which + * it was waiting for. + * So check first the matching between the received mac status and the received status code in Asoc Resp */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { + PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE \n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + } else if (u8MacStatus == MAC_DISCONNECTED) { + PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + } + + /* TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP */ + /* through a structure of type tstrConnectRespInfo */ + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n"); + WILC_memcpy(strConnectInfo.au8bssid, pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + WILC_memcpy(pstrWFIDrv->au8AssociatedBSSID, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN); + } + } + + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (u8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), NULL); + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + u8MacStatus, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + + /* if received mac status is MAC_CONNECTED and + * received status code in Asoc Resp is SUCCESSFUL_STATUSCODE, change state to CONNECTED + * else change state to IDLE */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTED; + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); + g_obtainingIP = WILC_TRUE; + WILC_TimerStart(&hDuringIpTimer, 10000, NULL, NULL); + #endif + + #ifdef WILC_PARSE_SCAN_IN_HOST + /* open a BA session if possible */ + /* if(pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable) */ + + #endif + + /* host_int_addBASession(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid,0, */ + /* BA_SESSION_DEFAULT_BUFFER_SIZE,BA_SESSION_DEFAULT_TIMEOUT); */ + } else { + PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + } + + /* Deallocation */ + if (strConnectInfo.pu8RespIEs != NULL) { + WILC_FREE(strConnectInfo.pu8RespIEs); + strConnectInfo.pu8RespIEs = NULL; + } + + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)) { + /* Disassociation or Deauthentication frame has been received */ + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >> \n\n"); + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), NULL); + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + } + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + } else { + PRINT_ER("Connect result callback function is NULL \n"); + } + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + + /* if Information Elements were retrieved from the Received deauth/disassoc frame, then they + * should be deallocated here */ + /* + * if(strDisconnectNotifInfo.ie != NULL) + * { + * WILC_FREE(strDisconnectNotifInfo.ie); + * strDisconnectNotifInfo.ie = NULL; + * } + */ + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + /*BugID_5213*/ + /*Freeing flushed join request params on receiving*/ + /*MAC_DISCONNECTED while connected*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL)) { + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >> \n\n"); + /*Abort the running scan*/ + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), NULL); + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + + } + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* Deallocate pstrRcvdGnrlAsyncInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdGnrlAsyncInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdGnrlAsyncInfo->pu8Buffer); + pstrRcvdGnrlAsyncInfo->pu8Buffer = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Key + * @details Sending config packet to firmware to set key + * @param[in] tstrHostIFkeyAttr* pstrHostIFkeyAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static int Handle_Key(void *drvHandler, tstrHostIFkeyAttr *pstrHostIFkeyAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + #ifdef WILC_AP_EXTERNAL_MLME + tstrWID strWIDList[5]; + #endif + u8 i; + u8 *pu8keybuf; + WILC_Sint8 s8idxarray[1]; + WILC_Sint8 ret = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + switch (pstrHostIFkeyAttr->enuKeyType) { + + + case WEP: + +#ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8mode)); + + strWIDList[1].u16WIDid = WID_AUTH_TYPE; + strWIDList[1].enuWIDtype = WID_CHAR; + strWIDList[1].s32ValueSize = sizeof(WILC_Char); + strWIDList[1].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type)); + + strWIDList[2].u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWIDList[2].enuWIDtype = WID_CHAR; + + strWIDList[2].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[2].s32ValueSize = sizeof(WILC_Char); + + + pu8keybuf = (u8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWIDList[3].u16WIDid = (WILC_Uint16)WID_WEP_KEY_VALUE; + strWIDList[3].enuWIDtype = WID_STR; + strWIDList[3].s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen; + strWIDList[3].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + + } +#endif + + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + pu8keybuf = (u8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + + WILC_memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, 1); + + WILC_memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_WEP_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + } else if (pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY) { + + PRINT_D(HOSTINF_DBG, "Removing key\n"); + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_WEP_KEY; + strWID.enuWIDtype = WID_STR; + + s8idxarray[0] = (WILC_Sint8)pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + strWID.ps8WidVal = s8idxarray; + strWID.s32ValueSize = 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } else { + strWID.u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting default key index\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } + up(&(pstrWFIDrv->hSemTestKeyBlock)); + break; + + case WPARxGtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + pu8keybuf = (u8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + + + if (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq != NULL) + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + /* pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = 0X51; */ + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + up(&(pstrWFIDrv->hSemTestKeyBlock)); + /* ///////////////////////// */ + } + + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n"); + + pu8keybuf = (u8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_memcpy(pu8keybuf, pstrWFIDrv->au8AssociatedBSSID, ETH_ALEN); + } else { + PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED \n"); + } + + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + up(&(pstrWFIDrv->hSemTestKeyBlock)); + /* ///////////////////////// */ + } +_WPARxGtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq); + if (ret == -1) + return ret; + + break; + + case WPAPtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + + pu8keybuf = (u8 *)WILC_MALLOC(PTK_KEY_MSG_LEN + 1); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | keyidx |Key Length |Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------ |--------------|----------------|---------------| + | 6 bytes | 1 byte | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + WILC_memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN + 1; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + up(&(pstrWFIDrv->hSemTestKeyBlock)); + /* ///////////////////////// */ + } + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + + + pu8keybuf = (u8 *)WILC_MALLOC(PTK_KEY_MSG_LEN); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = PTK_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + up(&(pstrWFIDrv->hSemTestKeyBlock)); + /* ///////////////////////// */ + } + +_WPAPtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + if (ret == -1) + return ret; + + break; + + + case PMKSA: + + PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n"); + + pu8keybuf = (u8 *)WILC_MALLOC((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PMKSA Key\n"); + return -1; + } + + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; + + for (i = 0; i < pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; i++) { + + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, ETH_ALEN); + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, PMKID_LEN); + } + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + break; + } + + if (s32Error) + PRINT_ER("Failed to send key config packet\n"); + + + return s32Error; +} + + +/** + * @brief Handle_Disconnect + * @details Sending config packet to firmware to disconnect + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_Disconnect(void *drvHandler) +{ + tstrWID strWID; + + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } else { + tstrDisconnectNotifInfo strDisconnectNotifInfo; + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), NULL); + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + + /*BugID_5193*/ + /*Stop connect timer, if connection in progress*/ + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), NULL); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, + 0, &strDisconnectNotifInfo, pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + } else { + PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL \n"); + } + + gbScanWhileConnected = WILC_FALSE; + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + + /*BugID_5137*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* ////////////////////////// */ + up(&(pstrWFIDrv->hSemTestDisconnectBlock)); + /* ///////////////////////// */ + +} + + +void resolve_disconnect_aberration(void *drvHandler) +{ + tstrWILC_WFIDrv *pstrWFIDrv; + + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + if (pstrWFIDrv == NULL) + return; + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTING)) { + PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); + host_int_disconnect((WILC_WFIDrvHandle)pstrWFIDrv, 1); + } +} +static WILC_Sint32 Switch_Log_Terminal(void *drvHandler) +{ + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + static char dummy = 9; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_LOGTerminal_Switch; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &dummy; + strWID.s32ValueSize = sizeof(WILC_Char); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to switch log terminal\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "MAC address set :: \n"); + + + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_GetChnl + * @details Sending config packet to get channel + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_GetChnl(void *drvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&gu8Chnl; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Getting channel value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get channel number\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + WILC_CATCH(s32Error) + { + + } + up(&(pstrWFIDrv->hSemGetCHNL)); + + return s32Error; + + + +} + + +/** + * @brief Handle_GetRssi + * @details Sending config packet to get RSSI + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_GetRssi(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_RSSI; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8Rssi; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get RSSI value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + up(&(pstrWFIDrv->hSemGetRSSI)); + + +} + + +static void Handle_GetLinkspeed(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + gs8lnkspd = 0; + + strWID.u16WIDid = (WILC_Uint16)WID_LINKSPEED; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8lnkspd; + strWID.s32ValueSize = sizeof(WILC_Char); + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get LINKSPEED value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + up(&(pstrWFIDrv->hSemGetLINKSPEED)); + + +} + +WILC_Sint32 Handle_GetStatistics(void *drvHandler, tstrStatistics *pstrStatistics) +{ + tstrWID strWIDList[5]; + uint32_t u32WidsCount = 0, s32Error = 0; + + strWIDList[u32WidsCount].u16WIDid = WID_LINKSPEED; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u8LinkSpeed)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RSSI; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->s8RSSI)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32RxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxFailureCount)); + u32WidsCount++; + + s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)drvHandler); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + /* WILC_ERRORREPORT(s32Error, s32Error); */ + } + up(&hWaitResponse); + return 0; + +} + + +#ifdef WILC_AP_EXTERNAL_MLME + + +/** + * @brief Handle_Get_InActiveTime + * @details Sending config packet to set mac adddress for station and + * get inactive time + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Get_InActiveTime(void *drvHandler, tstrHostIfStaInactiveT *strHostIfStaInactiveT) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 *stamac; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_SET_STA_MAC_INACTIVE_TIME; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = ETH_ALEN; + strWID.ps8WidVal = (u8 *)WILC_MALLOC(strWID.s32ValueSize); + + + stamac = strWID.ps8WidVal; + WILC_memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN); + + + PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); + + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to SET incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + strWID.u16WIDid = (WILC_Uint16)WID_GET_INACTIVE_TIME; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&gu32InactiveTime; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", gu32InactiveTime); + + up(&(pstrWFIDrv->hSemInactiveTime)); + WILC_CATCH(s32Error) + { + + } + + + return s32Error; + + + +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to add beacon + * @param[in] tstrHostIFSetBeacon* pstrSetBeaconParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddBeacon(void *drvHandler, tstrHostIFSetBeacon *pstrSetBeaconParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_BEACON; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen + pstrSetBeaconParam->u32TailLen + 16; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (pstrSetBeaconParam->u32Interval & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32DTIMPeriod & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32HeadLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 24) & 0xFF); + + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Head, pstrSetBeaconParam->u32HeadLen); + pu8CurrByte += pstrSetBeaconParam->u32HeadLen; + + *pu8CurrByte++ = (pstrSetBeaconParam->u32TailLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 24) & 0xFF); + + /* Bug 4599 : if tail length = 0 skip copying */ + if (pstrSetBeaconParam->pu8Tail > 0) + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Tail, pstrSetBeaconParam->u32TailLen); + pu8CurrByte += pstrSetBeaconParam->u32TailLen; + + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send add beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Head); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Tail); +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to delete beacon + * @param[in] tstrHostIFDelBeacon* pstrDelBeacon + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelBeacon(void *drvHandler, tstrHostIFDelBeacon *pstrDelBeacon) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_BEACON; + strWID.enuWIDtype = WID_CHAR; + strWID.s32ValueSize = sizeof(WILC_Char); + strWID.ps8WidVal = &gu8DelBcn; + + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); + /* TODO: build del beacon message*/ + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send delete beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } +} + + +/** + * @brief WILC_HostIf_PackStaParam + * @details Handling packing of the station params in a buffer + * @param[in] u8* pu8Buffer, tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static WILC_Uint32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, tstrWILC_AddStaParam *pstrStationParam) +{ + u8 *pu8CurrByte; + + pu8CurrByte = pu8Buffer; + + PRINT_D(HOSTINF_DBG, "Packing STA params\n"); + WILC_memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN); + pu8CurrByte += ETH_ALEN; + + *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8NumRates; + if (pstrStationParam->u8NumRates > 0) { + WILC_memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates); + } + pu8CurrByte += pstrStationParam->u8NumRates; + + *pu8CurrByte++ = pstrStationParam->bIsHTSupported; + *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8AmpduParams; + WILC_memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); + pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; + + *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8ASELCap; + + *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF; + + return pu8CurrByte - pu8Buffer; +} + +/** + * @brief Handle_AddStation + * @details Sending config packet to add station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Handling add station\n"); + strWID.u16WIDid = (WILC_Uint16)WID_ADD_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + + PRINT_ER("Failed to send add station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + +/** + * @brief Handle_DelAllSta + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelAllSta(void *drvHandler, tstrHostIFDelAllSta *pstrDelAllStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + u8 i; + UWORD8 au8Zero_Buff[6] = {0}; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_STA; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = (pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *(pu8CurrByte++) = pstrDelAllStaParam->u8Num_AssocSta; + + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pstrDelAllStaParam->au8Sta_DelAllSta[i], au8Zero_Buff, ETH_ALEN)) + WILC_memcpy(pu8CurrByte, pstrDelAllStaParam->au8Sta_DelAllSta[i], ETH_ALEN); + else + continue; + + pu8CurrByte += ETH_ALEN; + } + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + + up(&hWaitResponse); +} + + +/** + * @brief Handle_DelStation + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelStation(void *drvHandler, tstrHostIFDelSta *pstrDelStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = ETH_ALEN; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + WILC_memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_EditStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_EDIT_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + PRINT_D(HOSTINF_DBG, "Handling edit station\n"); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send edit station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} +#endif /*WILC_AP_EXTERNAL_MLME*/ + +#ifdef WILC_P2P +/** + * @brief Handle_RemainOnChan + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RemainOnChan(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 u8remain_on_chan_flag; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + /*If it's a pendig remain-on-channel, don't overwrite gWFiDrvHandle values (since incoming msg is garbbage)*/ + if (!pstrWFIDrv->u8RemainOnChan_pendingreq) { + pstrWFIDrv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; + pstrWFIDrv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel; + pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; + } else { + /*Set the channel to use it as a wid val*/ + pstrHostIfRemainOnChan->u16Channel = pstrWFIDrv->strHostIfRemainOnChan.u16Channel; + } + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n"); + pstrWFIDrv->u8RemainOnChan_pendingreq = 1; + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel); + + u8remain_on_chan_flag = WILC_TRUE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = (WILC_Sint8 *)WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = (WILC_Sint8)pstrHostIfRemainOnChan->u16Channel; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + } + + WILC_CATCH(-1) + { + P2P_LISTEN_STATE = 1; + WILC_TimerStart(&(pstrWFIDrv->hRemainOnChannel), pstrHostIfRemainOnChan->u32duration, (void *)pstrWFIDrv, NULL); + + /*Calling CFG ready_on_channel*/ + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady(pstrWFIDrv->strHostIfRemainOnChan.pVoid); + } + + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + pstrWFIDrv->u8RemainOnChan_pendingreq = 0; + } + return s32Error; +} + +/** + * @brief Handle_RegisterFrame + * @details + * @param[in] + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RegisterFrame(void *drvHandler, tstrHostIfRegisterFrame *pstrHostIfRegisterFrame) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_REGISTER_FRAME; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = WILC_MALLOC(sizeof(WILC_Uint16) + 2); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg; + *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; + WILC_memcpy(pu8CurrByte, &(pstrHostIfRegisterFrame->u16FrameType), sizeof(WILC_Uint16)); + + + strWID.s32ValueSize = sizeof(WILC_Uint16) + 2; + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to frame register config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + +/** + * @brief Handle_ListenStateExpired + * @details Handle of listen state expiration + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +#define FALSE_FRMWR_CHANNEL 100 +static WILC_Uint32 Handle_ListenStateExpired(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + u8 u8remain_on_chan_flag; + tstrWID strWID; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n"); + + /*BugID_5477*/ + /*Make sure we are already in listen state*/ + /*This is to handle duplicate expiry messages (listen timer fired and supplicant called cancel_remain_on_channel())*/ + if (P2P_LISTEN_STATE) { + u8remain_on_chan_flag = WILC_FALSE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == NULL) { + PRINT_ER("Failed to allocate memory\n"); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = FALSE_FRMWR_CHANNEL; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + goto _done_; + } + + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired(pstrWFIDrv->strHostIfRemainOnChan.pVoid + , pstrHostIfRemainOnChan->u32ListenSessionID); + } + P2P_LISTEN_STATE = 0; + } else { + PRINT_D(GENERIC_DBG, "Not in listen state\n"); + s32Error = WILC_FAIL; + } + +_done_: + return s32Error; +} + + +/** + * @brief ListenTimerCB + * @details Callback function of remain-on-channel timer + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static void ListenTimerCB(void *pvArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), NULL); + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = pstrWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } +} +#endif + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_PowerManagement(void *drvHandler, tstrHostIfPowerMgmtParam *strPowerMgmtParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Sint8 s8PowerMode; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_POWER_MANAGEMENT; + + if (strPowerMgmtParam->bIsEnabled == WILC_TRUE) { + s8PowerMode = MIN_FAST_PS; + } else { + s8PowerMode = NO_POWERSAVE; + } + PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode); + strWID.ps8WidVal = &s8PowerMode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send power management config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } +} + +/** + * @brief Handle_SetMulticastFilter + * @details Set Multicast filter in firmware + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author asobhy + * @date + * @version 1.0 + */ +static void Handle_SetMulticastFilter(void *drvHandler, tstrHostIFSetMulti *strHostIfSetMulti) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + u8 *pu8CurrByte; + + PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_SETUP_MULTICAST_FILTER; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = sizeof(tstrHostIFSetMulti) + ((strHostIfSetMulti->u32count) * ETH_ALEN); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (strHostIfSetMulti->bIsEnabled & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 24) & 0xFF); + + *pu8CurrByte++ = (strHostIfSetMulti->u32count & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 24) & 0xFF); + + if ((strHostIfSetMulti->u32count) > 0) + memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN)); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to send setup multicast config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + +} + + +/*BugID_5222*/ +/** + * @brief Handle_AddBASession + * @details Add block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2014 + * @version 9.0 + */ +static WILC_Sint32 Handle_AddBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + int AddbaTimeout = 100; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d \nBufferSize == %d \nSessionTimeOut = %d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u16BufferSize, + strHostIfBASessionInfo->u16SessionTimeout, + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (u8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x0; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA Policy*/ + *ptr++ = 1; + /* Buffer size*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF); + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /* ADDBA timeout*/ + *ptr++ = (AddbaTimeout & 0xFF); + *ptr++ = ((AddbaTimeout >> 16) & 0xFF); + /* Group Buffer Max Frames*/ + *ptr++ = 8; + /* Group Buffer Timeout */ + *ptr++ = 0; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* Max Num MSDU */ + *ptr++ = 8; + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /*Ack-Policy */ + *ptr++ = 3; + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + return s32Error; + +} + + +/*BugID_5222*/ +/** + * @brief Handle_DelBASession + * @details Delete block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (u8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x3; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + up(&hWaitResponse); + + return s32Error; + +} + + +/** + * @brief Handle_DelAllRxBASessions + * @details Delete all Rx BA sessions + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Abdelrahman Sobhy + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelAllRxBASessions(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_RX_BA; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (u8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + up(&hWaitResponse); + + return s32Error; + +} + +/** + * @brief hostIFthread + * @details Main thread to handle message queue requests + * @param[in] void* pvArg + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int hostIFthread(void *pvArg) +{ + WILC_Uint32 u32Ret; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + while (1) { + WILC_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret, NULL); + pstrWFIDrv = (tstrWILC_WFIDrv *)strHostIFmsg.drvHandler; + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT) { + PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); + break; + } + + + /*Re-Queue HIF message*/ + if ((!g_wilc_initialized)) { + PRINT_D(GENERIC_DBG, "--WAIT--"); + WILC_Sleep(200); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + continue; + } + + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_CONNECT && pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + WILC_Sleep(2); + continue; + } + + switch (strHostIFmsg.u16MsgId) { + case HOST_IF_MSG_Q_IDLE: + Handle_wait_msg_q_empty(); + break; + + case HOST_IF_MSG_SCAN: + Handle_Scan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr); + break; + + case HOST_IF_MSG_CONNECT: + Handle_Connect(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr); + break; + + /*BugID_5137*/ + case HOST_IF_MSG_FLUSH_CONNECT: + Handle_FlushConnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_NTWRK_INFO: + Handle_RcvdNtwrkInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo); + break; + + case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: + Handle_RcvdGnrlAsyncInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo); + break; + + case HOST_IF_MSG_KEY: + Handle_Key(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr); + break; + + case HOST_IF_MSG_CFG_PARAMS: + + Handle_CfgParam(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr); + break; + + case HOST_IF_MSG_SET_CHANNEL: + Handle_SetChannel(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan); + break; + + case HOST_IF_MSG_DISCONNECT: + Handle_Disconnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_SCAN_COMPLETE: + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), NULL); + PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); + + /*BugID_5213*/ + /*Allow chip sleep, only if both interfaces are not connected*/ + if (!linux_wlan_get_num_conn_ifcs()) { + chip_sleep_manually(INFINITE_SLEEP_TIME); + } + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_DONE); + + #ifdef WILC_P2P + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + #endif + + break; + + case HOST_IF_MSG_GET_RSSI: + Handle_GetRssi(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_LINKSPEED: + Handle_GetLinkspeed(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_STATISTICS: + Handle_GetStatistics(strHostIFmsg.drvHandler, (tstrStatistics *)strHostIFmsg.uniHostIFmsgBody.pUserData); + break; + + case HOST_IF_MSG_GET_CHNL: + Handle_GetChnl(strHostIFmsg.drvHandler); + break; + +#ifdef WILC_AP_EXTERNAL_MLME + case HOST_IF_MSG_ADD_BEACON: + Handle_AddBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon); + break; + + case HOST_IF_MSG_DEL_BEACON: + Handle_DelBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelBeacon); + break; + + case HOST_IF_MSG_ADD_STATION: + Handle_AddStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strAddStaParam); + break; + + case HOST_IF_MSG_DEL_STATION: + Handle_DelStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strDelStaParam); + break; + + case HOST_IF_MSG_EDIT_STATION: + Handle_EditStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strEditStaParam); + break; + + case HOST_IF_MSG_GET_INACTIVETIME: + Handle_Get_InActiveTime(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT); + break; + +#endif /*WILC_AP_EXTERNAL_MLME*/ + case HOST_IF_MSG_SCAN_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Scan Timeout\n"); + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_ABORTED); + break; + + case HOST_IF_MSG_CONNECT_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Connect Timeout \n"); + Handle_ConnectTimeout(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_POWER_MGMT: + Handle_PowerManagement(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam); + break; + + case HOST_IF_MSG_SET_WFIDRV_HANDLER: + Handle_SetWfiDrvHandler(&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler); + break; + + case HOST_IF_MSG_SET_OPERATION_MODE: + Handle_SetOperationMode(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode); + break; + + case HOST_IF_MSG_SET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_set_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + case HOST_IF_MSG_GET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_get_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + /*BugID_5077*/ + case HOST_IF_MSG_SET_MAC_ADDRESS: + Handle_SetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress); + break; + + /*BugID_5213*/ + case HOST_IF_MSG_GET_MAC_ADDRESS: + Handle_GetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress); + break; + +#ifdef WILC_P2P + case HOST_IF_MSG_REMAIN_ON_CHAN: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n"); + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + case HOST_IF_MSG_REGISTER_FRAME: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n"); + Handle_RegisterFrame(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame); + break; + + case HOST_IF_MSG_LISTEN_TIMER_FIRED: + Handle_ListenStateExpired(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + #endif + case HOST_IF_MSG_SET_MULTICAST_FILTER: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n"); + Handle_SetMulticastFilter(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti); + break; + + /*BugID_5222*/ + case HOST_IF_MSG_ADD_BA_SESSION: + Handle_AddBASession(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: + Handle_DelAllRxBASessions(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_STA: + Handle_DelAllSta(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta); + break; + + default: + PRINT_ER("[Host Interface] undefined Received Msg ID \n"); + break; + } + } + + PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n"); + up(&hSemHostIFthrdEnd); + return 0; +} + +static void TimerCB_Scan(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); +} + +static void TimerCB_Connect(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); +} + + +/** + * @brief removes wpa/wpa2 keys + * @details only in BSS STA mode if External Supplicant support is enabled. + * removes all WPA/WPA2 station key entries from MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +/* Check implementation in core adding 9 bytes to the input! */ +WILC_Sint32 host_int_remove_key(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8StaAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8StaAddress; + strWID.s32ValueSize = 6; + + return s32Error; + +} + +/** + * @brief removes WEP key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * remove a WEP key entry from MAC HW. + * The BSS Station automatically finds the index of the entry using its + * BSS ID and removes that entry from the MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note NO need for the STA add since it is not used for processing + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_wep_key(WILC_WFIDrvHandle hWFIDrv, u8 u8keyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Remove Wep Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = REMOVEKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Request to remove WEP key \n"); + down(&(pstrWFIDrv->hSemTestKeyBlock)); + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief sets WEP default key + * @details Sets the index of the WEP encryption key in use, + * in the key table + * @param[in,out] handle to the wifi driver + * @param[in] key index ( 0, 1, 2, 3) + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_WEPDefaultKeyID(WILC_WFIDrvHandle hWFIDrv, u8 u8Index) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = DEFAULTKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Default key index\n"); + down(&(pstrWFIDrv->hSemTestKeyBlock)); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief sets WEP deafault key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * @param[in] message containing WEP Key in the following format + *|---------------------------------------| + *|Key ID Value | Key Length | Key | + *|-------------|------------|------------| + | 1byte | 1byte | Key Length | + ||---------------------------------------| + | + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_sta(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (u8 *)WILC_MALLOC(u8WepKeylen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, u8WepKeylen); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + down(&(pstrWFIDrv->hSemTestKeyBlock)); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * + * @brief host_int_add_wep_key_bss_ap + * @details valid only in BSS AP mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 28 FEB 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_ap(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx, u8 u8mode, AUTHTYPE_T tenuAuth_type) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + u8 i; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (INFO) { + for (i = 0; i < u8WepKeylen; i++) + PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]); + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (u8 *)WILC_MALLOC((u8WepKeylen)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, (u8WepKeylen)); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8mode = u8mode; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + down(&(pstrWFIDrv->hSemTestKeyBlock)); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +#endif +/** + * @brief adds ptk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing PTK Key in the following format + *|-----------------------------------------------------------------------------| + *|Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + *|----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + ||-----------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_ptk(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen, + const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + u8 u8KeyLen = u8PtkKeylen; + WILC_Uint32 i; + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPAPtk; + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8Idx; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (u8 *)WILC_MALLOC(u8PtkKeylen); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8Ptk, u8PtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < RX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]); + } + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < TX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]); + } + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr = mac_addr; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue: PTK Key\n"); + + /* ////////////// */ + down(&(pstrWFIDrv->hSemTestKeyBlock)); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief adds Rx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] pu8RxGtk : contains temporal key | Rx Mic | Tx Mic + * u8GtkKeylen :The total key length + * + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_rx_gtk(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen, + u8 u8KeyIdx, WILC_Uint32 u32KeyRSClen, const u8 *KeyRSC, + const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + u8 u8KeyLen = u8GtkKeylen; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + if (KeyRSC != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = (u8 *)WILC_MALLOC(u32KeyRSClen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, + KeyRSC, u32KeyRSClen); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPARxGtk; + strHostIFmsg.drvHandler = hWFIDrv; + + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (u8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8RxGtk, u8GtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8KeyIdx; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8seqlen = u32KeyRSClen; + + + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: RX GTK\n"); + /* ////////////// */ + down(&(pstrWFIDrv->hSemTestKeyBlock)); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#if 0 +/** + * @brief host_int_add_tx_gtk + * @details adds Tx GTk Key + * @param[in,out] handle to the wifi driver + * @param[in] message containing Tx GTK Key in the following format + *|----------------------------------------------------| + | KeyID | Key Length | Temporal Key | Tx Michael Key | + ||-------|------------|--------------|----------------| + ||1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_tx_gtk(WILC_WFIDrvHandle hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPATxGtk; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (u8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8TxGtk, u8KeyLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: TX GTK\n"); + + /* ////////////// */ + down(&hSemTestKeyBlock); + WILC_Sleep(100); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#endif +/** + * @brief host_int_set_pmkid_info + * @details caches the pmkid valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver + * @param[in] message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_pmkid_info(WILC_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr *pu8PmkidInfoArray) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 i; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = PMKSA; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, &pu8PmkidInfoArray->pmkidlist[i].bssid, + ETH_ALEN); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, &pu8PmkidInfoArray->pmkidlist[i].pmkid, + PMKID_LEN); + } + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER(" Error in sending messagequeue: PMKID Info\n"); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the cached the pmkid info + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver, + * message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @param[in] + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_pmkid_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8PmkidInfoArray, + WILC_Uint32 u32PmkidInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u32PmkidInfoLen; + strWID.ps8WidVal = pu8PmkidInfoArray; + + return s32Error; +} + +/** + * @brief sets the pass phrase + * @details AP/STA mode. This function gives the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * @param[in] String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, u8 *pu8PassPhrase, + u8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + /* u8 u8Psklength = WILC_strlen(pu8PassPhrase); */ + /*validating psk length*/ + if ((u8Psklength > 7) && (u8Psklength < 65)) { + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8PassPhrase; + strWID.s32ValueSize = u8Psklength; + } + + return s32Error; +} +/** + * @brief host_int_get_MacAddress + * @details gets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 19 April 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_MacAddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_MAC_ADDRESS; + strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress.u8MacAddress = pu8MacAddress; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send get mac address\n"); + return WILC_FAIL; + } + + down(&hWaitResponse); + return s32Error; +} + +/** + * @brief host_int_set_MacAddress + * @details sets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 16 July 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_MacAddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); + + /* prepare setting mac address message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MAC_ADDRESS; + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress.u8MacAddress, pu8MacAddress, ETH_ALEN); + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set mac address\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + +} + +/** + * @brief host_int_get_RSNAConfigPSKPassPhrase + * @details gets the pass phrase:AP/STA mode. This function gets the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, + u8 *pu8PassPhrase, u8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u8Psklength; + strWID.ps8WidVal = pu8PassPhrase; + + return s32Error; +} + +/** + * @brief host_int_get_site_survey_results + * @details gets the site survey results + * @param[in,out] handle to the wifi driver, + * Message containing site survey results in the + * following format + *|---------------------------------------------------| + | MsgLength | fragNo. | MsgBodyLength | MsgBody | + ||-----------|-----------|---------------|-----------| + | 1 | 1 | 1 | 1 | + | ----------------------------------------- | ---------------- + | + ||---------------------------------------| + | Network1 | Netweork2 | ... | Network5 | + ||---------------------------------------| + | 44 | 44 | ... | 44 | + | -------------------------- | --------------------------------------- + | + ||---------------------------------------------------------------------| + | SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved | + | + | + ||------|----------|---------|----------------|-------|------|---------| + | 33 | 1 | 1 | 1 | 6 | 1 | 1 | + ||---------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +#ifndef CONNECT_DIRECT +WILC_Sint32 host_int_get_site_survey_results(WILC_WFIDrvHandle hWFIDrv, + u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + WILC_Uint32 u32MaxSiteSrvyFragLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID astrWIDList[2]; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + astrWIDList[0].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[0].enuWIDtype = WID_STR; + astrWIDList[0].ps8WidVal = ppu8RcvdSiteSurveyResults[0]; + astrWIDList[0].s32ValueSize = u32MaxSiteSrvyFragLen; + + astrWIDList[1].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[1].enuWIDtype = WID_STR; + astrWIDList[1].ps8WidVal = ppu8RcvdSiteSurveyResults[1]; + astrWIDList[1].s32ValueSize = u32MaxSiteSrvyFragLen; + + s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to send config packet to get survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +#endif + +/** + * @brief sets a start scan request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_start_scan_req(WILC_WFIDrvHandle hWFIDrv, u8 scanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&scanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_start_scan_req + * @details gets a start scan request + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_start_scan_req(WILC_WFIDrvHandle hWFIDrv, u8 *pu8ScanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8ScanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_set_join_req + * @details sets a join request + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the bss descriptor + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_join_req(WILC_WFIDrvHandle hWFIDrv, u8 *pu8bssid, + const u8 *pu8ssid, size_t ssidLen, + const u8 *pu8IEs, size_t IEsLen, + tWILCpfConnectResult pfConnectResult, void *pvUserArg, + u8 u8security, AUTHTYPE_T tenuAuth_type, + u8 u8channel, + void *pJoinParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == NULL || pfConnectResult == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (hWFIDrv == NULL) { + PRINT_ER("Driver not initialized: gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + if (pJoinParams == NULL) { + PRINT_ER("Unable to Join - JoinParams is NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } +/* + * if(gWFiDrvHandle->strWILC_UsrScanReq.u32RcvdChCount == 0) + * { + * PRINT_ER("No scan results exist: Scanning should be done\n"); + * WILC_ERRORREPORT(s32Error, WILC_FAIL); + * } + */ + /* prepare the Connect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT; + + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8security = u8security; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.tenuAuth_type = tenuAuth_type; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8channel = u8channel; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pfConnectResult = pfConnectResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pvUserArg = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pJoinParams = pJoinParams; + strHostIFmsg.drvHandler = hWFIDrv; + + if (pu8bssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = (u8 *)WILC_MALLOC(6); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid, + pu8bssid, 6); + } + + if (pu8ssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.ssidLen = ssidLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = (u8 *)WILC_MALLOC(ssidLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid, + + pu8ssid, ssidLen); + } + + if (pu8IEs != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = (u8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs, + pu8IEs, IEsLen); + } + if (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTING) { + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTING; + } else + PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", pstrWFIDrv->enuHostIFstate); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = CONNECT_TIMER; + WILC_TimerStart(&(pstrWFIDrv->hConnectTimer), HOST_IF_CONNECT_TIMEOUT, (void *) hWFIDrv, NULL); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Flush a join request parameters to FW, but actual connection + * @details The function is called in situation where WILC is connected to AP and + * required to switch to hybrid FW for P2P connection + * @param[in] handle to the wifi driver, + * @return Error code indicating success/failure + * @note + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +WILC_Sint32 host_int_flush_join_req(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + if (!gu8FlushedJoinReq) { + s32Error = WILC_FAIL; + return s32Error; + } + + + if (hWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_FLUSH_CONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Flush join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_disconnect + * @details disconnects from the currently associated network + * @param[in,out] handle to the wifi driver, + * @param[in] Reason Code of the Disconnection + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16ReasonCode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* prepare the Disconnect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_DISCONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Failed to send message queue: disconnect\n"); + /* ////////////// */ + down(&(pstrWFIDrv->hSemTestDisconnectBlock)); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_disconnect_station + * @details disconnects a sta + * @param[in,out] handle to the wifi driver, + * @param[in] Association Id of the station to be disconnected + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect_station(WILC_WFIDrvHandle hWFIDrv, u8 assoc_id) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&assoc_id; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_assoc_req_info + * @details gets a Association request info + * @param[in,out] handle to the wifi driver, + * Message containg assoc. req info in the following format + * ------------------------------------------------------------------------ + | Management Frame Format | + ||-------------------------------------------------------------------| + ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS | + ||-------------|--------|--|--|-----|----------------|----------|----| + | 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 | + ||-------------------------------------------------------------------| + | | + | Association Request Frame - Frame Body | + ||-------------------------------------------------------------------| + | Capability Information | Listen Interval | SSID | Supported Rates | + ||------------------------|-----------------|------|-----------------| + | 2 | 2 | 2-34 | 3-10 | + | --------------------------------------------------------------------- + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_req_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8AssocReqInfo, + WILC_Uint32 u32AssocReqInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_REQ_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocReqInfo; + strWID.s32ValueSize = u32AssocReqInfoLen; + + + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. resp info + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_assoc_res_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8AssocRespInfo, + WILC_Uint32 u32MaxAssocRespInfoLen, WILC_Uint32 *pu32RcvdAssocRespInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_RES_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocRespInfo; + strWID.s32ValueSize = u32MaxAssocRespInfoLen; + + + /* Sending Configuration packet */ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send association response config packet\n"); + *pu32RcvdAssocRespInfoLen = 0; + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + *pu32RcvdAssocRespInfoLen = strWID.s32ValueSize; + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details Valid only in STA mode. This function gives the RSSI + * values observed in all the channels at the time of scanning. + * The length of the field is 1 greater that the total number of + * channels supported. Byte 0 contains the number of channels while + * each of Byte N contains the observed RSSI value for the channel index N. + * @param[in,out] handle to the wifi driver, + * array of scanned channels' RSSI + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rx_power_level(WILC_WFIDrvHandle hWFIDrv, u8 *pu8RxPowerLevel, + WILC_Uint32 u32RxPowerLevelLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_RX_POWER_LEVEL; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8RxPowerLevel; + strWID.s32ValueSize = u32RxPowerLevelLen; + + + return s32Error; +} + +/** + * @brief sets a channel + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the channel to be set + *|-------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_mac_chnl_num(WILC_WFIDrvHandle hWFIDrv, u8 u8ChNum) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the set channel message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_CHANNEL; + strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan.u8SetChan = u8ChNum; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_wait_msg_queue_idle(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_Q_IDLE; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /* wait untill MSG Q is empty */ + down(&hWaitResponse); + + return s32Error; + +} + +WILC_Sint32 host_int_set_wfi_drv_handler(WILC_Uint32 u32address) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_WFIDRV_HANDLER; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address = u32address; + /* strHostIFmsg.drvHandler=hWFIDrv; */ + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + + +WILC_Sint32 host_int_set_operation_mode(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32mode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_OPERATION_MODE; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode.u32Mode = u32mode; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the current channel index + * @details + * @param[in,out] handle to the wifi driver, + * current channel index + *|-----------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-----------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_host_chnl_num(WILC_WFIDrvHandle hWFIDrv, u8 *pu8ChNo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Get Channel Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_CHNL; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + down(&(pstrWFIDrv->hSemGetCHNL)); + /* gu8Chnl = 11; */ + + *pu8ChNo = gu8Chnl; + + WILC_CATCH(s32Error) + { + } + + return s32Error; + + +} + + +/** + * @brief host_int_test_set_int_wid + * @details Test function for setting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_set_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Char *)&u32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Test Function: Failed to set wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully set wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_get_inactive_time + * @details + * @param[in,out] handle to the wifi driver, + * current sta macaddress, inactive_time + * @return + * @note + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_get_inactive_time(WILC_WFIDrvHandle hWFIDrv, const u8 *mac, WILC_Uint32 *pu32InactiveTime) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT.mac, + mac, ETH_ALEN); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_INACTIVETIME; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + + down(&(pstrWFIDrv->hSemInactiveTime)); + + *pu32InactiveTime = gu32InactiveTime; + + WILC_CATCH(s32Error) + { + } + + return s32Error; +} +#endif +/** + * @brief host_int_test_get_int_wid + * @details Test function for getting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32* pu32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_get_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 *pu32TestMemAddr) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)pu32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Test Function: Failed to get wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully got wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + + +/** + * @brief host_int_get_rssi + * @details gets the currently maintained RSSI value for the station. + * The received signal strength value in dB. + * The range of valid values is -128 to 0. + * @param[in,out] handle to the wifi driver, + * rssi value in dB + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rssi(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8Rssi) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + down(&(pstrWFIDrv->hSemGetRSSI)); + + + if (ps8Rssi == NULL) { + PRINT_ER("RSS pointer value is null"); + return WILC_FAIL; + } + + + *ps8Rssi = gs8Rssi; + + + return s32Error; +} + +WILC_Sint32 host_int_get_link_speed(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8lnkspd) +{ + tstrHostIFmsg strHostIFmsg; + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + + /* prepare the Get LINKSPEED Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_LINKSPEED; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send GET_LINKSPEED to message queue "); + return WILC_FAIL; + } + + down(&(pstrWFIDrv->hSemGetLINKSPEED)); + + + if (ps8lnkspd == NULL) { + PRINT_ER("LINKSPEED pointer value is null"); + return WILC_FAIL; + } + + + *ps8lnkspd = gs8lnkspd; + + + return s32Error; +} + +WILC_Sint32 host_int_get_statistics(WILC_WFIDrvHandle hWFIDrv, tstrStatistics *pstrStatistics) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_STATISTICS; + strHostIFmsg.uniHostIFmsgBody.pUserData = (WILC_Char *)pstrStatistics; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + down(&hWaitResponse); + return s32Error; +} + + +/** + * @brief host_int_scan + * @details scans a set of channels + * @param[in,out] handle to the wifi driver, + * @param[in] Scan source + * Scan Type PASSIVE_SCAN = 0, + * ACTIVE_SCAN = 1 + * Channels Array + * Channels Array length + * Scan Callback function + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_scan(WILC_WFIDrvHandle hWFIDrv, u8 u8ScanSource, + u8 u8ScanType, u8 *pu8ChnlFreqList, + u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, tWILCpfScanResult ScanResult, + void *pvUserArg, tstrHiddenNetwork *pstrHiddenNetwork) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == NULL || ScanResult == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + /* prepare the Scan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN; + + if (pstrHiddenNetwork != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.u8ssidnum = pstrHiddenNetwork->u8ssidnum; + + } else + PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); + + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanSource = u8ScanSource; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanType = u8ScanType; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pfScanResult = ScanResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pvUserArg = pvUserArg; + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ChnlListLen = u8ChnlListLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = (u8 *)WILC_MALLOC(u8ChnlListLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList, + pu8ChnlFreqList, u8ChnlListLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = (u8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs, + pu8IEs, IEsLen); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scanning parameters: Error(%d)\n", s32Error); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = SCAN_TIMER; + PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); + WILC_TimerStart(&(pstrWFIDrv->hScanTimer), HOST_IF_SCAN_TIMEOUT, (void *) hWFIDrv, NULL); + + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +/** + * @brief hif_set_cfg + * @details sets configuration wids values + * @param[in,out] handle to the wifi driver, + * @param[in] WID, WID value + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_set_cfg(WILC_WFIDrvHandle hWFIDrv, tstrCfgParamVal *pstrCfgParamVal) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the WiphyParams Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_CFG_PARAMS; + strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr.pstrCfgParamVal = *pstrCfgParamVal; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + + +/** + * @brief hif_get_cfg + * @details gets configuration wids values + * @param[in,out] handle to the wifi driver, + * WID value + * @param[in] WID, + * @return Error code indicating success/failure + * @note + * @author zsalah + * + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_get_cfg(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16WID, WILC_Uint16 *pu16WID_Value) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + down(&(pstrWFIDrv->gtOsCfgValuesSem)); + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); + switch (u16WID) { + + case WID_BSS_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.bss_type; + break; + + case WID_AUTH_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.auth_type; + break; + + case WID_AUTH_TIMEOUT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.auth_timeout; + break; + + case WID_POWER_MANAGEMENT: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.power_mgmt_mode; + break; + + case WID_SHORT_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.short_retry_limit; + break; + + case WID_LONG_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.long_retry_limit; + break; + + case WID_FRAG_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.frag_threshold; + break; + + case WID_RTS_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.rts_threshold; + break; + + case WID_PREAMBLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.preamble_type; + break; + + case WID_SHORT_SLOT_ALLOWED: + *pu16WID_Value = (WILC_Uint16) pstrWFIDrv->strCfgValues.short_slot_allowed; + break; + + case WID_11N_TXOP_PROT_DISABLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.txop_prot_disabled; + break; + + case WID_BEACON_INTERVAL: + *pu16WID_Value = pstrWFIDrv->strCfgValues.beacon_interval; + break; + + case WID_DTIM_PERIOD: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.dtim_period; + break; + + case WID_SITE_SURVEY: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.site_survey_enabled; + break; + + case WID_SITE_SURVEY_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.site_survey_scan_time; + break; + + case WID_ACTIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.active_scan_time; + break; + + case WID_PASSIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.passive_scan_time; + break; + + case WID_CURRENT_TX_RATE: + *pu16WID_Value = pstrWFIDrv->strCfgValues.curr_tx_rate; + break; + + default: + break; + } + + up(&(pstrWFIDrv->gtOsCfgValuesSem)); + + WILC_CATCH(s32Error) + { + } + return s32Error; + +} + +/*****************************************************************************/ +/* Notification Functions */ +/*****************************************************************************/ +/** + * @brief notifies host with join and leave requests + * @details This function prepares an Information frame having the + * information about a joining/leaving station. + * @param[in,out] handle to the wifi driver, + * @param[in] 6 byte Sta Adress + * Join or leave flag: + * Join = 1, + * Leave =0 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_join_leave_info_to_host + (WILC_Uint16 assocId, u8 *stationAddr, WILC_Bool joining) +{ +} +/** + * @brief notifies host with stations found in scan + * @details sends the beacon/probe response from scan + * @param[in,out] handle to the wifi driver, + * @param[in] Sta Address, + * Frame length, + * Rssi of the Station found + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +void GetPeriodicRSSI(void *pvArg) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return; + } + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = pstrWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return; + } + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); +} + + +void host_int_send_network_info_to_host + (u8 *macStartAddress, WILC_Uint16 u16RxFrameLen, WILC_Sint8 s8Rssi) +{ +} +/** + * @brief host_int_init + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +static WILC_Uint32 u32Intialized; +static WILC_Uint32 msgQ_created; +static WILC_Uint32 clients_count; + +WILC_Sint32 host_int_init(WILC_WFIDrvHandle *phWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv; + + /*if(u32Intialized == 1) + * { + * PRINT_D(HOSTINF_DBG,"Host interface is previously initialized\n"); + * *phWFIDrv = (WILC_WFIDrvHandle)gWFiDrvHandle; //Will be adjusted later for P2P + * return 0; + * } */ + PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1); + + gbScanWhileConnected = WILC_FALSE; + + sema_init(&hWaitResponse, 0); + + + + /*Allocate host interface private structure*/ + pstrWFIDrv = (tstrWILC_WFIDrv *)WILC_MALLOC(sizeof(tstrWILC_WFIDrv)); + if (pstrWFIDrv == NULL) { + /* WILC_ERRORREPORT(s32Error,WILC_NO_MEM); */ + s32Error = WILC_NO_MEM; + PRINT_ER("Failed to allocate memory\n"); + goto _fail_timer_2; + } + WILC_memset(pstrWFIDrv, 0, sizeof(tstrWILC_WFIDrv)); + /*return driver handle to user*/ + *phWFIDrv = (WILC_WFIDrvHandle)pstrWFIDrv; + /*save into globl handle*/ + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + #endif + + PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", pstrWFIDrv); + /* /////////////////////////////////////// */ + if (clients_count == 0) { + sema_init(&hSemHostIFthrdEnd, 0); + sema_init(&hSemDeinitDrvHandle, 0); + /*BugID_5348*/ + sema_init(&hSemHostIntDeinit, 1); + } + + sema_init(&(pstrWFIDrv->hSemTestKeyBlock), 0); + sema_init(&(pstrWFIDrv->hSemTestDisconnectBlock), 0); + sema_init(&(pstrWFIDrv->hSemGetRSSI), 0); + sema_init(&(pstrWFIDrv->hSemGetLINKSPEED), 0); + sema_init(&(pstrWFIDrv->hSemGetCHNL), 0); + sema_init(&(pstrWFIDrv->hSemInactiveTime), 0); + + /* /////////////////////////////////////// */ + + + + PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); + + if (clients_count == 0) { + + s32Error = WILC_MsgQueueCreate(&gMsgQHostIF, NULL); + + + if (s32Error < 0) { + PRINT_ER("Failed to creat MQ\n"); + goto _fail_; + } + msgQ_created = 1; + HostIFthreadHandler = kthread_run(hostIFthread, NULL, "WILC_kthread"); + if (IS_ERR(HostIFthreadHandler)) { + PRINT_ER("Failed to creat Thread\n"); + s32Error = WILC_FAIL; + goto _fail_mq_; + } + s32Error = WILC_TimerCreate(&(g_hPeriodicRSSI), GetPeriodicRSSI, NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); + + } + + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hScanTimer), TimerCB_Scan, NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_thread_; + } + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hConnectTimer), TimerCB_Connect, NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + + + #ifdef WILC_P2P + /*Remain on channel timer*/ + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hRemainOnChannel), ListenTimerCB, NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Remain-on-channel Timer\n"); + goto _fail_timer_3; + } + #endif + + sema_init(&(pstrWFIDrv->gtOsCfgValuesSem), 1); + down(&(pstrWFIDrv->gtOsCfgValuesSem)); + + + +#ifdef SIMULATION + TransportInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* gWFiDrvHandle->bPendingConnRequest = WILC_FALSE; */ + + /*Initialize CFG WIDS Defualt Values*/ + + pstrWFIDrv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; + pstrWFIDrv->strCfgValues.scan_source = DEFAULT_SCAN; + pstrWFIDrv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.curr_tx_rate = AUTORATE; + + + #ifdef WILC_P2P + + pstrWFIDrv->u64P2p_MgmtTimeout = 0; + + #endif + + PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", + + pstrWFIDrv->strCfgValues.site_survey_enabled, pstrWFIDrv->strCfgValues.scan_source, + pstrWFIDrv->strCfgValues.active_scan_time, pstrWFIDrv->strCfgValues.passive_scan_time, + pstrWFIDrv->strCfgValues.curr_tx_rate); + + + up(&(pstrWFIDrv->gtOsCfgValuesSem)); + + /*TODO Code to setup simulation to be removed later*/ + /*Intialize configurator module*/ + s32Error = CoreConfiguratorInit(); + if (s32Error < 0) { + PRINT_ER("Failed to initialize core configurator\n"); + goto _fail_mem_; + } + +#ifdef SIMULATION + /*Initialize Simulaor*/ + CoreConfigSimulatorInit(); +#endif + + u32Intialized = 1; + clients_count++; /* increase number of created entities */ + + return s32Error; + + +_fail_mem_: + if (pstrWFIDrv != NULL) + WILC_FREE(pstrWFIDrv); +#ifdef WILC_P2P +_fail_timer_3: + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), NULL); +#endif +_fail_timer_2: + up(&(pstrWFIDrv->gtOsCfgValuesSem)); + WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), NULL); +_fail_timer_1: + WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), NULL); +_fail_thread_: + kthread_stop(HostIFthreadHandler); +_fail_mq_: + WILC_MsgQueueDestroy(&gMsgQHostIF, NULL); +_fail_: + return s32Error; + + +} +/** + * @brief host_int_deinit + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_deinit(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /*obtain driver handle*/ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + /*if(u32Intialized == 0) + * { + * PRINT_ER("Host Interface is not initialized\n"); + * return 0; + * }*/ + + /*BugID_5348*/ + + if (pstrWFIDrv == NULL) { + PRINT_ER("pstrWFIDrv = NULL\n"); + return 0; + } + + down(&hSemHostIntDeinit); + + terminated_handle = pstrWFIDrv; + PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count); + + /*BugID_5348*/ + /*Destroy all timers before acquiring hSemDeinitDrvHandle*/ + /*to guarantee handling all messages befor proceeding*/ + if (WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), NULL)) { + PRINT_D(HOSTINF_DBG, ">> Scan timer is active \n"); + /* msleep(HOST_IF_SCAN_TIMEOUT+1000); */ + } + + if (WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + + if (WILC_TimerDestroy(&(g_hPeriodicRSSI), NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + #ifdef WILC_P2P + /*Destroy Remain-onchannel Timer*/ + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), NULL); + #endif + + host_int_set_wfi_drv_handler((WILC_Uint32)NULL); + down(&hSemDeinitDrvHandle); + + + /*Calling the CFG80211 scan done function with the abort flag set to true*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL; + } + /*deinit configurator and simulator*/ +#ifdef SIMULATION + CoreConfigSimulatorDeInit(); +#endif + CoreConfiguratorDeInit(); +#ifdef SIMULATION + TransportDeInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (clients_count == 1) { + if (WILC_TimerDestroy(&g_hPeriodicRSSI, NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_EXIT; + strHostIFmsg.drvHandler = hWFIDrv; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", s32Error); + } + + down(&hSemHostIFthrdEnd); + + + + WILC_MsgQueueDestroy(&gMsgQHostIF, NULL); + msgQ_created = 0; + } + + down(&(pstrWFIDrv->gtOsCfgValuesSem)); + + /*Setting the gloabl driver handler with NULL*/ + u32Intialized = 0; + /* gWFiDrvHandle = NULL; */ + if (pstrWFIDrv != NULL) { + WILC_FREE(pstrWFIDrv); + /* pstrWFIDrv=NULL; */ + + } + + clients_count--; /* Decrease number of created entities */ + terminated_handle = NULL; + up(&hSemHostIntDeinit); + return s32Error; +} + + +/** + * @brief NetworkInfoReceived + * @details function to to be called when network info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ +void NetworkInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = NULL; + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + PRINT_ER("NetworkInfo received but driver not init[%p]\n", pstrWFIDrv); + return; + } + + /* prepare the Asynchronous Network Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_NTWRK_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = (u8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", s32Error); + } + + + return; +} + +/** + * @brief GnrlAsyncInfoReceived + * @details function to be called when general Asynchronous info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 15 Mar 2012 + * @version 1.0 + */ +void GnrlAsyncInfoReceived(u8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = NULL; + + /*BugID_5348*/ + down(&hSemHostIntDeinit); + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "General asynchronous info packet received \n"); + + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n"); + /*BugID_5348*/ + up(&hSemHostIntDeinit); + return; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == NULL) { + /* received mac status is not needed when there is no current Connect Request */ + PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n"); + /*BugID_5348*/ + up(&hSemHostIntDeinit); + return; + } + + /* prepare the General Asynchronous Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = (u8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", s32Error); + } + + /*BugID_5348*/ + up(&hSemHostIntDeinit); + return; +} + +/** + * @brief host_int_ScanCompleteReceived + * @details Setting scan complete received notifcation in message queue + * @param[in] u8* pu8Buffer, WILC_Uint32 u32Length + * @return Error code. + * @author + * @date + * @version 1.0 + */ +void host_int_ScanCompleteReceived(u8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = NULL; + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + PRINT_D(GENERIC_DBG, "Scan notification received %p\n", pstrWFIDrv); + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + return; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + /* prepare theScan Done message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_SCAN_COMPLETE; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + /* will be deallocated by the receiving thread */ + /*no need to send message body*/ + + /*strHostIFmsg.uniHostIFmsgBody.strScanComplete.u32Length = u32Length; + * strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer = (u8*)WILC_MALLOC(u32Length); + * WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer, + * pu8Buffer, u32Length); */ + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", s32Error); + } + } + + + return; + +} + +#ifdef WILC_P2P +/** + * @brief host_int_remain_on_channel + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_remain_on_channel(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID, WILC_Uint32 u32duration, WILC_Uint16 chan, tWILCpfRemainOnChanExpired RemainOnChanExpired, tWILCpfRemainOnChanReady RemainOnChanReady, void *pvUserArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the remainonchan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REMAIN_ON_CHAN; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u16Channel = chan; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanExpired = RemainOnChanExpired; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanReady = RemainOnChanReady; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pVoid = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32duration = u32duration; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_ListenStateExpired + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_ListenStateExpired(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), NULL); + + /* prepare the timer fire Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_frame_register + * @details + * @param[in] Handle to wifi driver + * @return Error code. + * @author + * @date + * @version 1.0*/ +WILC_Sint32 host_int_frame_register(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16FrameType, WILC_Bool bReg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REGISTER_FRAME; + switch (u16FrameType) { + case ACTION: + PRINT_D(HOSTINF_DBG, "ACTION\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = ACTION_FRM_IDX; + break; + + case PROBE_REQ: + PRINT_D(HOSTINF_DBG, "PROBE REQ\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = PROBE_REQ_IDX; + break; + + default: + PRINT_D(HOSTINF_DBG, "Not valid frame type\n"); + break; + } + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u16FrameType = u16FrameType; + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.bReg = bReg; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} +#endif + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_add_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + * WILC_Uint32 u32DTIMPeriod,WILC_Uint32 u32HeadLen, u8* pu8Head, + * WILC_Uint32 u32TailLen, u8* pu8Tail + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + WILC_Uint32 u32DTIMPeriod, + WILC_Uint32 u32HeadLen, u8 *pu8Head, + WILC_Uint32 u32TailLen, u8 *pu8Tail) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetBeacon *pstrSetBeaconParam = &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + pstrSetBeaconParam->u32Interval = u32Interval; + pstrSetBeaconParam->u32DTIMPeriod = u32DTIMPeriod; + pstrSetBeaconParam->u32HeadLen = u32HeadLen; + pstrSetBeaconParam->pu8Head = (u8 *)WILC_MALLOC(u32HeadLen); + if (pstrSetBeaconParam->pu8Head == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen); + pstrSetBeaconParam->u32TailLen = u32TailLen; + + /* Bug 4599 : if tail length = 0 skip allocating & copying */ + if (u32TailLen > 0) { + pstrSetBeaconParam->pu8Tail = (u8 *)WILC_MALLOC(u32TailLen); + if (pstrSetBeaconParam->pu8Tail == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen); + } else { + pstrSetBeaconParam->pu8Tail = NULL; + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + if (pstrSetBeaconParam->pu8Head != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Head); + } + + if (pstrSetBeaconParam->pu8Tail != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Tail); + } + } + + return s32Error; + +} + + +/** + * @brief host_int_del_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + WILC_ERRORCHECK(s32Error); + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + +/** + * @brief host_int_add_station + * @details Setting add station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + u8 *rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, rates); + + WILC_memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + pstrAddStationMsg->pu8Rates = rates; + } + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief host_int_del_station + * @details Setting delete station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, u8* pu8MacAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8MacAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelSta *pstrDelStationMsg = &strHostIFmsg.uniHostIFmsgBody.strDelStaParam; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n"); + + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + /*BugID_4795: Handling situation of deleting all stations*/ + if (pu8MacAddr == NULL) + WILC_memset(pstrDelStationMsg->au8MacAddr, 255, ETH_ALEN); + else + WILC_memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} +/** + * @brief host_int_del_allstation + * @details Setting del station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]s + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelAllSta *pstrDelAllStationMsg = &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta; + u8 au8Zero_Buff[ETH_ALEN] = {0}; + WILC_Uint32 i; + u8 u8AssocNumb = 0; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n"); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_STA; + strHostIFmsg.drvHandler = hWFIDrv; + + /* Handling situation of deauthenticing all associated stations*/ + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) { + WILC_memcpy(pstrDelAllStationMsg->au8Sta_DelAllSta[i], pu8MacAddr[i], ETH_ALEN); + PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", pstrDelAllStationMsg->au8Sta_DelAllSta[i][0], pstrDelAllStationMsg->au8Sta_DelAllSta[i][1], pstrDelAllStationMsg->au8Sta_DelAllSta[i][2], pstrDelAllStationMsg->au8Sta_DelAllSta[i][3], pstrDelAllStationMsg->au8Sta_DelAllSta[i][4], + pstrDelAllStationMsg->au8Sta_DelAllSta[i][5]); + u8AssocNumb++; + } + } + if (!u8AssocNumb) { + PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n"); + return s32Error; + } + + pstrDelAllStationMsg->u8Num_AssocSta = u8AssocNumb; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + + + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + + } + WILC_CATCH(s32Error) + { + + } + down(&hWaitResponse); + + return s32Error; + +} + +/** + * @brief host_int_edit_station + * @details Setting edit station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_EDIT_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + u8 *rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, rates); + WILC_memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + pstrAddStationMsg->pu8Rates = rates; + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} +#endif /*WILC_AP_EXTERNAL_MLME*/ +uint32_t wilc_get_chipid(uint8_t); + +WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfPowerMgmtParam *pstrPowerMgmtParam = &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam; + + PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d << \n\n", bIsEnabled); + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_POWER_MGMT; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrPowerMgmtParam->bIsEnabled = bIsEnabled; + pstrPowerMgmtParam->u32Timeout = u32Timeout; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +WILC_Sint32 host_int_setup_multicast_filter(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32count) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetMulti *pstrMulticastFilterParam = &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti; + + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MULTICAST_FILTER; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrMulticastFilterParam->bIsEnabled = bIsEnabled; + pstrMulticastFilterParam->u32count = u32count; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST + +/*Bug4218: Parsing Join Param*/ +/** + * @brief host_int_ParseJoinBssParam + * @details Parse Needed Join Parameters and save it in a new JoinBssParam entry + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author zsalah + * @date + * @version 1.0**/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo) +{ + tstrJoinBssParam *pNewJoinBssParam = NULL; + u8 *pu8IEs; + WILC_Uint16 u16IEsLen; + WILC_Uint16 index = 0; + u8 suppRatesNo = 0; + u8 extSuppRatesNo; + WILC_Uint16 jumpOffset; + u8 pcipherCount; + u8 authCount; + u8 pcipherTotalCount = 0; + u8 authTotalCount = 0; + u8 i, j; + + pu8IEs = ptstrNetworkInfo->pu8IEs; + u16IEsLen = ptstrNetworkInfo->u16IEsLen; + + pNewJoinBssParam = WILC_MALLOC(sizeof(tstrJoinBssParam)); + if (pNewJoinBssParam != NULL) { + WILC_memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam)); + pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod; + pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod; + pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo; + WILC_memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6); + /*for(i=0; i<6;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->au8bssid[i]);*/ + WILC_memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1); + pNewJoinBssParam->ssidLen = ptstrNetworkInfo->u8SsidLen; + WILC_memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3); + WILC_memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3); + /*for(i=0; i<pNewJoinBssParam->ssidLen;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->ssid[i]);*/ + + /* parse supported rates: */ + while (index < u16IEsLen) { + /* supportedRates IE */ + if (pu8IEs[index] == SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Supported Rates\n"); */ + suppRatesNo = pu8IEs[index + 1]; + pNewJoinBssParam->supp_rates[0] = suppRatesNo; + index += 2; /* skipping ID and length bytes; */ + + for (i = 0; i < suppRatesNo; i++) { + pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[i+1]); */ + } + index += suppRatesNo; + continue; + } + /* Ext SupportedRates IE */ + else if (pu8IEs[index] == EXT_SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Extended Supported Rates\n"); */ + /* checking if no of ext. supp and supp rates < max limit */ + extSuppRatesNo = pu8IEs[index + 1]; + if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo)) + pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED; + else + pNewJoinBssParam->supp_rates[0] += extSuppRatesNo; + index += 2; + /* pNewJoinBssParam.supp_rates[0] contains now old number not the ext. no */ + for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) { + pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[suppRatesNo+i+1]); */ + } + index += extSuppRatesNo; + continue; + } + /* HT Cap. IE */ + else if (pu8IEs[index] == HT_CAPABILITY_IE) { + /* if IE found set the flag */ + pNewJoinBssParam->ht_capable = BTRUE; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + /* PRINT_D(HOSTINF_DBG,"HT_CAPABALE\n"); */ + continue; + } else if ((pu8IEs[index] == WMM_IE) && /* WMM Element ID */ + (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) && + (pu8IEs[index + 4] == 0xF2) && /* OUI */ + (pu8IEs[index + 5] == 0x02) && /* OUI Type */ + ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) && /* OUI Sub Type */ + (pu8IEs[index + 7] == 0x01)) { + /* Presence of WMM Info/Param element indicates WMM capability */ + pNewJoinBssParam->wmm_cap = BTRUE; + + /* Check if Bit 7 is set indicating U-APSD capability */ + if (pu8IEs[index + 8] & (1 << 7)) { + pNewJoinBssParam->uapsd_cap = BTRUE; + } + index += pu8IEs[index + 1] + 2; + continue; + } + #ifdef WILC_P2P + else if ((pu8IEs[index] == P2P_IE) && /* P2P Element ID */ + (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) && + (pu8IEs[index + 4] == 0x9a) && /* OUI */ + (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) { /* OUI Type */ + WILC_Uint16 u16P2P_count; + pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf; + pNewJoinBssParam->u8NoaEnbaled = 1; + pNewJoinBssParam->u8Index = pu8IEs[index + 9]; + + /* Check if Bit 7 is set indicating Opss capability */ + if (pu8IEs[index + 10] & (1 << 7)) { + pNewJoinBssParam->u8OppEnable = 1; + pNewJoinBssParam->u8CtWindow = pu8IEs[index + 10]; + } else + pNewJoinBssParam->u8OppEnable = 0; + /* HOSTINF_DBG */ + PRINT_D(GENERIC_DBG, "P2P Dump \n"); + for (i = 0; i < pu8IEs[index + 7]; i++) + PRINT_D(GENERIC_DBG, " %x \n", pu8IEs[index + 9 + i]); + + pNewJoinBssParam->u8Count = pu8IEs[index + 11]; + u16P2P_count = index + 12; + + WILC_memcpy(pNewJoinBssParam->au8Duration, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8Interval, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8StartTime, pu8IEs + u16P2P_count, 4); + + index += pu8IEs[index + 1] + 2; + continue; + + } + #endif + else if ((pu8IEs[index] == RSN_IE) || + ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) && + (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) && + (pu8IEs[index + 5] == 0x01))) { + WILC_Uint16 rsnIndex = index; + /*PRINT_D(HOSTINF_DBG,"RSN IE Length:%d\n",pu8IEs[rsnIndex+1]); + * for(i=0; i<pu8IEs[rsnIndex+1]; i++) + * { + * PRINT_D(HOSTINF_DBG,"%0x ",pu8IEs[rsnIndex+2+i]); + * }*/ + if (pu8IEs[rsnIndex] == RSN_IE) { + pNewJoinBssParam->mode_802_11i = 2; + /* PRINT_D(HOSTINF_DBG,"\nRSN_IE\n"); */ + } else { /* check if rsn was previously parsed */ + if (pNewJoinBssParam->mode_802_11i == 0) + pNewJoinBssParam->mode_802_11i = 1; + /* PRINT_D(HOSTINF_DBG,"\nWPA_IE\n"); */ + rsnIndex += 4; + } + rsnIndex += 7; /* skipping id, length, version(2B) and first 3 bytes of gcipher */ + pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex]; + rsnIndex++; + /* PRINT_D(HOSTINF_DBG,"Group Policy: %0x \n",pNewJoinBssParam->rsn_grp_policy); */ + /* initialize policies with invalid values */ + + jumpOffset = pu8IEs[rsnIndex] * 4; /* total no.of bytes of pcipher field (count*4) */ + + /*parsing pairwise cipher*/ + + /* saving 3 pcipher max. */ + pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + /* PRINT_D(HOSTINF_DBG,"\npcipher:%d \n",pcipherCount); */ + for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + /* PRINT_D(HOSTINF_DBG,"PAIR policy = [%0x,%0x]\n",pNewJoinBssParam->rsn_pcip_policy[i],i); */ + } + pcipherTotalCount += pcipherCount; + rsnIndex += jumpOffset; + + jumpOffset = pu8IEs[rsnIndex] * 4; + + /*parsing AKM suite (auth_policy)*/ + /* saving 3 auth policies max. */ + authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + } + authTotalCount += authCount; + rsnIndex += jumpOffset; + /*pasring rsn cap. only if rsn IE*/ + if (pu8IEs[index] == RSN_IE) { + pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex]; + pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1]; + rsnIndex += 2; + } + pNewJoinBssParam->rsn_found = 1; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + continue; + } else + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + + } + + + } + + return (void *)pNewJoinBssParam; + +} + +void host_int_freeJoinParams(void *pJoinParams) +{ + if ((tstrJoinBssParam *)pJoinParams != NULL) + WILC_FREE((tstrJoinBssParam *)pJoinParams); + else + PRINT_ER("Unable to FREE null pointer\n"); +} +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + + +/** + * @brief host_int_addBASession + * @details Open a block Ack session with the given parameters + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author anoureldin + * @date + * @version 1.0**/ + +static int host_int_addBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID, short int BufferSize, + short int SessionTimeout, void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + pBASessionInfo->u16BufferSize = BufferSize; + pBASessionInfo->u16SessionTimeout = SessionTimeout; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_delBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + down(&hWaitResponse); + + return s32Error; +} + +WILC_Sint32 host_int_del_All_Rx_BASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + down(&hWaitResponse); + + return s32Error; +} + +/** + * @brief host_int_setup_ipaddress + * @details setup IP in firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_setup_ipaddress(WILC_WFIDrvHandle hWFIDrv, u8 *u16ipadd, u8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + /* TODO: Enable This feature on softap firmware */ + return 0; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + +/** + * @brief host_int_get_ipaddress + * @details Get IP from firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, u8 *u16ipadd, u8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler=hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx= idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h new file mode 100644 index 000000000000..d03a5753cb33 --- /dev/null +++ b/drivers/staging/wilc1000/host_interface.h @@ -0,0 +1,1344 @@ +/*! + * @file host_interface.h + * @brief File containg host interface APIs + * @author zsalah + * @sa host_interface.c + * @date 8 March 2012 + * @version 1.0 + */ + +#ifndef HOST_INT_H +#define HOST_INT_H + +#include "coreconfigurator.h" +#include "coreconfigsimulator.h" +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ +#if 0 +#define WID_BSS_TYPE 0x0000 +#define WID_CURRENT_TX_RATE 0x0001 +#define WID_CURRENT_CHANNEL 0x0002 +#define WID_PREAMBLE 0x0003 +#define WID_STATUS 0x0005 +#define WID_SCAN_TYPE 0x0007 +#define WID_KEY_ID 0x0009 +#define WID_DTIM_PERIOD 0x0010 +#define WID_POWER_MANAGEMENT 0x000B +#define WID_AUTH_TYPE 0x000D +#define WID_SITE_SURVEY 0x000E +#define WID_DTIM_PERIOD 0x0010 +#define WID_DISCONNECT 0x0016 +#define WID_SHORT_SLOT_ALLOWED 0x001A +#define WID_START_SCAN_REQ 0x001E +#define WID_RSSI 0x001F +#define WID_JOIN_REQ 0x0020 +#define WID_11N_TXOP_PROT_DISABLE 0x00B0 +#define WID_RTS_THRESHOLD 0x1000 +#define WID_FRAG_THRESHOLD 0x1001 +#define WID_SHORT_RETRY_LIMIT 0x1002 +#define WID_LONG_RETRY_LIMIT 0x1003 +#define WID_BEACON_INTERVAL 0x1006 +#define WID_ACTIVE_SCAN_TIME 0x100C +#define WID_PASSIVE_SCAN_TIME 0x100D +#define WID_SITE_SURVEY_SCAN_TIME 0x100E +#define WID_AUTH_TIMEOUT 0x1010 +#define WID_11I_PSK 0x3008 +#define WID_SITE_SURVEY_RESULTS 0x3012 +#define WID_ADD_PTK 0x301B +#define WID_ADD_RX_GTK 0x301C +#define WID_ADD_TX_GTK 0x301D +#define WID_ADD_WEP_KEY 0x3019 +#define WID_REMOVE_WEP_KEY 0x301A +#define WID_REMOVE_KEY 0x301E +#define WID_ASSOC_REQ_INFO 0x301F +#define WID_ASSOC_RES_INFO 0x3020 +#define WID_PMKID_INFO 0x3082 +#define WID_SCAN_CHANNEL_LIST 0x4084 +#define WID_11I_MODE 0x000C +#endif +#define FAIL 0x0000 +#define SUCCESS 0x0001 + +#define IP_ALEN 4 + +#define BIT2 ((WILC_Uint32)(1 << 2)) +#define BIT1 ((WILC_Uint32)(1 << 1)) +#define BIT0 ((WILC_Uint32)(1 << 0)) + +#define AP_MODE 0x01 +#define STATION_MODE 0x02 +#define GO_MODE 0x03 +#define CLIENT_MODE 0x04 + + +#define MAX_NUM_STA 9 +#define ACTIVE_SCAN_TIME 10 +#define PASSIVE_SCAN_TIME 1200 +#define MIN_SCAN_TIME 10 +#define MAX_SCAN_TIME 1200 +#define DEFAULT_SCAN 0 +#define USER_SCAN BIT0 +#define OBSS_PERIODIC_SCAN BIT1 +#define OBSS_ONETIME_SCAN BIT2 +#define GTK_RX_KEY_BUFF_LEN 24 +#define ADDKEY 0x1 +#define REMOVEKEY 0x2 +#define DEFAULTKEY 0x4 +#define ADDKEY_AP 0x8 +#define MAX_NUM_SCANNED_NETWORKS 100 /* 30 // rachel */ +#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130 +#define MAX_NUM_PROBED_SSID 10 /*One more than the number of scanned ssids*/ +#define CHANNEL_SCAN_TIME 250 /* 250 */ + +#define TX_MIC_KEY_LEN 8 +#define RX_MIC_KEY_LEN 8 +#define PTK_KEY_LEN 16 + +#define TX_MIC_KEY_MSG_LEN 26 +#define RX_MIC_KEY_MSG_LEN 48 +#define PTK_KEY_MSG_LEN 39 + +#define PMKSA_KEY_LEN 22 +#define ETH_ALEN 6 +#define PMKID_LEN 16 +#define WILC_MAX_NUM_PMKIDS 16 +#define WILC_SUPP_MCS_SET_SIZE 16 +#define WILC_ADD_STA_LENGTH 40 /* Not including the rates field cause it has variable length*/ +#define SCAN_EVENT_DONE_ABORTED +/*****************************************************************************/ +/* Data Types */ +/*****************************************************************************/ +/* typedef unsigned char uint8; */ +/* typedef signed char int8; */ +/* typedef unsigned short uint16; */ +/* typedef unsigned long uint32; */ +/* typedef uint32 Bool; */ + +#if 0 +typedef enum {WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7} WID_TYPE_T; +#endif +typedef struct { + WILC_Uint16 cfg_wid; + WID_TYPE_T cfg_type; + WILC_Sint8 *pu8Para; +} cfg_param_t; + +typedef struct _tstrStatistics { + u8 u8LinkSpeed; + WILC_Sint8 s8RSSI; + WILC_Uint32 u32TxCount; + WILC_Uint32 u32RxCount; + WILC_Uint32 u32TxFailureCount; + +} tstrStatistics; + + +typedef enum { + HOST_IF_IDLE = 0, + HOST_IF_SCANNING = 1, + HOST_IF_CONNECTING = 2, + HOST_IF_WAITING_CONN_RESP = 3, + HOST_IF_CONNECTED = 4, + HOST_IF_P2P_LISTEN = 5, + HOST_IF_FORCE_32BIT = 0xFFFFFFFF +} tenuHostIFstate; + +typedef struct _tstrHostIFpmkid { + u8 bssid[ETH_ALEN]; + u8 pmkid[PMKID_LEN]; +} tstrHostIFpmkid; + +typedef struct _tstrHostIFpmkidAttr { + u8 numpmkid; + tstrHostIFpmkid pmkidlist[WILC_MAX_NUM_PMKIDS]; +} tstrHostIFpmkidAttr; +#if 0 +/* Scan type parameter for scan request */ +typedef enum { + PASSIVE_SCAN = 0, + ACTIVE_SCAN = 1, + NUM_SCANTYPE +} tenuScanType; + +typedef enum {SITE_SURVEY_1CH = 0, + SITE_SURVEY_ALL_CH = 1, + SITE_SURVEY_OFF = 2} SITE_SURVEY_T; +#endif +typedef enum { + AUTORATE = 0, + MBPS_1 = 1, + MBPS_2 = 2, + MBPS_5_5 = 5, + MBPS_11 = 11, + MBPS_6 = 6, + MBPS_9 = 9, + MBPS_12 = 12, + MBPS_18 = 18, + MBPS_24 = 24, + MBPS_36 = 36, + MBPS_48 = 48, + MBPS_54 = 54 +} CURRENT_TX_RATE_T; + +typedef struct { + WILC_Uint32 u32SetCfgFlag; + u8 ht_enable; + u8 bss_type; + u8 auth_type; + WILC_Uint16 auth_timeout; + u8 power_mgmt_mode; + WILC_Uint16 short_retry_limit; + WILC_Uint16 long_retry_limit; + WILC_Uint16 frag_threshold; + WILC_Uint16 rts_threshold; + WILC_Uint16 preamble_type; + u8 short_slot_allowed; + u8 txop_prot_disabled; + WILC_Uint16 beacon_interval; + WILC_Uint16 dtim_period; + SITE_SURVEY_T site_survey_enabled; + WILC_Uint16 site_survey_scan_time; + u8 scan_source; + WILC_Uint16 active_scan_time; + WILC_Uint16 passive_scan_time; + CURRENT_TX_RATE_T curr_tx_rate; + +} tstrCfgParamVal; + +typedef enum { + RETRY_SHORT = 1 << 0, + RETRY_LONG = 1 << 1, + FRAG_THRESHOLD = 1 << 2, + RTS_THRESHOLD = 1 << 3, + BSS_TYPE = 1 << 4, + AUTH_TYPE = 1 << 5, + AUTHEN_TIMEOUT = 1 << 6, + POWER_MANAGEMENT = 1 << 7, + PREAMBLE = 1 << 8, + SHORT_SLOT_ALLOWED = 1 << 9, + TXOP_PROT_DISABLE = 1 << 10, + BEACON_INTERVAL = 1 << 11, + DTIM_PERIOD = 1 << 12, + SITE_SURVEY = 1 << 13, + SITE_SURVEY_SCAN_TIME = 1 << 14, + ACTIVE_SCANTIME = 1 << 15, + PASSIVE_SCANTIME = 1 << 16, + CURRENT_TX_RATE = 1 << 17, + HT_ENABLE = 1 << 18, +} tenuCfgParam; + +typedef struct { + u8 au8bssid[6]; + WILC_Sint8 s8rssi; +} tstrFoundNetworkInfo; + +typedef enum {SCAN_EVENT_NETWORK_FOUND = 0, + SCAN_EVENT_DONE = 1, + SCAN_EVENT_ABORTED = 2, + SCAN_EVENT_FORCE_32BIT = 0xFFFFFFFF} tenuScanEvent; + +typedef enum { + CONN_DISCONN_EVENT_CONN_RESP = 0, + CONN_DISCONN_EVENT_DISCONN_NOTIF = 1, + CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF +} tenuConnDisconnEvent; + +typedef enum { + WEP, + WPARxGtk, + /* WPATxGtk, */ + WPAPtk, + PMKSA, +} tenuKeyType; + + +/*Scan callBack function definition*/ +typedef void (*tWILCpfScanResult)(tenuScanEvent, tstrNetworkInfo *, void *, void *); + +/*Connect callBack function definition*/ +typedef void (*tWILCpfConnectResult)(tenuConnDisconnEvent, + tstrConnectInfo *, + u8, + tstrDisconnectNotifInfo *, + void *); + +#ifdef WILC_P2P +typedef void (*tWILCpfRemainOnChanExpired)(void *, WILC_Uint32); /*Remain on channel expiration callback function*/ +typedef void (*tWILCpfRemainOnChanReady)(void *); /*Remain on channel callback function*/ +#endif + +/* typedef WILC_Uint32 WILC_WFIDrvHandle; */ +typedef struct { + WILC_Sint32 s32Dummy; +} *WILC_WFIDrvHandle; + +/*! + * @struct tstrRcvdNetworkInfo + * @brief Structure to hold Received Asynchronous Network info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdNetworkInfo { + u8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdNetworkInfo; + +/*BugID_4156*/ +typedef struct _tstrHiddenNetworkInfo { + u8 *pu8ssid; + u8 u8ssidlen; + +} tstrHiddenNetworkInfo; + +typedef struct _tstrHiddenNetwork { + /* MAX_SSID_LEN */ + tstrHiddenNetworkInfo *pstrHiddenNetworkInfo; + u8 u8ssidnum; + +} tstrHiddenNetwork; + +typedef struct { + /* Scan user call back function */ + tWILCpfScanResult pfUserScanResult; + + /* User specific parameter to be delivered through the Scan User Callback function */ + void *u32UserScanPvoid; + + WILC_Uint32 u32RcvdChCount; + tstrFoundNetworkInfo astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS]; +} tstrWILC_UsrScanReq; + +typedef struct { + u8 *pu8bssid; + u8 *pu8ssid; + u8 u8security; + AUTHTYPE_T tenuAuth_type; + size_t ssidLen; + u8 *pu8ConnReqIEs; + size_t ConnReqIEsLen; + /* Connect user call back function */ + tWILCpfConnectResult pfUserConnectResult; + WILC_Bool IsHTCapable; + /* User specific parameter to be delivered through the Connect User Callback function */ + void *u32UserConnectPvoid; +} tstrWILC_UsrConnReq; + +typedef struct { + WILC_Uint32 u32Address; +} tstrHostIfSetDrvHandler; + +typedef struct { + WILC_Uint32 u32Mode; +} tstrHostIfSetOperationMode; + +/*BugID_5077*/ +typedef struct { + u8 u8MacAddress[ETH_ALEN]; +} tstrHostIfSetMacAddress; + +/*BugID_5213*/ +typedef struct { + u8 *u8MacAddress; +} tstrHostIfGetMacAddress; + +/*BugID_5222*/ +typedef struct { + u8 au8Bssid[ETH_ALEN]; + u8 u8Ted; + WILC_Uint16 u16BufferSize; + WILC_Uint16 u16SessionTimeout; +} tstrHostIfBASessionInfo; + +#ifdef WILC_P2P +typedef struct { + WILC_Uint16 u16Channel; + WILC_Uint32 u32duration; + tWILCpfRemainOnChanExpired pRemainOnChanExpired; + tWILCpfRemainOnChanReady pRemainOnChanReady; + void *pVoid; + WILC_Uint32 u32ListenSessionID; +} tstrHostIfRemainOnChan; + +typedef struct { + + WILC_Bool bReg; + WILC_Uint16 u16FrameType; + u8 u8Regid; + + +} tstrHostIfRegisterFrame; + + +#define ACTION 0xD0 +#define PROBE_REQ 0x40 +#define PROBE_RESP 0x50 +#define ACTION_FRM_IDX 0 +#define PROBE_REQ_IDX 1 + + +enum p2p_listen_state { + P2P_IDLE, + P2P_LISTEN, + P2P_GRP_FORMATION +}; + +#endif +typedef struct { + /* Scan user structure */ + tstrWILC_UsrScanReq strWILC_UsrScanReq; + + /* Connect User structure */ + tstrWILC_UsrConnReq strWILC_UsrConnReq; + + #ifdef WILC_P2P + /*Remain on channel struvture*/ + tstrHostIfRemainOnChan strHostIfRemainOnChan; + u8 u8RemainOnChan_pendingreq; + WILC_Uint64 u64P2p_MgmtTimeout; + u8 u8P2PConnect; + #endif + + tenuHostIFstate enuHostIFstate; + + /* WILC_Bool bPendingConnRequest; */ + + #ifndef CONNECT_DIRECT + WILC_Uint32 u32SurveyResultsCount; + wid_site_survey_reslts_s astrSurveyResults[MAX_NUM_SCANNED_NETWORKS]; + #endif + + u8 au8AssociatedBSSID[ETH_ALEN]; + tstrCfgParamVal strCfgValues; +/* semaphores */ + struct semaphore gtOsCfgValuesSem; + struct semaphore hSemTestKeyBlock; + + struct semaphore hSemTestDisconnectBlock; + struct semaphore hSemGetRSSI; + struct semaphore hSemGetLINKSPEED; + struct semaphore hSemGetCHNL; + struct semaphore hSemInactiveTime; +/* timer handlers */ + WILC_TimerHandle hScanTimer; + WILC_TimerHandle hConnectTimer; + #ifdef WILC_P2P + WILC_TimerHandle hRemainOnChannel; + #endif + + WILC_Bool IFC_UP; +} tstrWILC_WFIDrv; + +/*! + * @enum tenuWILC_StaFlag + * @brief Used to decode the station flag set and mask in tstrWILC_AddStaParam + * @details + * @todo + * @sa tstrWILC_AddStaParam, enum nl80211_sta_flags + * @author Enumeraion's creator + * @date 12 July 2012 + * @version 1.0 Description + */ + +typedef enum { + WILC_STA_FLAG_INVALID = 0, + WILC_STA_FLAG_AUTHORIZED, /*!< station is authorized (802.1X)*/ + WILC_STA_FLAG_SHORT_PREAMBLE, /*!< station is capable of receiving frames with short barker preamble*/ + WILC_STA_FLAG_WME, /*!< station is WME/QoS capable*/ + WILC_STA_FLAG_MFP, /*!< station uses management frame protection*/ + WILC_STA_FLAG_AUTHENTICATED /*!< station is authenticated*/ +} tenuWILC_StaFlag; + +typedef struct { + u8 au8BSSID[ETH_ALEN]; + WILC_Uint16 u16AssocID; + u8 u8NumRates; + const u8 *pu8Rates; + WILC_Bool bIsHTSupported; + WILC_Uint16 u16HTCapInfo; + u8 u8AmpduParams; + u8 au8SuppMCsSet[16]; + WILC_Uint16 u16HTExtParams; + WILC_Uint32 u32TxBeamformingCap; + u8 u8ASELCap; + WILC_Uint16 u16FlagsMask; /*<! Determines which of u16FlagsSet were changed>*/ + WILC_Uint16 u16FlagsSet; /*<! Decoded according to tenuWILC_StaFlag */ +} tstrWILC_AddStaParam; + +/* extern void CfgDisconnected(void* pUserVoid, WILC_Uint16 u16reason, u8 * ie, size_t ie_len); */ + +/*****************************************************************************/ +/* */ +/* Host Interface API */ +/* */ +/*****************************************************************************/ + +/** + * @brief removes wpa/wpa2 keys + * @details only in BSS STA mode if External Supplicant support is enabled. + * removes all WPA/WPA2 station key entries from MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_key(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8StaAddress); +/** + * @brief removes WEP key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * remove a WEP key entry from MAC HW. + * The BSS Station automatically finds the index of the entry using its + * BSS ID and removes that entry from the MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note NO need for the STA add since it is not used for processing + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_wep_key(WILC_WFIDrvHandle hWFIDrv, u8 u8Index); +/** + * @brief sets WEP deafault key + * @details Sets the index of the WEP encryption key in use, + * in the key table + * @param[in,out] handle to the wifi driver + * @param[in] key index ( 0, 1, 2, 3) + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_WEPDefaultKeyID(WILC_WFIDrvHandle hWFIDrv, u8 u8Index); + +/** + * @brief sets WEP deafault key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * @param[in] message containing WEP Key in the following format + *|---------------------------------------| + *|Key ID Value | Key Length | Key | + *|-------------|------------|------------| + | 1byte | 1byte | Key Length | + ||---------------------------------------| + | + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_sta(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx); +/** + * @brief host_int_add_wep_key_bss_ap + * @details valid only in AP mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 28 Feb 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_ap(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx, u8 u8mode, AUTHTYPE_T tenuAuth_type); + +/** + * @brief adds ptk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing PTK Key in the following format + *|-------------------------------------------------------------------------| + *|Sta Adress | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + *|-----------|------------|---------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + ||-------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_ptk(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen, + const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx); + +/** + * @brief host_int_get_inactive_time + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing inactive time + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 15 April 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_get_inactive_time(WILC_WFIDrvHandle hWFIDrv, const u8 *mac, WILC_Uint32 *pu32InactiveTime); + +/** + * @brief adds Rx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing Rx GTK Key in the following format + *|----------------------------------------------------------------------------| + *|Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + *|------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_rx_gtk(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen, + u8 u8KeyIdx, WILC_Uint32 u32KeyRSClen, const u8 *KeyRSC, + const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode); + + +/** + * @brief adds Tx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing Tx GTK Key in the following format + *|----------------------------------------------------| + | KeyID | Key Length | Temporal Key | Tx Michael Key | + ||-------|------------|--------------|----------------| + ||1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_tx_gtk(WILC_WFIDrvHandle hWFIDrv, u8 u8KeyLen, u8 *pu8TxGtk, u8 u8KeyIdx); + +/** + * @brief caches the pmkid + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver + * @param[in] message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_pmkid_info(WILC_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr *pu8PmkidInfoArray); +/** + * @brief gets the cached the pmkid info + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver, + * + * message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @param[in] + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_pmkid_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8PmkidInfoArray, + WILC_Uint32 u32PmkidInfoLen); + +/** + * @brief sets the pass phrase + * @details AP/STA mode. This function gives the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * @param[in] String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, u8 *pu8PassPhrase, + u8 u8Psklength); +/** + * @brief gets the pass phrase + * @details AP/STA mode. This function gets the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, + u8 *pu8PassPhrase, u8 u8Psklength); + +/** + * @brief gets mac address + * @details + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 19 April 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_MacAddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8MacAddress); + +/** + * @brief sets mac address + * @details + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 16 July 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_MacAddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8MacAddress); + +/** + * @brief wait until msg q is empty + * @details + * @param[in,out] + * + * @return Error code indicating success/failure + * @note + * @author asobhy + * @date 19 march 2014 + * @version 1.0 + */ +WILC_Sint32 host_int_wait_msg_queue_idle(void); + +/** + * @brief gets the site survey results + * @details + * @param[in,out] handle to the wifi driver, + * Message containing site survey results in the + * following formate + *|---------------------------------------------------| + | MsgLength | fragNo. | MsgBodyLength | MsgBody | + ||-----------|-----------|---------------|-----------| + | 1 | 1 | 1 | 1 | + | ----------------------------------------- | ---------------- + | + ||---------------------------------------| + | Network1 | Netweork2 | ... | Network5 | + ||---------------------------------------| + | 44 | 44 | ... | 44 | + | -------------------------- | --------------------------------------- + | + ||---------------------------------------------------------------------| + | SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved | + ||------|----------|---------|----------------|-------|------|---------| + | 33 | 1 | 1 | 1 | 6 | 1 | 1 | + ||---------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +#ifndef CONNECT_DIRECT +WILC_Sint32 host_int_get_site_survey_results(WILC_WFIDrvHandle hWFIDrv, + u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + WILC_Uint32 u32MaxSiteSrvyFragLen); +#endif + +/** + * @brief sets a start scan request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_start_scan_req(WILC_WFIDrvHandle hWFIDrv, u8 scanSource); +/** + * @brief gets scan source of the last scan + * @details + * @param[in,out] handle to the wifi driver, + * Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_start_scan_req(WILC_WFIDrvHandle hWFIDrv, u8 *pu8ScanSource); + +/** + * @brief sets a join request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the bss descriptor + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_set_join_req(WILC_WFIDrvHandle hWFIDrv, u8 *pu8bssid, + const u8 *pu8ssid, size_t ssidLen, + const u8 *pu8IEs, size_t IEsLen, + tWILCpfConnectResult pfConnectResult, void *pvUserArg, + u8 u8security, AUTHTYPE_T tenuAuth_type, + u8 u8channel, + void *pJoinParams); + +/** + * @brief Flush a join request parameters to FW, but actual connection + * @details The function is called in situation where WILC is connected to AP and + * required to switch to hybrid FW for P2P connection + * @param[in] handle to the wifi driver, + * @return Error code indicating success/failure + * @note + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +WILC_Sint32 host_int_flush_join_req(WILC_WFIDrvHandle hWFIDrv); + + +/** + * @brief disconnects from the currently associated network + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Reason Code of the Disconnection + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16ReasonCode); + +/** + * @brief disconnects a sta + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Association Id of the station to be disconnected + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect_station(WILC_WFIDrvHandle hWFIDrv, u8 assoc_id); +/** + * @brief gets a Association request info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. req info in the following format + * ------------------------------------------------------------------------ + | Management Frame Format | + ||-------------------------------------------------------------------| + ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS | + ||-------------|--------|--|--|-----|----------------|----------|----| + | 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 | + ||-------------------------------------------------------------------| + | | + | Association Request Frame - Frame Body | + ||-------------------------------------------------------------------| + | Capability Information | Listen Interval | SSID | Supported Rates | + ||------------------------|-----------------|------|-----------------| + | 2 | 2 | 2-34 | 3-10 | + | --------------------------------------------------------------------- + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_req_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8AssocReqInfo, + WILC_Uint32 u32AssocReqInfoLen); +/** + * @brief gets a Association Response info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. resp info + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_res_info(WILC_WFIDrvHandle hWFIDrv, u8 *pu8AssocRespInfo, + WILC_Uint32 u32MaxAssocRespInfoLen, WILC_Uint32 *pu32RcvdAssocRespInfoLen); +/** + * @brief gets a Association Response info + * @details Valid only in STA mode. This function gives the RSSI + * values observed in all the channels at the time of scanning. + * The length of the field is 1 greater that the total number of + * channels supported. Byte 0 contains the number of channels while + * each of Byte N contains the observed RSSI value for the channel index N. + * @param[in,out] handle to the wifi driver, + * array of scanned channels' RSSI + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rx_power_level(WILC_WFIDrvHandle hWFIDrv, u8 *pu8RxPowerLevel, + WILC_Uint32 u32RxPowerLevelLen); + +/** + * @brief sets a channel + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the channel to be set + *|-------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_mac_chnl_num(WILC_WFIDrvHandle hWFIDrv, u8 u8ChNum); + +/** + * @brief gets the current channel index + * @details + * @param[in,out] handle to the wifi driver, + * current channel index + *|-----------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-----------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_host_chnl_num(WILC_WFIDrvHandle hWFIDrv, u8 *pu8ChNo); +/** + * @brief gets the sta rssi + * @details gets the currently maintained RSSI value for the station. + * The received signal strength value in dB. + * The range of valid values is -128 to 0. + * @param[in,out] handle to the wifi driver, + * rssi value in dB + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rssi(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8Rssi); +WILC_Sint32 host_int_get_link_speed(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8lnkspd); +/** + * @brief scans a set of channels + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan source + * Scan Type PASSIVE_SCAN = 0, + * ACTIVE_SCAN = 1 + * Channels Array + * Channels Array length + * Scan Callback function + * User Argument to be delivered back through the Scan Cllback function + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_scan(WILC_WFIDrvHandle hWFIDrv, u8 u8ScanSource, + u8 u8ScanType, u8 *pu8ChnlFreqList, + u8 u8ChnlListLen, const u8 *pu8IEs, + size_t IEsLen, tWILCpfScanResult ScanResult, + void *pvUserArg, tstrHiddenNetwork *pstrHiddenNetwork); +/** + * @brief sets configuration wids values + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] WID, WID value + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_set_cfg(WILC_WFIDrvHandle hWFIDrv, tstrCfgParamVal *pstrCfgParamVal); + +/** + * @brief gets configuration wids values + * @details + * @param[in,out] handle to the wifi driver, + * WID value + * @param[in] WID, + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_get_cfg(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16WID, WILC_Uint16 *pu16WID_Value); +/*****************************************************************************/ +/* Notification Functions */ +/*****************************************************************************/ +/** + * @brief notifies host with join and leave requests + * @details This function prepares an Information frame having the + * information about a joining/leaving station. + * @param[in,out] handle to the wifi driver, + * @param[in] 6 byte Sta Adress + * Join or leave flag: + * Join = 1, + * Leave =0 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_join_leave_info_to_host + (WILC_Uint16 assocId, u8 *stationAddr, WILC_Bool joining); + +/** + * @brief notifies host with stations found in scan + * @details sends the beacon/probe response from scan + * @param[in,out] handle to the wifi driver, + * @param[in] Sta Address, + * Frame length, + * Rssi of the Station found + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_network_info_to_host + (u8 *macStartAddress, WILC_Uint16 u16RxFrameLen, WILC_Sint8 s8Rssi); + +/** + * @brief host interface initialization function + * @details + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_init(WILC_WFIDrvHandle *phWFIDrv); + +/** + * @brief host interface initialization function + * @details + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_deinit(WILC_WFIDrvHandle hWFIDrv); + + +/*! + * @fn WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv,u8 u8Index) + * @brief Sends a beacon to the firmware to be transmitted over the air + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] u32Interval Beacon Interval. Period between two successive beacons on air + * @param[in] u32DTIMPeriod DTIM Period. Indicates how many Beacon frames + * (including the current frame) appear before the next DTIM + * @param[in] u32Headlen Length of the head buffer in bytes + * @param[in] pu8Head Pointer to the beacon's head buffer. Beacon's head + * is the part from the beacon's start till the TIM element, NOT including the TIM + * @param[in] u32Taillen Length of the tail buffer in bytes + * @param[in] pu8Tail Pointer to the beacon's tail buffer. Beacon's tail + * starts just after the TIM inormation element + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 Julys 2012 + * @version 1.0 Description + * + */ +WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + WILC_Uint32 u32DTIMPeriod, + WILC_Uint32 u32HeadLen, u8 *pu8Head, + WILC_Uint32 u32TailLen, u8 *pu8tail); + + +/*! + * @fn WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv) + * @brief Removes the beacon and stops trawilctting it over the air + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 Julys 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv); + +/*! + * @fn WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam strStaParams) + * @brief Notifies the firmware with a new associated stations + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pstrStaParams Station's parameters + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 12 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams); + +/*! + * @fn WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, const u8* pu8MacAddr) + * @brief Deauthenticates clients when group is terminating + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pu8MacAddr Station's mac address + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Mai Daftedar + * @date 09 April 2014 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]); + +/*! + * @fn WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, u8* pu8MacAddr) + * @brief Notifies the firmware with a new deleted station + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pu8MacAddr Station's mac address + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, const u8 *pu8MacAddr); + +/*! + * @fn WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam strStaParams) + * @brief Notifies the firmware with new parameters of an already associated station + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] pstrStaParams Station's parameters + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams); + +/*! + * @fn WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout) + * @brief Set the power management mode to enabled or disabled + * @details + * @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise + * @param[in] u32Timeout A timeout value of -1 allows the driver to adjust + * the dynamic ps timeout value + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout); +/* @param[in,out] hWFIDrv handle to the wifi driver + * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise + * @param[in] u8count count of mac address entries in the filter table + * + * @return 0 for Success, error otherwise + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 Description + */ +WILC_Sint32 host_int_setup_multicast_filter(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32count); +/** + * @brief host_int_setup_ipaddress + * @details set IP address on firmware + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_setup_ipaddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8IPAddr, u8 idx); + + +/** + * @brief host_int_delBASession + * @details Delete single Rx BA session + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_delBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID); + +/** + * @brief host_int_delBASession + * @details Delete all Rx BA session + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_All_Rx_BASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID); + + +/** + * @brief host_int_get_ipaddress + * @details get IP address on firmware + * @param[in] + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, u8 *pu8IPAddr, u8 idx); + +#ifdef WILC_P2P +/** + * @brief host_int_remain_on_channel + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_remain_on_channel(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID, WILC_Uint32 u32duration, WILC_Uint16 chan, tWILCpfRemainOnChanExpired RemainOnChanExpired, tWILCpfRemainOnChanReady RemainOnChanReady, void *pvUserArg); + +/** + * @brief host_int_ListenStateExpired + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_ListenStateExpired(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID); + +/** + * @brief host_int_frame_register + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_frame_register(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16FrameType, WILC_Bool bReg); +#endif +/** + * @brief host_int_set_wfi_drv_handler + * @details + * @param[in] + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_set_wfi_drv_handler(WILC_Uint32 u32address); +WILC_Sint32 host_int_set_operation_mode(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32mode); + +static WILC_Sint32 Handle_ScanDone(void *drvHandler, tenuScanEvent enuEvent); + +static int host_int_addBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID, short int BufferSize, + short int SessionTimeout, void *drvHandler); + + +void host_int_freeJoinParams(void *pJoinParams); + +WILC_Sint32 host_int_get_statistics(WILC_WFIDrvHandle hWFIDrv, tstrStatistics *pstrStatistics); + +/*****************************************************************************/ +/* */ +/* EOF */ +/* */ +/*****************************************************************************/ +#endif diff --git a/drivers/staging/wilc1000/itypes.h b/drivers/staging/wilc1000/itypes.h new file mode 100644 index 000000000000..6c2bd791a0b1 --- /dev/null +++ b/drivers/staging/wilc1000/itypes.h @@ -0,0 +1,60 @@ +/*****************************************************************************/ +/* */ +/* Ittiam 802.11 MAC SOFTWARE */ +/* */ +/* ITTIAM SYSTEMS PVT LTD, BANGALORE */ +/* COPYRIGHT(C) 2005 */ +/* */ +/* This program is proprietary to Ittiam Systems Private Limited and */ +/* is protected under Indian Copyright Law as an unpublished work. Its use */ +/* and disclosure is limited by the terms and conditions of a license */ +/* agreement. It may not be copied or otherwise reproduced or disclosed to */ +/* persons outside the licensee's organization except in accordance with the*/ +/* terms and conditions of such an agreement. All copies and */ +/* reproductions shall be the property of Ittiam Systems Private Limited and*/ +/* must bear this notice in its entirety. */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* File Name : itypes.h */ +/* */ +/* Description : This file contains all the data type definitions for */ +/* MAC implementation. */ +/* */ +/* List of Functions : None */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes */ +/* 01 05 2005 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +#ifndef ITYPES_H +#define ITYPES_H + + +/*****************************************************************************/ +/* Data Types */ +/*****************************************************************************/ + +typedef int WORD32; +typedef short WORD16; +typedef char WORD8; +typedef unsigned int UWORD32; +typedef unsigned short UWORD16; +typedef unsigned char UWORD8; + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ + +typedef enum { + BFALSE = 0, + BTRUE = 1 +} BOOL_T; + +#endif /* ITYPES_H */ diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c new file mode 100644 index 000000000000..cd6dc48b4b33 --- /dev/null +++ b/drivers/staging/wilc1000/linux_mon.c @@ -0,0 +1,643 @@ +/*! + * @file linux_mon.c + * @brief File Operations OS wrapper functionality + * @author mdaftedar + * @sa wilc_wfi_netdevice.h + * @date 01 MAR 2012 + * @version 1.0 + */ + +#ifndef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#include "linux_wlan_common.h" +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#endif +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +#endif +#ifdef WILC_AP_EXTERNAL_MLME +#ifdef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#endif + +struct wilc_wfi_radiotap_hdr { + struct ieee80211_radiotap_header hdr; + u8 rate; + /* u32 channel; */ +} __attribute__((packed)); + +struct wilc_wfi_radiotap_cb_hdr { + struct ieee80211_radiotap_header hdr; + u8 rate; + u8 dump; + u16 tx_flags; + /* u32 channel; */ +} __attribute__((packed)); + +extern linux_wlan_t *g_linux_wlan; + +static struct net_device *wilc_wfi_mon; /* global monitor netdev */ + +#ifdef SIMULATION +extern int WILC_WFI_Tx(struct sk_buff *skb, struct net_device *dev); +#elif USE_WIRELESS +extern int mac_xmit(struct sk_buff *skb, struct net_device *dev); +#endif + + +u8 srcAdd[6]; +u8 bssid[6]; +u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +/** + * @brief WILC_WFI_monitor_rx + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ + +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/ +#define IS_MANAGMEMENT 0x100 +#define IS_MANAGMEMENT_CALLBACK 0x080 +#define IS_MGMT_STATUS_SUCCES 0x040 +#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) + +void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size) +{ + uint32_t header, pkt_offset; + struct sk_buff *skb = NULL; + struct wilc_wfi_radiotap_hdr *hdr; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + PRINT_INFO(HOSTAPD_DBG, "In monitor interface receive function\n"); + + /* struct WILC_WFI_priv *priv = netdev_priv(dev); */ + + /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ + + /* Bug 4601 */ + if (wilc_wfi_mon == NULL) + return; + + if (!netif_running(wilc_wfi_mon)) { + PRINT_INFO(HOSTAPD_DBG, "Monitor interface already RUNNING\n"); + return; + } + + /* Get WILC header */ + memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); + + /* The packet offset field conain info about what type of managment frame */ + /* we are dealing with and ack status */ + pkt_offset = GET_PKT_OFFSET(header); + + if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { + + /* hostapd callback mgmt frame */ + + skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + if (skb == NULL) { + PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); + return; + } + + memcpy(skb_put(skb, size), buff, size); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + + if (pkt_offset & IS_MGMT_STATUS_SUCCES) { + /* success */ + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; + } else { + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; + } + + } else { + + skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_hdr)); + + if (skb == NULL) { + PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); + return; + } + + /* skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); */ + /* if (skb == NULL) */ + /* return; */ + + memcpy(skb_put(skb, size), buff, size); + hdr = (struct wilc_wfi_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); + memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr)); + hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + /* hdr->hdr.it_pad = 0; */ + hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_hdr)); + PRINT_INFO(HOSTAPD_DBG, "Radiotap len %d\n", hdr->hdr.it_len); + hdr->hdr.it_present = cpu_to_le32 + (1 << IEEE80211_RADIOTAP_RATE); /* | */ + /* (1 << IEEE80211_RADIOTAP_CHANNEL)); */ + PRINT_INFO(HOSTAPD_DBG, "Presentflags %d\n", hdr->hdr.it_present); + hdr->rate = 5; /* txrate->bitrate / 5; */ + + } + +/* if(INFO || if(skb->data[9] == 0x00 || skb->data[9] == 0xb0)) + * { + * for(i=0;i<skb->len;i++) + * PRINT_INFO(HOSTAPD_DBG,"Mon RxData[%d] = %02x\n",i,skb->data[i]); + * }*/ + + + skb->dev = wilc_wfi_mon; + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + + netif_rx(skb); + + +} + +struct tx_complete_mon_data { + int size; + void *buff; +}; + +static void mgmt_tx_complete(void *priv, int status) +{ + + /* struct sk_buff *skb2; */ + /* struct wilc_wfi_radiotap_cb_hdr *cb_hdr; */ + + struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; + u8 *buf = pv_data->buff; + + + + if (status == 1) { + if (INFO || buf[0] == 0x10 || buf[0] == 0xb0) + PRINT_INFO(HOSTAPD_DBG, "Packet sent successfully - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); + } else { + PRINT_INFO(HOSTAPD_DBG, "Couldn't send packet - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); + } + + +/* //(skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) + * { + * skb2 = dev_alloc_skb(pv_data->size+sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * memcpy(skb_put(skb2,pv_data->size),pv_data->buff, pv_data->size); + * + * cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); + * memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION; + * + * cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + * + * cb_hdr->hdr.it_present = cpu_to_le32( + * (1 << IEEE80211_RADIOTAP_RATE) | + * (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + * + * cb_hdr->rate = 5;//txrate->bitrate / 5; + * cb_hdr->tx_flags = 0x0004; + * + * skb2->dev = wilc_wfi_mon; + * skb_set_mac_header(skb2, 0); + * skb2->ip_summed = CHECKSUM_UNNECESSARY; + * skb2->pkt_type = PACKET_OTHERHOST; + * skb2->protocol = htons(ETH_P_802_2); + * memset(skb2->cb, 0, sizeof(skb2->cb)); + * + * netif_rx(skb2); + * }*/ + + /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ + #ifndef WILC_FULLY_HOSTING_AP + kfree(pv_data->buff); + + kfree(pv_data); + #endif +} +static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len) +{ + linux_wlan_t *nic; + struct tx_complete_mon_data *mgmt_tx = NULL; + + if (dev == NULL) { + PRINT_D(HOSTAPD_DBG, "ERROR: dev == NULL\n"); + return WILC_FAIL; + } + nic = netdev_priv(dev); + + netif_stop_queue(dev); + mgmt_tx = (struct tx_complete_mon_data *)kmalloc(sizeof(struct tx_complete_mon_data), GFP_ATOMIC); + if (mgmt_tx == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); + return WILC_FAIL; + } + + #ifdef WILC_FULLY_HOSTING_AP + /* add space for the pointer to tx_complete_mon_data */ + len += sizeof(struct tx_complete_mon_data *); + #endif + + mgmt_tx->buff = (char *)kmalloc(len, GFP_ATOMIC); + if (mgmt_tx->buff == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx buff\n"); + return WILC_FAIL; + + } + + mgmt_tx->size = len; + + #ifndef WILC_FULLY_HOSTING_AP + memcpy(mgmt_tx->buff, buf, len); + #else + memcpy(mgmt_tx->buff, buf, len - sizeof(struct tx_complete_mon_data *)); + memcpy((mgmt_tx->buff) + (len - sizeof(struct tx_complete_mon_data *)), &mgmt_tx, sizeof(struct tx_complete_mon_data *)); + + /* filter data frames to handle it's PS */ + if (filter_monitor_data_frames((mgmt_tx->buff), len) == WILC_TRUE) { + return; + } + + #endif /* WILC_FULLY_HOSTING_AP */ + + g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, mgmt_tx_complete); + + netif_wake_queue(dev); + return 0; +} + +/** + * @brief WILC_WFI_mon_xmit + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ieee80211_radiotap_header *rtap_hdr; + WILC_Uint32 rtap_len, i, ret = 0; + struct WILC_WFI_mon_priv *mon_priv; + + struct sk_buff *skb2; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + /* Bug 4601 */ + if (wilc_wfi_mon == NULL) + return WILC_FAIL; + + /* if(skb->data[3] == 0x10 || skb->data[3] == 0xb0) */ + + mon_priv = netdev_priv(wilc_wfi_mon); + + if (mon_priv == NULL) { + PRINT_ER("Monitor interface private structure is NULL\n"); + return WILC_FAIL; + } + + rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; + + rtap_len = ieee80211_get_radiotap_len(skb->data); + if (skb->len < rtap_len) { + PRINT_ER("Error in radiotap header\n"); + return -1; + } + /* skip the radiotap header */ + PRINT_INFO(HOSTAPD_DBG, "Radiotap len: %d\n", rtap_len); + + if (INFO) { + for (i = 0; i < rtap_len; i++) + PRINT_INFO(HOSTAPD_DBG, "Radiotap_hdr[%d] %02x\n", i, skb->data[i]); + } + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + + if (skb->data[0] == 0xc0) + PRINT_INFO(HOSTAPD_DBG, "%x:%x:%x:%x:%x%x\n", skb->data[4], skb->data[5], skb->data[6], skb->data[7], skb->data[8], skb->data[9]); + + if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) { + skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + memcpy(skb_put(skb2, skb->len), skb->data, skb->len); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + cb_hdr->tx_flags = 0x0004; + + skb2->dev = wilc_wfi_mon; + skb_set_mac_header(skb2, 0); + skb2->ip_summed = CHECKSUM_UNNECESSARY; + skb2->pkt_type = PACKET_OTHERHOST; + skb2->protocol = htons(ETH_P_802_2); + memset(skb2->cb, 0, sizeof(skb2->cb)); + + netif_rx(skb2); + + return 0; + } + skb->dev = mon_priv->real_ndev; + + PRINT_INFO(HOSTAPD_DBG, "Skipping the radiotap header\n"); + + + + /* actual deliver of data is device-specific, and not shown here */ + PRINT_INFO(HOSTAPD_DBG, "SKB netdevice name = %s\n", skb->dev->name); + PRINT_INFO(HOSTAPD_DBG, "MONITOR real dev name = %s\n", mon_priv->real_ndev->name); + + #ifdef SIMULATION + ret = WILC_WFI_Tx(skb, mon_priv->real_ndev); + #elif USE_WIRELESS + /* Identify if Ethernet or MAC header (data or mgmt) */ + memcpy(srcAdd, &skb->data[10], 6); + memcpy(bssid, &skb->data[16], 6); + /* if source address and bssid fields are equal>>Mac header */ + /*send it to mgmt frames handler */ + if (!(memcmp(srcAdd, bssid, 6))) { + mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len); + dev_kfree_skb(skb); + } else + ret = mac_xmit(skb, mon_priv->real_ndev); + #endif + + /* return NETDEV_TX_OK; */ + return ret; +} + +static const struct net_device_ops wilc_wfi_netdev_ops = { + .ndo_start_xmit = WILC_WFI_mon_xmit, + +}; + +#ifdef WILC_FULLY_HOSTING_AP +/* + * @brief WILC_mgm_HOSTAPD_ACK + * @details report the status of transmitted mgmt frames to HOSTAPD + * @param[in] priv : pointer to tx_complete_mon_data struct + * bStatus : status of transmission + * @author Abd Al-Rahman Diab + * @date 9 May 2013 + * @version 1.0 + */ +void WILC_mgm_HOSTAPD_ACK(void *priv, WILC_Bool bStatus) +{ + struct sk_buff *skb; + struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + + struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; + u8 *buf = pv_data->buff; + + /* len of the original frame without the added pointer at the tail */ + WILC_Uint16 u16len = (pv_data->size) - sizeof(struct tx_complete_mon_data *); + + + /*if(bStatus == 1){ + * if(INFO || buf[0] == 0x10 || buf[0] == 0xb0) + * PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",u16len,pv_data->buff); + * }else{ + * PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",u16len,pv_data->buff); + * } + */ + + /* (skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) */ + { + skb = dev_alloc_skb(u16len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + memcpy(skb_put(skb, u16len), pv_data->buff, u16len); + + cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); + memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ + + cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); + + cb_hdr->hdr.it_present = cpu_to_le32( + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TX_FLAGS)); + + cb_hdr->rate = 5; /* txrate->bitrate / 5; */ + + + if (WILC_TRUE == bStatus) { + /* success */ + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; + } else { + cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; + } + + skb->dev = wilc_wfi_mon; + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + + netif_rx(skb); + } + + /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ + kfree(pv_data->buff); + + kfree(pv_data); + +} +#endif /* WILC_FULLY_HOSTING_AP */ + +/** + * @brief WILC_WFI_mon_setup + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +static void WILC_WFI_mon_setup(struct net_device *dev) +{ + + dev->netdev_ops = &wilc_wfi_netdev_ops; + /* dev->destructor = free_netdev; */ + PRINT_INFO(CORECONFIG_DBG, "In Ethernet setup function\n"); + ether_setup(dev); + dev->tx_queue_len = 0; + dev->type = ARPHRD_IEEE80211_RADIOTAP; + memset(dev->dev_addr, 0, ETH_ALEN); + + #ifdef USE_WIRELESS + { + /* u8 * mac_add; */ + unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x8f}; + /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ + /* mac_add = (u8*)WILC_MALLOC(ETH_ALEN); */ + /* status = host_int_get_MacAddress(priv->hWILCWFIDrv,mac_add); */ + /* mac_add[ETH_ALEN-1]+=1; */ + memcpy(dev->dev_addr, mac_add, ETH_ALEN); + } + #else + dev->dev_addr[0] = 0x12; + #endif + +} + +/** + * @brief WILC_WFI_init_mon_interface + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_device *real_dev) +{ + + + WILC_Uint32 ret = WILC_SUCCESS; + struct WILC_WFI_mon_priv *priv; + + /*If monitor interface is already initialized, return it*/ + if (wilc_wfi_mon) { + return wilc_wfi_mon; + } +#if 0 + wilc_wfi_mon = alloc_netdev(sizeof(struct WILC_WFI_mon_priv), name, WILC_WFI_mon_setup); + if (wilc_wfi_mon == NULL) { + PRINT_ER("Failed to allocate netdevice\n"); + goto failed; + } + + /* rtnl_lock(); */ + PRINT_INFO(HOSTAPD_DBG, "Monitor interface name %s\n", wilc_wfi_mon->name); + + + ret = dev_alloc_name(wilc_wfi_mon, wilc_wfi_mon->name); + if (ret < 0) + goto failed_mon; + + + priv = netdev_priv(wilc_wfi_mon); + if (priv == NULL) { + PRINT_ER("private structure is NULL\n"); + return WILC_FAIL; + } + + priv->real_ndev = real_dev; + + + ret = register_netdevice(wilc_wfi_mon); + + + if (ret < 0) { + PRINT_ER("Failed to register netdevice\n"); + goto failed_mon; + } + + + return WILC_SUCCESS; + /* rtnl_unlock(); */ + +failed: + return ret; + +failed_mon: + /* rtnl_unlock(); */ + free_netdev(wilc_wfi_mon); + return ret; +#endif + + wilc_wfi_mon = alloc_etherdev(sizeof(struct WILC_WFI_mon_priv)); + if (!wilc_wfi_mon) { + PRINT_ER("failed to allocate memory\n"); + return NULL; + + } + + wilc_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(wilc_wfi_mon->name, name, IFNAMSIZ); + wilc_wfi_mon->name[IFNAMSIZ - 1] = 0; + wilc_wfi_mon->netdev_ops = &wilc_wfi_netdev_ops; + + ret = register_netdevice(wilc_wfi_mon); + if (ret) { + PRINT_ER(" register_netdevice failed (%d)\n", ret); + return NULL; + } + priv = netdev_priv(wilc_wfi_mon); + if (priv == NULL) { + PRINT_ER("private structure is NULL\n"); + return NULL; + } + + priv->real_ndev = real_dev; + + return wilc_wfi_mon; +} + +/** + * @brief WILC_WFI_deinit_mon_interface + * @details + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 12 JUL 2012 + * @version 1.0 + */ +int WILC_WFI_deinit_mon_interface() +{ + bool rollback_lock = false; + + if (wilc_wfi_mon != NULL) { + PRINT_D(HOSTAPD_DBG, "In Deinit monitor interface\n"); + PRINT_D(HOSTAPD_DBG, "RTNL is being locked\n"); + if (rtnl_is_locked()) { + rtnl_unlock(); + rollback_lock = true; + } + PRINT_D(HOSTAPD_DBG, "Unregister netdev\n"); + unregister_netdev(wilc_wfi_mon); + /* free_netdev(wilc_wfi_mon); */ + + if (rollback_lock) { + rtnl_lock(); + rollback_lock = false; + } + wilc_wfi_mon = NULL; + } + return WILC_SUCCESS; + +} +#endif /* WILC_AP_EXTERNAL_MLME */ diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c new file mode 100644 index 000000000000..e92ba59382ef --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -0,0 +1,2868 @@ +#ifndef SIMULATION +#include "wilc_wfi_cfgoperations.h" +#include "linux_wlan_common.h" +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#ifdef USE_WIRELESS +#include "wilc_wfi_cfgoperations.h" +#endif + +#include "linux_wlan_common.h" + +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/workqueue.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <linux/kthread.h> +#include <linux/firmware.h> +#include <linux/delay.h> + +#include <linux/init.h> +#include <linux/netdevice.h> +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +#include <linux/inetdevice.h> +#endif +#include <linux/etherdevice.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> + +#include <linux/version.h> +#include <linux/semaphore.h> + +#ifdef WILC_SDIO +#include "linux_wlan_sdio.h" +#else +#include "linux_wlan_spi.h" +#endif + +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +#endif + +#ifdef STATIC_MACADDRESS /* brandy_0724 [[ */ +#include <linux/vmalloc.h> +#include <linux/fs.h> +struct task_struct *wilc_mac_thread; +unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2}; +#endif /* brandy_0724 ]] */ + +#if defined(CUSTOMER_PLATFORM) +/* + TODO : Write power control functions as customer platform. + */ +#else + + #define _linux_wlan_device_power_on() {} + #define _linux_wlan_device_power_off() {} + + #define _linux_wlan_device_detection() {} + #define _linux_wlan_device_removal() {} +#endif + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_Bool g_obtainingIP; +#endif +extern WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue); +extern void resolve_disconnect_aberration(void *drvHandler); +extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; +void wilc1000_wlan_deinit(linux_wlan_t *nic); +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_TimerHandle hDuringIpTimer; +#endif + +static int linux_wlan_device_power(int on_off) +{ + PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off); + + if (on_off) { + _linux_wlan_device_power_on(); + } else { + _linux_wlan_device_power_off(); + } + + return 0; +} + +static int linux_wlan_device_detection(int on_off) +{ + PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off); + +#ifdef WILC_SDIO + if (on_off) { + _linux_wlan_device_detection(); + } else { + _linux_wlan_device_removal(); + } +#endif + + return 0; +} + + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr); + +static struct notifier_block g_dev_notifier = { + .notifier_call = dev_state_ev_handler +}; +#endif + +#define wilc_wlan_deinit(nic) { if (&g_linux_wlan->oup != NULL) \ + if (g_linux_wlan->oup.wlan_cleanup != NULL) \ + g_linux_wlan->oup.wlan_cleanup(); } + + +#ifndef STA_FIRMWARE +#define STA_FIRMWARE "wifi_firmware.bin" +#endif + +#ifndef AP_FIRMWARE +#define AP_FIRMWARE "wifi_firmware_ap.bin" +#endif + +#ifndef P2P_CONCURRENCY_FIRMWARE +#define P2P_CONCURRENCY_FIRMWARE "wifi_firmware_p2p_concurrency.bin" +#endif + + + +typedef struct android_wifi_priv_cmd { + char *buf; + int used_len; + int total_len; +} android_wifi_priv_cmd; + + +#define IRQ_WAIT 1 +#define IRQ_NO_WAIT 0 +/* + * to sync between mac_close and module exit. + * don't initialize or de-initialize from init/deinitlocks + * to be initialized from module wilc_netdev_init and + * deinitialized from mdoule_exit + */ +static struct semaphore close_exit_sync; +unsigned int int_rcvdU; +unsigned int int_rcvdB; +unsigned int int_clrd; + +static int wlan_deinit_locks(linux_wlan_t *nic); +static void wlan_deinitialize_threads(linux_wlan_t *nic); +static void linux_wlan_lock(void *vp); +void linux_wlan_unlock(void *vp); +extern void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size); +extern void WILC_WFI_p2p_rx(struct net_device *dev, uint8_t *buff, uint32_t size); + + +static void *internal_alloc(uint32_t size, uint32_t flag); +static void linux_wlan_tx_complete(void *priv, int status); +void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset); +static int mac_init_fn(struct net_device *ndev); +int mac_xmit(struct sk_buff *skb, struct net_device *dev); +int mac_open(struct net_device *ndev); +int mac_close(struct net_device *ndev); +static struct net_device_stats *mac_stats(struct net_device *dev); +static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd); +static void wilc_set_multicast_list(struct net_device *dev); + + + +/* + * for now - in frmw_to_linux there should be private data to be passed to it + * and this data should be pointer to net device + */ +linux_wlan_t *g_linux_wlan; +wilc_wlan_oup_t *gpstrWlanOps; +WILC_Bool bEnablePS = WILC_TRUE; + +static const struct net_device_ops wilc_netdev_ops = { + .ndo_init = mac_init_fn, + .ndo_open = mac_open, + .ndo_stop = mac_close, + .ndo_start_xmit = mac_xmit, + .ndo_do_ioctl = mac_ioctl, + .ndo_get_stats = mac_stats, + .ndo_set_rx_mode = wilc_set_multicast_list, + +}; + +#ifdef DEBUG_MODE + +extern volatile int timeNo; + +#define DEGUG_BUFFER_LENGTH 1000 +volatile int WatchDogdebuggerCounter; +char DebugBuffer[DEGUG_BUFFER_LENGTH + 20] = {0}; +static char *ps8current = DebugBuffer; + + + +void printk_later(const char *format, ...) +{ + va_list args; + va_start (args, format); + ps8current += vsprintf (ps8current, format, args); + va_end (args); + if ((ps8current - DebugBuffer) > DEGUG_BUFFER_LENGTH) { + ps8current = DebugBuffer; + } + +} + + +void dump_logs() +{ + if (DebugBuffer[0]) { + DebugBuffer[DEGUG_BUFFER_LENGTH] = 0; + PRINT_INFO(GENERIC_DBG, "early printed\n"); + PRINT_D(GENERIC_DBG, ps8current + 1); + ps8current[1] = 0; + PRINT_INFO(GENERIC_DBG, "latest printed\n"); + PRINT_D(GENERIC_DBG, DebugBuffer); + DebugBuffer[0] = 0; + ps8current = DebugBuffer; + } +} + +void Reset_WatchDogdebugger() +{ + WatchDogdebuggerCounter = 0; +} + +static int DebuggingThreadTask(void *vp) +{ + while (1) { + while (!WatchDogdebuggerCounter) { + PRINT_D(GENERIC_DBG, "Debug Thread Running %d\n", timeNo); + WatchDogdebuggerCounter = 1; + msleep(10000); + } + dump_logs(); + WatchDogdebuggerCounter = 0; + } +} + + +#endif + + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr; + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + struct net_device *dev; + u8 *pIP_Add_buff; + perInterface_wlan_t *nic; + u8 null_ip[4] = {0}; + char wlan_dev_name[5] = "wlan0"; + + if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) { + PRINT_D(GENERIC_DBG, "dev_iface = NULL\n"); + return NOTIFY_DONE; + } + + if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) { + PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n"); + return NOTIFY_DONE; + } + + dev = (struct net_device *)dev_iface->ifa_dev->dev; + if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless registerd\n"); + return NOTIFY_DONE; + } + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + if (priv == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); + return NOTIFY_DONE; + } + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + nic = netdev_priv(dev); + if (nic == NULL || pstrWFIDrv == NULL) { + PRINT_D(GENERIC_DBG, "No Wireless Priv\n"); + return NOTIFY_DONE; + } + + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */ + + switch (event) { + case NETDEV_UP: + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); /* tony */ + + PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n"); + + + /*If we are in station mode or client mode*/ + if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + pstrWFIDrv->IFC_UP = 1; + g_obtainingIP = WILC_FALSE; + WILC_TimerStop(&hDuringIpTimer, NULL); + PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n"); + } + + + + if (bEnablePS == WILC_TRUE) + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 1, 0); + + PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); + + pIP_Add_buff = (char *) (&(dev_iface->ifa_address)); + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d \n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); + host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + + break; + + case NETDEV_DOWN: + PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); /* tony */ + + PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n"); + if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) { + pstrWFIDrv->IFC_UP = 0; + g_obtainingIP = WILC_FALSE; + } + + if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + + resolve_disconnect_aberration(pstrWFIDrv); + + + PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); + + pIP_Add_buff = null_ip; + PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d \n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]); + + host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx); + + break; + + default: + PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); /* tony */ + PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event); + + break; + } + + return NOTIFY_DONE; + +} +#endif + +/* + * Interrupt initialization and handling functions + */ + +void linux_wlan_enable_irq(void) +{ + +#if (RX_BH_TYPE != RX_BH_THREADED_IRQ) +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + PRINT_D(INT_DBG, "Enabling IRQ ...\n"); + enable_irq(g_linux_wlan->dev_irq_num); +#endif +#endif +} + +void linux_wlan_disable_irq(int wait) +{ +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + if (wait) { + PRINT_D(INT_DBG, "Disabling IRQ ...\n"); + disable_irq(g_linux_wlan->dev_irq_num); + } else { + PRINT_D(INT_DBG, "Disabling IRQ ...\n"); + disable_irq_nosync(g_linux_wlan->dev_irq_num); + } +#endif +} + +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) +static irqreturn_t isr_uh_routine(int irq, void *user_data) +{ + + + int_rcvdU++; +#if (RX_BH_TYPE != RX_BH_THREADED_IRQ) + linux_wlan_disable_irq(IRQ_NO_WAIT); +#endif + PRINT_D(INT_DBG, "Interrupt received UH\n"); + + /*While mac is closing cacncel the handling of any interrupts received*/ + if (g_linux_wlan->close) { + PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n"); + #if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; + #else + return IRQ_NONE; + #endif + + } +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + schedule_work(&g_linux_wlan->rx_work_queue); + return IRQ_HANDLED; +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_unlock(&g_linux_wlan->rx_sem); + return IRQ_HANDLED; +#elif (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_WAKE_THREAD; +#endif + +} +#endif + +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE || RX_BH_TYPE == RX_BH_THREADED_IRQ) + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) +irqreturn_t isr_bh_routine(int irq, void *userdata) +{ + linux_wlan_t *nic; + nic = (linux_wlan_t *)userdata; +#else +static void isr_bh_routine(struct work_struct *work) +{ + perInterface_wlan_t *nic; + nic = (perInterface_wlan_t *)container_of(work, linux_wlan_t, rx_work_queue); +#endif + + /*While mac is closing cacncel the handling of any interrupts received*/ + if (g_linux_wlan->close) { + PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n"); + #if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; + #else + return; + #endif + + + + } + + int_rcvdB++; + PRINT_D(INT_DBG, "Interrupt received BH\n"); + if (g_linux_wlan->oup.wlan_handle_rx_isr != 0) { + g_linux_wlan->oup.wlan_handle_rx_isr(); + } else { + PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n"); + } + + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + return IRQ_HANDLED; +#endif +} +#elif (RX_BH_TYPE == RX_BH_KTHREAD) +static int isr_bh_routine(void *vp) +{ + linux_wlan_t *nic; + + nic = (linux_wlan_t *)vp; + + while (1) { + linux_wlan_lock(&nic->rx_sem); + if (g_linux_wlan->close) { + + while (!kthread_should_stop()) + schedule(); + + break; + } + int_rcvdB++; + PRINT_D(INT_DBG, "Interrupt received BH\n"); + if (g_linux_wlan->oup.wlan_handle_rx_isr != 0) { + g_linux_wlan->oup.wlan_handle_rx_isr(); + } else { + PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n"); + } + } + + return 0; +} +#endif + + +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) +static int init_irq(linux_wlan_t *p_nic) +{ + int ret = 0; + linux_wlan_t *nic = p_nic; + + /*initialize GPIO and register IRQ num*/ + /*GPIO request*/ + if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) && + (gpio_direction_input(GPIO_NUM) == 0)) { +#if defined(CUSTOMER_PLATFORM) +/* + TODO : save the registerd irq number to the private wilc context in kernel. + * + * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM); + */ +#elif defined (NM73131_0_BOARD) + nic->dev_irq_num = IRQ_WILC1000; +#elif defined (PANDA_BOARD) + gpio_export(GPIO_NUM, 1); + nic->dev_irq_num = OMAP_GPIO_IRQ(GPIO_NUM); + irq_set_irq_type(nic->dev_irq_num, IRQ_TYPE_LEVEL_LOW); +#else + nic->dev_irq_num = gpio_to_irq(GPIO_NUM); +#endif + } else { + ret = -1; + PRINT_ER("could not obtain gpio for WILC_INTR\n"); + } + + +#if (RX_BH_TYPE == RX_BH_THREADED_IRQ) + if ((ret != -1) && (request_threaded_irq(nic->dev_irq_num, isr_uh_routine, isr_bh_routine, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/ + "WILC_IRQ", nic)) < 0) { + +#else + /*Request IRQ*/ + if ((ret != -1) && (request_irq(nic->dev_irq_num, isr_uh_routine, + IRQF_TRIGGER_LOW, "WILC_IRQ", nic) < 0)) { + +#endif + PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM); + ret = -1; + } else { + + PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n", + nic->dev_irq_num, GPIO_NUM); + } + + return ret; +} +#endif + +static void deinit_irq(linux_wlan_t *nic) +{ +#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO) + /* Deintialize IRQ */ + if (&nic->dev_irq_num != 0) { + free_irq(nic->dev_irq_num, g_linux_wlan); + + gpio_free(GPIO_NUM); + } +#endif +} + + +/* + * OS functions + */ +static void linux_wlan_msleep(uint32_t msc) +{ + if (msc <= 4000000) { + WILC_Uint32 u32Temp = msc * 1000; + usleep_range(u32Temp, u32Temp); + } else { + msleep(msc); + } +} + +static void linux_wlan_atomic_msleep(uint32_t msc) +{ + mdelay(msc); +} +static void linux_wlan_dbg(uint8_t *buff) +{ + PRINT_D(INIT_DBG, "%d\n", *buff); +} + +static void *linux_wlan_malloc_atomic(uint32_t sz) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(sz, GFP_ATOMIC); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr); + return (void *)pntr; + +} +static void *linux_wlan_malloc(uint32_t sz) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(sz, GFP_KERNEL); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr); + return (void *)pntr; +} + +void linux_wlan_free(void *vp) +{ + if (vp != NULL) { + PRINT_D(MEM_DBG, "Freeing %p\n", vp); + kfree(vp); + } +} + + +static void *internal_alloc(uint32_t size, uint32_t flag) +{ + char *pntr = NULL; + pntr = (char *)kmalloc(size, flag); + PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", size, pntr); + return (void *)pntr; +} + + +static void linux_wlan_init_lock(char *lockName, void *plock, int count) +{ + sema_init((struct semaphore *)plock, count); + PRINT_D(LOCK_DBG, "Initializing [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_lock(void *plock) +{ + /* mutex_destroy((struct mutex*)plock); */ +} + +static void linux_wlan_lock(void *vp) +{ + PRINT_D(LOCK_DBG, "Locking %p\n", vp); + if (vp != NULL) { + while (down_interruptible((struct semaphore *) vp)) + ; + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + +static int linux_wlan_lock_timeout(void *vp, WILC_Uint32 timeout) +{ + int error = -1; + PRINT_D(LOCK_DBG, "Locking %p\n", vp); + if (vp != NULL) { + error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout)); + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } + return error; +} + +void linux_wlan_unlock(void *vp) +{ + PRINT_D(LOCK_DBG, "Unlocking %p\n", vp); + if (vp != NULL) { + up((struct semaphore *)vp); + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + + +static void linux_wlan_init_mutex(char *lockName, void *plock, int count) +{ + mutex_init((struct mutex *)plock); + PRINT_D(LOCK_DBG, "Initializing mutex [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_mutex(void *plock) +{ + mutex_destroy((struct mutex *)plock); +} + +static void linux_wlan_lock_mutex(void *vp) +{ + PRINT_D(LOCK_DBG, "Locking mutex %p\n", vp); + if (vp != NULL) { + /* + * if(mutex_is_locked((struct mutex*)vp)) + * { + * //PRINT_ER("Mutex already locked - %p \n",vp); + * } + */ + mutex_lock((struct mutex *)vp); + + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + +static void linux_wlan_unlock_mutex(void *vp) +{ + PRINT_D(LOCK_DBG, "Unlocking mutex %p\n", vp); + if (vp != NULL) { + + if (mutex_is_locked((struct mutex *)vp)) { + mutex_unlock((struct mutex *)vp); + } else { + /* PRINT_ER("Mutex already unlocked - %p\n",vp); */ + } + + } else { + PRINT_ER("Failed, mutex is NULL\n"); + } +} + + +/*Added by Amr - BugID_4720*/ +static void linux_wlan_init_spin_lock(char *lockName, void *plock, int count) +{ + spin_lock_init((spinlock_t *)plock); + PRINT_D(SPIN_DEBUG, "Initializing mutex [%s][%p]\n", lockName, plock); + +} + +static void linux_wlan_deinit_spin_lock(void *plock) +{ + +} +static void linux_wlan_spin_lock(void *vp, unsigned long *flags) +{ + unsigned long lflags; + PRINT_D(SPIN_DEBUG, "Lock spin %p\n", vp); + if (vp != NULL) { + spin_lock_irqsave((spinlock_t *)vp, lflags); + *flags = lflags; + } else { + PRINT_ER("Failed, spin lock is NULL\n"); + } +} +static void linux_wlan_spin_unlock(void *vp, unsigned long *flags) +{ + unsigned long lflags = *flags; + PRINT_D(SPIN_DEBUG, "Unlock spin %p\n", vp); + if (vp != NULL) { + spin_unlock_irqrestore((spinlock_t *)vp, lflags); + *flags = lflags; + } else { + PRINT_ER("Failed, spin lock is NULL\n"); + } +} + +static void linux_wlan_mac_indicate(int flag) +{ + /*I have to do it that way becuase there is no mean to encapsulate device pointer + * as a parameter + */ + linux_wlan_t *pd = g_linux_wlan; + int status; + + if (flag == WILC_MAC_INDICATE_STATUS) { + pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char *)&status, 4); + if (pd->mac_status == WILC_MAC_STATUS_INIT) { + pd->mac_status = status; + linux_wlan_unlock(&pd->sync_event); + } else { + pd->mac_status = status; + } + + if (pd->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */ +#if 0 + /** + * get the mac and bssid address + **/ + PRINT_D(RX_DBG, "Calling cfg_get to get MAC_ADDR\n"); + pd->oup.wlan_cfg_get(1, WID_MAC_ADDR, 0); + PRINT_D(RX_DBG, "Calling cfg_get to get BSSID\n"); + pd->oup.wlan_cfg_get(0, WID_BSSID, 1); + + /** + * get the value + **/ + pd->oup.wlan_cfg_get_value(WID_MAC_ADDR, pd->eth_src_address, 6); + pd->oup.wlan_cfg_get_value(WID_BSSID, pd->eth_dst_address, 6); + + PRINT_D(GENERIC_DBG, "Source Address = %s", pd->eth_src_address); + PRINT_D(GENERIC_DBG, "Destiation Address = %s", pd->eth_dst_address); + + /** + * launch ndis + **/ +#endif + } + + } else if (flag == WILC_MAC_INDICATE_SCAN) { + PRINT_D(GENERIC_DBG, "Scanning ...\n"); + + } + +} + +struct net_device *GetIfHandler(uint8_t *pMacHeader) +{ + uint8_t *Bssid, *Bssid1; + int i = 0; + + Bssid = pMacHeader + 10; + Bssid1 = pMacHeader + 4; + + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) || + !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) { + return g_linux_wlan->strInterfaceInfo[i].wilc_netdev; + } + } + PRINT_INFO(INIT_DBG, "Invalide handle\n"); + for (i = 0; i < 25; i++) { + PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]); + } + Bssid = pMacHeader + 18; + Bssid1 = pMacHeader + 12; + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) || + !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) { + PRINT_D(INIT_DBG, "Ctx [%p]\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + return g_linux_wlan->strInterfaceInfo[i].wilc_netdev; + } + } + PRINT_INFO(INIT_DBG, "\n"); + return NULL; +} + +int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID) +{ + int i = 0; + int ret = -1; + + PRINT_D(INIT_DBG, "set bssid on[%p]\n", wilc_netdev); + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev == wilc_netdev) { + PRINT_D(INIT_DBG, "set bssid [%x][%x][%x]\n", pBSSID[0], pBSSID[1], pBSSID[2]); + memcpy(g_linux_wlan->strInterfaceInfo[i].aBSSID, pBSSID, 6); + ret = 0; + break; + } + } + return ret; +} + +/*BugID_5213*/ +/*Function to get number of connected interfaces*/ +int linux_wlan_get_num_conn_ifcs(void) +{ + uint8_t i = 0; + uint8_t null_bssid[6] = {0}; + uint8_t ret_val = 0; + + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (memcmp(g_linux_wlan->strInterfaceInfo[i].aBSSID, null_bssid, 6)) { + ret_val++; + } + } + return ret_val; +} + +static int linux_wlan_rxq_task(void *vp) +{ + + /* inform wilc1000_wlan_init that RXQ task is started. */ + linux_wlan_unlock(&g_linux_wlan->rxq_thread_started); + while (1) { + linux_wlan_lock(&g_linux_wlan->rxq_event); + /* wait_for_completion(&g_linux_wlan->rxq_event); */ + + if (g_linux_wlan->close) { + /*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */ + linux_wlan_unlock(&g_linux_wlan->rxq_thread_started); + + while (!kthread_should_stop()) + schedule(); + + PRINT_D(RX_DBG, " RX thread stopped\n"); + break; + } + PRINT_D(RX_DBG, "Calling wlan_handle_rx_que()\n"); + + g_linux_wlan->oup.wlan_handle_rx_que(); + } + return 0; +} + +#define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS + +static int linux_wlan_txq_task(void *vp) +{ + int ret, txq_count; + +#if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS +#define TX_BACKOFF_WEIGHT_INCR_STEP (1) +#define TX_BACKOFF_WEIGHT_DECR_STEP (1) +#define TX_BACKOFF_WEIGHT_MAX (7) +#define TX_BACKOFF_WEIGHT_MIN (0) +#define TX_BACKOFF_WEIGHT_UNIT_MS (10) + int backoff_weight = TX_BACKOFF_WEIGHT_MIN; + signed long timeout; +#endif + + /* inform wilc1000_wlan_init that TXQ task is started. */ + linux_wlan_unlock(&g_linux_wlan->txq_thread_started); + while (1) { + + PRINT_D(TX_DBG, "txq_task Taking a nap :)\n"); + linux_wlan_lock(&g_linux_wlan->txq_event); + /* wait_for_completion(&pd->txq_event); */ + PRINT_D(TX_DBG, "txq_task Who waked me up :$\n"); + + if (g_linux_wlan->close) { + /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */ + linux_wlan_unlock(&g_linux_wlan->txq_thread_started); + + while (!kthread_should_stop()) + schedule(); + + PRINT_D(TX_DBG, "TX thread stopped\n"); + break; + } + PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n"); +#if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS + g_linux_wlan->oup.wlan_handle_tx_que(); +#else + do { + ret = g_linux_wlan->oup.wlan_handle_tx_que(&txq_count); + if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) { + PRINT_D(TX_DBG, "Waking up queue\n"); + /* netif_wake_queue(pd->wilc_netdev); */ + if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[0].wilc_netdev)) + netif_wake_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev); + if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) + netif_wake_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); + } + + if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */ + timeout = msecs_to_jiffies(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight); + do { + /* Back off from sending packets for some time. */ + /* schedule_timeout will allow RX task to run and free buffers.*/ + /* set_current_state(TASK_UNINTERRUPTIBLE); */ + /* timeout = schedule_timeout(timeout); */ + msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight); + } while (/*timeout*/ 0); + backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP; + if (backoff_weight > TX_BACKOFF_WEIGHT_MAX) { + backoff_weight = TX_BACKOFF_WEIGHT_MAX; + } + } else { + if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) { + backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP; + if (backoff_weight < TX_BACKOFF_WEIGHT_MIN) { + backoff_weight = TX_BACKOFF_WEIGHT_MIN; + } + } + } + /*TODO: drop packets after a certain time/number of retry count. */ + } while (ret == WILC_TX_ERR_NO_BUF && !g_linux_wlan->close); /* retry sending packets if no more buffers in chip. */ +#endif + } + return 0; +} + +static void linux_wlan_rx_complete(void) +{ + PRINT_D(RX_DBG, "RX completed\n"); +} + +int linux_wlan_get_firmware(perInterface_wlan_t *p_nic) +{ + + perInterface_wlan_t *nic = p_nic; + int ret = 0; + const struct firmware *wilc_firmware; + char *firmware; + + + if (nic->iftype == AP_MODE) + firmware = AP_FIRMWARE; + else if (nic->iftype == STATION_MODE) + firmware = STA_FIRMWARE; + + /*BugID_5137*/ + else { + PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n"); + firmware = P2P_CONCURRENCY_FIRMWARE; + } + + + + if (nic == NULL) { + PRINT_ER("NIC is NULL\n"); + goto _fail_; + } + + if (&nic->wilc_netdev->dev == NULL) { + PRINT_ER("&nic->wilc_netdev->dev is NULL\n"); + goto _fail_; + } + + + /* the firmare should be located in /lib/firmware in + * root file system with the name specified above */ + +#ifdef WILC_SDIO + if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) { + PRINT_ER("%s - firmare not available\n", firmware); + ret = -1; + goto _fail_; + } +#else + if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) { + PRINT_ER("%s - firmare not available\n", firmware); + ret = -1; + goto _fail_; + } +#endif + g_linux_wlan->wilc_firmware = wilc_firmware; /* Bug 4703 */ + +_fail_: + + return ret; + +} + +#ifdef COMPLEMENT_BOOT +int repeat_power_cycle(perInterface_wlan_t *nic); +#endif + +static int linux_wlan_start_firmware(perInterface_wlan_t *nic) +{ + + int ret = 0; + /* start firmware */ + PRINT_D(INIT_DBG, "Starting Firmware ...\n"); + ret = g_linux_wlan->oup.wlan_start(); + if (ret < 0) { + PRINT_ER("Failed to start Firmware\n"); + goto _fail_; + } + + /* wait for mac ready */ + PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n"); + ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000); + if (ret) { +#ifdef COMPLEMENT_BOOT + static int timeout = 5; + + if (timeout--) { + PRINT_D(INIT_DBG, "repeat power cycle[%d]", timeout); + ret = repeat_power_cycle(nic); + } else { + timeout = 5; + ret = -1; + goto _fail_; + } +#endif + PRINT_D(INIT_DBG, "Firmware start timed out"); + goto _fail_; + } + /* + * TODO: Driver shouoldn't wait forever for firmware to get started - + * in case of timeout this should be handled properly + */ + PRINT_D(INIT_DBG, "Firmware successfully started\n"); + +_fail_: + return ret; +} +static int linux_wlan_firmware_download(linux_wlan_t *p_nic) +{ + + int ret = 0; + + if (g_linux_wlan->wilc_firmware == NULL) { + PRINT_ER("Firmware buffer is NULL\n"); + ret = -ENOBUFS; + goto _FAIL_; + } + /** + * do the firmware download + **/ + PRINT_D(INIT_DBG, "Downloading Firmware ...\n"); + ret = g_linux_wlan->oup.wlan_firmware_download(g_linux_wlan->wilc_firmware->data, g_linux_wlan->wilc_firmware->size); + if (ret < 0) { + goto _FAIL_; + } + + /* Freeing FW buffer */ + PRINT_D(INIT_DBG, "Freeing FW buffer ...\n"); + PRINT_D(INIT_DBG, "Releasing firmware\n"); + release_firmware(g_linux_wlan->wilc_firmware); + g_linux_wlan->wilc_firmware = NULL; + + PRINT_D(INIT_DBG, "Download Succeeded \n"); + +_FAIL_: + return ret; +} + + +/* startup configuration - could be changed later using iconfig*/ +static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_nic) +{ + + unsigned char c_val[64]; + #ifndef STATIC_MACADDRESS + unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff}; + #endif + + /*BugID_5077*/ + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + + PRINT_D(TX_DBG, "Start configuring Firmware\n"); + #ifndef STATIC_MACADDRESS + get_random_bytes(&mac_add[5], 1); + get_random_bytes(&mac_add[4], 1); + #endif + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv); + + PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]); + wilc_get_chipid(0); + + + if (g_linux_wlan->oup.wlan_cfg_set == NULL) { + PRINT_D(INIT_DBG, "Null p[ointer\n"); + goto _fail_; + } + + *(int *)c_val = (WILC_Uint32)pstrWFIDrv; + + if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) + goto _fail_; + + /*to tell fw that we are going to use PC test - WILC specific*/ + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = INFRASTRUCTURE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + + /* c_val[0] = RATE_AUTO; / * bug 4275: Enable autorate and limit it to 24Mbps * / */ + c_val[0] = RATE_AUTO; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_MIXED_11B_2_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_SHORT_PREAMBLE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = AUTO_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) + goto _fail_; + +#ifdef SWITCH_LOG_TERMINAL + c_val[0] = AUTO_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0, 0)) + goto _fail_; +#endif + + c_val[0] = ACTIVE_SCAN; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = SITE_SURVEY_OFF; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0)) + goto _fail_; + + *((int *)c_val) = 0xffff; /* Never use RTS-CTS */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) + goto _fail_; + + *((int *)c_val) = 2346; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) + goto _fail_; + + /* SSID */ + /* -------------------------------------------------------------- */ + /* Configuration : String with length less than 32 bytes */ + /* Values to set : Any string with length less than 32 bytes */ + /* ( In BSS Station Set SSID to "" (null string) */ + /* to enable Broadcast SSID suppport ) */ + /* -------------------------------------------------------------- */ +#ifndef USE_WIRELESS + strcpy(c_val, "nwifi"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; +#endif + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NO_POWERSAVE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = OPEN_SYSTEM; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + /* WEP/802 11I Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : WEP Key */ + /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */ + /* In case more than 5 bytes are passed on for WEP 40 */ + /* only first 5 bytes will be used as the key */ + /* ------------------------------------------------------------------ */ + + strcpy(c_val, "123456790abcdef1234567890"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; + + /* WEP/802 11I Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */ + /* Values to set : Any string with length greater than equal to 8 bytes */ + /* and less than 64 bytes */ + /* ------------------------------------------------------------------ */ + strcpy(c_val, "12345678"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0)) + goto _fail_; + + /* IEEE802.1X Key Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : Radius Server Access Secret Key */ + /* Values to set : Any string with length greater than equal to 8 bytes */ + /* and less than 65 bytes */ + /* ------------------------------------------------------------------ */ + strcpy(c_val, "password"); + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0)) + goto _fail_; + + /* IEEE802.1X Server Address Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : Radius Server IP Address */ + /* Values to set : Any valid IP Address */ + /* ------------------------------------------------------------------ */ + c_val[0] = 192; + c_val[1] = 168; + c_val[2] = 1; + c_val[3] = 112; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) + goto _fail_; + + c_val[0] = 3; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 3; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = NORMAL_ACK; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 48; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 28; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0)) + goto _fail_; + + /* Beacon Interval */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets the beacon interval value */ + /* Values to set : Any 16-bit value */ + /* -------------------------------------------------------------------- */ + + *((int *)c_val) = 100; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) + goto _fail_; + + c_val[0] = REKEY_DISABLE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0)) + goto _fail_; + + /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets the Rekey Time (s) */ + /* Values to set : 32-bit value */ + /* -------------------------------------------------------------------- */ + *((int *)c_val) = 84600; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) + goto _fail_; + + /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets Rekey Group Packet count */ + /* Values to set : 32-bit Value */ + /* -------------------------------------------------------------------- */ + *((int *)c_val) = 500; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0)) + goto _fail_; + + c_val[0] = 1; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = G_SELF_CTS_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* Enable N */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = HT_MIXED_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0)) + goto _fail_; + + memcpy(c_val, mac_add, 6); + + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0)) + goto _fail_; + + /** + * AP only + **/ + c_val[0] = DETECT_PROTECT_REPORT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = RTS_CTS_NONHT_PROT; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 0; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = MIMO_MODE; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 7; + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0)) + goto _fail_; + + c_val[0] = 1; /* Enable N with immediate block ack. */ + if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, (WILC_Uint32)pstrWFIDrv)) + goto _fail_; + + return 0; + +_fail_: + return -1; +} + + +/**************************/ +void wilc1000_wlan_deinit(linux_wlan_t *nic) +{ + + if (g_linux_wlan->wilc1000_initialized) { + + printk("Deinitializing wilc1000 ...\n"); + + if (nic == NULL) { + PRINT_ER("nic is NULL\n"); + return; + } + +#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + /* johnny : remove */ + PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n"); +#else + wilc_bus_set_default_speed(); +#endif + + PRINT_D(INIT_DBG, "Disabling IRQ\n"); + #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + linux_wlan_disable_irq(IRQ_WAIT); + #else + #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + + #else + linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs); + disable_sdio_interrupt(); + linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs); + #endif + #endif + + + /* not sure if the following unlocks are needed or not*/ + if (&g_linux_wlan->rxq_event != NULL) { + linux_wlan_unlock(&g_linux_wlan->rxq_event); + } + + if (&g_linux_wlan->txq_event != NULL) { + linux_wlan_unlock(&g_linux_wlan->txq_event); + } + + + #if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + /*Removing the work struct from the linux kernel workqueue*/ + if (&g_linux_wlan->rx_work_queue != NULL) + flush_work(&g_linux_wlan->rx_work_queue); + + #elif (RX_BH_TYPE == RX_BH_KTHREAD) + /* if(&nic->rx_sem != NULL) */ + /* linux_wlan_unlock(&nic->rx_sem); */ + #endif + + PRINT_D(INIT_DBG, "Deinitializing Threads\n"); + wlan_deinitialize_threads(nic); + + PRINT_D(INIT_DBG, "Deinitializing IRQ\n"); + deinit_irq(g_linux_wlan); + + + if (&g_linux_wlan->oup != NULL) { + if (g_linux_wlan->oup.wlan_stop != NULL) + g_linux_wlan->oup.wlan_stop(); + } + + PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n"); + wilc_wlan_deinit(nic); +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) + PRINT_D(INIT_DBG, "Disabling IRQ 2\n"); + + linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs); + disable_sdio_interrupt(); + linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs); + #endif +#endif + + /*De-Initialize locks*/ + PRINT_D(INIT_DBG, "Deinitializing Locks\n"); + wlan_deinit_locks(g_linux_wlan); + + /* announce that wilc1000 is not initialized */ + g_linux_wlan->wilc1000_initialized = 0; + + PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n"); + + } else { + PRINT_D(INIT_DBG, "wilc1000 is not initialized\n"); + } + return; +} + +int wlan_init_locks(linux_wlan_t *p_nic) +{ + + PRINT_D(INIT_DBG, "Initializing Locks ...\n"); + + /*initialize mutexes*/ + linux_wlan_init_mutex("hif_lock/hif_cs", &g_linux_wlan->hif_cs, 1); + linux_wlan_init_mutex("rxq_lock/rxq_cs", &g_linux_wlan->rxq_cs, 1); + linux_wlan_init_mutex("txq_lock/txq_cs", &g_linux_wlan->txq_cs, 1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_spin_lock("txq_spin_lock/txq_cs", &g_linux_wlan->txq_spinlock, 1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_lock("txq_add_to_head_lock/txq_cs", &g_linux_wlan->txq_add_to_head_cs, 1); + + linux_wlan_init_lock("txq_wait/txq_event", &g_linux_wlan->txq_event, 0); + linux_wlan_init_lock("rxq_wait/rxq_event", &g_linux_wlan->rxq_event, 0); + + linux_wlan_init_lock("cfg_wait/cfg_event", &g_linux_wlan->cfg_event, 0); + linux_wlan_init_lock("sync_event", &g_linux_wlan->sync_event, 0); + + linux_wlan_init_lock("rxq_lock/rxq_started", &g_linux_wlan->rxq_thread_started, 0); + linux_wlan_init_lock("rxq_lock/txq_started", &g_linux_wlan->txq_thread_started, 0); + + #if (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_init_lock("BH_SEM", &g_linux_wlan->rx_sem, 0); + #endif + + return 0; +} + +static int wlan_deinit_locks(linux_wlan_t *nic) +{ + PRINT_D(INIT_DBG, "De-Initializing Locks\n"); + + if (&g_linux_wlan->hif_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->hif_cs); + + if (&g_linux_wlan->rxq_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->rxq_cs); + + if (&g_linux_wlan->txq_cs != NULL) + linux_wlan_deinit_mutex(&g_linux_wlan->txq_cs); + + /*Added by Amr - BugID_4720*/ + if (&g_linux_wlan->txq_spinlock != NULL) + linux_wlan_deinit_spin_lock(&g_linux_wlan->txq_spinlock); + + if (&g_linux_wlan->rxq_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->rxq_event); + + if (&g_linux_wlan->txq_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_event); + + /*Added by Amr - BugID_4720*/ + if (&g_linux_wlan->txq_add_to_head_cs != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_add_to_head_cs); + + if (&g_linux_wlan->rxq_thread_started != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->rxq_thread_started); + + if (&g_linux_wlan->txq_thread_started != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->txq_thread_started); + + if (&g_linux_wlan->cfg_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->cfg_event); + + if (&g_linux_wlan->sync_event != NULL) + linux_wlan_deinit_lock(&g_linux_wlan->sync_event); + + return 0; +} +void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic) +{ + + PRINT_D(INIT_DBG, "Linux to Wlan services ...\n"); + + nwi->os_context.hif_critical_section = (void *)&g_linux_wlan->hif_cs; + nwi->os_context.os_private = (void *)nic; + nwi->os_context.tx_buffer_size = LINUX_TX_SIZE; + nwi->os_context.txq_critical_section = (void *)&g_linux_wlan->txq_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_add_to_head_critical_section = (void *)&g_linux_wlan->txq_add_to_head_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_spin_lock = (void *)&g_linux_wlan->txq_spinlock; + + nwi->os_context.txq_wait_event = (void *)&g_linux_wlan->txq_event; + +#if defined (MEMORY_STATIC) + nwi->os_context.rx_buffer_size = LINUX_RX_SIZE; +#endif + nwi->os_context.rxq_critical_section = (void *)&g_linux_wlan->rxq_cs; + nwi->os_context.rxq_wait_event = (void *)&g_linux_wlan->rxq_event; + nwi->os_context.cfg_wait_event = (void *)&g_linux_wlan->cfg_event; + + nwi->os_func.os_sleep = linux_wlan_msleep; + nwi->os_func.os_atomic_sleep = linux_wlan_atomic_msleep; + nwi->os_func.os_debug = linux_wlan_dbg; + nwi->os_func.os_malloc = linux_wlan_malloc; + nwi->os_func.os_malloc_atomic = linux_wlan_malloc_atomic; + nwi->os_func.os_free = linux_wlan_free; + nwi->os_func.os_lock = linux_wlan_lock; + nwi->os_func.os_unlock = linux_wlan_unlock; + nwi->os_func.os_wait = linux_wlan_lock_timeout; + nwi->os_func.os_signal = linux_wlan_unlock; + nwi->os_func.os_enter_cs = linux_wlan_lock_mutex; + nwi->os_func.os_leave_cs = linux_wlan_unlock_mutex; + + /*Added by Amr - BugID_4720*/ + nwi->os_func.os_spin_lock = linux_wlan_spin_lock; + nwi->os_func.os_spin_unlock = linux_wlan_spin_unlock; + +#ifdef WILC_SDIO + nwi->io_func.io_type = HIF_SDIO; + nwi->io_func.io_init = linux_sdio_init; + nwi->io_func.io_deinit = linux_sdio_deinit; + nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52; + nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53; + nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed; + nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed; +#else + nwi->io_func.io_type = HIF_SPI; + nwi->io_func.io_init = linux_spi_init; + nwi->io_func.io_deinit = linux_spi_deinit; + nwi->io_func.u.spi.spi_tx = linux_spi_write; + nwi->io_func.u.spi.spi_rx = linux_spi_read; + nwi->io_func.u.spi.spi_trx = linux_spi_write_read; + nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed; +#endif + + /*for now - to be revised*/ + #ifdef WILC_FULLY_HOSTING_AP + /* incase of Fully hosted AP, all non cfg pkts are processed here*/ + nwi->net_func.rx_indicate = WILC_Process_rx_frame; + #else + nwi->net_func.rx_indicate = frmw_to_linux; + #endif + nwi->net_func.rx_complete = linux_wlan_rx_complete; + nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate; +} + +int wlan_initialize_threads(perInterface_wlan_t *nic) +{ + + int ret = 0; + PRINT_D(INIT_DBG, "Initializing Threads ...\n"); + +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + /*Initialize rx work queue task*/ + INIT_WORK(&g_linux_wlan->rx_work_queue, isr_bh_routine); +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + PRINT_D(INIT_DBG, "Creating kthread for Rxq BH\n"); + g_linux_wlan->rx_bh_thread = kthread_run(isr_bh_routine, (void *)g_linux_wlan, "K_RXQ_BH"); + if (g_linux_wlan->rx_bh_thread == 0) { + PRINT_ER("couldn't create RX BH thread\n"); + ret = -ENOBUFS; + goto _fail_; + } +#endif + +#ifndef TCP_ENHANCEMENTS + /* create rx task */ + PRINT_D(INIT_DBG, "Creating kthread for reception\n"); + g_linux_wlan->rxq_thread = kthread_run(linux_wlan_rxq_task, (void *)g_linux_wlan, "K_RXQ_TASK"); + if (g_linux_wlan->rxq_thread == 0) { + PRINT_ER("couldn't create RXQ thread\n"); + ret = -ENOBUFS; + goto _fail_1; + } + + /* wait for RXQ task to start. */ + linux_wlan_lock(&g_linux_wlan->rxq_thread_started); + +#endif + + /* create tx task */ + PRINT_D(INIT_DBG, "Creating kthread for transmission\n"); + g_linux_wlan->txq_thread = kthread_run(linux_wlan_txq_task, (void *)g_linux_wlan, "K_TXQ_TASK"); + if (g_linux_wlan->txq_thread == 0) { + PRINT_ER("couldn't create TXQ thread\n"); + ret = -ENOBUFS; + goto _fail_2; + } +#ifdef DEBUG_MODE + PRINT_D(INIT_DBG, "Creating kthread for Debugging\n"); + g_linux_wlan->txq_thread = kthread_run(DebuggingThreadTask, (void *)g_linux_wlan, "DebugThread"); + if (g_linux_wlan->txq_thread == 0) { + PRINT_ER("couldn't create TXQ thread\n"); + ret = -ENOBUFS; + goto _fail_2; + } +#endif + /* wait for TXQ task to start. */ + linux_wlan_lock(&g_linux_wlan->txq_thread_started); + + return 0; + +_fail_2: + /*De-Initialize 2nd thread*/ + g_linux_wlan->close = 1; + linux_wlan_unlock(&g_linux_wlan->rxq_event); + kthread_stop(g_linux_wlan->rxq_thread); + +#ifndef TCP_ENHANCEMENTS +_fail_1: +#endif + #if (RX_BH_TYPE == RX_BH_KTHREAD) + /*De-Initialize 1st thread*/ + g_linux_wlan->close = 1; + linux_wlan_unlock(&g_linux_wlan->rx_sem); + kthread_stop(g_linux_wlan->rx_bh_thread); +_fail_: + #endif + g_linux_wlan->close = 0; + return ret; +} + +static void wlan_deinitialize_threads(linux_wlan_t *nic) +{ + + g_linux_wlan->close = 1; + PRINT_D(INIT_DBG, "Deinitializing Threads\n"); + if (&g_linux_wlan->rxq_event != NULL) + linux_wlan_unlock(&g_linux_wlan->rxq_event); + + + if (g_linux_wlan->rxq_thread != NULL) { + kthread_stop(g_linux_wlan->rxq_thread); + g_linux_wlan->rxq_thread = NULL; + } + + + if (&g_linux_wlan->txq_event != NULL) + linux_wlan_unlock(&g_linux_wlan->txq_event); + + + if (g_linux_wlan->txq_thread != NULL) { + kthread_stop(g_linux_wlan->txq_thread); + g_linux_wlan->txq_thread = NULL; + } + + #if (RX_BH_TYPE == RX_BH_KTHREAD) + if (&g_linux_wlan->rx_sem != NULL) + linux_wlan_unlock(&g_linux_wlan->rx_sem); + + if (g_linux_wlan->rx_bh_thread != NULL) { + kthread_stop(g_linux_wlan->rx_bh_thread); + g_linux_wlan->rx_bh_thread = NULL; + } + #endif +} + +#ifdef STATIC_MACADDRESS +const char *path_string[] = { + "/etc/wlan", + "/data/wlan", +}; + +static int linux_wlan_read_mac_addr(void *vp) +{ + int ret = 0; + struct file *fp = (struct file *)-ENOENT; + mm_segment_t old_fs; + loff_t pos = 0; + int index; + int array_size = ARRAY_SIZE(path_string); + + /* change to KERNEL_DS address limit */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + + for (index = 0; index < array_size; index++) { + fp = filp_open(path_string[index], O_WRONLY, 0640); + if (!fp) { + ret = -1; + goto exit; + } + + /*No such file or directory */ + if (IS_ERR(fp) || !fp->f_op) { + get_random_bytes(&mac_add[3], 3); + /* open file to write */ + fp = filp_open(path_string[index], O_WRONLY | O_CREAT, 0640); + + if (!fp || IS_ERR(fp)) { + ret = -1; + continue; + } else { + /* write buf to file */ + fp->f_op->write(fp, mac_add, 6, &pos); + break; + } + } else { + /* read file to buf */ + fp->f_op->read(fp, mac_add, 6, &pos); + break; + } + } + + if (index == array_size) { + PRINT_ER("random MAC\n"); + } + +exit: + if (fp && !IS_ERR(fp)) { + filp_close(fp, NULL); + } + + set_fs(old_fs); + + return ret; +} +#endif + +#ifdef COMPLEMENT_BOOT + +extern volatile int probe; +extern uint8_t core_11b_ready(void); + +#define READY_CHECK_THRESHOLD 30 +extern void wilc_wlan_global_reset(void); +uint8_t wilc1000_prepare_11b_core(wilc_wlan_inp_t *nwi, wilc_wlan_oup_t *nwo, linux_wlan_t *nic) +{ + uint8_t trials = 0; + while ((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++)))) { + PRINT_D(INIT_DBG, "11b core not ready yet: %u\n", trials); + wilc_wlan_deinit(nic); + wilc_wlan_global_reset(); + sdio_unregister_driver(&wilc_bus); + + linux_wlan_device_detection(0); + + mdelay(100); + + linux_wlan_device_detection(1); + + sdio_register_driver(&wilc_bus); + + while (!probe) { + msleep(100); + } + probe = 0; + g_linux_wlan->wilc_sdio_func = local_sdio_func; + linux_to_wlan(nwi, nic); + wilc_wlan_init(nwi, nwo); + } + + if (READY_CHECK_THRESHOLD <= trials) + return 1; + else + return 0; + +} + +int repeat_power_cycle(perInterface_wlan_t *nic) +{ + int ret = 0; + wilc_wlan_inp_t nwi; + wilc_wlan_oup_t nwo; + sdio_unregister_driver(&wilc_bus); + + linux_wlan_device_detection(0); + linux_wlan_device_power(0); + msleep(100); + linux_wlan_device_power(1); + msleep(80); + linux_wlan_device_detection(1); + msleep(20); + + sdio_register_driver(&wilc_bus); + + /* msleep(1000); */ + while (!probe) { + msleep(100); + } + probe = 0; + g_linux_wlan->wilc_sdio_func = local_sdio_func; + linux_to_wlan(&nwi, g_linux_wlan); + ret = wilc_wlan_init(&nwi, &nwo); + + g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT; + #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + enable_sdio_interrupt(); + #endif + + if (linux_wlan_get_firmware(nic)) { + PRINT_ER("Can't get firmware \n"); + ret = -1; + goto __fail__; + } + + /*Download firmware*/ + ret = linux_wlan_firmware_download(g_linux_wlan); + if (ret < 0) { + PRINT_ER("Failed to download firmware\n"); + goto __fail__; + } + /* Start firmware*/ + ret = linux_wlan_start_firmware(nic); + if (ret < 0) { + PRINT_ER("Failed to start firmware\n"); + } +__fail__: + return ret; +} +#endif + +int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic) +{ + wilc_wlan_inp_t nwi; + wilc_wlan_oup_t nwo; + perInterface_wlan_t *nic = p_nic; + int ret = 0; + + if (!g_linux_wlan->wilc1000_initialized) { + g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT; + g_linux_wlan->close = 0; + g_linux_wlan->wilc1000_initialized = 0; + + wlan_init_locks(g_linux_wlan); + +#ifdef STATIC_MACADDRESS + wilc_mac_thread = kthread_run(linux_wlan_read_mac_addr, NULL, "wilc_mac_thread"); + if (wilc_mac_thread < 0) { + PRINT_ER("couldn't create Mac addr thread\n"); + } +#endif + + linux_to_wlan(&nwi, g_linux_wlan); + + ret = wilc_wlan_init(&nwi, &nwo); + if (ret < 0) { + PRINT_ER("Initializing WILC_Wlan FAILED\n"); + ret = -EIO; + goto _fail_locks_; + } + memcpy(&g_linux_wlan->oup, &nwo, sizeof(wilc_wlan_oup_t)); + + /*Save the oup structre into global pointer*/ + gpstrWlanOps = &g_linux_wlan->oup; + + + ret = wlan_initialize_threads(nic); + if (ret < 0) { + PRINT_ER("Initializing Threads FAILED\n"); + ret = -EIO; + goto _fail_wilc_wlan_; + } + +#if (defined WILC_SDIO) && (defined COMPLEMENT_BOOT) + if (wilc1000_prepare_11b_core(&nwi, &nwo, g_linux_wlan)) { + PRINT_ER("11b Core is not ready\n"); + ret = -EIO; + goto _fail_threads_; + } +#endif + +#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + if (init_irq(g_linux_wlan)) { + PRINT_ER("couldn't initialize IRQ\n"); + ret = -EIO; + goto _fail_threads_; + } +#endif + +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + if (enable_sdio_interrupt()) { + PRINT_ER("couldn't initialize IRQ\n"); + ret = -EIO; + goto _fail_irq_init_; + } +#endif + + if (linux_wlan_get_firmware(nic)) { + PRINT_ER("Can't get firmware \n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + + /*Download firmware*/ + ret = linux_wlan_firmware_download(g_linux_wlan); + if (ret < 0) { + PRINT_ER("Failed to download firmware\n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + /* Start firmware*/ + ret = linux_wlan_start_firmware(nic); + if (ret < 0) { + PRINT_ER("Failed to start firmware\n"); + ret = -EIO; + goto _fail_irq_enable_; + } + + wilc_bus_set_max_speed(); + + if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) { + int size; + char Firmware_ver[20]; + size = g_linux_wlan->oup.wlan_cfg_get_value( + WID_FIRMWARE_VERSION, + Firmware_ver, sizeof(Firmware_ver)); + Firmware_ver[size] = '\0'; + PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver); + } + /* Initialize firmware with default configuration */ + ret = linux_wlan_init_test_config(dev, g_linux_wlan); + + if (ret < 0) { + PRINT_ER("Failed to configure firmware\n"); + ret = -EIO; + goto _fail_fw_start_; + } + + g_linux_wlan->wilc1000_initialized = 1; + return 0; /*success*/ + + +_fail_fw_start_: + if (&g_linux_wlan->oup != NULL) { + if (g_linux_wlan->oup.wlan_stop != NULL) + g_linux_wlan->oup.wlan_stop(); + } + +_fail_irq_enable_: +#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO) + disable_sdio_interrupt(); +_fail_irq_init_: +#endif +#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + deinit_irq(g_linux_wlan); + +#endif +_fail_threads_: + wlan_deinitialize_threads(g_linux_wlan); +_fail_wilc_wlan_: + wilc_wlan_deinit(g_linux_wlan); +_fail_locks_: + wlan_deinit_locks(g_linux_wlan); + PRINT_ER("WLAN Iinitialization FAILED\n"); + } else { + PRINT_D(INIT_DBG, "wilc1000 already initialized\n"); + } + return ret; +} + + +/* + * - this function will be called automatically by OS when module inserted. + */ + +#if !defined (NM73131_0_BOARD) +int mac_init_fn(struct net_device *ndev) +{ + + /*Why we do this !!!*/ + netif_start_queue(ndev); /* ma */ + netif_stop_queue(ndev); /* ma */ + + return 0; +} +#else +int mac_init_fn(struct net_device *ndev) +{ + + unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x00}; + /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ + memcpy(ndev->dev_addr, mac_add, 6); + + if (!is_valid_ether_addr(ndev->dev_addr)) { + PRINT_ER("Error: Wrong MAC address\n"); + return -EINVAL; + } + + return 0; +} +#endif + + +void WILC_WFI_frame_register(struct wiphy *wiphy, struct net_device *dev, + u16 frame_type, bool reg); + +/* This fn is called, when this device is setup using ifconfig */ +#if !defined (NM73131_0_BOARD) +int mac_open(struct net_device *ndev) +{ + perInterface_wlan_t *nic; + + /*BugID_5213*/ + /*No need for setting mac address here anymore,*/ + /*Just set it in init_test_config()*/ + unsigned char mac_add[ETH_ALEN] = {0}; + int ret = 0; + int i = 0; + struct WILC_WFI_priv *priv; + + nic = netdev_priv(ndev); + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev); + + #ifdef USE_WIRELESS + ret = WILC_WFI_InitHostInt(ndev); + if (ret < 0) { + PRINT_ER("Failed to initialize host interface\n"); + + return ret; + } + #endif + + /*initialize platform*/ + PRINT_D(INIT_DBG, "*** re-init ***\n"); + ret = wilc1000_wlan_init(ndev, nic); + if (ret < 0) { + PRINT_ER("Failed to initialize wilc1000\n"); + WILC_WFI_DeInitHostInt(ndev); + return ret; + } + + Set_machw_change_vir_if(WILC_FALSE); + + host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add); + PRINT_D(INIT_DBG, "Mac address: %x:%x:%x:%x:%x:%x\n", mac_add[0], mac_add[1], mac_add[2], + mac_add[3], mac_add[4], mac_add[5]); + + /* loop through the NUM of supported devices and set the MAC address */ + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + if (ndev == g_linux_wlan->strInterfaceInfo[i].wilc_netdev) { + memcpy(g_linux_wlan->strInterfaceInfo[i].aSrcAddress, mac_add, ETH_ALEN); + g_linux_wlan->strInterfaceInfo[i].drvHandler = (WILC_Uint32)priv->hWILCWFIDrv; + break; + } + } + + /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ + memcpy(ndev->dev_addr, g_linux_wlan->strInterfaceInfo[i].aSrcAddress, ETH_ALEN); + + if (!is_valid_ether_addr(ndev->dev_addr)) { + PRINT_ER("Error: Wrong MAC address\n"); + ret = -EINVAL; + goto _err_; + } + + + WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev, + nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg); + WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev, + nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg); + netif_wake_queue(ndev); + g_linux_wlan->open_ifcs++; + nic->mac_opened = 1; + return 0; + +_err_: + WILC_WFI_DeInitHostInt(ndev); + wilc1000_wlan_deinit(g_linux_wlan); + return ret; +} +#else +int mac_open(struct net_device *ndev) +{ + + linux_wlan_t *nic; + nic = netdev_priv(ndev); + + /*initialize platform*/ + if (wilc1000_wlan_init(nic)) { + PRINT_ER("Failed to initialize platform\n"); + return 1; + } + /* Start the network interface queue for this device */ + PRINT_D(INIT_DBG, "Starting netifQ\n"); + netif_start_queue(ndev); +/* linux_wlan_lock(&close_exit_sync); */ + return 0; +} +#endif + +struct net_device_stats *mac_stats(struct net_device *dev) +{ + perInterface_wlan_t *nic = netdev_priv(dev); + + + return &nic->netstats; +} + +/* Setup the multicast filter */ +static void wilc_set_multicast_list(struct net_device *dev) +{ + + struct netdev_hw_addr *ha; + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + int i = 0; + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + + if (!dev) + return; + + PRINT_D(INIT_DBG, "Setting Multicast List with count = %d. \n", dev->mc.count); + + if (dev->flags & IFF_PROMISC) { + /* Normally, we should configure the chip to retrive all packets + * but we don't wanna support this right now */ + /* TODO: add promiscuous mode support */ + PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets \n"); + return; + } + + /* If there's more addresses than we handle, get all multicast + * packets and sort them out in software. */ + if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { + PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n"); + /* get all multicast packets */ + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_FALSE, 0); + return; + } + + /* No multicast? Just get our own stuff */ + if ((dev->mc.count) == 0) { + PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n"); + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_TRUE, 0); + return; + } + + /* Store all of the multicast addresses in the hardware filter */ + netdev_for_each_mc_addr(ha, dev) + { + WILC_memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN); + PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, + gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]); + i++; + } + + host_int_setup_multicast_filter((WILC_WFIDrvHandle)pstrWFIDrv, WILC_TRUE, (dev->mc.count)); + + return; + +} + +static void linux_wlan_tx_complete(void *priv, int status) +{ + + struct tx_complete_data *pv_data = (struct tx_complete_data *)priv; + if (status == 1) { + PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); + } else { + PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb); + } + /* Free the SK Buffer, its work is done */ + dev_kfree_skb(pv_data->skb); + linux_wlan_free(pv_data); +} + +int mac_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + perInterface_wlan_t *nic; + struct tx_complete_data *tx_data = NULL; + int QueueCount; + char *pu8UdpBuffer; + struct iphdr *ih; + struct ethhdr *eth_h; + nic = netdev_priv(ndev); + + PRINT_D(INT_DBG, "\n========\n IntUH: %d - IntBH: %d - IntCld: %d \n========\n", int_rcvdU, int_rcvdB, int_clrd); + PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n"); + + /* Stop the network interface queue */ + if (skb->dev != ndev) { + PRINT_ER("Packet not destined to this device\n"); + return 0; + } + + tx_data = (struct tx_complete_data *)internal_alloc(sizeof(struct tx_complete_data), GFP_ATOMIC); + if (tx_data == NULL) { + PRINT_ER("Failed to allocate memory for tx_data structure\n"); + dev_kfree_skb(skb); + netif_wake_queue(ndev); + return 0; + } + + tx_data->buff = skb->data; + tx_data->size = skb->len; + tx_data->skb = skb; + + eth_h = (struct ethhdr *)(skb->data); + if (eth_h->h_proto == 0x8e88) { + PRINT_D(INIT_DBG, "EAPOL transmitted\n"); + } + + /*get source and dest ip addresses*/ + ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); + + pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); + if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68)) { + PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]); + + } + PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb); + + /* Send packet to MAC HW - for now the tx_complete function will be just status + * indicator. still not sure if I need to suspend host transmission till the tx_complete + * function called or not? + * allocated buffer will be freed in tx_complete function. + */ + PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n"); + nic->netstats.tx_packets++; + nic->netstats.tx_bytes += tx_data->size; + tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID; + #ifndef WILC_FULLY_HOSTING_AP + QueueCount = g_linux_wlan->oup.wlan_add_to_tx_que((void *)tx_data, + tx_data->buff, + tx_data->size, + linux_wlan_tx_complete); + #else + QueueCount = WILC_Xmit_data((void *)tx_data, HOST_TO_WLAN); + #endif /* WILC_FULLY_HOSTING_AP */ + + + if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) { + netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev); + netif_stop_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); + } + + return 0; +} + + +int mac_close(struct net_device *ndev) +{ + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + tstrWILC_WFIDrv *pstrWFIDrv; + + nic = netdev_priv(ndev); + + if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) { + PRINT_ER("nic = NULL\n"); + return 0; + } + + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + + if (priv == NULL) { + PRINT_ER("priv = NULL\n"); + return 0; + } + + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + + + PRINT_D(GENERIC_DBG, "Mac close\n"); + + if (g_linux_wlan == NULL) { + PRINT_ER("g_linux_wlan = NULL\n"); + return 0; + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("pstrWFIDrv = NULL\n"); + return 0; + } + + if ((g_linux_wlan->open_ifcs) > 0) { + g_linux_wlan->open_ifcs--; + } else { + PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n"); + return 0; + } + + if (nic->wilc_netdev != NULL) { + /* Stop the network interface queue */ + netif_stop_queue(nic->wilc_netdev); + + #ifdef USE_WIRELESS + WILC_WFI_DeInitHostInt(nic->wilc_netdev); + #endif + } + + if (g_linux_wlan->open_ifcs == 0) { + PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n"); + g_linux_wlan->close = 1; + wilc1000_wlan_deinit(g_linux_wlan); + #ifdef USE_WIRELESS + #ifdef WILC_AP_EXTERNAL_MLME + WILC_WFI_deinit_mon_interface(); + #endif + #endif + } + + linux_wlan_unlock(&close_exit_sync); + nic->mac_opened = 0; + + return 0; +} + + +int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) +{ + + u8 *buff = NULL; + WILC_Sint8 rssi; + WILC_Uint32 size = 0, length = 0; + perInterface_wlan_t *nic; + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + + + + /* struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV */ + #ifdef USE_WIRELESS + nic = netdev_priv(ndev); + + if (!g_linux_wlan->wilc1000_initialized) + return 0; + + #endif + + switch (cmd) { + /* [[ added by tony for SIOCDEVPRIVATE */ + case SIOCDEVPRIVATE + 1: + { + android_wifi_priv_cmd priv_cmd; + + PRINT_INFO(GENERIC_DBG, "in SIOCDEVPRIVATE+1\n"); + + if (copy_from_user(&priv_cmd, req->ifr_data, sizeof(android_wifi_priv_cmd))) { + s32Error = -EFAULT; + goto done; + } + + buff = kmalloc(priv_cmd.total_len, GFP_KERNEL); + if (!buff) { + s32Error = -ENOMEM; + goto done; + } + + if (copy_from_user(buff, priv_cmd.buf, priv_cmd.total_len)) { + s32Error = -EFAULT; + goto done; + } + + PRINT_INFO(GENERIC_DBG, "%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, buff, req->ifr_name); + + if (strncasecmp(buff, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, SCAN-ACTIVE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, SCAN-PASSIVE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-START", strlen("RXFILTER-START")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-START command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-STOP", strlen("RXFILTER-STOP")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-STOP command\n", __FUNCTION__); + } else if (strncasecmp(buff, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) { + int filter_num = *(buff + strlen("RXFILTER-ADD") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-ADD command, filter_num=%d\n", __FUNCTION__, filter_num); + } else if (strncasecmp(buff, "RXFILTER-REMOVE", strlen("RXFILTER-REMOVE")) == 0) { + int filter_num = *(buff + strlen("RXFILTER-REMOVE") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-REMOVE command, filter_num=%d\n", __FUNCTION__, filter_num); + } else if (strncasecmp(buff, "BTCOEXSCAN-START", strlen("BTCOEXSCAN-START")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-START command\n", __FUNCTION__); + } else if (strncasecmp(buff, "BTCOEXSCAN-STOP", strlen("BTCOEXSCAN-STOP")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-STOP command\n", __FUNCTION__); + } else if (strncasecmp(buff, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, BTCOEXMODE command\n", __FUNCTION__); + } else if (strncasecmp(buff, "SETBAND", strlen("SETBAND")) == 0) { + uint band = *(buff + strlen("SETBAND") + 1) - '0'; + PRINT_INFO(GENERIC_DBG, "%s, SETBAND command, band=%d\n", __FUNCTION__, band); + } else if (strncasecmp(buff, "GETBAND", strlen("GETBAND")) == 0) { + PRINT_INFO(GENERIC_DBG, "%s, GETBAND command\n", __FUNCTION__); + } else if (strncasecmp(buff, "COUNTRY", strlen("COUNTRY")) == 0) { + char *country_code = buff + strlen("COUNTRY") + 1; + PRINT_INFO(GENERIC_DBG, "%s, COUNTRY command, country_code=%s\n", __FUNCTION__, country_code); + } else { + PRINT_INFO(GENERIC_DBG, "%s, Unknown command\n", __FUNCTION__); + } + } break; + + /* ]] 2013-06-24 */ + case SIOCSIWPRIV: + { + struct iwreq *wrq = (struct iwreq *) req; /* added by tony */ + + size = wrq->u.data.length; + + if (size && wrq->u.data.pointer) { + buff = kmalloc(size, GFP_KERNEL); + if (!buff) { + s32Error = -ENOMEM; + goto done; + } + + if (copy_from_user + (buff, wrq->u.data.pointer, + wrq->u.data.length)) { + s32Error = -EFAULT; + goto done; + } + + if (strncasecmp(buff, "RSSI", length) == 0) { + + #ifdef USE_WIRELESS + priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy); + s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); + if (s32Error) + PRINT_ER("Failed to send get rssi param's message queue "); + #endif + PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi); + + /*Rounding up the rssi negative value*/ + rssi += 5; + + snprintf(buff, size, "rssi %d", rssi); + + if (copy_to_user(wrq->u.data.pointer, buff, size)) { + PRINT_ER("%s: failed to copy data to user buffer\n", __FUNCTION__); + s32Error = -EFAULT; + goto done; + } + } + } + } + break; + + default: + { + PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd); + s32Error = -EOPNOTSUPP; + goto done; + } + } + +done: + + if (buff != NULL) { + kfree(buff); + } + + return s32Error; +} + +void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset) +{ + + unsigned int frame_len = 0; + int stats; + unsigned char *buff_to_send = NULL; + struct sk_buff *skb; +#ifndef TCP_ENHANCEMENTS + char *pu8UdpBuffer; + struct iphdr *ih; +#endif + struct net_device *wilc_netdev; + perInterface_wlan_t *nic; + + wilc_netdev = GetIfHandler(buff); + if (wilc_netdev == NULL) + return; + + buff += pkt_offset; + nic = netdev_priv(wilc_netdev); + + if (size > 0) { + + frame_len = size; + buff_to_send = buff; + + + /* Need to send the packet up to the host, allocate a skb buffer */ + skb = dev_alloc_skb(frame_len); + if (skb == NULL) { + PRINT_ER("Low memory - packet droped\n"); + return; + } + + skb_reserve(skb, (unsigned int)skb->data & 0x3); + + if (g_linux_wlan == NULL || wilc_netdev == NULL) { + PRINT_ER("wilc_netdev in g_linux_wlan is NULL"); + } + skb->dev = wilc_netdev; + + if (skb->dev == NULL) { + PRINT_ER("skb->dev is NULL\n"); + } + + /* + * for(i=0;i<40;i++) + * { + * if(i<frame_len) + * WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]); + * + * }*/ + + /* skb_put(skb, frame_len); */ + memcpy(skb_put(skb, frame_len), buff_to_send, frame_len); + + /* WILC_PRINTF("After MEM_CPY\n"); */ + + /* nic = netdev_priv(wilc_netdev); */ + +#ifdef USE_WIRELESS + /* if(nic->monitor_flag) + * { + * WILC_WFI_monitor_rx(nic->wilc_netdev,skb); + * return; + * }*/ +#endif + skb->protocol = eth_type_trans(skb, wilc_netdev); + #ifndef TCP_ENHANCEMENTS + /*get source and dest ip addresses*/ + ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); + + pu8UdpBuffer = (char *)ih + sizeof(struct iphdr); + if (buff_to_send[35] == 67 && buff_to_send[37] == 68) { + PRINT_D(RX_DBG, "DHCP Message received\n"); + } + if (buff_to_send[12] == 0x88 && buff_to_send[13] == 0x8e) + PRINT_D(GENERIC_DBG, "eapol received\n"); + #endif + /* Send the packet to the stack by giving it to the bridge */ + nic->netstats.rx_packets++; + nic->netstats.rx_bytes += frame_len; + skb->ip_summed = CHECKSUM_UNNECESSARY; + stats = netif_rx(skb); + PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats); + } + #ifndef TCP_ENHANCEMENTS + else { + PRINT_ER("Discard sending packet with len = %d\n", size); + } + #endif +} + +void WILC_WFI_mgmt_rx(uint8_t *buff, uint32_t size) +{ + int i = 0; + perInterface_wlan_t *nic; + + /*BugID_5450*/ + /*Pass the frame on the monitor interface, if any.*/ + /*Otherwise, pass it on p2p0 netdev, if registered on it*/ + for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) { + nic = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + if (nic->monitor_flag) { + WILC_WFI_monitor_rx(buff, size); + return; + } + } + + #ifdef WILC_P2P + nic = netdev_priv(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); /* p2p0 */ + if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) || + (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg)) { + WILC_WFI_p2p_rx(g_linux_wlan->strInterfaceInfo[1].wilc_netdev, buff, size); + } + #endif +} + +int wilc_netdev_init(void) +{ + + int i; + perInterface_wlan_t *nic; + struct net_device *ndev; + + linux_wlan_init_lock("close_exit_sync", &close_exit_sync, 0); + + /*create the common structure*/ + g_linux_wlan = (linux_wlan_t *)WILC_MALLOC(sizeof(linux_wlan_t)); + memset(g_linux_wlan, 0, sizeof(linux_wlan_t)); + + /*Reset interrupt count debug*/ + int_rcvdU = 0; + int_rcvdB = 0; + int_clrd = 0; + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + register_inetaddr_notifier(&g_dev_notifier); + #endif + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + /*allocate first ethernet device with perinterface_wlan_t as its private data*/ + ndev = alloc_etherdev(sizeof(perInterface_wlan_t)); + if (!ndev) { + PRINT_ER("Failed to allocate ethernet dev\n"); + return -1; + } + + nic = netdev_priv(ndev); + memset(nic, 0, sizeof(perInterface_wlan_t)); + + /*Name the Devices*/ + if (i == 0) { + #if defined(NM73131) /* tony, 2012-09-20 */ + strcpy(ndev->name, "wilc_eth%d"); + #elif defined(PLAT_CLM9722) /* rachel */ + strcpy(ndev->name, "eth%d"); + #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */ + strcpy(ndev->name, "wlan%d"); + #endif + } else + strcpy(ndev->name, "p2p%d"); + + nic->u8IfIdx = g_linux_wlan->u8NoIfcs; + nic->wilc_netdev = ndev; + g_linux_wlan->strInterfaceInfo[g_linux_wlan->u8NoIfcs].wilc_netdev = ndev; + g_linux_wlan->u8NoIfcs++; + ndev->netdev_ops = &wilc_netdev_ops; + + #ifdef USE_WIRELESS + { + struct wireless_dev *wdev; + /*Register WiFi*/ + wdev = WILC_WFI_WiphyRegister(ndev); + + #ifdef WILC_SDIO + /* set netdev, tony */ + SET_NETDEV_DEV(ndev, &local_sdio_func->dev); + #endif + + if (wdev == NULL) { + PRINT_ER("Can't register WILC Wiphy\n"); + return -1; + } + + /*linking the wireless_dev structure with the netdevice*/ + nic->wilc_netdev->ieee80211_ptr = wdev; + nic->wilc_netdev->ml_priv = nic; + wdev->netdev = nic->wilc_netdev; + nic->netstats.rx_packets = 0; + nic->netstats.tx_packets = 0; + nic->netstats.rx_bytes = 0; + nic->netstats.tx_bytes = 0; + + } + #endif + + + if (register_netdev(ndev)) { + PRINT_ER("Device couldn't be registered - %s\n", ndev->name); + return -1; /* ERROR */ + } + + nic->iftype = STATION_MODE; + nic->mac_opened = 0; + + } + + #ifndef WILC_SDIO + if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) { + PRINT_ER("Can't initialize SPI \n"); + return -1; /* ERROR */ + } + g_linux_wlan->wilc_spidev = wilc_spi_dev; + #else + g_linux_wlan->wilc_sdio_func = local_sdio_func; + #endif + + return 0; +} + + +/*The 1st function called after module inserted*/ +static int __init init_wilc_driver(void) +{ + + +#if defined (WILC_DEBUGFS) + if (wilc_debugfs_init() < 0) { + PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n"); + return -1; + } +#endif + + printk("IN INIT FUNCTION\n"); + printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n"); + + linux_wlan_device_power(1); + msleep(100); + linux_wlan_device_detection(1); + +#ifdef WILC_SDIO + { + int ret; + + ret = sdio_register_driver(&wilc_bus); + if (ret < 0) { + PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n"); + } + + return ret; + } +#else + PRINT_D(INIT_DBG, "Initializing netdev\n"); + if (wilc_netdev_init()) { + PRINT_ER("Couldn't initialize netdev\n"); + } + return 0; +#endif +} +late_initcall(init_wilc_driver); + +static void __exit exit_wilc_driver(void) +{ + int i = 0; + perInterface_wlan_t *nic[NUM_CONCURRENT_IFC] = {NULL,}; + #define CLOSE_TIMEOUT (12 * 1000) + + if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL) + || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + unregister_inetaddr_notifier(&g_dev_notifier); + #endif + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + nic[i] = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + + + if ((g_linux_wlan != NULL) && g_linux_wlan->wilc_firmware != NULL) { + release_firmware(g_linux_wlan->wilc_firmware); + g_linux_wlan->wilc_firmware = NULL; + } + + + if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL) + || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) { + PRINT_D(INIT_DBG, "Waiting for mac_close ....\n"); + + if (linux_wlan_lock_timeout(&close_exit_sync, CLOSE_TIMEOUT) < 0) + PRINT_D(INIT_DBG, "Closed TimedOUT\n"); + else + PRINT_D(INIT_DBG, "mac_closed\n"); + + + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + /* close all opened interfaces */ + if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev != NULL) { + if (nic[i]->mac_opened) { + mac_close(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + } + for (i = 0; i < NUM_CONCURRENT_IFC; i++) { + PRINT_D(INIT_DBG, "Unregistering netdev %p \n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + unregister_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + #ifdef USE_WIRELESS + PRINT_D(INIT_DBG, "Freeing Wiphy...\n"); + WILC_WFI_WiphyFree(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + #endif + PRINT_D(INIT_DBG, "Freeing netdev...\n"); + free_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev); + } + } + + +#ifdef USE_WIRELESS +#ifdef WILC_AP_EXTERNAL_MLME + /* Bug 4600 : WILC_WFI_deinit_mon_interface was already called at mac_close */ + /* WILC_WFI_deinit_mon_interface(); */ +#endif +#endif + + /* if(g_linux_wlan->open_ifcs==0) */ + { + #ifndef WILC_SDIO + PRINT_D(INIT_DBG, "SPI unregsiter...\n"); + spi_unregister_driver(&wilc_bus); + #else + PRINT_D(INIT_DBG, "SDIO unregsiter...\n"); + sdio_unregister_driver(&wilc_bus); + #endif + + linux_wlan_deinit_lock(&close_exit_sync); + if (g_linux_wlan != NULL) { + WILC_FREE(g_linux_wlan); + g_linux_wlan = NULL; + } + printk("Module_exit Done.\n"); + +#if defined (WILC_DEBUGFS) + wilc_debugfs_remove(); +#endif + + linux_wlan_device_detection(0); + linux_wlan_device_power(0); + } +} +module_exit(exit_wilc_driver); + +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h new file mode 100644 index 000000000000..541f19cf44ae --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan_common.h @@ -0,0 +1,170 @@ +#ifndef LINUX_WLAN_COMMON_H +#define LINUX_WLAN_COMMON_H + +enum debug_region { + Generic_debug = 0, + Hostapd_debug, + Hostinf_debug, + CFG80211_debug, + Coreconfig_debug, + Interrupt_debug, + TX_debug, + RX_debug, + Lock_debug, + Tcp_enhance, + /*Added by amr - BugID_4720*/ + Spin_debug, + + Init_debug, + Bus_debug, + Mem_debug, + Firmware_debug, + COMP = 0xFFFFFFFF, +}; + +#define GENERIC_DBG (1 << Generic_debug) +#define HOSTAPD_DBG (1 << Hostapd_debug) +#define HOSTINF_DBG (1 << Hostinf_debug) +#define CORECONFIG_DBG (1 << Coreconfig_debug) +#define CFG80211_DBG (1 << CFG80211_debug) +#define INT_DBG (1 << Interrupt_debug) +#define TX_DBG (1 << TX_debug) +#define RX_DBG (1 << RX_debug) +#define LOCK_DBG (1 << Lock_debug) +#define TCP_ENH (1 << Tcp_enhance) + + +/*Added by Amr - BugID_4720*/ +#define SPIN_DEBUG (1 << Spin_debug) + +#define INIT_DBG (1 << Init_debug) +#define BUS_DBG (1 << Bus_debug) +#define MEM_DBG (1 << Mem_debug) +#define FIRM_DBG (1 << Firmware_debug) + +#if defined (WILC_DEBUGFS) +extern int wilc_debugfs_init(void); +extern void wilc_debugfs_remove(void); + +extern atomic_t REGION; +extern atomic_t DEBUG_LEVEL; + +#define DEBUG (1 << 0) +#define INFO (1 << 1) +#define WRN (1 << 2) +#define ERR (1 << 3) + +#define PRINT_D(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & DEBUG) && ((atomic_read(®ION)) & (region))) { \ + printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_INFO(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & INFO) && ((atomic_read(®ION)) & (region))) { \ + printk("INFO [%s]", __FUNCTION__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_WRN(region, ...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & WRN) && ((atomic_read(®ION)) & (region))) { \ + printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#define PRINT_ER(...) do { \ + if ((atomic_read(&DEBUG_LEVEL) & ERR)) { \ + printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ +} while (0) + +#else + +#define REGION (INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG) + +#define DEBUG 1 +#define INFO 0 +#define WRN 0 +#define PRINT_D(region, ...) do { if (DEBUG == 1 && ((REGION)&(region))) { \ + printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_INFO(region, ...) do { if (INFO == 1 && ((REGION)&(region))) { \ + printk("INFO [%s]", __FUNCTION__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_WRN(region, ...) do { if (WRN == 1 && ((REGION)&(region))) { \ + printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } \ + } while (0) + +#define PRINT_ER(...) do { printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \ + printk(__VA_ARGS__); \ + } while (0) +#endif + +#define FN_IN /* PRINT_D(">>> \n") */ +#define FN_OUT /* PRINT_D("<<<\n") */ + +#ifdef MEMORY_STATIC +#define LINUX_RX_SIZE (96 * 1024) +#endif +#define LINUX_TX_SIZE (64 * 1024) + + +#define WILC_MULTICAST_TABLE_SIZE 8 + +#if defined (NM73131_0_BOARD) + +#define MODALIAS "wilc_spi" +#define GPIO_NUM IRQ_WILC1000_GPIO + +#elif defined (BEAGLE_BOARD) + #define SPI_CHANNEL 4 + + #if SPI_CHANNEL == 4 + #define MODALIAS "wilc_spi4" + #define GPIO_NUM 162 + #else + #define MODALIAS "wilc_spi3" + #define GPIO_NUM 133 + #endif +#elif defined(PANDA_BOARD) + #define MODALIAS "WILC_SPI" + #define GPIO_NUM 139 +#elif defined(PLAT_WMS8304) /* rachel */ + #define MODALIAS "wilc_spi" + #define GPIO_NUM 139 +#elif defined (PLAT_RKXXXX) + #define MODALIAS "WILC_IRQ" + #define GPIO_NUM RK30_PIN3_PD2 /* RK30_PIN3_PA1 */ +/* RK30_PIN3_PD2 */ +/* RK2928_PIN1_PA7 */ + +#elif defined(CUSTOMER_PLATFORM) +/* + TODO : specify MODALIAS name and GPIO number. This is certainly necessary for SPI interface. + * + * ex) + * #define MODALIAS "WILC_SPI" + * #define GPIO_NUM 139 + */ + +#else +/* base on SAMA5D3_Xplained Board */ + #define MODALIAS "WILC_SPI" + #define GPIO_NUM 0x44 +#endif + + +void linux_wlan_enable_irq(void); +#endif diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c new file mode 100644 index 000000000000..858e3a191bce --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan_sdio.c @@ -0,0 +1,249 @@ +#include "wilc_wfi_netdevice.h" + +#include <linux/mmc/sdio_func.h> +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio.h> +#include <linux/mmc/host.h> + + + +#if defined (NM73131_0_BOARD) +#define SDIO_MODALIAS "wilc_sdio" +#else +#define SDIO_MODALIAS "wilc1000_sdio" +#endif + +#if defined (NM73131_0_BOARD) + #define MAX_SPEED 50000000 +#elif defined(CUSTOMER_PLATFORM) +/* TODO : User have to stable bus clock as user's environment. */ + #ifdef MAX_BUS_SPEED + #define MAX_SPEED MAX_BUS_SPEED + #else + #define MAX_SPEED 50000000 + #endif +#else + #define MAX_SPEED (6 * 1000000) /* Max 50M */ +#endif + + +struct sdio_func *local_sdio_func; +extern linux_wlan_t *g_linux_wlan; +extern int wilc_netdev_init(void); +extern int sdio_clear_int(void); +extern void wilc_handle_isr(void); + +static unsigned int sdio_default_speed; + +#define SDIO_VENDOR_ID_WILC 0x0296 +#define SDIO_DEVICE_ID_WILC 0x5347 + +static const struct sdio_device_id wilc_sdio_ids[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) }, +}; + + +static void wilc_sdio_interrupt(struct sdio_func *func) +{ +#ifndef WILC_SDIO_IRQ_GPIO + sdio_release_host(func); + wilc_handle_isr(); + sdio_claim_host(func); +#endif +} + + +int linux_sdio_cmd52(sdio_cmd52_t *cmd) +{ + struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + int ret; + u8 data; + + sdio_claim_host(func); + + func->num = cmd->function; + if (cmd->read_write) { /* write */ + if (cmd->raw) { + sdio_writeb(func, cmd->data, cmd->address, &ret); + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } else { + sdio_writeb(func, cmd->data, cmd->address, &ret); + } + } else { /* read */ + data = sdio_readb(func, cmd->address, &ret); + cmd->data = data; + } + + sdio_release_host(func); + + if (ret < 0) { + PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret); + return 0; + } + return 1; +} + + +int linux_sdio_cmd53(sdio_cmd53_t *cmd) +{ + struct sdio_func *func = g_linux_wlan->wilc_sdio_func; + int size, ret; + + sdio_claim_host(func); + + func->num = cmd->function; + func->cur_blksize = cmd->block_size; + if (cmd->block_mode) + size = cmd->count * cmd->block_size; + else + size = cmd->count; + + if (cmd->read_write) { /* write */ + ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size); + } else { /* read */ + ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size); + } + + sdio_release_host(func); + + + if (ret < 0) { + PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret); + return 0; + } + + return 1; +} + +volatile int probe; /* COMPLEMENT_BOOT */ +static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + PRINT_D(INIT_DBG, "probe function\n"); + +#ifdef COMPLEMENT_BOOT + if (local_sdio_func != NULL) { + local_sdio_func = func; + probe = 1; + PRINT_D(INIT_DBG, "local_sdio_func isn't NULL\n"); + return 0; + } +#endif + PRINT_D(INIT_DBG, "Initializing netdev\n"); + local_sdio_func = func; + if (wilc_netdev_init()) { + PRINT_ER("Couldn't initialize netdev\n"); + return -1; + } + + printk("Driver Initializing success\n"); + return 0; +} + +static void linux_sdio_remove(struct sdio_func *func) +{ + /** + * TODO + **/ + +} + +struct sdio_driver wilc_bus = { + .name = SDIO_MODALIAS, + .id_table = wilc_sdio_ids, + .probe = linux_sdio_probe, + .remove = linux_sdio_remove, +}; + +int enable_sdio_interrupt(void) +{ + int ret = 0; +#ifndef WILC_SDIO_IRQ_GPIO + + sdio_claim_host(local_sdio_func); + ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt); + sdio_release_host(local_sdio_func); + + if (ret < 0) { + PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); + ret = -EIO; + } +#endif + return ret; +} + +void disable_sdio_interrupt(void) +{ + +#ifndef WILC_SDIO_IRQ_GPIO + int ret; + + PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n"); + + sdio_claim_host(local_sdio_func); + ret = sdio_release_irq(local_sdio_func); + if (ret < 0) { + PRINT_ER("can't release sdio_irq, err(%d)\n", ret); + } + sdio_release_host(local_sdio_func); + + PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n"); +#endif +} + +static int linux_sdio_set_speed(int speed) +{ + struct mmc_ios ios; + sdio_claim_host(local_sdio_func); + + memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios)); + local_sdio_func->card->host->ios.clock = speed; + ios.clock = speed; + local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios); + sdio_release_host(local_sdio_func); + PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); + + return 1; +} + +static int linux_sdio_get_speed(void) +{ + return local_sdio_func->card->host->ios.clock; +} + +int linux_sdio_init(void *pv) +{ + + /** + * TODO : + **/ + + + sdio_default_speed = linux_sdio_get_speed(); + return 1; +} + +void linux_sdio_deinit(void *pv) +{ + + /** + * TODO : + **/ + + + sdio_unregister_driver(&wilc_bus); +} + +int linux_sdio_set_max_speed(void) +{ + return linux_sdio_set_speed(MAX_SPEED); +} + +int linux_sdio_set_default_speed(void) +{ + return linux_sdio_set_speed(sdio_default_speed); +} + + + diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.h b/drivers/staging/wilc1000/linux_wlan_sdio.h new file mode 100644 index 000000000000..4b515f5108e7 --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan_sdio.h @@ -0,0 +1,14 @@ +extern struct sdio_func *local_sdio_func; +extern struct sdio_driver wilc_bus; + +#include <linux/mmc/sdio_func.h> + +int linux_sdio_init(void *); +void linux_sdio_deinit(void *); +int linux_sdio_cmd52(sdio_cmd52_t *cmd); +int linux_sdio_cmd53(sdio_cmd53_t *cmd); +int enable_sdio_interrupt(void); +void disable_sdio_interrupt(void); +int linux_sdio_set_max_speed(void); +int linux_sdio_set_default_speed(void); + diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c new file mode 100644 index 000000000000..1eee1d560bc7 --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan_spi.c @@ -0,0 +1,481 @@ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/cdev.h> +#include <asm/uaccess.h> +#include <linux/device.h> +#include <linux/spi/spi.h> + +#include "linux_wlan_common.h" + +#define USE_SPI_DMA 0 /* johnny add */ + +#ifdef WILC_ASIC_A0 + #if defined(PLAT_PANDA_ES_OMAP4460) + #define MIN_SPEED 12000000 + #define MAX_SPEED 24000000 + #elif defined(PLAT_WMS8304) + #define MIN_SPEED 12000000 + #define MAX_SPEED 24000000 /* 4000000 */ + #elif defined(CUSTOMER_PLATFORM) +/* + TODO : define Clock speed under 48M. + * + * ex) + * #define MIN_SPEED 24000000 + * #define MAX_SPEED 48000000 + */ + #else + #define MIN_SPEED 24000000 + #define MAX_SPEED 48000000 + #endif +#else /* WILC_ASIC_A0 */ +/* Limit clk to 6MHz on FPGA. */ + #define MIN_SPEED 6000000 + #define MAX_SPEED 6000000 +#endif /* WILC_ASIC_A0 */ + +static uint32_t SPEED = MIN_SPEED; + +struct spi_device *wilc_spi_dev; +void linux_spi_deinit(void *vp); + +static int __init wilc_bus_probe(struct spi_device *spi) +{ + + PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias); + PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz); + wilc_spi_dev = spi; + + printk("Driver Initializing success\n"); + return 0; +} + +static int __exit wilc_bus_remove(struct spi_device *spi) +{ + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id wilc1000_of_match[] = { + { .compatible = "atmel,wilc_spi", }, + {} +}; +MODULE_DEVICE_TABLE(of, wilc1000_of_match); +#endif + +struct spi_driver wilc_bus __refdata = { + .driver = { + .name = MODALIAS, +#ifdef CONFIG_OF + .of_match_table = wilc1000_of_match, +#endif + }, + .probe = wilc_bus_probe, + .remove = __exit_p(wilc_bus_remove), +}; + + +void linux_spi_deinit(void *vp) +{ + + spi_unregister_driver(&wilc_bus); + + SPEED = MIN_SPEED; + PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED); + +} + + + +int linux_spi_init(void *vp) +{ + int ret = 1; + static int called; + + + if (called == 0) { + called++; + ret = spi_register_driver(&wilc_bus); + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#if defined(PLAT_WMS8304) +#define TXRX_PHASE_SIZE (4096) +#endif + +#if defined (NM73131_0_BOARD) + +int linux_spi_write(uint8_t *b, uint32_t len) +{ + + int ret; + + if (len > 0 && b != NULL) { + struct spi_message msg; + PRINT_D(BUS_DBG, "Request writing %d bytes\n", len); + struct spi_transfer tr = { + .tx_buf = b, + .len = len, + .speed_hz = SPEED, + .delay_usecs = 0, + }; + + spi_message_init(&msg); + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + + return ret; +} + +#elif defined(TXRX_PHASE_SIZE) + +int linux_spi_write(uint8_t *b, uint32_t len) +{ + int ret; + if (len > 0 && b != NULL) { + int i = 0; + int blk = len / TXRX_PHASE_SIZE; + int remainder = len % TXRX_PHASE_SIZE; + + char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); + if (!r_buffer) { + PRINT_ER("Failed to allocate memory for r_buffer\n"); + } + + if (blk) { + while (i < blk) { + struct spi_message msg; + struct spi_transfer tr = { + .tx_buf = b + (i * TXRX_PHASE_SIZE), + .len = TXRX_PHASE_SIZE, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + + tr.rx_buf = r_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + i++; + + } + } + if (remainder) { + struct spi_message msg; + struct spi_transfer tr = { + .tx_buf = b + (blk * TXRX_PHASE_SIZE), + .len = remainder, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + tr.rx_buf = r_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } + if (r_buffer) + kfree(r_buffer); + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; + +} + +#else +int linux_spi_write(uint8_t *b, uint32_t len) +{ + + int ret; + struct spi_message msg; + + if (len > 0 && b != NULL) { + struct spi_transfer tr = { + .tx_buf = b, + .len = len, + .speed_hz = SPEED, + .delay_usecs = 0, + }; + char *r_buffer = kzalloc(len, GFP_KERNEL); + if (!r_buffer) { + PRINT_ER("Failed to allocate memory for r_buffer\n"); + } + tr.rx_buf = r_buffer; + PRINT_D(BUS_DBG, "Request writing %d bytes\n", len); + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); +/* [[johnny add */ + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; +/* ]] */ + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + + kfree(r_buffer); + } else { + PRINT_ER("can't write data with the following length: %d\n", len); + PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len); + ret = -1; + } + + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + + return ret; +} + +#endif + +#if defined (NM73131_0_BOARD) + +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .len = rlen, + .speed_hz = SPEED, + .delay_usecs = 0, + + }; + + spi_message_init(&msg); + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#elif defined(TXRX_PHASE_SIZE) + +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + int ret; + + if (rlen > 0) { + int i = 0; + + int blk = rlen / TXRX_PHASE_SIZE; + int remainder = rlen % TXRX_PHASE_SIZE; + + char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL); + if (!t_buffer) { + PRINT_ER("Failed to allocate memory for t_buffer\n"); + } + + if (blk) { + while (i < blk) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb + (i * TXRX_PHASE_SIZE), + .len = TXRX_PHASE_SIZE, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + i++; + } + } + if (remainder) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb + (blk * TXRX_PHASE_SIZE), + .len = remainder, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + }; + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; /* rachel */ + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } + + if (t_buffer) + kfree(t_buffer); + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#else +int linux_spi_read(unsigned char *rb, unsigned long rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .len = rlen, + .speed_hz = SPEED, + .delay_usecs = 0, + + }; + char *t_buffer = kzalloc(rlen, GFP_KERNEL); + if (!t_buffer) { + PRINT_ER("Failed to allocate memory for t_buffer\n"); + } + tr.tx_buf = t_buffer; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); +/* [[ johnny add */ + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; +/* ]] */ + spi_message_add_tail(&tr, &msg); + + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + kfree(t_buffer); + } else { + PRINT_ER("can't read data with the following length: %ld\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +#endif + +int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen) +{ + + int ret; + + if (rlen > 0) { + struct spi_message msg; + struct spi_transfer tr = { + .rx_buf = rb, + .tx_buf = wb, + .len = rlen, + .speed_hz = SPEED, + .bits_per_word = 8, + .delay_usecs = 0, + + }; + + memset(&msg, 0, sizeof(msg)); + spi_message_init(&msg); + msg.spi = wilc_spi_dev; + msg.is_dma_mapped = USE_SPI_DMA; + + spi_message_add_tail(&tr, &msg); + ret = spi_sync(wilc_spi_dev, &msg); + if (ret < 0) { + PRINT_ER("SPI transaction failed\n"); + } + } else { + PRINT_ER("can't read data with the following length: %d\n", rlen); + ret = -1; + } + /* change return value to match WILC interface */ + (ret < 0) ? (ret = 0) : (ret = 1); + + return ret; +} + +int linux_spi_set_max_speed(void) +{ + SPEED = MAX_SPEED; + + PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED); + return 1; +} diff --git a/drivers/staging/wilc1000/linux_wlan_spi.h b/drivers/staging/wilc1000/linux_wlan_spi.h new file mode 100644 index 000000000000..0ecad477de1c --- /dev/null +++ b/drivers/staging/wilc1000/linux_wlan_spi.h @@ -0,0 +1,14 @@ +#ifndef LINUX_WLAN_SPI_H +#define LINUX_WLAN_SPI_H + +#include <linux/spi/spi.h> +extern struct spi_device *wilc_spi_dev; +extern struct spi_driver wilc_bus; + +int linux_spi_init(void *vp); +void linux_spi_deinit(void *vp); +int linux_spi_write(uint8_t *b, uint32_t len); +int linux_spi_read(uint8_t *rb, uint32_t rlen); +int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen); +int linux_spi_set_max_speed(void); +#endif diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c new file mode 100644 index 000000000000..c328208cda29 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -0,0 +1,191 @@ +/* + * NewportMedia WiFi chipset driver test tools - wilc-debug + * Copyright (c) 2012 NewportMedia Inc. + * Author: SSW <sswd@wilcsemic.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#if defined(WILC_DEBUGFS) +#include <linux/module.h> +#include <linux/debugfs.h> +#include <linux/poll.h> +#include <linux/sched.h> + +#include "wilc_wlan_if.h" + + +static struct dentry *wilc_dir; + +/* + * -------------------------------------------------------------------------------- + */ + +#define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG) +#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR) +atomic_t REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG); +atomic_t DEBUG_LEVEL = ATOMIC_INIT(ERR); + +/* + * -------------------------------------------------------------------------------- + */ + + +static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) +{ + char buf[128]; + int res = 0; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&DEBUG_LEVEL)); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static ssize_t wilc_debug_level_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) +{ + char buffer[128] = {}; + int flag = 0; + + if (count > sizeof(buffer)) + return -EINVAL; + + if (copy_from_user(buffer, buf, count)) { + return -EFAULT; + } + + flag = buffer[0] - '0'; + + if (flag > 0) { + flag = DEBUG | ERR; + } else if (flag < 0) { + flag = 100; + } + + if (flag > DBG_LEVEL_ALL) { + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&DEBUG_LEVEL)); + return -EFAULT; + } + + atomic_set(&DEBUG_LEVEL, (int)flag); + + if (flag == 0) { + printk("Debug-level disabled\n"); + } else { + printk("Debug-level enabled\n"); + } + return count; +} + +static ssize_t wilc_debug_region_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) +{ + char buf[128]; + int res = 0; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(®ION)); + + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static ssize_t wilc_debug_region_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) +{ + char buffer[128] = {}; + int flag; + + if (count > sizeof(buffer)) + return -EINVAL; + + if (copy_from_user(buffer, buf, count)) { + return -EFAULT; + } + + flag = buffer[0] - '0'; + + if (flag > DBG_REGION_ALL) { + printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(®ION)); + return -EFAULT; + } + + atomic_set(®ION, (int)flag); + printk("new debug-region is %x\n", atomic_read(®ION)); + + return count; +} + +/* + * -------------------------------------------------------------------------------- + */ + +#define FOPS(_open, _read, _write, _poll) { \ + .owner = THIS_MODULE, \ + .open = (_open), \ + .read = (_read), \ + .write = (_write), \ + .poll = (_poll), \ +} + +struct wilc_debugfs_info_t { + const char *name; + int perm; + unsigned int data; + struct file_operations fops; +}; + +static struct wilc_debugfs_info_t debugfs_info[] = { + { "wilc_debug_level", 0666, (DEBUG | ERR), FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL), }, + { "wilc_debug_region", 0666, (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(NULL, wilc_debug_region_read, wilc_debug_region_write, NULL), }, +}; + +int wilc_debugfs_init(void) +{ + int i; + + struct dentry *debugfs_files; + struct wilc_debugfs_info_t *info; + + wilc_dir = debugfs_create_dir("wilc_wifi", NULL); + if (wilc_dir == ERR_PTR(-ENODEV)) { + /* it's not error. the debugfs is just not being enabled. */ + printk("ERR, kernel has built without debugfs support\n"); + return 0; + } + + if (!wilc_dir) { + printk("ERR, debugfs create dir\n"); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) { + info = &debugfs_info[i]; + debugfs_files = debugfs_create_file(info->name, + info->perm, + wilc_dir, + &info->data, + &info->fops); + + if (!debugfs_files) { + printk("ERR fail to create the debugfs file, %s\n", info->name); + debugfs_remove_recursive(wilc_dir); + return -1; + } + } + return 0; +} + +void wilc_debugfs_remove(void) +{ + debugfs_remove_recursive(wilc_dir); +} + +#endif + diff --git a/drivers/staging/wilc1000/wilc_errorsupport.h b/drivers/staging/wilc1000/wilc_errorsupport.h new file mode 100644 index 000000000000..dd8affabc80d --- /dev/null +++ b/drivers/staging/wilc1000/wilc_errorsupport.h @@ -0,0 +1,67 @@ +#ifndef __WILC_ERRORSUPPORT_H__ +#define __WILC_ERRORSUPPORT_H__ + +/*! + * @file wilc_errorsupport.h + * @brief Error reporting and handling support + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 10 Aug 2010 + * @version 1.0 + */ + +#include "linux_wlan_common.h" + +/* Psitive Numbers to indicate sucess with special status */ +#define WILC_ALREADY_EXSIT (+100) /** The requested object already exists */ + +/* Generic success will return 0 */ +#define WILC_SUCCESS 0 /** Generic success */ + +/* Negative numbers to indicate failures */ +#define WILC_FAIL -100 /** Generic Fail */ +#define WILC_BUSY -101 /** Busy with another operation*/ +#define WILC_INVALID_ARGUMENT -102 /** A given argument is invalid*/ +#define WILC_INVALID_STATE -103 /** An API request would violate the Driver state machine (i.e. to start PID while not camped)*/ +#define WILC_BUFFER_OVERFLOW -104 /** In copy operations if the copied data is larger than the allocated buffer*/ +#define WILC_NULL_PTR -105 /** null pointer is passed or used */ +#define WILC_EMPTY -107 +#define WILC_FULL -108 +#define WILC_TIMEOUT -109 +#define WILC_CANCELED -110 /** The required operation have been canceled by the user*/ +#define WILC_INVALID_FILE -112 /** The Loaded file is corruped or having an invalid format */ +#define WILC_NOT_FOUND -113 /** Cant find the file to load */ +#define WILC_NO_MEM -114 +#define WILC_UNSUPPORTED_VERSION -115 +#define WILC_FILE_EOF -116 + + +/* Error type */ +typedef WILC_Sint32 WILC_ErrNo; + +#define WILC_IS_ERR(__status__) (__status__ < WILC_SUCCESS) + +#define WILC_ERRORCHECK(__status__) do { \ + if (WILC_IS_ERR(__status__)) { \ + PRINT_ER("PRINT_ER(%d)\n", __status__); \ + goto ERRORHANDLER; \ + } \ +} while (0) + +#define WILC_ERRORREPORT(__status__, __err__) do { \ + PRINT_ER("PRINT_ER(%d)\n", __err__); \ + __status__ = __err__; \ + goto ERRORHANDLER; \ +} while (0) + +#define WILC_NULLCHECK(__status__, __ptr__) do { \ + if (__ptr__ == NULL) { \ + WILC_ERRORREPORT(__status__, WILC_NULL_PTR); \ + } \ +} while (0) + +#define WILC_CATCH(__status__) \ +ERRORHANDLER: \ + if (WILC_IS_ERR(__status__)) \ + +#endif diff --git a/drivers/staging/wilc1000/wilc_exported_buf.c b/drivers/staging/wilc1000/wilc_exported_buf.c new file mode 100644 index 000000000000..529457816f65 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_exported_buf.c @@ -0,0 +1,76 @@ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/slab.h> + +#define LINUX_RX_SIZE (96 * 1024) +#define LINUX_TX_SIZE (64 * 1024) +#define WILC1000_FW_SIZE (4 * 1024) + +#define DECLARE_WILC_BUFFER(name) \ + void *exported_ ## name = NULL; + +#define MALLOC_WILC_BUFFER(name, size) \ + exported_ ## name = kmalloc(size, GFP_KERNEL); \ + if (!exported_ ## name) { \ + printk("fail to alloc: %s memory\n", exported_ ## name); \ + return -ENOBUFS; \ + } + +#define FREE_WILC_BUFFER(name) \ + kfree(exported_ ## name); + +/* + * Add necessary buffer pointers + */ +DECLARE_WILC_BUFFER(g_tx_buf) +DECLARE_WILC_BUFFER(g_rx_buf) +DECLARE_WILC_BUFFER(g_fw_buf) + +void *get_tx_buffer(void) +{ + return exported_g_tx_buf; +} +EXPORT_SYMBOL(get_tx_buffer); + +void *get_rx_buffer(void) +{ + return exported_g_rx_buf; +} +EXPORT_SYMBOL(get_rx_buffer); + +void *get_fw_buffer(void) +{ + return exported_g_fw_buf; +} +EXPORT_SYMBOL(get_fw_buffer); + +static int __init wilc_module_init(void) +{ + printk("wilc_module_init\n"); + /* + * alloc necessary memory + */ + MALLOC_WILC_BUFFER(g_tx_buf, LINUX_TX_SIZE) + MALLOC_WILC_BUFFER(g_rx_buf, LINUX_RX_SIZE) + MALLOC_WILC_BUFFER(g_fw_buf, WILC1000_FW_SIZE) + + return 0; +} + +static void __exit wilc_module_deinit(void) +{ + printk("wilc_module_deinit\n"); + FREE_WILC_BUFFER(g_tx_buf) + FREE_WILC_BUFFER(g_rx_buf) + FREE_WILC_BUFFER(g_fw_buf) + + return; +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Tony Cho"); +MODULE_DESCRIPTION("WILC1xxx Memory Manager"); +pure_initcall(wilc_module_init); +module_exit(wilc_module_deinit);
\ No newline at end of file diff --git a/drivers/staging/wilc1000/wilc_log.h b/drivers/staging/wilc1000/wilc_log.h new file mode 100644 index 000000000000..2269ebdec129 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_log.h @@ -0,0 +1,47 @@ +#ifndef __WILC_LOG_H__ +#define __WILC_LOG_H__ + +/* Errors will always get printed */ +#define WILC_ERROR(...) do { WILC_PRINTF("(ERR)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) + +/* Wraning only printed if verbosity is 1 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 0) +#define WILC_WARN(...) do { WILC_PRINTF("(WRN)"); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) +#else +#define WILC_WARN(...) (0) +#endif + +/* Info only printed if verbosity is 2 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 1) +#define WILC_INFO(...) do { WILC_PRINTF("(INF)"); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) +#else +#define WILC_INFO(...) (0) +#endif + +/* Debug is only printed if verbosity is 3 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 2) +#define WILC_DBG(...) do { WILC_PRINTF("(DBG)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \ + WILC_PRINTF(__VA_ARGS__); \ + } while (0) + +#else +#define WILC_DBG(...) (0) +#endif + +/* Function In/Out is only printed if verbosity is 4 or more */ +#if (WILC_LOG_VERBOSITY_LEVEL > 3) +#define WILC_FN_IN do { WILC_PRINTF("(FIN) (%s:%d) \n", __WILC_FUNCTION__, __WILC_LINE__); } while (0) +#define WILC_FN_OUT(ret) do { WILC_PRINTF("(FOUT) (%s:%d) %d.\n", __WILC_FUNCTION__, __WILC_LINE__, (ret)); } while (0) +#else +#define WILC_FN_IN (0) +#define WILC_FN_OUT(ret) (0) +#endif + + +#endif
\ No newline at end of file diff --git a/drivers/staging/wilc1000/wilc_memory.c b/drivers/staging/wilc1000/wilc_memory.c new file mode 100644 index 000000000000..f44827528667 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_memory.c @@ -0,0 +1,58 @@ + +#include "wilc_oswrapper.h" + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryAlloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + if (u32Size > 0) { + return kmalloc(u32Size, GFP_ATOMIC); + } else { + return NULL; + } +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryCalloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + return kcalloc(u32Size, 1, GFP_KERNEL); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryRealloc(void *pvOldBlock, WILC_Uint32 u32NewSize, + tstrWILC_MemoryAttrs *strAttrs, WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + if (u32NewSize == 0) { + kfree(pvOldBlock); + return NULL; + } else if (pvOldBlock == NULL) { + return kmalloc(u32NewSize, GFP_KERNEL); + } else { + return krealloc(pvOldBlock, u32NewSize, GFP_KERNEL); + } + +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_MemoryFree(const void *pvBlock, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo) +{ + kfree(pvBlock); +} diff --git a/drivers/staging/wilc1000/wilc_memory.h b/drivers/staging/wilc1000/wilc_memory.h new file mode 100644 index 000000000000..6f404ac272a1 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_memory.h @@ -0,0 +1,237 @@ +#ifndef __WILC_MEMORY_H__ +#define __WILC_MEMORY_H__ + +/*! + * @file wilc_memory.h + * @brief Memory OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +/*! + * @struct tstrWILC_MemoryAttrs + * @brief Memory API options + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +typedef struct { +} tstrWILC_MemoryAttrs; + +/*! + * @brief Allocates a given size of bytes + * @param[in] u32Size size of memory in bytes to be allocated + * @param[in] strAttrs Optional attributes, NULL for default + * if not NULL, pAllocationPool should point to the pool to use for + * this allocation. if NULL memory will be allocated directly from + * the system + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, NULL if allocation fails + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_MALLOC + * @sa WILC_MALLOC_EX + * @sa WILC_NEW + * @sa WILC_NEW_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryAlloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Allocates a given size of bytes and zero filling it + * @param[in] u32Size size of memory in bytes to be allocated + * @param[in] strAttrs Optional attributes, NULL for default + * if not NULL, pAllocationPool should point to the pool to use for + * this allocation. if NULL memory will be allocated directly from + * the system + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, NULL if allocation fails + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_CALLOC + * @sa WILC_CALLOC_EX + * @sa WILC_NEW_0 + * @sa WILC_NEW_0_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryCalloc(WILC_Uint32 u32Size, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Reallocates a given block to a new size + * @param[in] pvOldBlock the old memory block, if NULL then this function + * behaves as a new allocation function + * @param[in] u32NewSize size of the new memory block in bytes, if zero then + * this function behaves as a free function + * @param[in] strAttrs Optional attributes, NULL for default + * if pAllocationPool!=NULL and pvOldBlock==NULL, pAllocationPool + * should point to the pool to use for this allocation. + * if pAllocationPool==NULL and pvOldBlock==NULL memory will be + * allocated directly from the system + * if and pvOldBlock!=NULL, pAllocationPool will not be inspected + * and reallocation is done from the same pool as the original block + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @return The new allocated block, possibly same as pvOldBlock + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_REALLOC + * @sa WILC_REALLOC_EX + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void *WILC_MemoryRealloc(void *pvOldBlock, WILC_Uint32 u32NewSize, + tstrWILC_MemoryAttrs *strAttrs, WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief Frees given block + * @param[in] pvBlock the memory block to be freed + * @param[in] strAttrs Optional attributes, NULL for default + * @param[in] pcFileName file name of the calling code for debugging + * @param[in] u32LineNo line number of the calling code for debugging + * @note It is recommended to use of of the wrapper macros instead of + * calling this function directly + * @sa sttrWILC_MemoryAttrs + * @sa WILC_FREE + * @sa WILC_FREE_EX + * @sa WILC_FREE_SET_NULL + * @sa WILC_FREE_IF_TRUE + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +void WILC_MemoryFree(const void *pvBlock, tstrWILC_MemoryAttrs *strAttrs, + WILC_Char *pcFileName, WILC_Uint32 u32LineNo); + +/*! + * @brief standrad malloc wrapper with custom attributes + */ + #define WILC_MALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryAlloc( \ + (__size__), __attrs__, NULL, 0)) + +/*! + * @brief standrad calloc wrapper with custom attributes + */ + #define WILC_CALLOC_EX(__size__, __attrs__) \ + (WILC_MemoryCalloc( \ + (__size__), __attrs__, NULL, 0)) + +/*! + * @brief standrad realloc wrapper with custom attributes + */ + #define WILC_REALLOC_EX(__ptr__, __new_size__, __attrs__) \ + (WILC_MemoryRealloc( \ + (__ptr__), (__new_size__), __attrs__, NULL, 0)) +/*! + * @brief standrad free wrapper with custom attributes + */ + #define WILC_FREE_EX(__ptr__, __attrs__) \ + (WILC_MemoryFree( \ + (__ptr__), __attrs__, NULL, 0)) + +/*! + * @brief Allocates a block (with custom attributes) of given type and number of + * elements + */ +#define WILC_NEW_EX(__struct_type__, __n_structs__, __attrs__) \ + ((__struct_type__ *)WILC_MALLOC_EX( \ + sizeof(__struct_type__) * (WILC_Uint32)(__n_structs__), __attrs__)) + +/*! + * @brief Allocates a block (with custom attributes) of given type and number of + * elements and Zero-fills it + */ +#define WILC_NEW_0_EX(__struct_type__, __n_structs__, __attrs__) \ + ((__struct_type__ *)WILC_CALLOC_EX( \ + sizeof(__struct_type__) * (WILC_Uint32)(__n_structs__), __attrs__)) + +/*! + * @brief Frees a block (with custom attributes), also setting the original pointer + * to NULL + */ +#define WILC_FREE_SET_NULL_EX(__ptr__, __attrs__) do { \ + if (__ptr__ != NULL) { \ + WILC_FREE_EX(__ptr__, __attrs__); \ + __ptr__ = NULL; \ + } \ +} while (0) + +/*! + * @brief Frees a block (with custom attributes) if the pointer expression evaluates + * to true + */ +#define WILC_FREE_IF_TRUE_EX(__ptr__, __attrs__) do { \ + if (__ptr__ != NULL) { \ + WILC_FREE_EX(__ptr__, __attrs__); \ + } \ +} while (0) + +/*! + * @brief standrad malloc wrapper with default attributes + */ +#define WILC_MALLOC(__size__) \ + WILC_MALLOC_EX(__size__, NULL) + +/*! + * @brief standrad calloc wrapper with default attributes + */ +#define WILC_CALLOC(__size__) \ + WILC_CALLOC_EX(__size__, NULL) + +/*! + * @brief standrad realloc wrapper with default attributes + */ +#define WILC_REALLOC(__ptr__, __new_size__) \ + WILC_REALLOC_EX(__ptr__, __new_size__, NULL) + +/*! + * @brief standrad free wrapper with default attributes + */ +#define WILC_FREE(__ptr__) \ + WILC_FREE_EX(__ptr__, NULL) + +/*! + * @brief Allocates a block (with default attributes) of given type and number of + * elements + */ +#define WILC_NEW(__struct_type__, __n_structs__) \ + WILC_NEW_EX(__struct_type__, __n_structs__, NULL) + +/*! + * @brief Allocates a block (with default attributes) of given type and number of + * elements and Zero-fills it + */ +#define WILC_NEW_0(__struct_type__, __n_structs__) \ + WILC_NEW_O_EX(__struct_type__, __n_structs__, NULL) + +/*! + * @brief Frees a block (with default attributes), also setting the original pointer + * to NULL + */ +#define WILC_FREE_SET_NULL(__ptr__) \ + WILC_FREE_SET_NULL_EX(__ptr__, NULL) + +/*! + * @brief Frees a block (with default attributes) if the pointer expression evaluates + * to true + */ +#define WILC_FREE_IF_TRUE(__ptr__) \ + WILC_FREE_IF_TRUE_EX(__ptr__, NULL) + + +#endif + diff --git a/drivers/staging/wilc1000/wilc_msgqueue.c b/drivers/staging/wilc1000/wilc_msgqueue.c new file mode 100644 index 000000000000..ebbba8b24de0 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_msgqueue.c @@ -0,0 +1,190 @@ + +#include "wilc_oswrapper.h" +#include <linux/spinlock.h> + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + spin_lock_init(&pHandle->strCriticalSection); + sema_init(&pHandle->hSem, 0); + pHandle->pstrMessageList = NULL; + pHandle->u32ReceiversCount = 0; + pHandle->bExiting = WILC_FALSE; + return WILC_SUCCESS; +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + pHandle->bExiting = WILC_TRUE; + + /* Release any waiting receiver thread. */ + while (pHandle->u32ReceiversCount > 0) { + up(&(pHandle->hSem)); + pHandle->u32ReceiversCount--; + } + + while (pHandle->pstrMessageList != NULL) { + Message *pstrMessge = pHandle->pstrMessageList->pstrNext; + WILC_FREE(pHandle->pstrMessageList); + pHandle->pstrMessageList = pstrMessge; + } + + return WILC_SUCCESS; +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle, + const void *pvSendBuffer, WILC_Uint32 u32SendBufferSize, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + unsigned long flags; + Message *pstrMessage = NULL; + + if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == WILC_TRUE) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + /* construct a new message */ + pstrMessage = WILC_NEW(Message, 1); + WILC_NULLCHECK(s32RetStatus, pstrMessage); + pstrMessage->u32Length = u32SendBufferSize; + pstrMessage->pstrNext = NULL; + pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize); + WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer); + WILC_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize); + + + /* add it to the message queue */ + if (pHandle->pstrMessageList == NULL) { + pHandle->pstrMessageList = pstrMessage; + } else { + Message *pstrTailMsg = pHandle->pstrMessageList; + while (pstrTailMsg->pstrNext != NULL) { + pstrTailMsg = pstrTailMsg->pstrNext; + } + pstrTailMsg->pstrNext = pstrMessage; + } + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + up(&pHandle->hSem); + + WILC_CATCH(s32RetStatus) + { + /* error occured, free any allocations */ + if (pstrMessage != NULL) { + if (pstrMessage->pvBuffer != NULL) { + WILC_FREE(pstrMessage->pvBuffer); + } + WILC_FREE(pstrMessage); + } + } + + return s32RetStatus; +} + + + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle, + void *pvRecvBuffer, WILC_Uint32 u32RecvBufferSize, + WILC_Uint32 *pu32ReceivedLength, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + Message *pstrMessage; + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + unsigned long flags; + if ((pHandle == NULL) || (u32RecvBufferSize == 0) + || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == WILC_TRUE) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount++; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + down(&(pHandle->hSem)); + + if (s32RetStatus == WILC_TIMEOUT) { + /* timed out, just exit without consumeing the message */ + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount--; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + } else { + /* other non-timeout scenarios */ + WILC_ERRORCHECK(s32RetStatus); + + if (pHandle->bExiting) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + pstrMessage = pHandle->pstrMessageList; + if (pstrMessage == NULL) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + /* check buffer size */ + if (u32RecvBufferSize < pstrMessage->u32Length) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + up(&pHandle->hSem); + WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW); + } + + /* consume the message */ + pHandle->u32ReceiversCount--; + WILC_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length); + *pu32ReceivedLength = pstrMessage->u32Length; + + pHandle->pstrMessageList = pstrMessage->pstrNext; + + WILC_FREE(pstrMessage->pvBuffer); + WILC_FREE(pstrMessage); + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + } + + WILC_CATCH(s32RetStatus) + { + } + + return s32RetStatus; +} diff --git a/drivers/staging/wilc1000/wilc_msgqueue.h b/drivers/staging/wilc1000/wilc_msgqueue.h new file mode 100644 index 000000000000..d7e4b1ce3497 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_msgqueue.h @@ -0,0 +1,103 @@ +#ifndef __WILC_MSG_QUEUE_H__ +#define __WILC_MSG_QUEUE_H__ + +/*! + * @file wilc_msgqueue.h + * @brief Message Queue OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 30 Aug 2010 + * @version 1.0 + */ + +/*! + * @struct tstrWILC_MsgQueueAttrs + * @brief Message Queue API options + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +typedef struct { + /* a dummy member to avoid compiler errors*/ + u8 dummy; + +} tstrWILC_MsgQueueAttrs; + +/*! + * @brief Creates a new Message queue + * @details Creates a new Message queue, if the feature + * CONFIG_WILC_MSG_QUEUE_IPC_NAME is enabled and pstrAttrs->pcName + * is not Null, then this message queue can be used for IPC with + * any other message queue having the same name in the system + * @param[in,out] pHandle handle to the message queue object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Sends a message + * @details Sends a message, this API will block unil the message is + * actually sent or until it is timedout (as long as the feature + * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout + * is not set to WILC_OS_INFINITY), zero timeout is a valid value + * @param[in] pHandle handle to the message queue object + * @param[in] pvSendBuffer pointer to the data to send + * @param[in] u32SendBufferSize the size of the data to send + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle, + const void *pvSendBuffer, WILC_Uint32 u32SendBufferSize, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Receives a message + * @details Receives a message, this API will block unil a message is + * received or until it is timedout (as long as the feature + * CONFIG_WILC_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout + * is not set to WILC_OS_INFINITY), zero timeout is a valid value + * @param[in] pHandle handle to the message queue object + * @param[out] pvRecvBuffer pointer to a buffer to fill with the received message + * @param[in] u32RecvBufferSize the size of the receive buffer + * @param[out] pu32ReceivedLength the length of received data + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle, + void *pvRecvBuffer, WILC_Uint32 u32RecvBufferSize, + WILC_Uint32 *pu32ReceivedLength, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + +/*! + * @brief Destroys an existing Message queue + * @param[in] pHandle handle to the message queue object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa tstrWILC_MsgQueueAttrs + * @author syounan + * @date 30 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs); + + + +#endif diff --git a/drivers/staging/wilc1000/wilc_osconfig.h b/drivers/staging/wilc1000/wilc_osconfig.h new file mode 100644 index 000000000000..f9c25140393e --- /dev/null +++ b/drivers/staging/wilc1000/wilc_osconfig.h @@ -0,0 +1,9 @@ +/* Logs options */ +#define WILC_LOGS_NOTHING 0 +#define WILC_LOGS_WARN 1 +#define WILC_LOGS_WARN_INFO 2 +#define WILC_LOGS_WARN_INFO_DBG 3 +#define WILC_LOGS_WARN_INFO_DBG_FN 4 +#define WILC_LOGS_ALL 5 + +#define WILC_LOG_VERBOSITY_LEVEL WILC_LOGS_ALL diff --git a/drivers/staging/wilc1000/wilc_oswrapper.h b/drivers/staging/wilc1000/wilc_oswrapper.h new file mode 100644 index 000000000000..4b4cfa202043 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_oswrapper.h @@ -0,0 +1,59 @@ +#ifndef __WILC_OSWRAPPER_H__ +#define __WILC_OSWRAPPER_H__ + +/*! + * @file wilc_oswrapper.h + * @brief Top level OS Wrapper, include this file and it will include all + * other files as necessary + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + */ + +/* OS Wrapper interface version */ +#define WILC_OSW_INTERFACE_VER 2 + +/* Integer Types */ +typedef unsigned short WILC_Uint16; +typedef unsigned int WILC_Uint32; +typedef unsigned long long WILC_Uint64; +typedef signed char WILC_Sint8; +typedef signed short WILC_Sint16; +typedef signed int WILC_Sint32; +typedef signed long long WILC_Sint64; + +/* Boolean type */ +typedef enum { + WILC_FALSE = 0, + WILC_TRUE = 1 +} WILC_Bool; + +/* Character types */ +typedef char WILC_Char; + +/* Os Configuration File */ +#include "wilc_osconfig.h" +#include "wilc_platform.h" + +/* Logging Functions */ +#include "wilc_log.h" + +/* Error reporting and handling support */ +#include "wilc_errorsupport.h" + +/* Sleep support */ +#include "wilc_sleep.h" + +/* Timer support */ +#include "wilc_timer.h" + +/* Memory support */ +#include "wilc_memory.h" + +/* String Utilities */ +#include "wilc_strutils.h" + +/* Message Queue */ +#include "wilc_msgqueue.h" + +#endif diff --git a/drivers/staging/wilc1000/wilc_platform.h b/drivers/staging/wilc1000/wilc_platform.h new file mode 100644 index 000000000000..ae42bbcbd5eb --- /dev/null +++ b/drivers/staging/wilc1000/wilc_platform.h @@ -0,0 +1,52 @@ +#ifndef __WILC_platfrom_H__ +#define __WILC_platfrom_H__ + +#include <linux/kthread.h> +#include <linux/semaphore.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/types.h> +#include <linux/stat.h> +#include <linux/time.h> +#include <linux/version.h> +#include "linux/string.h" +/****************************************************************** + * OS specific types + *******************************************************************/ + +typedef struct timer_list WILC_TimerHandle; + + + +/* Message Queue type is a structure */ +typedef struct __Message_struct { + void *pvBuffer; + WILC_Uint32 u32Length; + struct __Message_struct *pstrNext; +} Message; + +typedef struct __MessageQueue_struct { + struct semaphore hSem; + spinlock_t strCriticalSection; + WILC_Bool bExiting; + WILC_Uint32 u32ReceiversCount; + Message *pstrMessageList; +} WILC_MsgQueueHandle; + + + +/*Time represented in 64 bit format*/ +typedef time_t WILC_Time; + + +/******************************************************************* + * others + ********************************************************************/ + +/* Generic printf function */ +#define __WILC_FILE__ __FILE__ +#define __WILC_FUNCTION__ __FUNCTION__ +#define __WILC_LINE__ __LINE__ +#endif diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c new file mode 100644 index 000000000000..d96abb05a83e --- /dev/null +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -0,0 +1,1298 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_sdio.c */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" + + +#ifdef WILC1000_SINGLE_TRANSFER +#define WILC_SDIO_BLOCK_SIZE 256 +#else + #if defined(PLAT_AML8726_M3) /* johnny */ + #define WILC_SDIO_BLOCK_SIZE 512 + #define MAX_SEG_SIZE (1 << 12) /* 4096 */ + #else + #define WILC_SDIO_BLOCK_SIZE 512 + #endif +#endif + +typedef struct { + void *os_context; + wilc_wlan_os_func_t os_func; + uint32_t block_size; + int (*sdio_cmd52)(sdio_cmd52_t *); + int (*sdio_cmd53)(sdio_cmd53_t *); + int (*sdio_set_max_speed)(void); + int (*sdio_set_default_speed)(void); + wilc_debug_func dPrint; + int nint; +#define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */ + int has_thrpt_enh3; +} wilc_sdio_t; + +static wilc_sdio_t g_sdio; + +#ifdef WILC_SDIO_IRQ_GPIO +static int sdio_write_reg(uint32_t addr, uint32_t data); +static int sdio_read_reg(uint32_t addr, uint32_t *data); +#endif +extern unsigned int int_clrd; + +/******************************************** + * + * Function 0 + * + ********************************************/ + +static int sdio_set_func0_csa_address(uint32_t adr) +{ + sdio_cmd52_t cmd; + + /** + * Review: BIG ENDIAN + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10c; + cmd.data = (uint8_t)adr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); + goto _fail_; + } + + cmd.address = 0x10d; + cmd.data = (uint8_t)(adr >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n"); + goto _fail_; + } + + cmd.address = 0x10e; + cmd.data = (uint8_t)(adr >> 16); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +static int sdio_set_func0_csa_address_byte0(uint32_t adr) +{ + sdio_cmd52_t cmd; + + + /** + * Review: BIG ENDIAN + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10c; + cmd.data = (uint8_t)adr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} +static int sdio_set_func0_block_size(uint32_t block_size) +{ + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x10; + cmd.data = (uint8_t)block_size; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n"); + goto _fail_; + } + + cmd.address = 0x11; + cmd.data = (uint8_t)(block_size >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +/******************************************** + * + * Function 1 + * + ********************************************/ + +static int sdio_set_func1_block_size(uint32_t block_size) +{ + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x110; + cmd.data = (uint8_t)block_size; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n"); + goto _fail_; + } + cmd.address = 0x111; + cmd.data = (uint8_t)(block_size >> 8); + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n"); + goto _fail_; + } + + return 1; +_fail_: + return 0; +} + +static int sdio_clear_int(void) +{ +#ifndef WILC_SDIO_IRQ_GPIO + /* uint32_t sts; */ + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x4; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + int_clrd++; + + return cmd.data; +#else + uint32_t reg; + if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + return 0; + } + reg &= ~0x1; + sdio_write_reg(WILC_HOST_RX_CTRL_0, reg); + int_clrd++; + return 1; +#endif + +} + +uint32_t sdio_xfer_cnt(void) +{ + uint32_t cnt = 0; + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1C; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt = cmd.data; + + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1D; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt |= (cmd.data << 8); + + cmd.read_write = 0; + cmd.function = 1; + cmd.raw = 0; + cmd.address = 0x1E; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + cnt |= (cmd.data << 16); + + return cnt; + + +} + +/******************************************** + * + * Sdio interfaces + * + ********************************************/ +int sdio_check_bs(void) +{ + sdio_cmd52_t cmd; + + /** + * poll until BS is 0 + **/ + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xc; + cmd.data = 0; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n"); + goto _fail_; + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_write_reg(uint32_t addr, uint32_t data) +{ +#ifdef BIG_ENDIAN + data = BYTE_SWAP(data); +#endif + + if ((addr >= 0xf0) && (addr <= 0xff)) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = addr; + cmd.data = data; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + goto _fail_; + } + } else { + sdio_cmd53_t cmd; + + /** + * set the AHB address + **/ + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + + cmd.read_write = 1; + cmd.function = 0; + cmd.address = 0x10f; + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = 4; + cmd.buffer = (uint8_t *)&data; + cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ + + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_write(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint32_t block_size = g_sdio.block_size; + sdio_cmd53_t cmd; + int nblk, nleft; + + cmd.read_write = 1; + if (addr > 0) { + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } + + /** + * func 0 access + **/ + cmd.function = 0; + cmd.address = 0x10f; + } else { +#ifdef WILC1000_SINGLE_TRANSFER + /** + * has to be block aligned... + **/ + nleft = size % block_size; + if (nleft > 0) { + size += block_size; + size &= ~(block_size - 1); + } +#else + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } +#endif + + /** + * func 1 access + **/ + cmd.function = 1; + cmd.address = 0; + } + + nblk = size / block_size; + nleft = size % block_size; + + if (nblk > 0) { + +#if defined(PLAT_AML8726_M3_BACKUP) /* johnny */ + int i; + + for (i = 0; i < nblk; i++) { + cmd.block_mode = 0; /* 1; */ + cmd.increment = 1; + cmd.count = block_size; /* nblk; */ + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += block_size; /* addr += nblk*block_size; */ + + buf += block_size; /* buf += nblk*block_size; */ + } + +#elif defined(PLAT_AML8726_M3) /* johnny */ + + int i; + int rest; + int seg_cnt; + + seg_cnt = (nblk * block_size) / MAX_SEG_SIZE; + rest = (nblk * block_size) & (MAX_SEG_SIZE - 1); + + for (i = 0; i < seg_cnt; i++) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = MAX_SEG_SIZE / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += MAX_SEG_SIZE; + + buf += MAX_SEG_SIZE; + + } + + + if (rest > 0) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = rest / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += rest; + + buf += rest; + + } + +#else + + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = nblk; + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += nblk * block_size; + buf += nblk * block_size; + +#endif /* platform */ + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + + } + + + if (nleft > 0) { + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = nleft; + cmd.buffer = buf; + + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +static int sdio_read_reg(uint32_t addr, uint32_t *data) +{ + if ((addr >= 0xf0) && (addr <= 0xff)) { + sdio_cmd52_t cmd; + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = addr; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr); + goto _fail_; + } + *data = cmd.data; + } else { + sdio_cmd53_t cmd; + + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + + cmd.read_write = 0; + cmd.function = 0; + cmd.address = 0x10f; + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = 4; + cmd.buffer = (uint8_t *)data; + + cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */ + + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; + +_fail_: + + return 0; +} + +static int sdio_read(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint32_t block_size = g_sdio.block_size; + sdio_cmd53_t cmd; + int nblk, nleft; + + cmd.read_write = 0; + if (addr > 0) { + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } + + /** + * func 0 access + **/ + cmd.function = 0; + cmd.address = 0x10f; + } else { +#ifdef WILC1000_SINGLE_TRANSFER + /** + * has to be block aligned... + **/ + nleft = size % block_size; + if (nleft > 0) { + size += block_size; + size &= ~(block_size - 1); + } +#else + /** + * has to be word aligned... + **/ + if (size & 0x3) { + size += 4; + size &= ~0x3; + } +#endif + + /** + * func 1 access + **/ + cmd.function = 1; + cmd.address = 0; + } + + nblk = size / block_size; + nleft = size % block_size; + + if (nblk > 0) { + +#if defined(PLAT_AML8726_M3_BACKUP) /* johnny */ + + int i; + + for (i = 0; i < nblk; i++) { + cmd.block_mode = 0; /* 1; */ + cmd.increment = 1; + cmd.count = block_size; /* nblk; */ + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += block_size; /* addr += nblk*block_size; */ + buf += block_size; /* buf += nblk*block_size; */ + } + +#elif defined(PLAT_AML8726_M3) /* johnny */ + + int i; + int rest; + int seg_cnt; + + seg_cnt = (nblk * block_size) / MAX_SEG_SIZE; + rest = (nblk * block_size) & (MAX_SEG_SIZE - 1); + + for (i = 0; i < seg_cnt; i++) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = MAX_SEG_SIZE / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; + + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += MAX_SEG_SIZE; + + buf += MAX_SEG_SIZE; + + } + + + if (rest > 0) { + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = rest / block_size; + cmd.buffer = buf; + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + + if (addr > 0) + addr += rest; + + buf += rest; + + } + +#else + + cmd.block_mode = 1; + cmd.increment = 1; + cmd.count = nblk; + cmd.buffer = buf; + cmd.block_size = block_size; + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr); + goto _fail_; + } + if (addr > 0) + addr += nblk * block_size; + buf += nblk * block_size; + +#endif /* platform */ + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + + } /* if (nblk > 0) */ + + if (nleft > 0) { + cmd.block_mode = 0; + cmd.increment = 1; + cmd.count = nleft; + cmd.buffer = buf; + + cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */ + + if (addr > 0) { + if (!sdio_set_func0_csa_address(addr)) + goto _fail_; + } + if (!g_sdio.sdio_cmd53(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr); + goto _fail_; + } + +#if 0 + if (!sdio_check_bs()) + goto _fail_; +#else + /* g_sdio.os_func.os_sleep(1); */ +#endif + } + + return 1; + +_fail_: + + return 0; +} + +/******************************************** + * + * Bus interfaces + * + ********************************************/ + +static int sdio_deinit(void *pv) +{ + return 1; +} + +static int sdio_sync(void) +{ + uint32_t reg; + + /** + * Disable power sequencer + **/ + if (!sdio_read_reg(WILC_MISC, ®)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + return 0; + } + + reg &= ~(1 << 8); + if (!sdio_write_reg(WILC_MISC, reg)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + return 0; + } + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t reg; + int ret; + + /** + * interrupt pin mux select + **/ + ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + reg |= (1 << 16); + ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + } +#endif + + return 1; +} + +static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +{ + sdio_cmd52_t cmd; + int loop; + uint32_t chipid; + memset(&g_sdio, 0, sizeof(wilc_sdio_t)); + + g_sdio.dPrint = func; + g_sdio.os_context = inp->os_context.os_private; + memcpy((void *)&g_sdio.os_func, (void *)&inp->os_func, sizeof(wilc_wlan_os_func_t)); + + if (inp->io_func.io_init) { + if (!inp->io_func.io_init(g_sdio.os_context)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n"); + return 0; + } + } else { + return 0; + } + + g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52; + g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53; + g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed; + g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed; + + /** + * function 0 csa enable + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x100; + cmd.data = 0x80; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n"); + goto _fail_; + } + + /** + * function 0 block size + **/ + if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n"); + goto _fail_; + } + g_sdio.block_size = WILC_SDIO_BLOCK_SIZE; + + /** + * enable func1 IO + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x2; + cmd.data = 0x2; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n"); + goto _fail_; + } + + /** + * make sure func 1 is up + **/ + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0x3; + loop = 3; + do { + cmd.data = 0; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n"); + goto _fail_; + } + if (cmd.data == 0x2) + break; + } while (loop--); + + if (loop <= 0) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n"); + goto _fail_; + } + + /** + * func 1 is ready, set func 1 block size + **/ + if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n"); + goto _fail_; + } + + /** + * func 1 interrupt enable + **/ + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 1; + cmd.address = 0x4; + cmd.data = 0x3; + if (!g_sdio.sdio_cmd52(&cmd)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n"); + goto _fail_; + } + + /** + * make sure can read back chip id correctly + **/ + if (!sdio_read_reg(0x1000, &chipid)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n"); + goto _fail_; + } + g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid); + if ((chipid & 0xfff) > 0x2a0) { + g_sdio.has_thrpt_enh3 = 1; + } else { + g_sdio.has_thrpt_enh3 = 0; + } + g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3); + + + return 1; + +_fail_: + + return 0; +} + +static void sdio_set_max_speed(void) +{ + g_sdio.sdio_set_max_speed(); +} + +static void sdio_set_default_speed(void) +{ + g_sdio.sdio_set_default_speed(); +} + +static int sdio_read_size(uint32_t *size) +{ + + uint32_t tmp; + sdio_cmd52_t cmd; + + /** + * Read DMA count in words + **/ + { + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf2; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + tmp = cmd.data; + + /* cmd.read_write = 0; */ + /* cmd.function = 0; */ + /* cmd.raw = 0; */ + cmd.address = 0xf3; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + tmp |= (cmd.data << 8); + } + + *size = tmp; + return 1; +} + +static int sdio_read_int(uint32_t *int_status) +{ + + uint32_t tmp; + sdio_cmd52_t cmd; + + sdio_read_size(&tmp); + + /** + * Read IRQ flags + **/ +#ifndef WILC_SDIO_IRQ_GPIO + /* cmd.read_write = 0; */ + cmd.function = 1; + /* cmd.raw = 0; */ + cmd.address = 0x04; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + + if (cmd.data & (1 << 0)) { + tmp |= INT_0; + } + if (cmd.data & (1 << 2)) { + tmp |= INT_1; + } + if (cmd.data & (1 << 3)) { + tmp |= INT_2; + } + if (cmd.data & (1 << 4)) { + tmp |= INT_3; + } + if (cmd.data & (1 << 5)) { + tmp |= INT_4; + } + if (cmd.data & (1 << 6)) { + tmp |= INT_5; + } + { + int i; + for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data); + break; + } + } + } +#else + { + uint32_t irq_flags; + + cmd.read_write = 0; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf7; + cmd.data = 0; + g_sdio.sdio_cmd52(&cmd); + irq_flags = cmd.data & 0x1f; + tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET); + } + +#endif + + *int_status = tmp; + + return 1; +} + +static int sdio_clear_int_ext(uint32_t val) +{ + int ret; + + if (g_sdio.has_thrpt_enh3) { + uint32_t reg; + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t flags; + flags = val & ((1 << MAX_NUN_INT_THRPT_ENH2) - 1); + reg = flags; + } +#else + reg = 0; +#endif + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + reg |= (1 << 5); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + reg |= (1 << 6); + /* enable VMM */ + if ((val & EN_VMM) == EN_VMM) + reg |= (1 << 7); + if (reg) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf8; + cmd.data = reg; + + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + goto _fail_; + } + + } + } else { +#ifdef WILC_SDIO_IRQ_GPIO + { + /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */ + /* Cannot clear multiple interrupts. Must clear each interrupt individually */ + uint32_t flags; + flags = val & ((1 << MAX_NUM_INT) - 1); + if (flags) { + int i; + + ret = 1; + for (i = 0; i < g_sdio.nint; i++) { + if (flags & 1) { + sdio_cmd52_t cmd; + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf8; + cmd.data = (1 << i); + + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__); + goto _fail_; + } + + } + if (!ret) + break; + flags >>= 1; + } + if (!ret) { + goto _fail_; + } + for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + if (flags & 1) + g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i); + flags >>= 1; + } + } + } +#endif /* WILC_SDIO_IRQ_GPIO */ + + + { + uint32_t vmm_ctl; + + vmm_ctl = 0; + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + vmm_ctl |= (1 << 0); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + vmm_ctl |= (1 << 1); + /* enable VMM */ + if ((val & EN_VMM) == EN_VMM) + vmm_ctl |= (1 << 2); + + if (vmm_ctl) { + sdio_cmd52_t cmd; + + cmd.read_write = 1; + cmd.function = 0; + cmd.raw = 0; + cmd.address = 0xf6; + cmd.data = vmm_ctl; + ret = g_sdio.sdio_cmd52(&cmd); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__); + goto _fail_; + } + } + } + } + + return 1; +_fail_: + return 0; +} + +static int sdio_sync_ext(int nint /* how mant interrupts to enable. */) +{ + uint32_t reg; + + + if (nint > MAX_NUM_INT) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint); + return 0; + } + if (nint > MAX_NUN_INT_THRPT_ENH2) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n"); + return 0; + } + + + g_sdio.nint = nint; + + /** + * Disable power sequencer + **/ + if (!sdio_read_reg(WILC_MISC, ®)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n"); + return 0; + } + + reg &= ~(1 << 8); + if (!sdio_write_reg(WILC_MISC, reg)) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n"); + return 0; + } + +#ifdef WILC_SDIO_IRQ_GPIO + { + uint32_t reg; + int ret, i; + + + /** + * interrupt pin mux select + **/ + ret = sdio_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = sdio_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = sdio_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + for (i = 0; (i < 5) && (nint > 0); i++, nint--) { + reg |= (1 << (27 + i)); + } + ret = sdio_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + if (nint) { + ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + + for (i = 0; (i < 3) && (nint > 0); i++, nint--) { + reg |= (1 << i); + } + + ret = sdio_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + } + } +#endif /* WILC_SDIO_IRQ_GPIO */ + return 1; +} + + +/******************************************** + * + * Global sdio HIF function table + * + ********************************************/ + +wilc_hif_func_t hif_sdio = { + sdio_init, + sdio_deinit, + sdio_read_reg, + sdio_write_reg, + sdio_read, + sdio_write, + sdio_sync, + sdio_clear_int, + sdio_read_int, + sdio_clear_int_ext, + sdio_read_size, + sdio_write, + sdio_read, + sdio_sync_ext, + + sdio_set_max_speed, + sdio_set_default_speed, +}; + diff --git a/drivers/staging/wilc1000/wilc_sleep.c b/drivers/staging/wilc1000/wilc_sleep.c new file mode 100644 index 000000000000..98a079f3d6c9 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_sleep.c @@ -0,0 +1,18 @@ + +#include "wilc_oswrapper.h" + +/* + * @author mdaftedar + * @date 10 Aug 2010 + * @version 1.0 + */ +void WILC_Sleep(WILC_Uint32 u32TimeMilliSec) +{ + if (u32TimeMilliSec <= 4000000) { + WILC_Uint32 u32Temp = u32TimeMilliSec * 1000; + usleep_range(u32Temp, u32Temp); + } else { + msleep(u32TimeMilliSec); + } + +} diff --git a/drivers/staging/wilc1000/wilc_sleep.h b/drivers/staging/wilc1000/wilc_sleep.h new file mode 100644 index 000000000000..2865c8e44346 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_sleep.h @@ -0,0 +1,17 @@ +#ifndef __WILC_SLEEP_H__ +#define __WILC_SLEEP_H__ + +/*! + * @brief forces the current thread to sleep until the given time has elapsed + * @param[in] u32TimeMilliSec Time to sleep in Milli seconds + * @sa WILC_SleepMicrosec + * @author syounan + * @date 10 Aug 2010 + * @version 1.0 + * @note This function offers a relatively innacurate and low resolution + * sleep, for accurate high resolution sleep use u32TimeMicoSec + */ +/* TODO: remove and open-code in callers */ +void WILC_Sleep(WILC_Uint32 u32TimeMilliSec); + +#endif diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c new file mode 100644 index 000000000000..6d854fd9101d --- /dev/null +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -0,0 +1,1475 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_spi.c */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" + +extern unsigned int int_clrd; + +/* + * #include <linux/kernel.h> + * #include <linux/string.h> + */ +typedef struct { + void *os_context; + int (*spi_tx)(uint8_t *, uint32_t); + int (*spi_rx)(uint8_t *, uint32_t); + int (*spi_trx)(uint8_t *, uint8_t *, uint32_t); + int (*spi_max_speed)(void); + wilc_debug_func dPrint; + int crc_off; + int nint; + int has_thrpt_enh; +} wilc_spi_t; + +static wilc_spi_t g_spi; + +static int spi_read(uint32_t, uint8_t *, uint32_t); +static int spi_write(uint32_t, uint8_t *, uint32_t); + +/******************************************** + * + * Crc7 + * + ********************************************/ + +static const uint8_t crc7_syndrome_table[256] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 +}; + +static uint8_t crc7_byte(uint8_t crc, uint8_t data) +{ + return crc7_syndrome_table[(crc << 1) ^ data]; +} + +static uint8_t crc7(uint8_t crc, const uint8_t *buffer, uint32_t len) +{ + while (len--) + crc = crc7_byte(crc, *buffer++); + return crc; +} + +/******************************************** + * + * Spi protocol Function + * + ********************************************/ + +#define CMD_DMA_WRITE 0xc1 +#define CMD_DMA_READ 0xc2 +#define CMD_INTERNAL_WRITE 0xc3 +#define CMD_INTERNAL_READ 0xc4 +#define CMD_TERMINATE 0xc5 +#define CMD_REPEAT 0xc6 +#define CMD_DMA_EXT_WRITE 0xc7 +#define CMD_DMA_EXT_READ 0xc8 +#define CMD_SINGLE_WRITE 0xc9 +#define CMD_SINGLE_READ 0xca +#define CMD_RESET 0xcf + +#define N_OK 1 +#define N_FAIL 0 +#define N_RESET -1 +#define N_RETRY -2 + +#define DATA_PKT_SZ_256 256 +#define DATA_PKT_SZ_512 512 +#define DATA_PKT_SZ_1K 1024 +#define DATA_PKT_SZ_4K (4 * 1024) +#define DATA_PKT_SZ_8K (8 * 1024) +#define DATA_PKT_SZ DATA_PKT_SZ_8K + +static int spi_cmd(uint8_t cmd, uint32_t adr, uint32_t data, uint32_t sz, uint8_t clockless) +{ + uint8_t bc[9]; + int len = 5; + int result = N_OK; + + bc[0] = cmd; + switch (cmd) { + case CMD_SINGLE_READ: /* single word (4 bytes) read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + len = 5; + break; + + case CMD_INTERNAL_READ: /* internal register read */ + bc[1] = (uint8_t)(adr >> 8); + if (clockless) + bc[1] |= (1 << 7); + bc[2] = (uint8_t)adr; + bc[3] = 0x00; + len = 5; + break; + + case CMD_TERMINATE: /* termination */ + bc[1] = 0x00; + bc[2] = 0x00; + bc[3] = 0x00; + len = 5; + break; + + case CMD_REPEAT: /* repeat */ + bc[1] = 0x00; + bc[2] = 0x00; + bc[3] = 0x00; + len = 5; + break; + + case CMD_RESET: /* reset */ + bc[1] = 0xff; + bc[2] = 0xff; + bc[3] = 0xff; + len = 5; + break; + + case CMD_DMA_WRITE: /* dma write */ + case CMD_DMA_READ: /* dma read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + bc[4] = (uint8_t)(sz >> 8); + bc[5] = (uint8_t)(sz); + len = 7; + break; + + case CMD_DMA_EXT_WRITE: /* dma extended write */ + case CMD_DMA_EXT_READ: /* dma extended read */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)adr; + bc[4] = (uint8_t)(sz >> 16); + bc[5] = (uint8_t)(sz >> 8); + bc[6] = (uint8_t)(sz); + len = 8; + break; + + case CMD_INTERNAL_WRITE: /* internal register write */ + bc[1] = (uint8_t)(adr >> 8); + if (clockless) + bc[1] |= (1 << 7); + bc[2] = (uint8_t)(adr); + bc[3] = (uint8_t)(data >> 24); + bc[4] = (uint8_t)(data >> 16); + bc[5] = (uint8_t)(data >> 8); + bc[6] = (uint8_t)(data); + len = 8; + break; + + case CMD_SINGLE_WRITE: /* single word write */ + bc[1] = (uint8_t)(adr >> 16); + bc[2] = (uint8_t)(adr >> 8); + bc[3] = (uint8_t)(adr); + bc[4] = (uint8_t)(data >> 24); + bc[5] = (uint8_t)(data >> 16); + bc[6] = (uint8_t)(data >> 8); + bc[7] = (uint8_t)(data); + len = 9; + break; + + default: + result = N_FAIL; + break; + } + + if (result) { + if (!g_spi.crc_off) + bc[len - 1] = (crc7(0x7f, (const uint8_t *)&bc[0], len - 1)) << 1; + else + len -= 1; + + if (!g_spi.spi_tx(bc, len)) { + PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); + result = N_FAIL; + } + } + + return result; +} + +static int spi_cmd_rsp(uint8_t cmd) +{ + uint8_t rsp; + int result = N_OK; + + /** + * Command/Control response + **/ + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + if (!g_spi.spi_rx(&rsp, 1)) { + result = N_FAIL; + goto _fail_; + } + } + + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n"); + result = N_FAIL; + goto _fail_; + } + + if (rsp != cmd) { + PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp); + result = N_FAIL; + goto _fail_; + } + + /** + * State response + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n"); + result = N_FAIL; + goto _fail_; + } + + if (rsp != 0x00) { + PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp); + result = N_FAIL; + } + +_fail_: + + return result; +} + +static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless) +{ + uint8_t wb[32], rb[32]; + uint8_t wix, rix; + uint32_t len2; + uint8_t rsp; + int len = 0; + int result = N_OK; + + wb[0] = cmd; + switch (cmd) { + case CMD_SINGLE_READ: /* single word (4 bytes) read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + len = 5; + break; + + case CMD_INTERNAL_READ: /* internal register read */ + wb[1] = (uint8_t)(adr >> 8); + if (clockless == 1) + wb[1] |= (1 << 7); + wb[2] = (uint8_t)adr; + wb[3] = 0x00; + len = 5; + break; + + case CMD_TERMINATE: /* termination */ + wb[1] = 0x00; + wb[2] = 0x00; + wb[3] = 0x00; + len = 5; + break; + + case CMD_REPEAT: /* repeat */ + wb[1] = 0x00; + wb[2] = 0x00; + wb[3] = 0x00; + len = 5; + break; + + case CMD_RESET: /* reset */ + wb[1] = 0xff; + wb[2] = 0xff; + wb[3] = 0xff; + len = 5; + break; + + case CMD_DMA_WRITE: /* dma write */ + case CMD_DMA_READ: /* dma read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + wb[4] = (uint8_t)(sz >> 8); + wb[5] = (uint8_t)(sz); + len = 7; + break; + + case CMD_DMA_EXT_WRITE: /* dma extended write */ + case CMD_DMA_EXT_READ: /* dma extended read */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)adr; + wb[4] = (uint8_t)(sz >> 16); + wb[5] = (uint8_t)(sz >> 8); + wb[6] = (uint8_t)(sz); + len = 8; + break; + + case CMD_INTERNAL_WRITE: /* internal register write */ + wb[1] = (uint8_t)(adr >> 8); + if (clockless == 1) + wb[1] |= (1 << 7); + wb[2] = (uint8_t)(adr); + wb[3] = b[3]; + wb[4] = b[2]; + wb[5] = b[1]; + wb[6] = b[0]; + len = 8; + break; + + case CMD_SINGLE_WRITE: /* single word write */ + wb[1] = (uint8_t)(adr >> 16); + wb[2] = (uint8_t)(adr >> 8); + wb[3] = (uint8_t)(adr); + wb[4] = b[3]; + wb[5] = b[2]; + wb[6] = b[1]; + wb[7] = b[0]; + len = 9; + break; + + default: + result = N_FAIL; + break; + } + + if (result != N_OK) { + return result; + } + + if (!g_spi.crc_off) { + wb[len - 1] = (crc7(0x7f, (const uint8_t *)&wb[0], len - 1)) << 1; + } else { + len -= 1; + } + +#define NUM_SKIP_BYTES (1) +#define NUM_RSP_BYTES (2) +#define NUM_DATA_HDR_BYTES (1) +#define NUM_DATA_BYTES (4) +#define NUM_CRC_BYTES (2) +#define NUM_DUMMY_BYTES (3) + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES); + } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + if (!g_spi.crc_off) { + len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + + NUM_CRC_BYTES + NUM_DUMMY_BYTES); + } else { + len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + + NUM_DUMMY_BYTES); + } + } else { + len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES); + } +#undef NUM_DUMMY_BYTES + + if (len2 > (sizeof(wb) / sizeof(wb[0]))) { + PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%lu)\n", + len2, (sizeof(wb) / sizeof(wb[0]))); + result = N_FAIL; + return result; + } + /* zero spi write buffers. */ + for (wix = len; wix < len2; wix++) { + wb[wix] = 0; + } + rix = len; + + if (!g_spi.spi_trx(wb, rb, len2)) { + PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n"); + result = N_FAIL; + return result; + } + +#if 0 + { + int jj; + PRINT_D(BUS_DBG, "--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2); + for (jj = 0; jj < sizeof(wb) / sizeof(wb[0]); jj++) { + + if (jj >= len2) + break; + if (((jj + 1) % 16) != 0) { + if ((jj % 16) == 0) { + PRINT_D(BUS_DBG, "wb[%02x]: %02x ", jj, wb[jj]); + } else { + PRINT_D(BUS_DBG, "%02x ", wb[jj]); + } + } else { + PRINT_D(BUS_DBG, "%02x\n", wb[jj]); + } + } + + for (jj = 0; jj < sizeof(rb) / sizeof(rb[0]); jj++) { + + if (jj >= len2) + break; + if (((jj + 1) % 16) != 0) { + if ((jj % 16) == 0) { + PRINT_D(BUS_DBG, "rb[%02x]: %02x ", jj, rb[jj]); + } else { + PRINT_D(BUS_DBG, "%02x ", rb[jj]); + } + } else { + PRINT_D(BUS_DBG, "%02x\n", rb[jj]); + } + } + } +#endif + + /** + * Command/Control response + **/ + if ((cmd == CMD_RESET) || + (cmd == CMD_TERMINATE) || + (cmd == CMD_REPEAT)) { + rix++; /* skip 1 byte */ + } + + /* do { */ + rsp = rb[rix++]; + /* if(rsp == cmd) break; */ + /* } while(&rptr[1] <= &rb[len2]); */ + + if (rsp != cmd) { + PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)" + ", resp (%02x)\n", cmd, rsp); + result = N_FAIL; + return result; + } + + /** + * State response + **/ + rsp = rb[rix++]; + if (rsp != 0x00) { + PRINT_ER("[wilc spi]: Failed cmd state response " + "state (%02x)\n", rsp); + result = N_FAIL; + return result; + } + + if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ) + || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) { + int retry; + /* uint16_t crc1, crc2; */ + uint8_t crc[2]; + /** + * Data Respnose header + **/ + retry = 100; + do { + /* ensure there is room in buffer later to read data and crc */ + if (rix < len2) { + rsp = rb[rix++]; + } else { + retry = 0; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (retry <= 0) { + PRINT_ER("[wilc spi]: Error, data read " + "response (%02x)\n", rsp); + result = N_RESET; + return result; + } + + if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + /** + * Read bytes + **/ + if ((rix + 3) < len2) { + b[0] = rb[rix++]; + b[1] = rb[rix++]; + b[2] = rb[rix++]; + b[3] = rb[rix++]; + } else { + PRINT_ER("[wilc spi]: buffer overrun when reading data.\n"); + result = N_FAIL; + return result; + } + + if (!g_spi.crc_off) { + /** + * Read Crc + **/ + if ((rix + 1) < len2) { + crc[0] = rb[rix++]; + crc[1] = rb[rix++]; + } else { + PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n"); + result = N_FAIL; + return result; + } + } + } else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) { + int ix; + + /* some data may be read in response to dummy bytes. */ + for (ix = 0; (rix < len2) && (ix < sz); ) { + b[ix++] = rb[rix++]; + } +#if 0 + if (ix) + PRINT_D(BUS_DBG, "ttt %d %d\n", sz, ix); +#endif + sz -= ix; + + if (sz > 0) { + int nbytes; + + if (sz <= (DATA_PKT_SZ - ix)) { + nbytes = sz; + } else { + nbytes = DATA_PKT_SZ - ix; + } + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + goto _error_; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + goto _error_; + } + } + + + ix += nbytes; + sz -= nbytes; + } + + /* if any data in left unread, then read the rest using normal DMA code.*/ + while (sz > 0) { + int nbytes; + +#if 0 + PRINT_INFO(BUS_DBG, "rrr %d %d\n", sz, ix); +#endif + if (sz <= DATA_PKT_SZ) { + nbytes = sz; + } else { + nbytes = DATA_PKT_SZ; + } + + /** + * read data response only on the next DMA cycles not + * the first DMA since data response header is already + * handled above for the first DMA. + **/ + /** + * Data Respnose header + **/ + retry = 10; + do { + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); + result = N_FAIL; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (result == N_FAIL) + break; + + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + break; + } + } + + ix += nbytes; + sz -= nbytes; + } + } + } +_error_: + return result; +} + +static int spi_data_read(uint8_t *b, uint32_t sz) +{ + int retry, ix, nbytes; + int result = N_OK; + uint8_t crc[2]; + uint8_t rsp; + + /** + * Data + **/ + ix = 0; + do { + if (sz <= DATA_PKT_SZ) + nbytes = sz; + else + nbytes = DATA_PKT_SZ; + + /** + * Data Respnose header + **/ + retry = 10; + do { + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data response read, bus error...\n"); + result = N_FAIL; + break; + } + if (((rsp >> 4) & 0xf) == 0xf) + break; + } while (retry--); + + if (result == N_FAIL) + break; + + if (retry <= 0) { + PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp); + result = N_FAIL; + break; + } + + /** + * Read bytes + **/ + if (!g_spi.spi_rx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block read, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Read Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_rx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n"); + result = N_FAIL; + break; + } + } + + ix += nbytes; + sz -= nbytes; + + } while (sz); + + return result; +} + +static int spi_data_write(uint8_t *b, uint32_t sz) +{ + int ix, nbytes; + int result = 1; + uint8_t cmd, order, crc[2] = {0}; + /* uint8_t rsp; */ + + /** + * Data + **/ + ix = 0; + do { + if (sz <= DATA_PKT_SZ) + nbytes = sz; + else + nbytes = DATA_PKT_SZ; + + /** + * Write command + **/ + cmd = 0xf0; + if (ix == 0) { + if (sz <= DATA_PKT_SZ) + + order = 0x3; + else + order = 0x1; + } else { + if (sz <= DATA_PKT_SZ) + order = 0x3; + else + order = 0x2; + } + cmd |= order; + if (!g_spi.spi_tx(&cmd, 1)) { + PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Write data + **/ + if (!g_spi.spi_tx(&b[ix], nbytes)) { + PRINT_ER("[wilc spi]: Failed data block write, bus error...\n"); + result = N_FAIL; + break; + } + + /** + * Write Crc + **/ + if (!g_spi.crc_off) { + if (!g_spi.spi_tx(crc, 2)) { + PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n"); + result = N_FAIL; + break; + } + } + + /** + * No need to wait for response + **/ +#if 0 + /** + * Respnose + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data block write, response read, bus error...\n"); + result = N_FAIL; + break; + } + + if (((rsp >> 4) & 0xf) != 0xc) { + result = N_FAIL; + PRINT_ER("[wilc spi]: Failed data block write response...(%02x)\n", rsp); + break; + } + + /** + * State + **/ + if (!g_spi.spi_rx(&rsp, 1)) { + PRINT_ER("[wilc spi]: Failed data block write, read state, bus error...\n"); + result = N_FAIL; + break; + } +#endif + + ix += nbytes; + sz -= nbytes; + } while (sz); + + + return result; +} + +/******************************************** + * + * Spi Internal Read/Write Function + * + ********************************************/ + +static int spi_internal_write(uint32_t adr, uint32_t dat) +{ + int result; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(CMD_INTERNAL_WRITE, adr, dat, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); + return 0; + } + + result = spi_cmd_rsp(CMD_INTERNAL_WRITE, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd response...\n"); + } +#else + +#ifdef BIG_ENDIAN + dat = BYTE_SWAP(dat); +#endif + result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (uint8_t *)&dat, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal write cmd...\n"); + } + +#endif + return result; +} + +static int spi_internal_read(uint32_t adr, uint32_t *data) +{ + int result; + +#if defined USE_OLD_SPI_SW + result = spi_cmd(CMD_INTERNAL_READ, adr, 0, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); + return 0; + } + + result = spi_cmd_rsp(CMD_INTERNAL_READ, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd response...\n"); + return 0; + } + + /** + * Data + **/ + result = spi_data_read((uint8_t *)data, 4); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read data...\n"); + return 0; + } +#else + result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (uint8_t *)data, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed internal read cmd...\n"); + return 0; + } +#endif + + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; +} + +/******************************************** + * + * Spi interfaces + * + ********************************************/ + +static int spi_write_reg(uint32_t addr, uint32_t data) +{ + int result = N_OK; + uint8_t cmd = CMD_SINGLE_WRITE; + uint8_t clockless = 0; + + +#if defined USE_OLD_SPI_SW + { + result = spi_cmd(cmd, addr, data, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, write reg (%08x)...\n", addr); + return 0; + } + + return 1; + } +#else +#ifdef BIG_ENDIAN + data = BYTE_SWAP(data); +#endif + if (addr < 0x30) { + /* Clockless register*/ + cmd = CMD_INTERNAL_WRITE; + clockless = 1; + } + + result = spi_cmd_complete(cmd, addr, (uint8_t *)&data, 4, clockless); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr); + } + + return result; +#endif + +} + +static int spi_write(uint32_t addr, uint8_t *buf, uint32_t size) +{ + int result; + uint8_t cmd = CMD_DMA_EXT_WRITE; + + /** + * has to be greated than 4 + **/ + if (size <= 4) + return 0; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(cmd, addr, 0, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi ]: Failed cmd response, write block (%08x)...\n", addr); + return 0; + } +#else + result = spi_cmd_complete(cmd, addr, NULL, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr); + return 0; + } +#endif + + /** + * Data + **/ + result = spi_data_write(buf, size); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed block data write...\n"); + } + + return 1; +} + +static int spi_read_reg(uint32_t addr, uint32_t *data) +{ + int result = N_OK; + uint8_t cmd = CMD_SINGLE_READ; + uint8_t clockless = 0; + +#if defined USE_OLD_SPI_SW + result = spi_cmd(cmd, addr, 0, 4, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); + return 0; + } + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, read reg (%08x)...\n", addr); + return 0; + } + + result = spi_data_read((uint8_t *)data, 4); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed data read...\n"); + return 0; + } +#else + if (addr < 0x30) { + /* PRINT_ER("***** read addr %d\n\n", addr); */ + /* Clockless register*/ + cmd = CMD_INTERNAL_READ; + clockless = 1; + } + + result = spi_cmd_complete(cmd, addr, (uint8_t *)data, 4, clockless); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr); + return 0; + } +#endif + + +#ifdef BIG_ENDIAN + *data = BYTE_SWAP(*data); +#endif + + return 1; +} + +static int spi_read(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint8_t cmd = CMD_DMA_EXT_READ; + int result; + + if (size <= 4) + return 0; + +#if defined USE_OLD_SPI_SW + /** + * Command + **/ + result = spi_cmd(cmd, addr, 0, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); + return 0; + } + + result = spi_cmd_rsp(cmd, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd response, read block (%08x)...\n", addr); + return 0; + } + + /** + * Data + **/ + result = spi_data_read(buf, size); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed block data read...\n"); + return 0; + } +#else + result = spi_cmd_complete(cmd, addr, buf, size, 0); + if (result != N_OK) { + PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr); + return 0; + } +#endif + + + return 1; +} + +/******************************************** + * + * Bus interfaces + * + ********************************************/ + +static int spi_clear_int(void) +{ + uint32_t reg; + if (!spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0); + return 0; + } + reg &= ~0x1; + spi_write_reg(WILC_HOST_RX_CTRL_0, reg); + int_clrd++; + return 1; +} + +static int spi_deinit(void *pv) +{ + /** + * TODO: + **/ + return 1; +} + +static int spi_sync(void) +{ + uint32_t reg; + int ret; + + /** + * interrupt pin mux select + **/ + ret = spi_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = spi_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = spi_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + reg |= (1 << 16); + ret = spi_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + return 1; +} + +static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func) +{ + uint32_t reg; + uint32_t chipid; + + static int isinit; + + if (isinit) { + + if (!spi_read_reg(0x1000, &chipid)) { + PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + return 0; + } + return 1; + } + + memset(&g_spi, 0, sizeof(wilc_spi_t)); + + g_spi.dPrint = func; + g_spi.os_context = inp->os_context.os_private; + if (inp->io_func.io_init) { + if (!inp->io_func.io_init(g_spi.os_context)) { + PRINT_ER("[wilc spi]: Failed io init bus...\n"); + return 0; + } + } else { + return 0; + } + g_spi.spi_tx = inp->io_func.u.spi.spi_tx; + g_spi.spi_rx = inp->io_func.u.spi.spi_rx; + g_spi.spi_trx = inp->io_func.u.spi.spi_trx; + g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed; + + /** + * configure protocol + **/ + g_spi.crc_off = 0; + + /* TODO: We can remove the CRC trials if there is a definite way to reset */ + /* the SPI to it's initial value. */ + if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + /* Read failed. Try with CRC off. This might happen when module + * is removed but chip isn't reset*/ + g_spi.crc_off = 1; + PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n"); + if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) { + /* Reaad failed with both CRC on and off, something went bad */ + PRINT_ER("[wilc spi]: Failed internal read protocol...\n"); + return 0; + } + } + if (g_spi.crc_off == 0) { + reg &= ~0xc; /* disable crc checking */ + reg &= ~0x70; + reg |= (0x5 << 4); + if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) { + PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__); + return 0; + } + g_spi.crc_off = 1; + } + + + /** + * make sure can read back chip id correctly + **/ + if (!spi_read_reg(0x1000, &chipid)) { + PRINT_ER("[wilc spi]: Fail cmd read chip id...\n"); + return 0; + } + /* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */ + + g_spi.has_thrpt_enh = 1; + + isinit = 1; + + return 1; +} + +static void spi_max_bus_speed(void) +{ + g_spi.spi_max_speed(); +} + +static void spi_default_bus_speed(void) +{ +} + +static int spi_read_size(uint32_t *size) +{ + int ret; + if (g_spi.has_thrpt_enh) { + ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size); + *size = *size & IRQ_DMA_WD_CNT_MASK; + } else { + uint32_t tmp; + uint32_t byte_cnt; + + ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + goto _fail_; + } + tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; + *size = tmp; + } + + + +_fail_: + return ret; +} + + + +static int spi_read_int(uint32_t *int_status) +{ + int ret; + if (g_spi.has_thrpt_enh) { + ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status); + } else { + uint32_t tmp; + uint32_t byte_cnt; + + ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n"); + goto _fail_; + } + tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK; + + { + int happended, j; + + j = 0; + do { + uint32_t irq_flags; + + happended = 0; + + spi_read_reg(0x1a90, &irq_flags); + tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET); + + if (g_spi.nint > 5) { + spi_read_reg(0x1a94, &irq_flags); + tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5)); + } + + { + uint32_t unkmown_mask; + + unkmown_mask = ~((1ul << g_spi.nint) - 1); + + if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) { + PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask); + happended = 1; + } + } + j++; + } while (happended); + } + + *int_status = tmp; + + } + +_fail_: + return ret; +} + +static int spi_clear_int_ext(uint32_t val) +{ + int ret; + + if (g_spi.has_thrpt_enh) { + ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val); + } else { + uint32_t flags; + flags = val & ((1 << MAX_NUM_INT) - 1); + if (flags) { + int i; + + ret = 1; + for (i = 0; i < g_spi.nint; i++) { + /* No matter what you write 1 or 0, it will clear interrupt. */ + if (flags & 1) + ret = spi_write_reg(0x10c8 + i * 4, 1); + if (!ret) + break; + flags >>= 1; + } + if (!ret) { + PRINT_ER("[wilc spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4); + goto _fail_; + } + for (i = g_spi.nint; i < MAX_NUM_INT; i++) { + if (flags & 1) + PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i); + flags >>= 1; + } + } + + { + uint32_t tbl_ctl; + + tbl_ctl = 0; + /* select VMM table 0 */ + if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) + tbl_ctl |= (1 << 0); + /* select VMM table 1 */ + if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) + tbl_ctl |= (1 << 1); + + ret = spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl); + if (!ret) { + PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n"); + goto _fail_; + } + + if ((val & EN_VMM) == EN_VMM) { + /** + * enable vmm transfer. + **/ + ret = spi_write_reg(WILC_VMM_CORE_CTL, 1); + if (!ret) { + PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n"); + goto _fail_; + } + } + } + } +_fail_: + return ret; +} + +static int spi_sync_ext(int nint /* how mant interrupts to enable. */) +{ + uint32_t reg; + int ret, i; + + if (nint > MAX_NUM_INT) { + PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint); + return 0; + } + + g_spi.nint = nint; + + /** + * interrupt pin mux select + **/ + ret = spi_read_reg(WILC_PIN_MUX_0, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + reg |= (1 << 8); + ret = spi_write_reg(WILC_PIN_MUX_0, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0); + return 0; + } + + /** + * interrupt enable + **/ + ret = spi_read_reg(WILC_INTR_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + + for (i = 0; (i < 5) && (nint > 0); i++, nint--) { + reg |= (1 << (27 + i)); + } + ret = spi_write_reg(WILC_INTR_ENABLE, reg); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE); + return 0; + } + if (nint) { + ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + + for (i = 0; (i < 3) && (nint > 0); i++, nint--) { + reg |= (1 << i); + } + + ret = spi_read_reg(WILC_INTR2_ENABLE, ®); + if (!ret) { + PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE); + return 0; + } + } + + return 1; +} +/******************************************** + * + * Global spi HIF function table + * + ********************************************/ +wilc_hif_func_t hif_spi = { + spi_init, + spi_deinit, + spi_read_reg, + spi_write_reg, + spi_read, + spi_write, + spi_sync, + spi_clear_int, + spi_read_int, + spi_clear_int_ext, + spi_read_size, + spi_write, + spi_read, + spi_sync_ext, + spi_max_bus_speed, + spi_default_bus_speed, +}; + diff --git a/drivers/staging/wilc1000/wilc_strutils.c b/drivers/staging/wilc1000/wilc_strutils.c new file mode 100644 index 000000000000..c6af13cba543 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_strutils.c @@ -0,0 +1,80 @@ + +#define _CRT_SECURE_NO_DEPRECATE + +#include "wilc_oswrapper.h" + + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_memcmp(const void *pvArg1, const void *pvArg2, WILC_Uint32 u32Count) +{ + return memcmp(pvArg1, pvArg2, u32Count); +} + + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_memcpy_INTERNAL(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count) +{ + memcpy(pvTarget, pvSource, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_memset(void *pvTarget, u8 u8SetValue, WILC_Uint32 u32Count) +{ + return memset(pvTarget, u8SetValue, u32Count); +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncpy(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count) +{ + return strncpy(pcTarget, pcSource, u32Count); +} + +WILC_Sint32 WILC_strncmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count) +{ + WILC_Sint32 s32Result; + + if (pcStr1 == NULL && pcStr2 == NULL) { + s32Result = 0; + } else if (pcStr1 == NULL) { + s32Result = -1; + } else if (pcStr2 == NULL) { + s32Result = 1; + } else { + s32Result = strncmp(pcStr1, pcStr2, u32Count); + if (s32Result < 0) { + s32Result = -1; + } else if (s32Result > 0) { + s32Result = 1; + } + } + + return s32Result; +} + +/*! + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strlen(const WILC_Char *pcStr) +{ + return (WILC_Uint32)strlen(pcStr); +} diff --git a/drivers/staging/wilc1000/wilc_strutils.h b/drivers/staging/wilc1000/wilc_strutils.h new file mode 100644 index 000000000000..ddc54ab21f67 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_strutils.h @@ -0,0 +1,130 @@ +#ifndef __WILC_STRUTILS_H__ +#define __WILC_STRUTILS_H__ + +/*! + * @file wilc_strutils.h + * @brief Basic string utilities + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +/*! + * @brief Compares two memory buffers + * @param[in] pvArg1 pointer to the first memory location + * @param[in] pvArg2 pointer to the second memory location + * @param[in] u32Count the size of the memory buffers + * @return 0 if the 2 buffers are equal, 1 if pvArg1 is bigger than pvArg2, + * -1 if pvArg1 smaller than pvArg2 + * @note this function repeats the functionality of standard memcmp + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_memcmp(const void *pvArg1, const void *pvArg2, WILC_Uint32 u32Count); + +/*! + * @brief Internal implementation for memory copy + * @param[in] pvTarget the target buffer to which the data is copied into + * @param[in] pvSource pointer to the second memory location + * @param[in] u32Count the size of the data to copy + * @note this function should not be used directly, use WILC_memcpy instead + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void WILC_memcpy_INTERNAL(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count); + +/*! + * @brief Copies the contents of a memory buffer into another + * @param[in] pvTarget the target buffer to which the data is copied into + * @param[in] pvSource pointer to the second memory location + * @param[in] u32Count the size of the data to copy + * @return WILC_SUCCESS if copy is successfully handeled + * WILC_FAIL if copy failed + * @note this function repeats the functionality of standard memcpy, + * however memcpy is undefined if the two buffers overlap but this + * implementation will check for overlap and report error + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +static WILC_ErrNo WILC_memcpy(void *pvTarget, const void *pvSource, WILC_Uint32 u32Count) +{ + if ( + (((u8 *)pvTarget <= (u8 *)pvSource) + && (((u8 *)pvTarget + u32Count) > (u8 *)pvSource)) + + || (((u8 *)pvSource <= (u8 *)pvTarget) + && (((u8 *)pvSource + u32Count) > (u8 *)pvTarget)) + ) { + /* ovelapped memory, return Error */ + return WILC_FAIL; + } else { + WILC_memcpy_INTERNAL(pvTarget, pvSource, u32Count); + return WILC_SUCCESS; + } +} + +/*! + * @brief Sets the contents of a memory buffer with the given value + * @param[in] pvTarget the target buffer which contsnts will be set + * @param[in] u8SetValue the value to be used + * @param[in] u32Count the size of the memory buffer + * @return value of pvTarget + * @note this function repeats the functionality of standard memset + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +void *WILC_memset(void *pvTarget, u8 u8SetValue, WILC_Uint32 u32Count); + +/*! + * @brief copies the contents of source string into the target string + * @param[in] pcTarget the target string buffer + * @param[in] pcSource the source string the will be copied + * @param[in] u32Count copying will proceed until a null character in pcSource + * is encountered or u32Count of bytes copied + * @return value of pcTarget + * @note this function repeats the functionality of standard strncpy + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Char *WILC_strncpy(WILC_Char *pcTarget, const WILC_Char *pcSource, + WILC_Uint32 u32Count); + +/*! + * @brief Compares two strings up to u32Count characters + * @details Compares 2 strings reporting which is bigger, NULL is considered + * the smallest string, then a zero length string then all other + * strings depending on thier ascii characters order with small case + * converted to uppder case + * @param[in] pcStr1 the first string, NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] pcStr2 the second string, NULL is valid and considered smaller + * than any other non-NULL string (incliding zero lenght strings) + * @param[in] u32Count copying will proceed until a null character in pcStr1 or + * pcStr2 is encountered or u32Count of bytes copied + * @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2, + * -1 if pcStr1 smaller than pcStr2 + * @author aabozaeid + * @date 7 Dec 2010 + * @version 1.0 + */ +WILC_Sint32 WILC_strncmp(const WILC_Char *pcStr1, const WILC_Char *pcStr2, + WILC_Uint32 u32Count); + +/*! + * @brief gets the length of a string + * @param[in] pcStr the string + * @return the length + * @note this function repeats the functionality of standard strlen + * @author syounan + * @date 18 Aug 2010 + * @version 1.0 + */ +WILC_Uint32 WILC_strlen(const WILC_Char *pcStr); + +#endif diff --git a/drivers/staging/wilc1000/wilc_timer.c b/drivers/staging/wilc1000/wilc_timer.c new file mode 100644 index 000000000000..7d2e6f19c00b --- /dev/null +++ b/drivers/staging/wilc1000/wilc_timer.c @@ -0,0 +1,45 @@ + +#include "wilc_oswrapper.h" + +WILC_ErrNo WILC_TimerCreate(WILC_TimerHandle *pHandle, + tpfWILC_TimerFunction pfCallback, tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + setup_timer(pHandle, (void(*)(unsigned long))pfCallback, 0); + + return s32RetStatus; +} + +WILC_ErrNo WILC_TimerDestroy(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) { + s32RetStatus = del_timer_sync(pHandle); + pHandle = NULL; + } + + return s32RetStatus; +} + + +WILC_ErrNo WILC_TimerStart(WILC_TimerHandle *pHandle, WILC_Uint32 u32Timeout, + void *pvArg, tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) { + pHandle->data = (unsigned long)pvArg; + s32RetStatus = mod_timer(pHandle, (jiffies + msecs_to_jiffies(u32Timeout))); + } + return s32RetStatus; +} + +WILC_ErrNo WILC_TimerStop(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_FAIL; + if (pHandle != NULL) + s32RetStatus = del_timer(pHandle); + + return s32RetStatus; +} diff --git a/drivers/staging/wilc1000/wilc_timer.h b/drivers/staging/wilc1000/wilc_timer.h new file mode 100644 index 000000000000..72b27155293e --- /dev/null +++ b/drivers/staging/wilc1000/wilc_timer.h @@ -0,0 +1,126 @@ +#ifndef __WILC_TIMER_H__ +#define __WILC_TIMER_H__ + +/*! + * @file wilc_timer.h + * @brief Timer (One Shot and Periodic) OS wrapper functionality + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 16 Aug 2010 + * @version 1.0 + */ + +typedef void (*tpfWILC_TimerFunction)(void *); + +/*! + * @struct tstrWILC_TimerAttrs + * @brief Timer API options + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +typedef struct { + /* a dummy member to avoid compiler errors*/ + u8 dummy; +} tstrWILC_TimerAttrs; + +/*! + * @brief Creates a new timer + * @details Timers are a useful utility to execute some callback function + * in the future. + * A timer object has 3 states : IDLE, PENDING and EXECUTING + * IDLE : initial timer state after creation, no execution for the + * callback function is planned + * PENDING : a request to execute the callback function is made + * using WILC_TimerStart. + * EXECUTING : the timer has expired and its callback is now + * executing, when execution is done the timer returns to PENDING + * if the feature CONFIG_WILC_TIMER_PERIODIC is enabled and + * the flag tstrWILC_TimerAttrs.bPeriodicTimer is set. otherwise the + * timer will return to IDLE + * @param[out] pHandle handle to the newly created timer object + * @param[in] pfEntry pointer to the callback function to be called when the + * timer expires + * the underlaying OS may put many restrictions on what can be + * called inside a timer's callback, as a general rule no blocking + * operations (IO or semaphore Acquision) should be perfomred + * It is recommended that the callback will be as short as possible + * and only flags other threads to do the actual work + * also it should be noted that the underlaying OS maynot give any + * guarentees on which contect this callback will execute in + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerCreate(WILC_TimerHandle *pHandle, + tpfWILC_TimerFunction pfCallback, tstrWILC_TimerAttrs *pstrAttrs); + + +/*! + * @brief Destroys a given timer + * @details This will destroy a given timer freeing any resources used by it + * if the timer was PENDING Then must be cancelled as well(i.e. + * goes to IDLE, same effect as calling WILC_TimerCancel first) + * if the timer was EXECUTING then the callback will be allowed to + * finish first then all resources are freed + * @param[in] pHandle handle to the timer object + * @param[in] pstrAttrs Optional attributes, NULL for default + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerDestroy(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs); + +/*! + * @brief Starts a given timer + * @details This function will move the timer to the PENDING state until the + * given time expires (in msec) then the callback function will be + * executed (timer in EXECUTING state) after execution is dene the + * timer either goes to IDLE (if bPeriodicTimer==WILC_FALSE) or + * PENDING with same timeout value (if bPeriodicTimer==WILC_TRUE) + * @param[in] pHandle handle to the timer object + * @param[in] u32Timeout timeout value in msec after witch the callback + * function will be executed. Timeout value of 0 is not allowed for + * periodic timers + * @param[in] pstrAttrs Optional attributes, NULL for default, + * set bPeriodicTimer to run this timer as a periodic timer + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerStart(WILC_TimerHandle *pHandle, WILC_Uint32 u32Timeout, void *pvArg, + tstrWILC_TimerAttrs *pstrAttrs); + + +/*! + * @brief Stops a given timer + * @details This function will move the timer to the IDLE state cancelling + * any sheduled callback execution. + * if this function is called on a timer already in the IDLE state + * it will have no effect. + * if this function is called on a timer in EXECUTING state + * (callback has already started) it will wait until executing is + * done then move the timer to the IDLE state (which is trivial + * work if the timer is non periodic) + * @param[in] pHandle handle to the timer object + * @param[in] pstrAttrs Optional attributes, NULL for default, + * @return Error code indicating sucess/failure + * @sa WILC_TimerAttrs + * @author syounan + * @date 16 Aug 2010 + * @version 1.0 + */ +WILC_ErrNo WILC_TimerStop(WILC_TimerHandle *pHandle, + tstrWILC_TimerAttrs *pstrAttrs); + + + +#endif diff --git a/drivers/staging/wilc1000/wilc_type.h b/drivers/staging/wilc1000/wilc_type.h new file mode 100644 index 000000000000..5f36e7f92cd1 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_type.h @@ -0,0 +1,34 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_type.h */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ +#ifndef WILC_TYPE_H +#define WILC_TYPE_H + +/******************************************** + * + * Type Defines + * + ********************************************/ +#ifdef WIN32 +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#else +#ifdef _linux_ +/*typedef unsigned char uint8_t; + * typedef unsigned short uint16_t; + * typedef unsigned long uint32_t;*/ +#include <stdint.h> +#else +#include "wilc_oswrapper.h" +#endif +#endif +#endif diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c new file mode 100644 index 000000000000..5844eba90b91 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -0,0 +1,3957 @@ +/*! + * @file wilc_wfi_cfgopertaions.c + * @brief CFG80211 Function Implementation functionality + * @author aabouzaeid + * mabubakr + * mdaftedar + * zsalah + * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file + * @date 31 Aug 2010 + * @version 1.0 + */ + +#include "wilc_wfi_cfgoperations.h" +#include "wilc_wlan.c" +#ifdef WILC_SDIO +#include "linux_wlan_sdio.h" /* tony : for set_wiphy_dev() */ +#endif + + +#define IS_MANAGMEMENT 0x100 +#define IS_MANAGMEMENT_CALLBACK 0x080 +#define IS_MGMT_STATUS_SUCCES 0x040 +#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) + +extern void linux_wlan_free(void *vp); +extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic); +extern void linux_wlan_unlock(void *vp); +extern WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue); + +extern int mac_open(struct net_device *ndev); +extern int mac_close(struct net_device *ndev); + +tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; +WILC_Uint32 u32LastScannedNtwrksCountShadow; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +WILC_TimerHandle hDuringIpTimer; +#endif +WILC_TimerHandle hAgingTimer; +static u8 op_ifcs; +extern u8 u8ConnectedSSID[6]; + +/*BugID_5137*/ +u8 g_wilc_initialized = 1; +extern linux_wlan_t *g_linux_wlan; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_Bool g_obtainingIP; +#endif + +#define CHAN2G(_channel, _freq, _flags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +/*Frequency range for channels*/ +static struct ieee80211_channel WILC_WFI_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0), + CHAN2G(7, 2442, 0), + CHAN2G(8, 2447, 0), + CHAN2G(9, 2452, 0), + CHAN2G(10, 2457, 0), + CHAN2G(11, 2462, 0), + CHAN2G(12, 2467, 0), + CHAN2G(13, 2472, 0), + CHAN2G(14, 2484, 0), +}; + +#define RATETAB_ENT(_rate, _hw_value, _flags) { \ + .bitrate = (_rate), \ + .hw_value = (_hw_value), \ + .flags = (_flags), \ +} + + +/* Table 6 in section 3.2.1.1 */ +static struct ieee80211_rate WILC_WFI_rates[] = { + RATETAB_ENT(10, 0, 0), + RATETAB_ENT(20, 1, 0), + RATETAB_ENT(55, 2, 0), + RATETAB_ENT(110, 3, 0), + RATETAB_ENT(60, 9, 0), + RATETAB_ENT(90, 6, 0), + RATETAB_ENT(120, 7, 0), + RATETAB_ENT(180, 8, 0), + RATETAB_ENT(240, 9, 0), + RATETAB_ENT(360, 10, 0), + RATETAB_ENT(480, 11, 0), + RATETAB_ENT(540, 12, 0), +}; + +#ifdef WILC_P2P +struct p2p_mgmt_data { + int size; + u8 *buff; +}; + +/*Global variable used to state the current connected STA channel*/ +u8 u8WLANChannel = INVALID_CHANNEL; + +/*BugID_5442*/ +u8 u8CurrChannel; + +u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09}; +u8 u8P2Plocalrandom = 0x01; +u8 u8P2Precvrandom = 0x00; +u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; +WILC_Bool bWilc_ie = WILC_FALSE; +#endif + +static struct ieee80211_supported_band WILC_WFI_band_2ghz = { + .channels = WILC_WFI_2ghz_channels, + .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels), + .bitrates = WILC_WFI_rates, + .n_bitrates = ARRAY_SIZE(WILC_WFI_rates), +}; + + +/*BugID_5137*/ +struct add_key_params { + u8 key_idx; + bool pairwise; + u8 *mac_addr; +}; +struct add_key_params g_add_gtk_key_params; +struct wilc_wfi_key g_key_gtk_params; +struct add_key_params g_add_ptk_key_params; +struct wilc_wfi_key g_key_ptk_params; +struct wilc_wfi_wep_key g_key_wep_params; +u8 g_flushing_in_progress; +WILC_Bool g_ptk_keys_saved = WILC_FALSE; +WILC_Bool g_gtk_keys_saved = WILC_FALSE; +WILC_Bool g_wep_keys_saved = WILC_FALSE; + +#define AGING_TIME (9 * 1000) +#define duringIP_TIME 15000 + +void clear_shadow_scan(void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + int i; + priv = (struct WILC_WFI_priv *)pUserVoid; + if (op_ifcs == 0) { + WILC_TimerDestroy(&hAgingTimer, NULL); + PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n"); + + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + if (astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL) { + WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs); + astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs = NULL; + } + + host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams); + astrLastScannedNtwrksShadow[i].pJoinParams = NULL; + } + u32LastScannedNtwrksCountShadow = 0; + } + +} + +uint32_t get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo) +{ + uint8_t i; + int rssi_v = 0; + uint8_t num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index); + + for (i = 0; i < num_rssi; i++) + rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i]; + + rssi_v /= num_rssi; + return rssi_v; +} + +void refresh_scan(void *pUserVoid, uint8_t all, WILC_Bool bDirectScan) +{ + struct WILC_WFI_priv *priv; + struct wiphy *wiphy; + struct cfg80211_bss *bss = NULL; + int i; + int rssi = 0; + + priv = (struct WILC_WFI_priv *)pUserVoid; + wiphy = priv->dev->ieee80211_ptr->wiphy; + + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + tstrNetworkInfo *pstrNetworkInfo; + pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); + + + if ((!pstrNetworkInfo->u8Found) || all) { + WILC_Sint32 s32Freq; + struct ieee80211_channel *channel; + + if (pstrNetworkInfo != NULL) { + + s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ); + channel = ieee80211_get_channel(wiphy, s32Freq); + + rssi = get_rssi_avg(pstrNetworkInfo); + if (WILC_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) { + bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)rssi) * 100), GFP_KERNEL); + cfg80211_put_bss(wiphy, bss); + } + } + + } + } + +} + +void reset_shadow_found(void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + int i; + priv = (struct WILC_WFI_priv *)pUserVoid; + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + astrLastScannedNtwrksShadow[i].u8Found = 0; + + } +} + +void update_scan_time(void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + int i; + priv = (struct WILC_WFI_priv *)pUserVoid; + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies; + } +} + +void remove_network_from_shadow(void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + unsigned long now = jiffies; + int i, j; + + priv = (struct WILC_WFI_priv *)pUserVoid; + + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) { + PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s \n", astrLastScannedNtwrksShadow[i].au8ssid); + + if (astrLastScannedNtwrksShadow[i].pu8IEs != NULL) { + WILC_FREE(astrLastScannedNtwrksShadow[i].pu8IEs); + astrLastScannedNtwrksShadow[i].pu8IEs = NULL; + } + + host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams); + + for (j = i; (j < u32LastScannedNtwrksCountShadow - 1); j++) { + astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1]; + } + u32LastScannedNtwrksCountShadow--; + } + } + + PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n", u32LastScannedNtwrksCountShadow); + if (u32LastScannedNtwrksCountShadow != 0) + WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NULL); + else + PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n"); +} + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +void clear_duringIP(void *pUserVoid) +{ + PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n"); + g_obtainingIP = WILC_FALSE; +} +#endif + +int8_t is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + int8_t state = -1; + int i; + + priv = (struct WILC_WFI_priv *)pUserVoid; + if (u32LastScannedNtwrksCountShadow == 0) { + PRINT_D(CFG80211_DBG, "Starting Aging timer\n"); + WILC_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NULL); + state = -1; + } else { + /* Linear search for now */ + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) { + state = i; + break; + } + } + } + return state; +} + +void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) +{ + struct WILC_WFI_priv *priv; + int8_t ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid); + uint32_t ap_index = 0; + uint8_t rssi_index = 0; + priv = (struct WILC_WFI_priv *)pUserVoid; + + if (u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW) { + PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n"); + return; + } + if (ap_found == -1) { + ap_index = u32LastScannedNtwrksCountShadow; + u32LastScannedNtwrksCountShadow++; + + } else { + ap_index = ap_found; + } + rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index; + astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi; + if (rssi_index == NUM_RSSI) { + rssi_index = 0; + astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1; + } + astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index; + + astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi; + astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo; + + astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen; + WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid, + pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen); + + WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid, + pstrNetworkInfo->au8bssid, ETH_ALEN); + + astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod; + astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod; + astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel; + + astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen; + astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf; + if (ap_found != -1) + WILC_FREE(astrLastScannedNtwrksShadow[ap_index].pu8IEs); + astrLastScannedNtwrksShadow[ap_index].pu8IEs = + (u8 *)WILC_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated by the WILC_WFI_CfgScan() function */ + WILC_memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs, + pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); + + astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies; + astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies; + astrLastScannedNtwrksShadow[ap_index].u8Found = 1; + if (ap_found != -1) + host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams); + astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams; + +} + + +/** + * @brief CfgScanResult + * @details Callback function which returns the scan results found + * + * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is + * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE + * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information + * void* pUserVoid: Private structure associated with the wireless interface + * @return NONE + * @author mabubakr + * @date + * @version 1.0 + */ +static void CfgScanResult(tenuScanEvent enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams) +{ + struct WILC_WFI_priv *priv; + struct wiphy *wiphy; + WILC_Sint32 s32Freq; + struct ieee80211_channel *channel; + WILC_Sint32 s32Error = WILC_SUCCESS; + struct cfg80211_bss *bss = NULL; + + priv = (struct WILC_WFI_priv *)pUserVoid; + if (priv->bCfgScanning == WILC_TRUE) { + if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) { + wiphy = priv->dev->ieee80211_ptr->wiphy; + WILC_NULLCHECK(s32Error, wiphy); + if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC + && + ((((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100) < 0 + || + (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100) > 100) + ) { + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + if (pstrNetworkInfo != NULL) { + s32Freq = ieee80211_channel_to_frequency((WILC_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ); + channel = ieee80211_get_channel(wiphy, s32Freq); + + WILC_NULLCHECK(s32Error, channel); + + PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d," + "BeaconPeriod: %d \n", channel->center_freq, (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100), + pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod); + + if (pstrNetworkInfo->bNewNetwork == WILC_TRUE) { + if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ + /* max_scan_ssids */ + PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid); + + + priv->u32RcvdChCount++; + + + + if (pJoinParams == NULL) { + PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n"); + } + add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams); + + /*P2P peers are sent to WPA supplicant and added to shadow table*/ + + if (!(WILC_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) { + bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((WILC_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + cfg80211_put_bss(wiphy, bss); + } + + + } else { + PRINT_ER("Discovered networks exceeded the max limit\n"); + } + } else { + WILC_Uint32 i; + /* So this network is discovered before, we'll just update its RSSI */ + for (i = 0; i < priv->u32RcvdChCount; i++) { + if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) { + PRINT_D(CFG80211_DBG, "Update RSSI of %s \n", astrLastScannedNtwrksShadow[i].au8ssid); + + astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi; + astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies; + break; + } + } + } + } + } else if (enuScanEvent == SCAN_EVENT_DONE) { + PRINT_D(CFG80211_DBG, "Scan Done[%p] \n", priv->dev); + PRINT_D(CFG80211_DBG, "Refreshing Scan ... \n"); + refresh_scan(priv, 1, WILC_FALSE); + + if (priv->u32RcvdChCount > 0) { + PRINT_D(CFG80211_DBG, "%d Network(s) found \n", priv->u32RcvdChCount); + } else { + PRINT_D(CFG80211_DBG, "No networks found \n"); + } + + down(&(priv->hSemScanReq)); + + if (priv->pstrScanReq != NULL) { + cfg80211_scan_done(priv->pstrScanReq, WILC_FALSE); + priv->u32RcvdChCount = 0; + priv->bCfgScanning = WILC_FALSE; + priv->pstrScanReq = NULL; + } + up(&(priv->hSemScanReq)); + + } + /*Aborting any scan operation during mac close*/ + else if (enuScanEvent == SCAN_EVENT_ABORTED) { + down(&(priv->hSemScanReq)); + + PRINT_D(CFG80211_DBG, "Scan Aborted \n"); + if (priv->pstrScanReq != NULL) { + + update_scan_time(priv); + refresh_scan(priv, 1, WILC_FALSE); + + cfg80211_scan_done(priv->pstrScanReq, WILC_FALSE); + priv->bCfgScanning = WILC_FALSE; + priv->pstrScanReq = NULL; + } + up(&(priv->hSemScanReq)); + } + } + + + WILC_CATCH(s32Error) + { + } +} + + +/** + * @brief WILC_WFI_Set_PMKSA + * @details Check if pmksa is cached and set it. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Set_PMKSA(u8 *bssid, struct WILC_WFI_priv *priv) +{ + WILC_Uint32 i; + WILC_Sint32 s32Error = WILC_SUCCESS; + + + for (i = 0; i < priv->pmkid_list.numpmkid; i++) { + + if (!WILC_memcmp(bssid, priv->pmkid_list.pmkidlist[i].bssid, + ETH_ALEN)) { + PRINT_D(CFG80211_DBG, "PMKID successful comparison"); + + /*If bssid is found, set the values*/ + s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); + + if (s32Error != WILC_SUCCESS) + PRINT_ER("Error in pmkid\n"); + + break; + } + } + + return s32Error; + + +} +int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID); + + +/** + * @brief CfgConnectResult + * @details + * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either + * connection response or disconnection notification. + * tstrConnectInfo* pstrConnectInfo: COnnection information. + * u8 u8MacStatus: Mac Status from firmware + * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification + * void* pUserVoid: Private data associated with wireless interface + * @return NONE + * @author mabubakr + * @date 01 MAR 2012 + * @version 1.0 + */ +int connecting; + +static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent, + tstrConnectInfo *pstrConnectInfo, + u8 u8MacStatus, + tstrDisconnectNotifInfo *pstrDisconnectNotifInfo, + void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + struct net_device *dev; + #ifdef WILC_P2P + tstrWILC_WFIDrv *pstrWFIDrv; + #endif + u8 NullBssid[ETH_ALEN] = {0}; + connecting = 0; + + priv = (struct WILC_WFI_priv *)pUserVoid; + dev = priv->dev; + #ifdef WILC_P2P + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + #endif + + if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) { + /*Initialization*/ + WILC_Uint16 u16ConnectStatus = WLAN_STATUS_SUCCESS; + + u16ConnectStatus = pstrConnectInfo->u16ConnectStatus; + + PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus); + + if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + /* The case here is that our station was waiting for association response frame and has just received it containing status code + * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */ + u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE; + linux_wlan_set_bssid(priv->dev, NullBssid); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + /*BugID_5457*/ + /*Invalidate u8WLANChannel value on wlan0 disconnect*/ + #ifdef WILC_P2P + if (!pstrWFIDrv->u8P2PConnect) + u8WLANChannel = INVALID_CHANNEL; + #endif + + PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d \n", u16ConnectStatus, u8MacStatus); + } + + if (u16ConnectStatus == WLAN_STATUS_SUCCESS) { + WILC_Bool bNeedScanRefresh = WILC_FALSE; + WILC_Uint32 i; + + PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0], + pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]); + WILC_memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN); + + /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling + * cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid + * Linux kernel warning generated at the nl80211 layer */ + + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, + pstrConnectInfo->au8bssid, ETH_ALEN) == 0) { + unsigned long now = jiffies; + + if (time_after(now, + astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) { + bNeedScanRefresh = WILC_TRUE; + } + + break; + } + } + + if (bNeedScanRefresh == WILC_TRUE) { + /*BugID_5418*/ + /*Also, refrsh DIRECT- results if */ + refresh_scan(priv, 1, WILC_TRUE); + + } + + } + + + PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen); + + PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen); + + cfg80211_connect_result(dev, pstrConnectInfo->au8bssid, + pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen, + pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen, + u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */ + /* be replaced by pstrConnectInfo->u16ConnectStatus */ + } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + g_obtainingIP = WILC_FALSE; + #endif + PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n", + pstrDisconnectNotifInfo->u16reason, priv->dev); + u8P2Plocalrandom = 0x01; + u8P2Precvrandom = 0x00; + bWilc_ie = WILC_FALSE; + WILC_memset(priv->au8AssociatedBss, 0, ETH_ALEN); + linux_wlan_set_bssid(priv->dev, NullBssid); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + /*BugID_5457*/ + /*Invalidate u8WLANChannel value on wlan0 disconnect*/ + #ifdef WILC_P2P + if (!pstrWFIDrv->u8P2PConnect) + u8WLANChannel = INVALID_CHANNEL; + #endif + /*BugID_5315*/ + /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change + * virtual interface to station*/ + if ((pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) { + pstrDisconnectNotifInfo->u16reason = 3; + } + /*BugID_5315*/ + /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT + * to scan again and retry the connection*/ + else if ((!pstrWFIDrv->IFC_UP) && (dev == g_linux_wlan->strInterfaceInfo[1].wilc_netdev)) { + pstrDisconnectNotifInfo->u16reason = 1; + } + cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie, + pstrDisconnectNotifInfo->ie_len, GFP_KERNEL); + + } + +} + + +/** + * @brief WILC_WFI_CfgSetChannel + * @details Set channel for a given wireless interface. Some devices + * may support multi-channel operation (by channel hopping) so cfg80211 + * doesn't verify much. Note, however, that the passed netdev may be + * %NULL as well if the user requested changing the channel for the + * device itself, or for a monitor interface. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_CfgSetChannel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + + WILC_Uint32 channelnum = 0; + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + priv = wiphy_priv(wiphy); + + channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq); + PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq); + + u8CurrChannel = channelnum; + s32Error = host_int_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum); + + if (s32Error != WILC_SUCCESS) + PRINT_ER("Error in setting channel %d\n", channelnum); + + return s32Error; +} + +/** + * @brief WILC_WFI_CfgScan + * @details Request to do a scan. If returning zero, the scan request is given + * the driver, and will be valid until passed to cfg80211_scan_done(). + * For scan results, call cfg80211_inform_bss(); you can call this outside + * the scan/scan_done bracket too. + * @param[in] + * @return int : Return 0 on Success + * @author mabubakr + * @date 01 MAR 2012 + * @version 1.0 + */ + +/* + * kernel version 3.8.8 supported + * tony, sswd, WILC-KR, 2013-10-29 + */ +static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *request) +{ + struct WILC_WFI_priv *priv; + WILC_Uint32 i; + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS]; + tstrHiddenNetwork strHiddenNetwork; + + priv = wiphy_priv(wiphy); + + priv->pstrScanReq = request; + + priv->u32RcvdChCount = 0; + + host_int_set_wfi_drv_handler((WILC_Uint32)priv->hWILCWFIDrv); + + + reset_shadow_found(priv); + + priv->bCfgScanning = WILC_TRUE; + if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */ + /* max_scan_ssids */ + for (i = 0; i < request->n_channels; i++) { + au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq); + PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]); + } + + PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels); + PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len); + + PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids); + + if (request->n_ssids >= 1) { + + + strHiddenNetwork.pstrHiddenNetworkInfo = WILC_MALLOC(request->n_ssids * sizeof(tstrHiddenNetwork)); + strHiddenNetwork.u8ssidnum = request->n_ssids; + + + /*BugID_4156*/ + for (i = 0; i < request->n_ssids; i++) { + + if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) { + strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = WILC_MALLOC(request->ssids[i].ssid_len); + WILC_memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len); + strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len; + } else { + PRINT_D(CFG80211_DBG, "Received one NULL SSID \n"); + strHiddenNetwork.u8ssidnum -= 1; + } + } + PRINT_D(CFG80211_DBG, "Trigger Scan Request \n"); + s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, request->n_channels, + (const u8 *)request->ie, request->ie_len, + CfgScanResult, (void *)priv, &strHiddenNetwork); + } else { + PRINT_D(CFG80211_DBG, "Trigger Scan Request \n"); + s32Error = host_int_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, request->n_channels, + (const u8 *)request->ie, request->ie_len, + CfgScanResult, (void *)priv, NULL); + } + + } else { + PRINT_ER("Requested num of scanned channels is greater than the max, supported" + " channels \n"); + } + + if (s32Error != WILC_SUCCESS) { + s32Error = -EBUSY; + PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error); + } + + return s32Error; +} + +/** + * @brief WILC_WFI_CfgConnect + * @details Connect to the ESS with the specified parameters. When connected, + * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. + * If the connection fails for some reason, call cfg80211_connect_result() + * with the status from the AP. + * @param[in] + * @return int : Return 0 on Success + * @author mabubakr + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_connect_params *sme) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint32 i; + u8 u8security = NO_ENCRYPT; + AUTHTYPE_T tenuAuth_type = ANY; + WILC_Char *pcgroup_encrypt_val = NULL; + WILC_Char *pccipher_group = NULL; + WILC_Char *pcwpa_version = NULL; + + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + tstrNetworkInfo *pstrNetworkInfo = NULL; + + + connecting = 1; + priv = wiphy_priv(wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)(priv->hWILCWFIDrv); + + host_int_set_wfi_drv_handler((WILC_Uint32)priv->hWILCWFIDrv); + + PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv); + #ifdef WILC_P2P + if (!(WILC_strncmp(sme->ssid, "DIRECT-", 7))) { + PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n"); + pstrWFIDrv->u8P2PConnect = 1; + } else + pstrWFIDrv->u8P2PConnect = 0; + #endif + PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d \n", sme->ssid, sme->auth_type); + + for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) { + if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) && + WILC_memcmp(astrLastScannedNtwrksShadow[i].au8ssid, + sme->ssid, + sme->ssid_len) == 0) { + PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid); + if (sme->bssid == NULL) { + /* BSSID is not passed from the user, so decision of matching + * is done by SSID only */ + PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n"); + break; + } else { + /* BSSID is also passed from the user, so decision of matching + * should consider also this passed BSSID */ + if (WILC_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, + sme->bssid, + ETH_ALEN) == 0) { + PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if (i < u32LastScannedNtwrksCountShadow) { + PRINT_D(CFG80211_DBG, "Required bss is in scan results\n"); + + pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]); + + PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n", + pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1], + pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3], + pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]); + } else { + s32Error = -ENOENT; + if (u32LastScannedNtwrksCountShadow == 0) + PRINT_D(CFG80211_DBG, "No Scan results yet\n"); + else + PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error); + + goto done; + } + + priv->WILC_WFI_wep_default = 0; + WILC_memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key)); + WILC_memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len)); + + PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions); + PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group); + + PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise); + + if (INFO) { + for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) + PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]); + } + + if (sme->crypto.cipher_group != NO_ENCRYPT) { + /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2} + * we will add to it the pairwise cipher suite(s) */ + pcwpa_version = "Default"; + PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions); + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) { + u8security = ENCRYPT_ENABLED | WEP; + pcgroup_encrypt_val = "WEP40"; + pccipher_group = "WLAN_CIPHER_SUITE_WEP40"; + PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx); + + if (INFO) { + for (i = 0; i < sme->key_len; i++) + PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]); + } + priv->WILC_WFI_wep_default = sme->key_idx; + priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len; + WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len); + + /*BugID_5137*/ + g_key_wep_params.key_len = sme->key_len; + g_key_wep_params.key = WILC_MALLOC(sme->key_len); + memcpy(g_key_wep_params.key, sme->key, sme->key_len); + g_key_wep_params.key_idx = sme->key_idx; + g_wep_keys_saved = WILC_TRUE; + + host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx); + host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) { + u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; + pcgroup_encrypt_val = "WEP104"; + pccipher_group = "WLAN_CIPHER_SUITE_WEP104"; + + priv->WILC_WFI_wep_default = sme->key_idx; + priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len; + WILC_memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len); + + /*BugID_5137*/ + g_key_wep_params.key_len = sme->key_len; + g_key_wep_params.key = WILC_MALLOC(sme->key_len); + memcpy(g_key_wep_params.key, sme->key, sme->key_len); + g_key_wep_params.key_idx = sme->key_idx; + g_wep_keys_saved = WILC_TRUE; + + host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, sme->key_idx); + host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx); + } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) { + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { + u8security = ENCRYPT_ENABLED | WPA2 | TKIP; + pcgroup_encrypt_val = "WPA2_TKIP"; + pccipher_group = "TKIP"; + } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ + /* tenuSecurity_t = WPA2_AES; */ + u8security = ENCRYPT_ENABLED | WPA2 | AES; + pcgroup_encrypt_val = "WPA2_AES"; + pccipher_group = "AES"; + } + pcwpa_version = "WPA_VERSION_2"; + } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) { + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { + u8security = ENCRYPT_ENABLED | WPA | TKIP; + pcgroup_encrypt_val = "WPA_TKIP"; + pccipher_group = "TKIP"; + } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ + /* tenuSecurity_t = WPA_AES; */ + u8security = ENCRYPT_ENABLED | WPA | AES; + pcgroup_encrypt_val = "WPA_AES"; + pccipher_group = "AES"; + + } + pcwpa_version = "WPA_VERSION_1"; + + } else { + s32Error = -ENOTSUPP; + PRINT_ER("Not supported cipher: Error(%d)\n", s32Error); + + goto done; + } + + } + + /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will + * add to it the pairwise cipher suite(s) */ + if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) + || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) { + for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) { + if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) { + u8security = u8security | TKIP; + } else { /* TODO: mostafa: here we assume that any other encryption type is AES */ + u8security = u8security | AES; + } + } + } + + PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group); + + PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type); + switch (sme->auth_type) { + case NL80211_AUTHTYPE_OPEN_SYSTEM: + PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n"); + tenuAuth_type = OPEN_SYSTEM; + break; + + case NL80211_AUTHTYPE_SHARED_KEY: + tenuAuth_type = SHARED_KEY; + PRINT_D(CFG80211_DBG, "In SHARED KEY\n"); + break; + + default: + PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type); + } + + + /* ai: key_mgmt: enterprise case */ + if (sme->crypto.n_akm_suites) { + switch (sme->crypto.akm_suites[0]) { + case WLAN_AKM_SUITE_8021X: + tenuAuth_type = IEEE8021; + break; + + default: + break; + } + } + + + PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel); + + PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n", + pcgroup_encrypt_val, pccipher_group, pcwpa_version); + + /*BugID_5442*/ + u8CurrChannel = pstrNetworkInfo->u8channel; + + if (!pstrWFIDrv->u8P2PConnect) { + u8WLANChannel = pstrNetworkInfo->u8channel; + } + + linux_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid); + + s32Error = host_int_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid, + sme->ssid_len, sme->ie, sme->ie_len, + CfgConnectResult, (void *)priv, u8security, + tenuAuth_type, pstrNetworkInfo->u8channel, + pstrNetworkInfo->pJoinParams); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("host_int_set_join_req(): Error(%d) \n", s32Error); + s32Error = -ENOENT; + goto done; + } + +done: + + return s32Error; +} + + +/** + * @brief WILC_WFI_disconnect + * @details Disconnect from the BSS/ESS. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + #ifdef WILC_P2P + tstrWILC_WFIDrv *pstrWFIDrv; + #endif + uint8_t NullBssid[ETH_ALEN] = {0}; + connecting = 0; + priv = wiphy_priv(wiphy); + + /*BugID_5457*/ + /*Invalidate u8WLANChannel value on wlan0 disconnect*/ + #ifdef WILC_P2P + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + if (!pstrWFIDrv->u8P2PConnect) + u8WLANChannel = INVALID_CHANNEL; + #endif + linux_wlan_set_bssid(priv->dev, NullBssid); + + PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code); + + u8P2Plocalrandom = 0x01; + u8P2Precvrandom = 0x00; + bWilc_ie = WILC_FALSE; + #ifdef WILC_P2P + pstrWFIDrv->u64P2p_MgmtTimeout = 0; + #endif + + s32Error = host_int_disconnect(priv->hWILCWFIDrv, reason_code); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error); + s32Error = -EINVAL; + } + + return s32Error; +} + +/** + * @brief WILC_WFI_add_key + * @details Add a key with the given parameters. @mac_addr will be %NULL + * when adding a group key. + * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, + bool pairwise, + const u8 *mac_addr, struct key_params *params) + +{ + WILC_Sint32 s32Error = WILC_SUCCESS, KeyLen = params->key_len; + WILC_Uint32 i; + struct WILC_WFI_priv *priv; + const u8 *pu8RxMic = NULL; + const u8 *pu8TxMic = NULL; + u8 u8mode = NO_ENCRYPT; + #ifdef WILC_AP_EXTERNAL_MLME + u8 u8gmode = NO_ENCRYPT; + u8 u8pmode = NO_ENCRYPT; + AUTHTYPE_T tenuAuth_type = ANY; + #endif + + priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher); + + /*BugID_5137*/ + PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index); + + PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0], + params->key[1], + params->key[2]); + + + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + #ifdef WILC_AP_EXTERNAL_MLME + if (priv->wdev->iftype == NL80211_IFTYPE_AP) { + + priv->WILC_WFI_wep_default = key_index; + priv->WILC_WFI_wep_key_len[key_index] = params->key_len; + WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len); + + PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index); + PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len); + + for (i = 0; i < params->key_len; i++) + PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]); + + tenuAuth_type = OPEN_SYSTEM; + + if (params->cipher == WLAN_CIPHER_SUITE_WEP40) + u8mode = ENCRYPT_ENABLED | WEP; + else + u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED; + + host_int_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type); + break; + } + #endif + if (WILC_memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) { + priv->WILC_WFI_wep_default = key_index; + priv->WILC_WFI_wep_key_len[key_index] = params->key_len; + WILC_memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len); + + PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index); + PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len); + if (INFO) { + for (i = 0; i < params->key_len; i++) + PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]); + } + host_int_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index); + } + + break; + + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + #ifdef WILC_AP_EXTERNAL_MLME + if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) { + + if (priv->wilc_gtk[key_index] == NULL) { + priv->wilc_gtk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key)); + priv->wilc_gtk[key_index]->key = NULL; + priv->wilc_gtk[key_index]->seq = NULL; + + } + if (priv->wilc_ptk[key_index] == NULL) { + priv->wilc_ptk[key_index] = (struct wilc_wfi_key *)WILC_MALLOC(sizeof(struct wilc_wfi_key)); + priv->wilc_ptk[key_index]->key = NULL; + priv->wilc_ptk[key_index]->seq = NULL; + } + + + + if (!pairwise) + { + if (params->cipher == WLAN_CIPHER_SUITE_TKIP) + u8gmode = ENCRYPT_ENABLED | WPA | TKIP; + else + u8gmode = ENCRYPT_ENABLED | WPA2 | AES; + + priv->wilc_groupkey = u8gmode; + + if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { + + pu8TxMic = params->key + 24; + pu8RxMic = params->key + 16; + KeyLen = params->key_len - 16; + } + /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/ + if (priv->wilc_gtk[key_index]->key) + WILC_FREE(priv->wilc_gtk[key_index]->key); + + priv->wilc_gtk[key_index]->key = (u8 *)WILC_MALLOC(params->key_len); + WILC_memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len); + + /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/ + if (priv->wilc_gtk[key_index]->seq) + WILC_FREE(priv->wilc_gtk[key_index]->seq); + + if ((params->seq_len) > 0) { + priv->wilc_gtk[key_index]->seq = (u8 *)WILC_MALLOC(params->seq_len); + WILC_memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len); + } + + priv->wilc_gtk[key_index]->cipher = params->cipher; + priv->wilc_gtk[key_index]->key_len = params->key_len; + priv->wilc_gtk[key_index]->seq_len = params->seq_len; + + if (INFO) { + for (i = 0; i < params->key_len; i++) + PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]); + for (i = 0; i < params->seq_len; i++) + PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]); + } + + + host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode); + + } else { + PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]); + + if (params->cipher == WLAN_CIPHER_SUITE_TKIP) + u8pmode = ENCRYPT_ENABLED | WPA | TKIP; + else + u8pmode = priv->wilc_groupkey | AES; + + + if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { + + pu8TxMic = params->key + 24; + pu8RxMic = params->key + 16; + KeyLen = params->key_len - 16; + } + + if (priv->wilc_ptk[key_index]->key) + WILC_FREE(priv->wilc_ptk[key_index]->key); + + priv->wilc_ptk[key_index]->key = (u8 *)WILC_MALLOC(params->key_len); + + if (priv->wilc_ptk[key_index]->seq) + WILC_FREE(priv->wilc_ptk[key_index]->seq); + + if ((params->seq_len) > 0) + priv->wilc_ptk[key_index]->seq = (u8 *)WILC_MALLOC(params->seq_len); + + if (INFO) { + for (i = 0; i < params->key_len; i++) + PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]); + + for (i = 0; i < params->seq_len; i++) + PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]); + } + + WILC_memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len); + + if ((params->seq_len) > 0) + WILC_memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len); + + priv->wilc_ptk[key_index]->cipher = params->cipher; + priv->wilc_ptk[key_index]->key_len = params->key_len; + priv->wilc_ptk[key_index]->seq_len = params->seq_len; + + host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index); + } + break; + } + #endif + + { + u8mode = 0; + if (!pairwise) + { + if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { + /* swap the tx mic by rx mic */ + pu8RxMic = params->key + 24; + pu8TxMic = params->key + 16; + KeyLen = params->key_len - 16; + } + + /*BugID_5137*/ + /*save keys only on interface 0 (wifi interface)*/ + if (!g_gtk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) { + g_add_gtk_key_params.key_idx = key_index; + g_add_gtk_key_params.pairwise = pairwise; + if (!mac_addr) { + g_add_gtk_key_params.mac_addr = NULL; + } else { + g_add_gtk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN); + memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN); + } + g_key_gtk_params.key_len = params->key_len; + g_key_gtk_params.seq_len = params->seq_len; + g_key_gtk_params.key = WILC_MALLOC(params->key_len); + memcpy(g_key_gtk_params.key, params->key, params->key_len); + if (params->seq_len > 0) { + g_key_gtk_params.seq = WILC_MALLOC(params->seq_len); + memcpy(g_key_gtk_params.seq, params->seq, params->seq_len); + } + g_key_gtk_params.cipher = params->cipher; + + PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0], + g_key_gtk_params.key[1], + g_key_gtk_params.key[2]); + g_gtk_keys_saved = WILC_TRUE; + } + + host_int_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen, + key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode); + } else { + if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { + /* swap the tx mic by rx mic */ + pu8RxMic = params->key + 24; + pu8TxMic = params->key + 16; + KeyLen = params->key_len - 16; + } + + /*BugID_5137*/ + /*save keys only on interface 0 (wifi interface)*/ + if (!g_ptk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) { + g_add_ptk_key_params.key_idx = key_index; + g_add_ptk_key_params.pairwise = pairwise; + if (!mac_addr) { + g_add_ptk_key_params.mac_addr = NULL; + } else { + g_add_ptk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN); + memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN); + } + g_key_ptk_params.key_len = params->key_len; + g_key_ptk_params.seq_len = params->seq_len; + g_key_ptk_params.key = WILC_MALLOC(params->key_len); + memcpy(g_key_ptk_params.key, params->key, params->key_len); + if (params->seq_len > 0) { + g_key_ptk_params.seq = WILC_MALLOC(params->seq_len); + memcpy(g_key_ptk_params.seq, params->seq, params->seq_len); + } + g_key_ptk_params.cipher = params->cipher; + + PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0], + g_key_ptk_params.key[1], + g_key_ptk_params.key[2]); + g_ptk_keys_saved = WILC_TRUE; + } + + host_int_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr, + pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index); + PRINT_D(CFG80211_DBG, "Adding pairwise key\n"); + if (INFO) { + for (i = 0; i < params->key_len; i++) + PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]); + } + } + } + break; + + default: + PRINT_ER("Not supported cipher: Error(%d)\n", s32Error); + s32Error = -ENOTSUPP; + + } + + return s32Error; +} + +/** + * @brief WILC_WFI_del_key + * @details Remove a key given the @mac_addr (%NULL for a group key) + * and @key_index, return -ENOENT if the key doesn't exist. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_del_key(struct wiphy *wiphy, struct net_device *netdev, + u8 key_index, + bool pairwise, + const u8 *mac_addr) +{ + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + + priv = wiphy_priv(wiphy); + + /*BugID_5137*/ + /*delete saved keys, if any*/ + if (netdev == g_linux_wlan->strInterfaceInfo[0].wilc_netdev) { + g_ptk_keys_saved = WILC_FALSE; + g_gtk_keys_saved = WILC_FALSE; + g_wep_keys_saved = WILC_FALSE; + + /*Delete saved WEP keys params, if any*/ + if (g_key_wep_params.key != NULL) { + WILC_FREE(g_key_wep_params.key); + g_key_wep_params.key = NULL; + } + + /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/ + + #ifdef WILC_AP_EXTERNAL_MLME + if ((priv->wilc_gtk[key_index]) != NULL) { + + if (priv->wilc_gtk[key_index]->key != NULL) { + + WILC_FREE(priv->wilc_gtk[key_index]->key); + priv->wilc_gtk[key_index]->key = NULL; + } + if (priv->wilc_gtk[key_index]->seq) { + + WILC_FREE(priv->wilc_gtk[key_index]->seq); + priv->wilc_gtk[key_index]->seq = NULL; + } + + WILC_FREE(priv->wilc_gtk[key_index]); + priv->wilc_gtk[key_index] = NULL; + + } + + if ((priv->wilc_ptk[key_index]) != NULL) { + + if (priv->wilc_ptk[key_index]->key) { + + WILC_FREE(priv->wilc_ptk[key_index]->key); + priv->wilc_ptk[key_index]->key = NULL; + } + if (priv->wilc_ptk[key_index]->seq) { + + WILC_FREE(priv->wilc_ptk[key_index]->seq); + priv->wilc_ptk[key_index]->seq = NULL; + } + WILC_FREE(priv->wilc_ptk[key_index]); + priv->wilc_ptk[key_index] = NULL; + } + #endif + + /*Delete saved PTK and GTK keys params, if any*/ + if (g_key_ptk_params.key != NULL) { + WILC_FREE(g_key_ptk_params.key); + g_key_ptk_params.key = NULL; + } + if (g_key_ptk_params.seq != NULL) { + WILC_FREE(g_key_ptk_params.seq); + g_key_ptk_params.seq = NULL; + } + + if (g_key_gtk_params.key != NULL) { + WILC_FREE(g_key_gtk_params.key); + g_key_gtk_params.key = NULL; + } + if (g_key_gtk_params.seq != NULL) { + WILC_FREE(g_key_gtk_params.seq); + g_key_gtk_params.seq = NULL; + } + + /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ + Set_machw_change_vir_if(WILC_FALSE); + } + + if (key_index >= 0 && key_index <= 3) { + WILC_memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]); + priv->WILC_WFI_wep_key_len[key_index] = 0; + + PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index); + host_int_remove_wep_key(priv->hWILCWFIDrv, key_index); + } else { + PRINT_D(CFG80211_DBG, "Removing all installed keys\n"); + host_int_remove_key(priv->hWILCWFIDrv, mac_addr); + } + + return s32Error; +} + +/** + * @brief WILC_WFI_get_key + * @details Get information about the key with the given parameters. + * @mac_addr will be %NULL when requesting information for a group + * key. All pointers given to the @callback function need not be valid + * after it returns. This function should return an error if it is + * not possible to retrieve the key, -ENOENT if it doesn't exist. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, + bool pairwise, + const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *)) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + + struct WILC_WFI_priv *priv; + struct key_params key_params; + WILC_Uint32 i; + priv = wiphy_priv(wiphy); + + + if (!pairwise) + { + PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index); + + key_params.key = priv->wilc_gtk[key_index]->key; + key_params.cipher = priv->wilc_gtk[key_index]->cipher; + key_params.key_len = priv->wilc_gtk[key_index]->key_len; + key_params.seq = priv->wilc_gtk[key_index]->seq; + key_params.seq_len = priv->wilc_gtk[key_index]->seq_len; + if (INFO) { + for (i = 0; i < key_params.key_len; i++) + PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]); + } + } else { + PRINT_D(CFG80211_DBG, "Getting pairwise key\n"); + + key_params.key = priv->wilc_ptk[key_index]->key; + key_params.cipher = priv->wilc_ptk[key_index]->cipher; + key_params.key_len = priv->wilc_ptk[key_index]->key_len; + key_params.seq = priv->wilc_ptk[key_index]->seq; + key_params.seq_len = priv->wilc_ptk[key_index]->seq_len; + } + + callback(cookie, &key_params); + + return s32Error; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */ +} + +/** + * @brief WILC_WFI_set_default_key + * @details Set the default management frame key on an interface + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, + bool unicast, bool multicast) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + + + priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Setting default key with idx = %d \n", key_index); + + if (key_index != priv->WILC_WFI_wep_default) { + + host_int_set_WEPDefaultKeyID(priv->hWILCWFIDrv, key_index); + } + + return s32Error; +} + +/** + * @brief WILC_WFI_dump_survey + * @details Get site survey information + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_dump_survey(struct wiphy *wiphy, struct net_device *netdev, + int idx, struct survey_info *info) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + + if (idx != 0) { + s32Error = -ENOENT; + PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n", s32Error); + + } + + return s32Error; +} + + +/** + * @brief WILC_WFI_get_station + * @details Get station information for the station identified by @mac + * @param[in] NONE + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ + +extern uint32_t Statisitcs_totalAcks, Statisitcs_DroppedAcks; +static int WILC_WFI_get_station(struct wiphy *wiphy, struct net_device *dev, + const u8 *mac, struct station_info *sinfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + #ifdef WILC_AP_EXTERNAL_MLME + WILC_Uint32 i = 0; + WILC_Uint32 associatedsta = 0; + WILC_Uint32 inactive_time = 0; + #endif + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + #ifdef WILC_AP_EXTERNAL_MLME + if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + PRINT_D(HOSTAPD_DBG, "Getting station parameters\n"); + + PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]); + + for (i = 0; i < NUM_STA_ASSOCIATED; i++) { + + if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) { + associatedsta = i; + break; + } + + } + + if (associatedsta == -1) { + s32Error = -ENOENT; + PRINT_ER("Station required is not associated : Error(%d)\n", s32Error); + + return s32Error; + } + + sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME); + + host_int_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time)); + sinfo->inactive_time = 1000 * inactive_time; + PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time); + + } + #endif + + if (nic->iftype == STATION_MODE) { + tstrStatistics strStatistics; + host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics); + + /* + * tony: 2013-11-13 + * tx_failed introduced more than + * kernel version 3.0.0 + */ + sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | + BIT( NL80211_STA_INFO_RX_PACKETS) | + BIT(NL80211_STA_INFO_TX_PACKETS) | + BIT(NL80211_STA_INFO_TX_FAILED) | + BIT(NL80211_STA_INFO_TX_BITRATE); + + sinfo->signal = strStatistics.s8RSSI; + sinfo->rx_packets = strStatistics.u32RxCount; + sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount; + sinfo->tx_failed = strStatistics.u32TxFailureCount; + sinfo->txrate.legacy = strStatistics.u8LinkSpeed * 10; + +#ifdef TCP_ENHANCEMENTS + if ((strStatistics.u8LinkSpeed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED)) { + Enable_TCP_ACK_Filter(WILC_TRUE); + } else if (strStatistics.u8LinkSpeed != DEFAULT_LINK_SPEED) { + Enable_TCP_ACK_Filter(WILC_FALSE); + } +#endif + + PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets, + sinfo->tx_failed, sinfo->txrate.legacy); + } + return s32Error; +} + + +/** + * @brief WILC_WFI_change_bss + * @details Modify parameters for a given BSS. + * @param[in] + * -use_cts_prot: Whether to use CTS protection + * (0 = no, 1 = yes, -1 = do not change) + * -use_short_preamble: Whether the use of short preambles is allowed + * (0 = no, 1 = yes, -1 = do not change) + * -use_short_slot_time: Whether the use of short slot time is allowed + * (0 = no, 1 = yes, -1 = do not change) + * -basic_rates: basic rates in IEEE 802.11 format + * (or NULL for no change) + * -basic_rates_len: number of basic rates + * -ap_isolate: do not forward packets between connected stations + * -ht_opmode: HT Operation mode + * (u16 = opmode, -1 = do not change) + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_change_bss(struct wiphy *wiphy, struct net_device *dev, + struct bss_parameters *params) +{ + PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n"); + return 0; +} + +/** + * @brief WILC_WFI_auth + * @details Request to authenticate with the specified peer + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_auth(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_auth_request *req) +{ + PRINT_D(CFG80211_DBG, "In Authentication Function\n"); + return 0; +} + +/** + * @brief WILC_WFI_assoc + * @details Request to (re)associate with the specified peer + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_assoc(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_assoc_request *req) +{ + PRINT_D(CFG80211_DBG, "In Association Function\n"); + return 0; +} + +/** + * @brief WILC_WFI_deauth + * @details Request to deauthenticate from the specified peer + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_deauth(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_deauth_request *req, void *cookie) +{ + PRINT_D(CFG80211_DBG, "In De-authentication Function\n"); + return 0; +} + +/** + * @brief WILC_WFI_disassoc + * @details Request to disassociate from the specified peer + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_disassoc(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_disassoc_request *req, void *cookie) +{ + PRINT_D(CFG80211_DBG, "In Disassociation Function\n"); + return 0; +} + +/** + * @brief WILC_WFI_set_wiphy_params + * @details Notify that wiphy parameters have changed; + * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values + * have changed. + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrCfgParamVal pstrCfgParamVal; + struct WILC_WFI_priv *priv; + + priv = wiphy_priv(wiphy); + + pstrCfgParamVal.u32SetCfgFlag = 0; + PRINT_D(CFG80211_DBG, "Setting Wiphy params \n"); + + if (changed & WIPHY_PARAM_RETRY_SHORT) { + PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n", + priv->dev->ieee80211_ptr->wiphy->retry_short); + pstrCfgParamVal.u32SetCfgFlag |= RETRY_SHORT; + pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short; + } + if (changed & WIPHY_PARAM_RETRY_LONG) { + + PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long); + pstrCfgParamVal.u32SetCfgFlag |= RETRY_LONG; + pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long; + + } + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { + PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold); + pstrCfgParamVal.u32SetCfgFlag |= FRAG_THRESHOLD; + pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold; + + } + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { + PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold); + + pstrCfgParamVal.u32SetCfgFlag |= RTS_THRESHOLD; + pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold; + + } + + PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n"); + s32Error = hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal); + if (s32Error) + PRINT_ER("Error in setting WIPHY PARAMS\n"); + + + return s32Error; +} + +/** + * @brief WILC_WFI_set_bitrate_mask + * @details set the bitrate mask configuration + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, const u8 *peer, + const struct cfg80211_bitrate_mask *mask) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n"); + return s32Error; + +} + +/** + * @brief WILC_WFI_set_pmksa + * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac + * devices running firmwares capable of generating the (re) association + * RSN IE. It allows for faster roaming between WPA2 BSSIDs. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + WILC_Uint32 i; + WILC_Sint32 s32Error = WILC_SUCCESS; + u8 flag = 0; + + struct WILC_WFI_priv *priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Setting PMKSA\n"); + + + for (i = 0; i < priv->pmkid_list.numpmkid; i++) { + if (!WILC_memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid, + ETH_ALEN)) { + /*If bssid already exists and pmkid value needs to reset*/ + flag = PMKID_FOUND; + PRINT_D(CFG80211_DBG, "PMKID already exists\n"); + break; + } + } + if (i < WILC_MAX_NUM_PMKIDS) { + PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n"); + WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid, + ETH_ALEN); + WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid, + PMKID_LEN); + if (!(flag == PMKID_FOUND)) + priv->pmkid_list.numpmkid++; + } else { + PRINT_ER("Invalid PMKID index\n"); + s32Error = -EINVAL; + } + + if (!s32Error) { + PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n"); + s32Error = host_int_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list); + } + return s32Error; +} + +/** + * @brief WILC_WFI_del_pmksa + * @details Delete a cached PMKID. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + + WILC_Uint32 i; + u8 flag = 0; + WILC_Sint32 s32Error = WILC_SUCCESS; + + struct WILC_WFI_priv *priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n"); + + for (i = 0; i < priv->pmkid_list.numpmkid; i++) { + if (!WILC_memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid, + ETH_ALEN)) { + /*If bssid is found, reset the values*/ + PRINT_D(CFG80211_DBG, "Reseting PMKID values\n"); + WILC_memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(tstrHostIFpmkid)); + flag = PMKID_FOUND; + break; + } + } + + if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) { + for (; i < (priv->pmkid_list.numpmkid - 1); i++) { + WILC_memcpy(priv->pmkid_list.pmkidlist[i].bssid, + priv->pmkid_list.pmkidlist[i + 1].bssid, + ETH_ALEN); + WILC_memcpy(priv->pmkid_list.pmkidlist[i].pmkid, + priv->pmkid_list.pmkidlist[i].pmkid, + PMKID_LEN); + } + priv->pmkid_list.numpmkid--; + } else { + s32Error = -EINVAL; + } + + return s32Error; +} + +/** + * @brief WILC_WFI_flush_pmksa + * @details Flush all cached PMKIDs. + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) +{ + struct WILC_WFI_priv *priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n"); + + /*Get cashed Pmkids and set all with zeros*/ + WILC_memset(&priv->pmkid_list, 0, sizeof(tstrHostIFpmkidAttr)); + + return 0; +} + +#ifdef WILC_P2P + +/** + * @brief WILC_WFI_CfgParseRxAction + * @details Function parses the received frames and modifies the following attributes: + * -GO Intent + * -Channel list + * -Operating Channel + * + * @param[in] u8* Buffer, u32 length + * @return NONE. + * @author mdaftedar + * @date 12 DEC 2012 + * @version + */ + +void WILC_WFI_CfgParseRxAction(u8 *buf, WILC_Uint32 len) +{ + WILC_Uint32 index = 0; + WILC_Uint32 i = 0, j = 0; + + /*BugID_5460*/ + #ifdef USE_SUPPLICANT_GO_INTENT + u8 intent; + u8 tie_breaker; + WILC_Bool is_wilc_go = WILC_TRUE; + #endif + u8 op_channel_attr_index = 0; + u8 channel_list_attr_index = 0; + + while (index < len) { + if (buf[index] == GO_INTENT_ATTR_ID) { + #ifdef USE_SUPPLICANT_GO_INTENT + /*BugID_5460*/ + /*Case 1: If we are going to be p2p client, no need to modify channels attributes*/ + /*In negotiation frames, go intent attr value determines who will be GO*/ + intent = GET_GO_INTENT(buf[index + 3]); + tie_breaker = GET_TIE_BREAKER(buf[index + 3]); + if (intent > SUPPLICANT_GO_INTENT + || (intent == SUPPLICANT_GO_INTENT && tie_breaker == 1)) { + PRINT_D(GENERIC_DBG, "WILC will be client (intent %d tie breaker %d)\n", intent, tie_breaker); + is_wilc_go = WILC_FALSE; + } else { + PRINT_D(GENERIC_DBG, "WILC will be GO (intent %d tie breaker %d)\n", intent, tie_breaker); + is_wilc_go = WILC_TRUE; + } + + #else /* USE_SUPPLICANT_GO_INTENT */ + #ifdef FORCE_P2P_CLIENT + buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1); + #else + buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1); + #endif + #endif /* USE_SUPPLICANT_GO_INTENT */ + } + + #ifdef USE_SUPPLICANT_GO_INTENT + /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/ + /*In invitation req and rsp, group bssid attr presence determines who will be GO*/ + if (buf[index] == GROUP_BSSID_ATTR_ID) { + PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3] + , buf[index + 4] + , buf[index + 5]); + is_wilc_go = WILC_FALSE; + } + #endif /* USE_SUPPLICANT_GO_INTENT */ + + if (buf[index] == CHANLIST_ATTR_ID) { + channel_list_attr_index = index; + } else if (buf[index] == OPERCHAN_ATTR_ID) { + op_channel_attr_index = index; + } + index += buf[index + 1] + 3; /* ID,Length byte */ + } + + #ifdef USE_SUPPLICANT_GO_INTENT + if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go) + #else + if (u8WLANChannel != INVALID_CHANNEL) + #endif + { + /*Modify channel list attribute*/ + if (channel_list_attr_index) { + PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); + for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { + if (buf[i] == 0x51) { + for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { + buf[j] = u8WLANChannel; + } + break; + } + } + } + /*Modify operating channel attribute*/ + if (op_channel_attr_index) { + PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); + buf[op_channel_attr_index + 6] = 0x51; + buf[op_channel_attr_index + 7] = u8WLANChannel; + } + } +} + +/** + * @brief WILC_WFI_CfgParseTxAction + * @details Function parses the transmitted action frames and modifies the + * GO Intent attribute + * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype + * @return NONE. + * @author mdaftedar + * @date 12 DEC 2012 + * @version + */ +void WILC_WFI_CfgParseTxAction(u8 *buf, WILC_Uint32 len, WILC_Bool bOperChan, u8 iftype) +{ + WILC_Uint32 index = 0; + WILC_Uint32 i = 0, j = 0; + + u8 op_channel_attr_index = 0; + u8 channel_list_attr_index = 0; + #ifdef USE_SUPPLICANT_GO_INTENT + WILC_Bool is_wilc_go = WILC_FALSE; + + /*BugID_5460*/ + /*Case 1: If we are already p2p client, no need to modify channels attributes*/ + /*This to handle the case of inviting a p2p peer to join an existing group which we are a member in*/ + if (iftype == CLIENT_MODE) + return; + #endif + + while (index < len) { + #ifdef USE_SUPPLICANT_GO_INTENT + /*Case 2: If group bssid attribute is present, no need to modify channels attributes*/ + /*In invitation req and rsp, group bssid attr presence determines who will be GO*/ + /*Note: If we are already p2p client, group bssid attr may also be present (handled in Case 1)*/ + if (buf[index] == GROUP_BSSID_ATTR_ID) { + PRINT_D(GENERIC_DBG, "Group BSSID: %2x:%2x:%2x\n", buf[index + 3] + , buf[index + 4] + , buf[index + 5]); + is_wilc_go = WILC_TRUE; + } + + #else /* USE_SUPPLICANT_GO_INTENT */ + if (buf[index] == GO_INTENT_ATTR_ID) { + #ifdef FORCE_P2P_CLIENT + buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1); + #else + buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1); + #endif + + break; + } + #endif + + if (buf[index] == CHANLIST_ATTR_ID) { + channel_list_attr_index = index; + } else if (buf[index] == OPERCHAN_ATTR_ID) { + op_channel_attr_index = index; + } + index += buf[index + 1] + 3; /* ID,Length byte */ + } + + #ifdef USE_SUPPLICANT_GO_INTENT + /*No need to check bOperChan since only transmitted invitation frames are parsed*/ + if (u8WLANChannel != INVALID_CHANNEL && is_wilc_go) + #else + if (u8WLANChannel != INVALID_CHANNEL && bOperChan) + #endif + { + /*Modify channel list attribute*/ + if (channel_list_attr_index) { + PRINT_D(GENERIC_DBG, "Modify channel list attribute\n"); + for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { + if (buf[i] == 0x51) { + for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { + buf[j] = u8WLANChannel; + } + break; + } + } + } + /*Modify operating channel attribute*/ + if (op_channel_attr_index) { + PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n"); + buf[op_channel_attr_index + 6] = 0x51; + buf[op_channel_attr_index + 7] = u8WLANChannel; + } + } +} + +/* @brief WILC_WFI_p2p_rx + * @details + * @param[in] + * + * @return None + * @author Mai Daftedar + * @date 2 JUN 2013 + * @version 1.0 + */ + +void WILC_WFI_p2p_rx (struct net_device *dev, uint8_t *buff, uint32_t size) +{ + + struct WILC_WFI_priv *priv; + WILC_Uint32 header, pkt_offset; + tstrWILC_WFIDrv *pstrWFIDrv; + WILC_Uint32 i = 0; + WILC_Sint32 s32Freq; + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + /* Get WILC header */ + WILC_memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); + + /* The packet offset field conain info about what type of managment frame */ + /* we are dealing with and ack status */ + pkt_offset = GET_PKT_OFFSET(header); + + if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { + if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) { + PRINT_D(GENERIC_DBG, "Probe response ACK\n"); + cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL); + return; + } else { + if (pkt_offset & IS_MGMT_STATUS_SUCCES) { + PRINT_D(GENERIC_DBG, "Success Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID], + buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]); + cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL); + } else { + PRINT_D(GENERIC_DBG, "Fail Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID], + buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]); + cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL); + } + return; + } + } else { + + PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]); + + /*BugID_5442*/ + /*Upper layer is informed that the frame is received on this freq*/ + s32Freq = ieee80211_channel_to_frequency(u8CurrChannel, IEEE80211_BAND_2GHZ); + + if (ieee80211_is_action(buff[FRAME_TYPE_ID])) { + PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]); + + if (priv->bCfgScanning == WILC_TRUE && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->u64P2p_MgmtTimeout)) { + PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n"); + return; + } + if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) { + + switch (buff[ACTION_SUBTYPE_ID]) { + case GAS_INTIAL_REQ: + PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]); + break; + + case GAS_INTIAL_RSP: + PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]); + break; + + case PUBLIC_ACT_VENDORSPEC: + /*Now we have a public action vendor specific action frame, check if its a p2p public action frame + * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/ + if (!WILC_memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) { + if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { + if (!bWilc_ie) { + for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { + if (!WILC_memcmp(u8P2P_vendorspec, &buff[i], 6)) { + u8P2Precvrandom = buff[i + 6]; + bWilc_ie = WILC_TRUE; + PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom); + break; + } + } + } + } + if (u8P2Plocalrandom > u8P2Precvrandom) { + if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP + || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { + for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) { + if (buff[i] == P2PELEM_ATTR_ID && !(WILC_memcmp(u8P2P_oui, &buff[i + 2], 4))) { + WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6)); + break; + } + } + } + } else + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + } + + + if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) { + PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n"); + /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */ + cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0); + return; + } + break; + + default: + PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]); + break; + } + } + } + + cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0); + } +} + +/** + * @brief WILC_WFI_mgmt_tx_complete + * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here) + * @param[in] priv + * transmitting status + * @return None + * @author Amr Abdelmoghny + * @date 20 MAY 2013 + * @version 1.0 + */ +static void WILC_WFI_mgmt_tx_complete(void *priv, int status) +{ + struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv; + + + kfree(pv_data->buff); + kfree(pv_data); +} + +/** + * @brief WILC_WFI_RemainOnChannelReady + * @details Callback function, called from handle_remain_on_channel on being ready on channel + * @param + * @return none + * @author Amr abdelmoghny + * @date 9 JUNE 2013 + * @version + */ + +static void WILC_WFI_RemainOnChannelReady(void *pUserVoid) +{ + struct WILC_WFI_priv *priv; + priv = (struct WILC_WFI_priv *)pUserVoid; + + PRINT_D(HOSTINF_DBG, "Remain on channel ready \n"); + + priv->bInP2PlistenState = WILC_TRUE; + + cfg80211_ready_on_channel(priv->wdev, + priv->strRemainOnChanParams.u64ListenCookie, + priv->strRemainOnChanParams.pstrListenChan, + priv->strRemainOnChanParams.u32ListenDuration, + GFP_KERNEL); +} + +/** + * @brief WILC_WFI_RemainOnChannelExpired + * @details Callback function, called on expiration of remain-on-channel duration + * @param + * @return none + * @author Amr abdelmoghny + * @date 15 MAY 2013 + * @version + */ + +static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, WILC_Uint32 u32SessionID) +{ + struct WILC_WFI_priv *priv; + priv = (struct WILC_WFI_priv *)pUserVoid; + + /*BugID_5477*/ + if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) { + PRINT_D(GENERIC_DBG, "Remain on channel expired \n"); + + priv->bInP2PlistenState = WILC_FALSE; + + /*Inform wpas of remain-on-channel expiration*/ + cfg80211_remain_on_channel_expired(priv->wdev, + priv->strRemainOnChanParams.u64ListenCookie, + priv->strRemainOnChanParams.pstrListenChan, + GFP_KERNEL); + } else { + PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID + , priv->strRemainOnChanParams.u32ListenSessionID); + } +} + + +/** + * @brief WILC_WFI_remain_on_channel + * @details Request the driver to remain awake on the specified + * channel for the specified duration to complete an off-channel + * operation (e.g., public action frame exchange). When the driver is + * ready on the requested channel, it must indicate this with an event + * notification by calling cfg80211_ready_on_channel(). + * @param[in] + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + priv = wiphy_priv(wiphy); + + PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value); + + /*BugID_4800: if in AP mode, return.*/ + /*This check is to handle the situation when user*/ + /*requests "create group" during a running scan*/ + + if (wdev->iftype == NL80211_IFTYPE_AP) { + PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode"); + return s32Error; + } + + u8CurrChannel = chan->hw_value; + + /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/ + priv->strRemainOnChanParams.pstrListenChan = chan; + priv->strRemainOnChanParams.u64ListenCookie = *cookie; + priv->strRemainOnChanParams.u32ListenDuration = duration; + priv->strRemainOnChanParams.u32ListenSessionID++; + + s32Error = host_int_remain_on_channel(priv->hWILCWFIDrv + , priv->strRemainOnChanParams.u32ListenSessionID + , duration + , chan->hw_value + , WILC_WFI_RemainOnChannelExpired + , WILC_WFI_RemainOnChannelReady + , (void *)priv); + + return s32Error; +} + +/** + * @brief WILC_WFI_cancel_remain_on_channel + * @details Cancel an on-going remain-on-channel operation. + * This allows the operation to be terminated prior to timeout based on + * the duration value. + * @param[in] struct wiphy *wiphy, + * @param[in] struct net_device *dev + * @param[in] u64 cookie, + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG, "Cancel remain on channel\n"); + + s32Error = host_int_ListenStateExpired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID); + return s32Error; +} +/** + * @brief WILC_WFI_add_wilcvendorspec + * @details Adding WILC information elemet to allow two WILC devices to + * identify each other and connect + * @param[in] u8 * buf + * @return void + * @author mdaftedar + * @date 01 JAN 2014 + * @version 1.0 + */ +void WILC_WFI_add_wilcvendorspec(u8 *buff) +{ + WILC_memcpy(buff, u8P2P_vendorspec, sizeof(u8P2P_vendorspec)); +} +/** + * @brief WILC_WFI_mgmt_tx_frame + * @details + * + * @param[in] + * @return NONE. + * @author mdaftedar + * @date 01 JUL 2012 + * @version + */ +extern linux_wlan_t *g_linux_wlan; +extern WILC_Bool bEnablePS; +int WILC_WFI_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie) +{ + struct ieee80211_channel *chan = params->chan; + unsigned int wait = params->wait; + const u8 *buf = params->buf; + size_t len = params->len; + const struct ieee80211_mgmt *mgmt; + struct p2p_mgmt_data *mgmt_tx; + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv; + WILC_Uint32 i; + perInterface_wlan_t *nic; + WILC_Uint32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom); + + nic = netdev_priv(wdev->netdev); + priv = wiphy_priv(wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + *cookie = (unsigned long)buf; + priv->u64tx_cookie = *cookie; + mgmt = (const struct ieee80211_mgmt *) buf; + + if (ieee80211_is_mgmt(mgmt->frame_control)) { + + /*mgmt frame allocation*/ + mgmt_tx = (struct p2p_mgmt_data *)WILC_MALLOC(sizeof(struct p2p_mgmt_data)); + if (mgmt_tx == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); + return WILC_FAIL; + } + mgmt_tx->buff = (char *)WILC_MALLOC(buf_len); + if (mgmt_tx->buff == NULL) { + PRINT_ER("Failed to allocate memory for mgmt_tx buff\n"); + return WILC_FAIL; + } + WILC_memcpy(mgmt_tx->buff, buf, len); + mgmt_tx->size = len; + + + if (ieee80211_is_probe_resp(mgmt->frame_control)) { + PRINT_D(GENERIC_DBG, "TX: Probe Response\n"); + PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); + host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + /*Save the current channel after we tune to it*/ + u8CurrChannel = chan->hw_value; + } else if (ieee80211_is_action(mgmt->frame_control)) { + PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (WILC_Uint16)mgmt->frame_control); + + + /*BugID_4847*/ + if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) { + /*BugID_4847*/ + /*Only set the channel, if not a negotiation confirmation frame + * (If Negotiation confirmation frame, force it + * to be transmitted on the same negotiation channel)*/ + + if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || + buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { + PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value); + host_int_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value); + /*Save the current channel after we tune to it*/ + u8CurrChannel = chan->hw_value; + } + switch (buf[ACTION_SUBTYPE_ID]) { + case GAS_INTIAL_REQ: + { + PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]); + break; + } + + case GAS_INTIAL_RSP: + { + PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]); + break; + } + + case PUBLIC_ACT_VENDORSPEC: + { + /*Now we have a public action vendor specific action frame, check if its a p2p public action frame + * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/ + if (!WILC_memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) { + /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/ + if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) { + if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) { + get_random_bytes(&u8P2Plocalrandom, 1); + /*Increment the number to prevent if its 0*/ + u8P2Plocalrandom++; + } + } + + if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP + || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { + if (u8P2Plocalrandom > u8P2Precvrandom) { + PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + + /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/ + for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { + if (buf[i] == P2PELEM_ATTR_ID && !(WILC_memcmp(u8P2P_oui, &buf[i + 2], 4))) { + if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP) + WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), WILC_TRUE, nic->iftype); + + /*BugID_5460*/ + /*If using supplicant go intent, no need at all*/ + /*to parse transmitted negotiation frames*/ + #ifndef USE_SUPPLICANT_GO_INTENT + else + WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), WILC_FALSE, nic->iftype); + #endif + break; + } + } + + if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) { + WILC_WFI_add_wilcvendorspec(&mgmt_tx->buff[len]); + mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom; + mgmt_tx->size = buf_len; + } + } else + PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom); + } + + } else { + PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n"); + } + + break; + } + + default: + { + PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]); + break; + } + } + + } + + PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value); + pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait)); + + PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout); + + } + + g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, WILC_WFI_mgmt_tx_complete); + } else { + PRINT_D(GENERIC_DBG, "This function transmits only management frames\n"); + } + return s32Error; +} + +int WILC_WFI_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + struct WILC_WFI_priv *priv; + tstrWILC_WFIDrv *pstrWFIDrv; + priv = wiphy_priv(wiphy); + pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv; + + + PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies); + pstrWFIDrv->u64P2p_MgmtTimeout = jiffies; + + if (priv->bInP2PlistenState == WILC_FALSE) { + /* Bug 5504: This is just to avoid connection failure when getting stuck when the supplicant + * considers the driver falsely that it is in Listen state */ + cfg80211_remain_on_channel_expired(priv->wdev, + priv->strRemainOnChanParams.u64ListenCookie, + priv->strRemainOnChanParams.pstrListenChan, + GFP_KERNEL); + } + + return 0; +} + +/** + * @brief WILC_WFI_frame_register + * @details Notify driver that a management frame type was + * registered. Note that this callback may not sleep, and cannot run + * concurrently with itself. + * @param[in] + * @return NONE. + * @author mdaftedar + * @date 01 JUL 2012 + * @version + */ +void WILC_WFI_frame_register(struct wiphy *wiphy, + struct wireless_dev *wdev, + u16 frame_type, bool reg) +{ + + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + + + priv = wiphy_priv(wiphy); + nic = netdev_priv(priv->wdev->netdev); + + + + /*BugID_5137*/ + if (!frame_type) + return; + + PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg); + switch (frame_type) { + case PROBE_REQ: + { + nic->g_struct_frame_reg[0].frame_type = frame_type; + nic->g_struct_frame_reg[0].reg = reg; + } + break; + + case ACTION: + { + nic->g_struct_frame_reg[1].frame_type = frame_type; + nic->g_struct_frame_reg[1].reg = reg; + } + break; + + default: + { + break; + } + + } + /*If mac is closed, then return*/ + if (!g_linux_wlan->wilc1000_initialized) { + PRINT_D(GENERIC_DBG, "Return since mac is closed\n"); + return; + } + host_int_frame_register(priv->hWILCWFIDrv, frame_type, reg); + + +} +#endif /*WILC_P2P*/ + +/** + * @brief WILC_WFI_set_cqm_rssi_config + * @details Configure connection quality monitor RSSI threshold. + * @param[in] struct wiphy *wiphy: + * @param[in] struct net_device *dev: + * @param[in] s32 rssi_thold: + * @param[in] u32 rssi_hyst: + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_set_cqm_rssi_config(struct wiphy *wiphy, + struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) +{ + PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n"); + return 0; + +} +/** + * @brief WILC_WFI_dump_station + * @details Configure connection quality monitor RSSI threshold. + * @param[in] struct wiphy *wiphy: + * @param[in] struct net_device *dev + * @param[in] int idx + * @param[in] u8 *mac + * @param[in] struct station_info *sinfo + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_dump_station(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *mac, struct station_info *sinfo) +{ + struct WILC_WFI_priv *priv; + PRINT_D(CFG80211_DBG, "Dumping station information\n"); + + if (idx != 0) + return -ENOENT; + + priv = wiphy_priv(wiphy); + + sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); + + host_int_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal)); + + return 0; + +} + + +/** + * @brief WILC_WFI_set_power_mgmt + * @details + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 JUL 2012 + * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config + */ +int WILC_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct WILC_WFI_priv *priv; + PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout); + + if (wiphy == NULL) + return -ENOENT; + + priv = wiphy_priv(wiphy); + if (priv->hWILCWFIDrv == NULL) { + PRINT_ER("Driver is NULL\n"); + return -EIO; + } + + if (bEnablePS == WILC_TRUE) + host_int_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout); + + + return WILC_SUCCESS; + +} +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief WILC_WFI_change_virt_intf + * @details Change type/configuration of virtual interface, + * keep the struct wireless_dev's iftype updated. + * @param[in] NONE + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void wilc1000_wlan_deinit(linux_wlan_t *nic); +int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic); + +static int WILC_WFI_change_virt_intf(struct wiphy *wiphy, struct net_device *dev, + enum nl80211_iftype type, u32 *flags, struct vif_params *params) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + u8 interface_type; + WILC_Uint16 TID = 0; + #ifdef WILC_P2P + u8 i; + #endif + + nic = netdev_priv(dev); + priv = wiphy_priv(wiphy); + + PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n"); + PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name); + u8P2Plocalrandom = 0x01; + u8P2Precvrandom = 0x00; + + bWilc_ie = WILC_FALSE; + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + g_obtainingIP = WILC_FALSE; + WILC_TimerStop(&hDuringIpTimer, NULL); + PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n"); + #endif + /*BugID_5137*/ + /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/ + if (g_ptk_keys_saved && g_gtk_keys_saved) { + Set_machw_change_vir_if(WILC_TRUE); + } + + switch (type) { + case NL80211_IFTYPE_STATION: + connecting = 0; + PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n"); + + /* send delba over wlan interface */ + + + dev->ieee80211_ptr->iftype = type; + priv->wdev->iftype = type; + nic->monitor_flag = 0; + nic->iftype = STATION_MODE; + + /*Remove the enteries of the previously connected clients*/ + memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN); + #ifndef SIMULATION + #ifdef WILC_P2P + interface_type = nic->iftype; + nic->iftype = STATION_MODE; + + if (g_linux_wlan->wilc1000_initialized) { + host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID); + /* ensure that the message Q is empty */ + host_int_wait_msg_queue_idle(); + + /*BugID_5213*/ + /*Eliminate host interface blocking state*/ + linux_wlan_unlock((void *)&g_linux_wlan->cfg_event); + + wilc1000_wlan_deinit(g_linux_wlan); + wilc1000_wlan_init(dev, nic); + g_wilc_initialized = 1; + nic->iftype = interface_type; + + /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ + host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler); + host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_linux_wlan->strInterfaceInfo[0].aSrcAddress); + host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + + /*Add saved WEP keys, if any*/ + if (g_wep_keys_saved) { + host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key_idx); + host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); + } + + /*No matter the driver handler passed here, it will be overwriiten*/ + /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ + host_int_flush_join_req(priv->hWILCWFIDrv); + + /*Add saved PTK and GTK keys, if any*/ + if (g_ptk_keys_saved && g_gtk_keys_saved) { + PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], + g_key_ptk_params.key[1], + g_key_ptk_params.key[2]); + PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0], + g_key_gtk_params.key[1], + g_key_gtk_params.key[2]); + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_ptk_key_params.key_idx, + g_add_ptk_key_params.pairwise, + g_add_ptk_key_params.mac_addr, + (struct key_params *)(&g_key_ptk_params)); + + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_gtk_key_params.key_idx, + g_add_gtk_key_params.pairwise, + g_add_gtk_key_params.mac_addr, + (struct key_params *)(&g_key_gtk_params)); + } + + /*BugID_4847: registered frames in firmware are now*/ + /*lost due to mac close. So re-register those frames*/ + if (g_linux_wlan->wilc1000_initialized) { + for (i = 0; i < num_reg_frame; i++) { + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + host_int_frame_register(priv->hWILCWFIDrv, + nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + } + } + + bEnablePS = WILC_TRUE; + host_int_set_power_mgmt(priv->hWILCWFIDrv, 1, 0); + } + #endif + #endif + break; + + case NL80211_IFTYPE_P2P_CLIENT: + bEnablePS = WILC_FALSE; + host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); + connecting = 0; + PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n"); + + host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID); + + dev->ieee80211_ptr->iftype = type; + priv->wdev->iftype = type; + nic->monitor_flag = 0; + + #ifndef SIMULATION + #ifdef WILC_P2P + + PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n"); + nic->iftype = CLIENT_MODE; + + + if (g_linux_wlan->wilc1000_initialized) { + /* ensure that the message Q is empty */ + host_int_wait_msg_queue_idle(); + + wilc1000_wlan_deinit(g_linux_wlan); + wilc1000_wlan_init(dev, nic); + g_wilc_initialized = 1; + + host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler); + host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_linux_wlan->strInterfaceInfo[0].aSrcAddress); + host_int_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE); + + /*Add saved WEP keys, if any*/ + if (g_wep_keys_saved) { + host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key_idx); + host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); + } + + /*No matter the driver handler passed here, it will be overwriiten*/ + /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ + host_int_flush_join_req(priv->hWILCWFIDrv); + + /*Add saved PTK and GTK keys, if any*/ + if (g_ptk_keys_saved && g_gtk_keys_saved) { + PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0], + g_key_ptk_params.key[1], + g_key_ptk_params.key[2]); + PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0], + g_key_gtk_params.key[1], + g_key_gtk_params.key[2]); + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_ptk_key_params.key_idx, + g_add_ptk_key_params.pairwise, + g_add_ptk_key_params.mac_addr, + (struct key_params *)(&g_key_ptk_params)); + + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_gtk_key_params.key_idx, + g_add_gtk_key_params.pairwise, + g_add_gtk_key_params.mac_addr, + (struct key_params *)(&g_key_gtk_params)); + } + + /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/ + refresh_scan(priv, 1, WILC_TRUE); + Set_machw_change_vir_if(WILC_FALSE); + + /*BugID_4847: registered frames in firmware are now lost + * due to mac close. So re-register those frames */ + if (g_linux_wlan->wilc1000_initialized) { + for (i = 0; i < num_reg_frame; i++) { + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + host_int_frame_register(priv->hWILCWFIDrv, + nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + } + } + } + #endif + #endif + break; + + case NL80211_IFTYPE_AP: + bEnablePS = WILC_FALSE; + PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type); + dev->ieee80211_ptr->iftype = type; + priv->wdev->iftype = type; + nic->iftype = AP_MODE; + PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv); + + #ifndef SIMULATION + PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n"); + linux_wlan_get_firmware(nic); + #ifdef WILC_P2P + /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/ + if (g_linux_wlan->wilc1000_initialized) { + nic->iftype = AP_MODE; + g_linux_wlan->wilc1000_initialized = 1; + mac_close(dev); + mac_open(dev); + + /*BugID_4847: registered frames in firmware are now lost + * due to mac close. So re-register those frames */ + for (i = 0; i < num_reg_frame; i++) { + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + host_int_frame_register(priv->hWILCWFIDrv, + nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + } + } + #endif + #endif + break; + + case NL80211_IFTYPE_P2P_GO: + PRINT_D(GENERIC_DBG, "start duringIP timer\n"); + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + g_obtainingIP = WILC_TRUE; + WILC_TimerStart(&hDuringIpTimer, duringIP_TIME, NULL, NULL); + #endif + host_int_set_power_mgmt(priv->hWILCWFIDrv, 0, 0); + /*BugID_5222*/ + /*Delete block ack has to be the latest config packet*/ + /*sent before downloading new FW. This is because it blocks on*/ + /*hWaitResponse semaphore, which allows previous config*/ + /*packets to actually take action on old FW*/ + host_int_del_All_Rx_BASession(priv->hWILCWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID); + bEnablePS = WILC_FALSE; + PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n"); + dev->ieee80211_ptr->iftype = type; + priv->wdev->iftype = type; + + PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv); + + #ifndef SIMULATION + #ifdef WILC_P2P + PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n"); + + + #if 1 + nic->iftype = GO_MODE; + + /* ensure that the message Q is empty */ + host_int_wait_msg_queue_idle(); + wilc1000_wlan_deinit(g_linux_wlan); + wilc1000_wlan_init(dev, nic); + g_wilc_initialized = 1; + + + /*Setting interface 1 drv handler and mac address in newly downloaded FW*/ + host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler); + host_int_set_MacAddress((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_linux_wlan->strInterfaceInfo[0].aSrcAddress); + host_int_set_operation_mode(priv->hWILCWFIDrv, AP_MODE); + + /*Add saved WEP keys, if any*/ + if (g_wep_keys_saved) { + host_int_set_WEPDefaultKeyID((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key_idx); + host_int_add_wep_key_bss_sta((WILC_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler), + g_key_wep_params.key, + g_key_wep_params.key_len, + g_key_wep_params.key_idx); + } + + /*No matter the driver handler passed here, it will be overwriiten*/ + /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/ + host_int_flush_join_req(priv->hWILCWFIDrv); + + /*Add saved PTK and GTK keys, if any*/ + if (g_ptk_keys_saved && g_gtk_keys_saved) { + PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0], + g_key_ptk_params.key[1], + g_key_ptk_params.key[2], + g_key_ptk_params.cipher); + PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0], + g_key_gtk_params.key[1], + g_key_gtk_params.key[2], + g_key_gtk_params.cipher); + #if 1 + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_ptk_key_params.key_idx, + g_add_ptk_key_params.pairwise, + g_add_ptk_key_params.mac_addr, + (struct key_params *)(&g_key_ptk_params)); + + WILC_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].wilc_netdev->ieee80211_ptr->wiphy, + g_linux_wlan->strInterfaceInfo[0].wilc_netdev, + g_add_gtk_key_params.key_idx, + g_add_gtk_key_params.pairwise, + g_add_gtk_key_params.mac_addr, + (struct key_params *)(&g_key_gtk_params)); + #endif + } + #endif + + /*BugID_4847: registered frames in firmware are now*/ + /*lost due to mac close. So re-register those frames*/ + if (g_linux_wlan->wilc1000_initialized) { + for (i = 0; i < num_reg_frame; i++) { + PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + host_int_frame_register(priv->hWILCWFIDrv, + nic->g_struct_frame_reg[i].frame_type, + nic->g_struct_frame_reg[i].reg); + } + } + #endif + #endif + break; + + default: + PRINT_ER("Unknown interface type= %d\n", type); + s32Error = -EINVAL; + return s32Error; + break; + } + + return s32Error; +} + +/* (austin.2013-07-23) + * + * To support revised cfg80211_ops + * + * add_beacon --> start_ap + * set_beacon --> change_beacon + * del_beacon --> stop_ap + * + * beacon_parameters --> cfg80211_ap_settings + * cfg80211_beacon_data + * + * applicable for linux kernel 3.4+ + */ + +/** + * @brief WILC_WFI_start_ap + * @details Add a beacon with given parameters, @head, @interval + * and @dtim_period will be valid, @tail is optional. + * @param[in] wiphy + * @param[in] dev The net device structure + * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added + * @return int : Return 0 on Success. + * @author austin + * @date 23 JUL 2013 + * @version 1.0 + */ +static int WILC_WFI_start_ap(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ap_settings *settings) +{ + struct cfg80211_beacon_data *beacon = &(settings->beacon); + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + + priv = wiphy_priv(wiphy); + PRINT_D(HOSTAPD_DBG, "Starting ap\n"); + + PRINT_D(HOSTAPD_DBG, "Interval = %d \n DTIM period = %d\n Head length = %zu Tail length = %zu\n", + settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len); + + s32Error = WILC_WFI_CfgSetChannel(wiphy, &settings->chandef); + + if (s32Error != WILC_SUCCESS) + PRINT_ER("Error in setting channel\n"); + + linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress); + + #ifndef WILC_FULLY_HOSTING_AP + s32Error = host_int_add_beacon(priv->hWILCWFIDrv, + settings->beacon_interval, + settings->dtim_period, + beacon->head_len, (u8 *)beacon->head, + beacon->tail_len, (u8 *)beacon->tail); + #else + s32Error = host_add_beacon(priv->hWILCWFIDrv, + settings->beacon_interval, + settings->dtim_period, + beacon->head_len, (u8 *)beacon->head, + beacon->tail_len, (u8 *)beacon->tail); + #endif + + return s32Error; +} + +/** + * @brief WILC_WFI_change_beacon + * @details Add a beacon with given parameters, @head, @interval + * and @dtim_period will be valid, @tail is optional. + * @param[in] wiphy + * @param[in] dev The net device structure + * @param[in] beacon cfg80211_beacon_data for the beacon to be changed + * @return int : Return 0 on Success. + * @author austin + * @date 23 JUL 2013 + * @version 1.0 + */ +static int WILC_WFI_change_beacon(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_beacon_data *beacon) +{ + struct WILC_WFI_priv *priv; + WILC_Sint32 s32Error = WILC_SUCCESS; + + priv = wiphy_priv(wiphy); + PRINT_D(HOSTAPD_DBG, "Setting beacon\n"); + + +#ifndef WILC_FULLY_HOSTING_AP + s32Error = host_int_add_beacon(priv->hWILCWFIDrv, + 0, + 0, + beacon->head_len, (u8 *)beacon->head, + beacon->tail_len, (u8 *)beacon->tail); +#else + s32Error = host_add_beacon(priv->hWILCWFIDrv, + 0, + 0, + beacon->head_len, (u8 *)beacon->head, + beacon->tail_len, (u8 *)beacon->tail); +#endif + + return s32Error; +} + +/** + * @brief WILC_WFI_stop_ap + * @details Remove beacon configuration and stop sending the beacon. + * @param[in] + * @return int : Return 0 on Success. + * @author austin + * @date 23 JUL 2013 + * @version 1.0 + */ +static int WILC_WFI_stop_ap(struct wiphy *wiphy, struct net_device *dev) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + u8 NullBssid[ETH_ALEN] = {0}; + + + WILC_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + + PRINT_D(HOSTAPD_DBG, "Deleting beacon\n"); + + /*BugID_5188*/ + linux_wlan_set_bssid(dev, NullBssid); + + #ifndef WILC_FULLY_HOSTING_AP + s32Error = host_int_del_beacon(priv->hWILCWFIDrv); + #else + s32Error = host_del_beacon(priv->hWILCWFIDrv); + #endif + + WILC_ERRORCHECK(s32Error); + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief WILC_WFI_add_station + * @details Add a new station. + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_add_station(struct wiphy *wiphy, struct net_device *dev, + const u8 *mac, struct station_parameters *params) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + tstrWILC_AddStaParam strStaParams = {{0}}; + perInterface_wlan_t *nic; + + + WILC_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + #ifndef WILC_FULLY_HOSTING_AP + + WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN); + WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); + strStaParams.u16AssocID = params->aid; + strStaParams.u8NumRates = params->supported_rates_len; + strStaParams.pu8Rates = params->supported_rates; + + PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid); + + PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4], + priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]); + PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID); + PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); + + if (params->ht_capa == NULL) { + strStaParams.bIsHTSupported = WILC_FALSE; + } else { + strStaParams.bIsHTSupported = WILC_TRUE; + strStaParams.u16HTCapInfo = params->ht_capa->cap_info; + strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; + WILC_memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); + strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; + strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; + strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; + } + + strStaParams.u16FlagsMask = params->sta_flags_mask; + strStaParams.u16FlagsSet = params->sta_flags_set; + + PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported); + PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); + PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); + PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); + PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); + PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); + PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); + PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); + + s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams); + WILC_ERRORCHECK(s32Error); + + #else + PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid); + WILC_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); + + PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4], + priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]); + + WILC_AP_AddSta(mac, params); + WILC_ERRORCHECK(s32Error); + #endif /* WILC_FULLY_HOSTING_AP */ + + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief WILC_WFI_del_station + * @details Remove a station; @mac may be NULL to remove all stations. + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_del_station(struct wiphy *wiphy, struct net_device *dev, + struct station_del_parameters *params) +{ + const u8 *mac = params->mac; + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + perInterface_wlan_t *nic; + WILC_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + PRINT_D(HOSTAPD_DBG, "Deleting station\n"); + + + if (mac == NULL) { + PRINT_D(HOSTAPD_DBG, "All associated stations \n"); + s32Error = host_int_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss); + } else { + PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + } + + #ifndef WILC_FULLY_HOSTING_AP + s32Error = host_int_del_station(priv->hWILCWFIDrv, mac); + #else + WILC_AP_RemoveSta(mac); + #endif /* WILC_FULLY_HOSTING_AP */ + + WILC_ERRORCHECK(s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief WILC_WFI_change_station + * @details Modify a given station. + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_change_station(struct wiphy *wiphy, struct net_device *dev, + const u8 *mac, struct station_parameters *params) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + struct WILC_WFI_priv *priv; + tstrWILC_AddStaParam strStaParams = {{0}}; + perInterface_wlan_t *nic; + + + PRINT_D(HOSTAPD_DBG, "Change station paramters\n"); + + WILC_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) { + #ifndef WILC_FULLY_HOSTING_AP + + WILC_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN); + strStaParams.u16AssocID = params->aid; + strStaParams.u8NumRates = params->supported_rates_len; + strStaParams.pu8Rates = params->supported_rates; + + PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n", strStaParams.au8BSSID[0], strStaParams.au8BSSID[1], strStaParams.au8BSSID[2], strStaParams.au8BSSID[3], strStaParams.au8BSSID[4], + strStaParams.au8BSSID[5]); + PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.u16AssocID); + PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n", strStaParams.u8NumRates); + + if (params->ht_capa == NULL) { + strStaParams.bIsHTSupported = WILC_FALSE; + } else { + strStaParams.bIsHTSupported = WILC_TRUE; + strStaParams.u16HTCapInfo = params->ht_capa->cap_info; + strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info; + WILC_memcpy(strStaParams.au8SuppMCsSet, ¶ms->ht_capa->mcs, WILC_SUPP_MCS_SET_SIZE); + strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info; + strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info; + strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info; + + } + + strStaParams.u16FlagsMask = params->sta_flags_mask; + strStaParams.u16FlagsSet = params->sta_flags_set; + + PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n", strStaParams.bIsHTSupported); + PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n", strStaParams.u16HTCapInfo); + PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n", strStaParams.u8AmpduParams); + PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n", strStaParams.u16HTExtParams); + PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n", strStaParams.u32TxBeamformingCap); + PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n", strStaParams.u8ASELCap); + PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n", strStaParams.u16FlagsMask); + PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n", strStaParams.u16FlagsSet); + + s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams); + WILC_ERRORCHECK(s32Error); + + #else + WILC_AP_EditSta(mac, params); + WILC_ERRORCHECK(s32Error); + #endif /* WILC_FULLY_HOSTING_AP */ + + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + +/** + * @brief WILC_WFI_add_virt_intf + * @details + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 JUL 2012 + * @version 1.0 + */ +struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + perInterface_wlan_t *nic; + struct WILC_WFI_priv *priv; + struct net_device *new_ifc = NULL; + priv = wiphy_priv(wiphy); + + + + PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev); + + nic = netdev_priv(priv->wdev->netdev); + + + if (type == NL80211_IFTYPE_MONITOR) { + PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n"); + PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev); + new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev); + if (new_ifc != NULL) { + PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n"); + #ifdef SIMULATION + priv = netdev_priv(priv->wdev->netdev); + priv->monitor_flag = 1; + #else + nic = netdev_priv(priv->wdev->netdev); + nic->monitor_flag = 1; + #endif + } else + PRINT_ER("Error in initializing monitor interface\n "); + } + return priv->wdev; +} + +/** + * @brief WILC_WFI_del_virt_intf + * @details + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 JUL 2012 + * @version 1.0 + */ +int WILC_WFI_del_virt_intf(struct wiphy *wiphy, struct wireless_dev *wdev) /* tony for v3.8 support */ +{ + PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n"); + return WILC_SUCCESS; +} + + + +#endif /*WILC_AP_EXTERNAL_MLME*/ +static struct cfg80211_ops WILC_WFI_cfg80211_ops = { + + .set_monitor_channel = WILC_WFI_CfgSetChannel, + .scan = WILC_WFI_CfgScan, + .connect = WILC_WFI_CfgConnect, + .disconnect = WILC_WFI_disconnect, + .add_key = WILC_WFI_add_key, + .del_key = WILC_WFI_del_key, + .get_key = WILC_WFI_get_key, + .set_default_key = WILC_WFI_set_default_key, + #ifdef WILC_AP_EXTERNAL_MLME + .add_virtual_intf = WILC_WFI_add_virt_intf, + .del_virtual_intf = WILC_WFI_del_virt_intf, + .change_virtual_intf = WILC_WFI_change_virt_intf, + + .start_ap = WILC_WFI_start_ap, + .change_beacon = WILC_WFI_change_beacon, + .stop_ap = WILC_WFI_stop_ap, + .add_station = WILC_WFI_add_station, + .del_station = WILC_WFI_del_station, + .change_station = WILC_WFI_change_station, + #endif /* WILC_AP_EXTERNAL_MLME*/ + #ifndef WILC_FULLY_HOSTING_AP + .get_station = WILC_WFI_get_station, + #endif + .dump_station = WILC_WFI_dump_station, + .change_bss = WILC_WFI_change_bss, + .set_wiphy_params = WILC_WFI_set_wiphy_params, + + .set_pmksa = WILC_WFI_set_pmksa, + .del_pmksa = WILC_WFI_del_pmksa, + .flush_pmksa = WILC_WFI_flush_pmksa, +#ifdef WILC_P2P + .remain_on_channel = WILC_WFI_remain_on_channel, + .cancel_remain_on_channel = WILC_WFI_cancel_remain_on_channel, + .mgmt_tx_cancel_wait = WILC_WFI_mgmt_tx_cancel_wait, + .mgmt_tx = WILC_WFI_mgmt_tx, + .mgmt_frame_register = WILC_WFI_frame_register, + .set_power_mgmt = WILC_WFI_set_power_mgmt, + .set_cqm_rssi_config = WILC_WFI_set_cqm_rssi_config, +#endif + +}; + + + + + +/** + * @brief WILC_WFI_update_stats + * @details Modify parameters for a given BSS. + * @param[in] + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0WILC_WFI_set_cqmWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_configWILC_WFI_set_cqm_rssi_config_rssi_config + */ +int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed) +{ + + struct WILC_WFI_priv *priv; + + priv = wiphy_priv(wiphy); +#if 1 + switch (changed) { + + case WILC_WFI_RX_PKT: + { + priv->netstats.rx_packets++; + priv->netstats.rx_bytes += pktlen; + priv->netstats.rx_time = get_jiffies_64(); + } + break; + + case WILC_WFI_TX_PKT: + { + priv->netstats.tx_packets++; + priv->netstats.tx_bytes += pktlen; + priv->netstats.tx_time = get_jiffies_64(); + + } + break; + + default: + break; + } +#endif + return 0; +} + +/** + * @brief WILC_WFI_CfgAlloc + * @details Allocation of the wireless device structure and assigning it + * to the cfg80211 operations structure. + * @param[in] NONE + * @return wireless_dev : Returns pointer to wireless_dev structure. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +struct wireless_dev *WILC_WFI_CfgAlloc(void) +{ + + struct wireless_dev *wdev; + + + PRINT_D(CFG80211_DBG, "Allocating wireless device\n"); + /*Allocating the wireless device structure*/ + wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!wdev) { + PRINT_ER("Cannot allocate wireless device\n"); + goto _fail_; + } + + /*Creating a new wiphy, linking wireless structure with the wiphy structure*/ + wdev->wiphy = wiphy_new(&WILC_WFI_cfg80211_ops, sizeof(struct WILC_WFI_priv)); + if (!wdev->wiphy) { + PRINT_ER("Cannot allocate wiphy\n"); + goto _fail_mem_; + + } + + #ifdef WILC_AP_EXTERNAL_MLME + /* enable 802.11n HT */ + WILC_WFI_band_2ghz.ht_cap.ht_supported = 1; + WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; + WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K; + WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; + #endif + + /*wiphy bands*/ + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz; + + return wdev; + +_fail_mem_: + kfree(wdev); +_fail_: + return NULL; + +} +/** + * @brief WILC_WFI_WiphyRegister + * @details Registering of the wiphy structure and interface modes + * @param[in] NONE + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +struct wireless_dev *WILC_WFI_WiphyRegister(struct net_device *net) +{ + struct WILC_WFI_priv *priv; + struct wireless_dev *wdev; + WILC_Sint32 s32Error = WILC_SUCCESS; + + PRINT_D(CFG80211_DBG, "Registering wifi device\n"); + + wdev = WILC_WFI_CfgAlloc(); + if (wdev == NULL) { + PRINT_ER("CfgAlloc Failed\n"); + return NULL; + } + + + /*Return hardware description structure (wiphy)'s priv*/ + priv = wdev_priv(wdev); + sema_init(&(priv->SemHandleUpdateStats), 1); + + /*Link the wiphy with wireless structure*/ + priv->wdev = wdev; + + /*Maximum number of probed ssid to be added by user for the scan request*/ + wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID; + /*Maximum number of pmkids to be cashed*/ + wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS; + PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids); + + wdev->wiphy->max_scan_ie_len = 1000; + + /*signal strength in mBm (100*dBm) */ + wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + /*Set the availaible cipher suites*/ + wdev->wiphy->cipher_suites = cipher_suites; + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + /*Setting default managment types: for register action frame: */ + wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types; + +#ifdef WILC_P2P + wdev->wiphy->max_remain_on_channel_duration = 500; + /*Setting the wiphy interfcae mode and type before registering the wiphy*/ + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; +#else + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR); +#endif + wdev->iftype = NL80211_IFTYPE_STATION; + + + + PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n", + wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type, + wdev->wiphy->interface_modes, wdev->iftype); + + #ifdef WILC_SDIO + set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); /* tony */ + #endif + + /*Register wiphy structure*/ + s32Error = wiphy_register(wdev->wiphy); + if (s32Error) { + PRINT_ER("Cannot register wiphy device\n"); + /*should define what action to be taken in such failure*/ + } else { + PRINT_D(CFG80211_DBG, "Successful Registering\n"); + } + + priv->dev = net; + return wdev; + + +} +/** + * @brief WILC_WFI_WiphyFree + * @details Freeing allocation of the wireless device structure + * @param[in] NONE + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_InitHostInt(struct net_device *net) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + + struct WILC_WFI_priv *priv; + + PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr); + priv = wdev_priv(net->ieee80211_ptr); + if (op_ifcs == 0) { + s32Error = WILC_TimerCreate(&(hAgingTimer), remove_network_from_shadow, NULL); + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + s32Error = WILC_TimerCreate(&(hDuringIpTimer), clear_duringIP, NULL); + #endif + } + op_ifcs++; + if (s32Error < 0) { + PRINT_ER("Failed to creat refresh Timer\n"); + return s32Error; + } + + priv->gbAutoRateAdjusted = WILC_FALSE; + + priv->bInP2PlistenState = WILC_FALSE; + + sema_init(&(priv->hSemScanReq), 1); + s32Error = host_int_init(&priv->hWILCWFIDrv); + if (s32Error) { + PRINT_ER("Error while initializing hostinterface\n"); + } + return s32Error; +} + +/** + * @brief WILC_WFI_WiphyFree + * @details Freeing allocation of the wireless device structure + * @param[in] NONE + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_DeInitHostInt(struct net_device *net) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + struct WILC_WFI_priv *priv; + priv = wdev_priv(net->ieee80211_ptr); + + priv->gbAutoRateAdjusted = WILC_FALSE; + + priv->bInP2PlistenState = WILC_FALSE; + + op_ifcs--; + + s32Error = host_int_deinit(priv->hWILCWFIDrv); + + /* Clear the Shadow scan */ + clear_shadow_scan(priv); + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (op_ifcs == 0) { + PRINT_D(CORECONFIG_DBG, "destroy during ip\n"); + WILC_TimerDestroy(&hDuringIpTimer, NULL); + } + #endif + + if (s32Error) { + PRINT_ER("Error while deintializing host interface\n"); + } + return s32Error; +} + + +/** + * @brief WILC_WFI_WiphyFree + * @details Freeing allocation of the wireless device structure + * @param[in] NONE + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_WiphyFree(struct net_device *net) +{ + + PRINT_D(CFG80211_DBG, "Unregistering wiphy\n"); + + if (net == NULL) { + PRINT_D(INIT_DBG, "net_device is NULL\n"); + return; + } + + if (net->ieee80211_ptr == NULL) { + PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n"); + return; + } + + if (net->ieee80211_ptr->wiphy == NULL) { + PRINT_D(INIT_DBG, "wiphy is NULL\n"); + return; + } + + wiphy_unregister(net->ieee80211_ptr->wiphy); + + PRINT_D(INIT_DBG, "Freeing wiphy\n"); + wiphy_free(net->ieee80211_ptr->wiphy); + kfree(net->ieee80211_ptr); + +} diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h new file mode 100644 index 000000000000..f45a15f4650f --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -0,0 +1,129 @@ +/*! + * @file wilc_wfi_cfgoperations.h + * @brief Definitions for the network module + * @author syounan + * @sa wilc_oswrapper.h top level OS wrapper file + * @date 31 Aug 2010 + * @version 1.0 + */ +#ifndef NM_WFI_CFGOPERATIONS +#define NM_WFI_CFGOPERATIONS +#include "wilc_wfi_netdevice.h" + +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +#endif + + +/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */ +#define NO_ENCRYPT 0 +#define ENCRYPT_ENABLED (1 << 0) +#define WEP (1 << 1) +#define WEP_EXTENDED (1 << 2) +#define WPA (1 << 3) +#define WPA2 (1 << 4) +#define AES (1 << 5) +#define TKIP (1 << 6) + +#ifdef WILC_P2P +/* #define USE_SUPPLICANT_GO_INTENT */ + +/*Public action frame index IDs*/ +#define FRAME_TYPE_ID 0 +#define ACTION_CAT_ID 24 +#define ACTION_SUBTYPE_ID 25 +#define P2P_PUB_ACTION_SUBTYPE 30 + +/*Public action frame Attribute IDs*/ +#define ACTION_FRAME 0xd0 +#define GO_INTENT_ATTR_ID 0x04 +#define CHANLIST_ATTR_ID 0x0b +#define OPERCHAN_ATTR_ID 0x11 +#ifdef USE_SUPPLICANT_GO_INTENT +#define GROUP_BSSID_ATTR_ID 0x07 +#endif +#define PUB_ACTION_ATTR_ID 0x04 +#define P2PELEM_ATTR_ID 0xdd + +/*Public action subtype values*/ +#define GO_NEG_REQ 0x00 +#define GO_NEG_RSP 0x01 +#define GO_NEG_CONF 0x02 +#define P2P_INV_REQ 0x03 +#define P2P_INV_RSP 0x04 +#define PUBLIC_ACT_VENDORSPEC 0x09 +#define GAS_INTIAL_REQ 0x0a +#define GAS_INTIAL_RSP 0x0b + +#define INVALID_CHANNEL 0 +#ifdef USE_SUPPLICANT_GO_INTENT +#define SUPPLICANT_GO_INTENT 6 +#define GET_GO_INTENT(a) (((a) >> 1) & 0x0f) +#define GET_TIE_BREAKER(a) (((a)) & 0x01) +#else +/* #define FORCE_P2P_CLIENT */ +#endif +#endif + +#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) +#define SCAN_RESULT_EXPIRE (40 * HZ) + +static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + WLAN_CIPHER_SUITE_AES_CMAC, +}; + +static const struct ieee80211_txrx_stypes + wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) + } +}; + +/* Time to stay on the channel */ +#define WILC_WFI_DWELL_PASSIVE 100 +#define WILC_WFI_DWELL_ACTIVE 40 + +struct wireless_dev *WILC_WFI_CfgAlloc(void); +struct wireless_dev *WILC_WFI_WiphyRegister(struct net_device *net); +void WILC_WFI_WiphyFree(struct net_device *net); +int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed); +int WILC_WFI_DeInitHostInt(struct net_device *net); +int WILC_WFI_InitHostInt(struct net_device *net); +void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size); +int WILC_WFI_deinit_mon_interface(void); +struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_device *real_dev); + +#ifdef TCP_ENHANCEMENTS +#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 +#define DEFAULT_LINK_SPEED 72 +extern void Enable_TCP_ACK_Filter(WILC_Bool value); +#endif + +#endif diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.c b/drivers/staging/wilc1000/wilc_wfi_netdevice.c new file mode 100644 index 000000000000..fbc4b857aa35 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.c @@ -0,0 +1,960 @@ +/*! + * @file wilc_wfi_netdevice.c + * @brief File Operations OS wrapper functionality + * @author mdaftedar + * @sa wilc_wfi_netdevice.h + * @date 01 MAR 2012 + * @version 1.0 + */ + +#ifdef SIMULATION + +#include "wilc_wfi_cfgoperations.h" +#include "host_interface.h" + + +MODULE_AUTHOR("Mai Daftedar"); +MODULE_LICENSE("Dual BSD/GPL"); + + +struct net_device *WILC_WFI_devs[2]; + +/* + * Transmitter lockup simulation, normally disabled. + */ +static int lockup; +module_param(lockup, int, 0); + +static int timeout = WILC_WFI_TIMEOUT; +module_param(timeout, int, 0); + +/* + * Do we run in NAPI mode? + */ +static int use_napi ; +module_param(use_napi, int, 0); + + +/* + * A structure representing an in-flight packet. + */ +struct WILC_WFI_packet { + struct WILC_WFI_packet *next; + struct net_device *dev; + int datalen; + u8 data[ETH_DATA_LEN]; +}; + + + +int pool_size = 8; +module_param(pool_size, int, 0); + + +static void WILC_WFI_TxTimeout(struct net_device *dev); +static void (*WILC_WFI_Interrupt)(int, void *, struct pt_regs *); + +/** + * @brief WILC_WFI_SetupPool + * @details Set up a device's packet pool. + * @param[in] struct net_device *dev : Network Device Pointer + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_SetupPool(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + int i; + struct WILC_WFI_packet *pkt; + + priv->ppool = NULL; + for (i = 0; i < pool_size; i++) { + pkt = kmalloc (sizeof (struct WILC_WFI_packet), GFP_KERNEL); + if (pkt == NULL) { + PRINT_D(RX_DBG, "Ran out of memory allocating packet pool\n"); + return; + } + pkt->dev = dev; + pkt->next = priv->ppool; + priv->ppool = pkt; + } +} + +/** + * @brief WILC_WFI_TearDownPool + * @details Internal cleanup function that's called after the network device + * driver is unregistered + * @param[in] struct net_device *dev : Network Device Driver + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_TearDownPool(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + struct WILC_WFI_packet *pkt; + + while ((pkt = priv->ppool)) { + priv->ppool = pkt->next; + kfree (pkt); + /* FIXME - in-flight packets ? */ + } +} + +/** + * @brief WILC_WFI_GetTxBuffer + * @details Buffer/pool management + * @param[in] net_device *dev : Network Device Driver Structure + * @return struct WILC_WFI_packet + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +struct WILC_WFI_packet *WILC_WFI_GetTxBuffer(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + unsigned long flags; + struct WILC_WFI_packet *pkt; + + spin_lock_irqsave(&priv->lock, flags); + pkt = priv->ppool; + priv->ppool = pkt->next; + if (priv->ppool == NULL) { + PRINT_INFO(RX_DBG, "Pool empty\n"); + netif_stop_queue(dev); + } + spin_unlock_irqrestore(&priv->lock, flags); + return pkt; +} +/** + * @brief WILC_WFI_ReleaseBuffer + * @details Buffer/pool management + * @param[in] WILC_WFI_packet *pkt : Structure holding in-flight packet + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_ReleaseBuffer(struct WILC_WFI_packet *pkt) +{ + unsigned long flags; + struct WILC_WFI_priv *priv = netdev_priv(pkt->dev); + + spin_lock_irqsave(&priv->lock, flags); + pkt->next = priv->ppool; + priv->ppool = pkt; + spin_unlock_irqrestore(&priv->lock, flags); + if (netif_queue_stopped(pkt->dev) && pkt->next == NULL) + netif_wake_queue(pkt->dev); +} + +/** + * @brief WILC_WFI_EnqueueBuf + * @details Enqueuing packets in an RX buffer queue + * @param[in] WILC_WFI_packet *pkt : Structure holding in-flight packet + * @param[in] net_device *dev : Network Device Driver Structure + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_EnqueueBuf(struct net_device *dev, struct WILC_WFI_packet *pkt) +{ + unsigned long flags; + struct WILC_WFI_priv *priv = netdev_priv(dev); + + spin_lock_irqsave(&priv->lock, flags); + pkt->next = priv->rx_queue; /* FIXME - misorders packets */ + priv->rx_queue = pkt; + spin_unlock_irqrestore(&priv->lock, flags); +} + +/** + * @brief WILC_WFI_DequeueBuf + * @details Dequeuing packets from the RX buffer queue + * @param[in] net_device *dev : Network Device Driver Structure + * @return WILC_WFI_packet *pkt : Structure holding in-flight pac + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +struct WILC_WFI_packet *WILC_WFI_DequeueBuf(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + struct WILC_WFI_packet *pkt; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + pkt = priv->rx_queue; + if (pkt != NULL) + priv->rx_queue = pkt->next; + spin_unlock_irqrestore(&priv->lock, flags); + return pkt; +} +/** + * @brief WILC_WFI_RxInts + * @details Enable and disable receive interrupts. + * @param[in] net_device *dev : Network Device Driver Structure + * @param[in] enable : Enable/Disable flag + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static void WILC_WFI_RxInts(struct net_device *dev, int enable) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + priv->rx_int_enabled = enable; +} + +/** + * @brief WILC_WFI_Open + * @details Open Network Device Driver, called when the network + * interface is opened. It starts the interface's transmit queue. + * @param[in] net_device *dev : Network Device Driver Structure + * @param[in] enable : Enable/Disable flag + * @return int : Returns 0 upon success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Open(struct net_device *dev) +{ + /* request_region(), request_irq(), .... (like fops->open) */ + /* + * Assign the hardware address of the board: use "\0SNULx", where + * x is 0 or 1. The first byte is '\0' to avoid being a multicast + * address (the first byte of multicast addrs is odd). + */ + memcpy(dev->dev_addr, "\0WLAN0", ETH_ALEN); + if (dev == WILC_WFI_devs[1]) + dev->dev_addr[ETH_ALEN - 1]++; /* \0SNUL1 */ + + WILC_WFI_InitHostInt(dev); + netif_start_queue(dev); + return 0; +} +/** + * @brief WILC_WFI_Release + * @details Release Network Device Driver, called when the network + * interface is stopped or brought down. This function marks + * the network driver as not being able to transmit + * @param[in] net_device *dev : Network Device Driver Structure + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Release(struct net_device *dev) +{ + /* release ports, irq and such -- like fops->close */ + + netif_stop_queue(dev); /* can't transmit any more */ + + return 0; +} +/** + * @brief WILC_WFI_Config + * @details Configuration changes (passed on by ifconfig) + * @param[in] net_device *dev : Network Device Driver Structure + * @param[in] struct ifmap *map : Contains the ioctl implementation for the + * network driver. + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Config(struct net_device *dev, struct ifmap *map) +{ + if (dev->flags & IFF_UP) /* can't act on a running interface */ + return -EBUSY; + + /* Don't allow changing the I/O address */ + if (map->base_addr != dev->base_addr) { + PRINT_D(RX_DBG, KERN_WARNING "WILC_WFI: Can't change I/O address\n"); + return -EOPNOTSUPP; + } + + /* Allow changing the IRQ */ + if (map->irq != dev->irq) { + dev->irq = map->irq; + /* request_irq() is delayed to open-time */ + } + + /* ignore other fields */ + return 0; +} +/** + * @brief WILC_WFI_Rx + * @details Receive a packet: retrieve, encapsulate and pass over to upper + * levels + * @param[in] net_device *dev : Network Device Driver Structure + * @param[in] WILC_WFI_packet : + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_Rx(struct net_device *dev, struct WILC_WFI_packet *pkt) +{ + int i; + struct sk_buff *skb; + struct WILC_WFI_priv *priv = netdev_priv(dev); + s8 rssi; + /* + * The packet has been retrieved from the transmission + * medium. Build an skb around it, so upper layers can handle it + */ + + + skb = dev_alloc_skb(pkt->datalen + 2); + if (!skb) { + if (printk_ratelimit()) + PRINT_D(RX_DBG, "WILC_WFI rx: low on mem - packet dropped\n"); + priv->stats.rx_dropped++; + goto out; + } + skb_reserve(skb, 2); /* align IP on 16B boundary */ + memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen); + + if (priv->monitor_flag) { + PRINT_INFO(RX_DBG, "In monitor device name %s\n", dev->name); + priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); + PRINT_D(RX_DBG, "VALUE PASSED IN OF HRWD %p\n", priv->hWILCWFIDrv); + /* host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); */ + if (INFO) { + for (i = 14; i < skb->len; i++) + PRINT_INFO(RX_DBG, "RXdata[%d] %02x\n", i, skb->data[i]); + } + WILC_WFI_monitor_rx(dev, skb); + return; + } +#if 0 + PRINT_D(RX_DBG, "In RX NORMAl Device name %s\n", dev->name); + /* Write metadata, and then pass to the receive level */ + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ + WILC_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy, pkt->datalen, WILC_WFI_RX_PKT); + netif_rx(skb); +#endif +out: + return; +} + +/** + * @brief WILC_WFI_Poll + * @details The poll implementation + * @param[in] struct napi_struct *napi : + * @param[in] int budget : + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static int WILC_WFI_Poll(struct napi_struct *napi, int budget) +{ + int npackets = 0; + struct sk_buff *skb; + struct WILC_WFI_priv *priv = container_of(napi, struct WILC_WFI_priv, napi); + struct net_device *dev = priv->dev; + struct WILC_WFI_packet *pkt; + + while (npackets < budget && priv->rx_queue) { + pkt = WILC_WFI_DequeueBuf(dev); + skb = dev_alloc_skb(pkt->datalen + 2); + if (!skb) { + if (printk_ratelimit()) + PRINT_D(RX_DBG, "WILC_WFI: packet dropped\n"); + priv->stats.rx_dropped++; + WILC_WFI_ReleaseBuffer(pkt); + continue; + } + skb_reserve(skb, 2); /* align IP on 16B boundary */ + memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ + netif_receive_skb(skb); + /* Maintain stats */ + npackets++; + WILC_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy, pkt->datalen, WILC_WFI_RX_PKT); + WILC_WFI_ReleaseBuffer(pkt); + } + /* If we processed all packets, we're done; tell the kernel and re-enable ints */ + if (npackets < budget) { + napi_complete(napi); + WILC_WFI_RxInts(dev, 1); + } + return npackets; +} + +/** + * @brief WILC_WFI_Poll + * @details The typical interrupt entry point + * @param[in] struct napi_struct *napi : + * @param[in] int budget : + * @return int : Return 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static void WILC_WFI_RegularInterrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int statusword; + struct WILC_WFI_priv *priv; + struct WILC_WFI_packet *pkt = NULL; + /* + * As usual, check the "device" pointer to be sure it is + * really interrupting. + * Then assign "struct device *dev" + */ + struct net_device *dev = (struct net_device *)dev_id; + /* ... and check with hw if it's really ours */ + + /* paranoid */ + if (!dev) + return; + + /* Lock the device */ + priv = netdev_priv(dev); + spin_lock(&priv->lock); + + /* retrieve statusword: real netdevices use I/O instructions */ + statusword = priv->status; + priv->status = 0; + if (statusword & WILC_WFI_RX_INTR) { + /* send it to WILC_WFI_rx for handling */ + pkt = priv->rx_queue; + if (pkt) { + priv->rx_queue = pkt->next; + WILC_WFI_Rx(dev, pkt); + } + } + if (statusword & WILC_WFI_TX_INTR) { + /* a transmission is over: free the skb */ + WILC_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy, priv->tx_packetlen, WILC_WFI_TX_PKT); + dev_kfree_skb(priv->skb); + } + + /* Unlock the device and we are done */ + spin_unlock(&priv->lock); + if (pkt) + WILC_WFI_ReleaseBuffer(pkt); /* Do this outside the lock! */ + return; +} +/** + * @brief WILC_WFI_NapiInterrupt + * @details A NAPI interrupt handler + * @param[in] irq: + * @param[in] dev_id: + * @param[in] pt_regs: + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +static void WILC_WFI_NapiInterrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int statusword; + struct WILC_WFI_priv *priv; + + /* + * As usual, check the "device" pointer for shared handlers. + * Then assign "struct device *dev" + */ + struct net_device *dev = (struct net_device *)dev_id; + /* ... and check with hw if it's really ours */ + + /* paranoid */ + if (!dev) + return; + + /* Lock the device */ + priv = netdev_priv(dev); + spin_lock(&priv->lock); + + /* retrieve statusword: real netdevices use I/O instructions */ + statusword = priv->status; + priv->status = 0; + if (statusword & WILC_WFI_RX_INTR) { + WILC_WFI_RxInts(dev, 0); /* Disable further interrupts */ + napi_schedule(&priv->napi); + } + if (statusword & WILC_WFI_TX_INTR) { + /* a transmission is over: free the skb */ + + WILC_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy, priv->tx_packetlen, WILC_WFI_TX_PKT); + dev_kfree_skb(priv->skb); + } + + /* Unlock the device and we are done */ + spin_unlock(&priv->lock); + return; +} + +/** + * @brief MI_WFI_HwTx + * @details Transmit a packet (low level interface) + * @param[in] buf: + * @param[in] len: + * @param[in] net_device *dev: + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_HwTx(char *buf, int len, struct net_device *dev) +{ + /* + * This function deals with hw details. This interface loops + * back the packet to the other WILC_WFI interface (if any). + * In other words, this function implements the WILC_WFI behaviour, + * while all other procedures are rather device-independent + */ + struct iphdr *ih; + struct net_device *dest; + struct WILC_WFI_priv *priv; + u32 *saddr, *daddr; + struct WILC_WFI_packet *tx_buffer; + + + /* I am paranoid. Ain't I? */ + if (len < sizeof(struct ethhdr) + sizeof(struct iphdr)) { + PRINT_D(RX_DBG, "WILC_WFI: Hmm... packet too short (%i octets)\n", + len); + return; + } + + if (0) { /* enable this conditional to look at the data */ + int i; + PRINT_D(RX_DBG, "len is %i", len); + for (i = 14; i < len; i++) + PRINT_D(RX_DBG, "TXdata[%d] %02x\n", i, buf[i] & 0xff); + /* PRINT_D(RX_DBG, "\n"); */ + } + /* + * Ethhdr is 14 bytes, but the kernel arranges for iphdr + * to be aligned (i.e., ethhdr is unaligned) + */ + ih = (struct iphdr *)(buf + sizeof(struct ethhdr)); + saddr = &ih->saddr; + daddr = &ih->daddr; + + ((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */ + ((u8 *)daddr)[2] ^= 1; + + ih->check = 0; /* and rebuild the checksum (ip needs it) */ + ih->check = ip_fast_csum((unsigned char *)ih, ih->ihl); + + + if (dev == WILC_WFI_devs[0]) + PRINT_D(RX_DBG, "%08x:%05i --> %08x:%05i\n", + ntohl(ih->saddr), ntohs(((struct tcphdr *)(ih + 1))->source), + ntohl(ih->daddr), ntohs(((struct tcphdr *)(ih + 1))->dest)); + else + PRINT_D(RX_DBG, "%08x:%05i <-- %08x:%05i\n", + ntohl(ih->daddr), ntohs(((struct tcphdr *)(ih + 1))->dest), + ntohl(ih->saddr), ntohs(((struct tcphdr *)(ih + 1))->source)); + + /* + * Ok, now the packet is ready for transmission: first simulate a + * receive interrupt on the twin device, then a + * transmission-done on the transmitting device + */ + dest = WILC_WFI_devs[dev == WILC_WFI_devs[0] ? 1 : 0]; + priv = netdev_priv(dest); + + tx_buffer = WILC_WFI_GetTxBuffer(dev); + tx_buffer->datalen = len; + memcpy(tx_buffer->data, buf, len); + WILC_WFI_EnqueueBuf(dest, tx_buffer); + if (priv->rx_int_enabled) { + priv->status |= WILC_WFI_RX_INTR; + WILC_WFI_Interrupt(0, dest, NULL); + } + + priv = netdev_priv(dev); + priv->tx_packetlen = len; + priv->tx_packetdata = buf; + priv->status |= WILC_WFI_TX_INTR; + if (lockup && ((priv->stats.tx_packets + 1) % lockup) == 0) { + /* Simulate a dropped transmit interrupt */ + netif_stop_queue(dev); + PRINT_D(RX_DBG, "Simulate lockup at %ld, txp %ld\n", jiffies, + (unsigned long) priv->stats.tx_packets); + } else + WILC_WFI_Interrupt(0, dev, NULL); + +} + +/** + * @brief WILC_WFI_Tx + * @details Transmit a packet (called by the kernel) + * @param[in] sk_buff *skb: + * @param[in] net_device *dev: + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Tx(struct sk_buff *skb, struct net_device *dev) +{ + int len; + char *data, shortpkt[ETH_ZLEN]; + struct WILC_WFI_priv *priv = netdev_priv(dev); + + /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ + + /* if(priv->monitor_flag) */ + /* mac80211_hwsim_monitor_rx(skb); */ + + + data = skb->data; + len = skb->len; + + if (len < ETH_ZLEN) { + memset(shortpkt, 0, ETH_ZLEN); + memcpy(shortpkt, skb->data, skb->len); + len = ETH_ZLEN; + data = shortpkt; + } + dev->trans_start = jiffies; /* save the timestamp */ + + /* Remember the skb, so we can free it at interrupt time */ + priv->skb = skb; + + /* actual deliver of data is device-specific, and not shown here */ + WILC_WFI_HwTx(data, len, dev); + + return 0; /* Our simple device can not fail */ +} + +/** + * @brief WILC_WFI_TxTimeout + * @details Deal with a transmit timeout. + * @param[in] net_device *dev: + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_TxTimeout(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + + PRINT_D(RX_DBG, "Transmit timeout at %ld, latency %ld\n", jiffies, + jiffies - dev->trans_start); + /* Simulate a transmission interrupt to get things moving */ + priv->status = WILC_WFI_TX_INTR; + WILC_WFI_Interrupt(0, dev, NULL); + priv->stats.tx_errors++; + netif_wake_queue(dev); + return; +} + +/** + * @brief WILC_WFI_Ioctl + * @details Ioctl commands + * @param[in] net_device *dev: + * @param[in] ifreq *rq + * @param[in] cmd: + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + PRINT_D(RX_DBG, "ioctl\n"); + return 0; +} + +/** + * @brief WILC_WFI_Stat + * @details Return statistics to the caller + * @param[in] net_device *dev: + * @return WILC_WFI_Stats : Return net_device_stats stucture with the + * network device driver private data contents. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +struct net_device_stats *WILC_WFI_Stats(struct net_device *dev) +{ + struct WILC_WFI_priv *priv = netdev_priv(dev); + return &priv->stats; +} + +/** + * @brief WILC_WFI_RebuildHeader + * @details This function is called to fill up an eth header, since arp is not + * available on the interface + * @param[in] sk_buff *skb: + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_RebuildHeader(struct sk_buff *skb) +{ + struct ethhdr *eth = (struct ethhdr *) skb->data; + struct net_device *dev = skb->dev; + + memcpy(eth->h_source, dev->dev_addr, dev->addr_len); + memcpy(eth->h_dest, dev->dev_addr, dev->addr_len); + eth->h_dest[ETH_ALEN - 1] ^= 0x01; /* dest is us xor 1 */ + return 0; +} +/** + * @brief WILC_WFI_RebuildHeader + * @details This function is called to fill up an eth header, since arp is not + * available on the interface + * @param[in] sk_buff *skb: + * @param[in] struct net_device *dev: + * @param[in] unsigned short type: + * @param[in] const void *saddr, + * @param[in] const void *daddr: + * @param[in] unsigned int len + * @return int : Return 0 on Success + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_Header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, const void *saddr, + unsigned int len) +{ + struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); + + eth->h_proto = htons(type); + memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len); + memcpy(eth->h_dest, daddr ? daddr : dev->dev_addr, dev->addr_len); + eth->h_dest[ETH_ALEN - 1] ^= 0x01; /* dest is us xor 1 */ + return dev->hard_header_len; +} + +/** + * @brief WILC_WFI_ChangeMtu + * @details The "change_mtu" method is usually not needed. + * If you need it, it must be like this. + * @param[in] net_device *dev : Network Device Driver Structure + * @param[in] new_mtu : + * @return int : Returns 0 on Success. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_ChangeMtu(struct net_device *dev, int new_mtu) +{ + unsigned long flags; + struct WILC_WFI_priv *priv = netdev_priv(dev); + spinlock_t *lock = &priv->lock; + + /* check ranges */ + if ((new_mtu < 68) || (new_mtu > 1500)) + return -EINVAL; + /* + * Do anything you need, and the accept the value + */ + spin_lock_irqsave(lock, flags); + dev->mtu = new_mtu; + spin_unlock_irqrestore(lock, flags); + return 0; /* success */ +} + +static const struct header_ops WILC_WFI_header_ops = { + .create = WILC_WFI_Header, + .rebuild = WILC_WFI_RebuildHeader, + .cache = NULL, /* disable caching */ +}; + + +static const struct net_device_ops WILC_WFI_netdev_ops = { + .ndo_open = WILC_WFI_Open, + .ndo_stop = WILC_WFI_Release, + .ndo_set_config = WILC_WFI_Config, + .ndo_start_xmit = WILC_WFI_Tx, + .ndo_do_ioctl = WILC_WFI_Ioctl, + .ndo_get_stats = WILC_WFI_Stats, + .ndo_change_mtu = WILC_WFI_ChangeMtu, + .ndo_tx_timeout = WILC_WFI_TxTimeout, +}; + +/** + * @brief WILC_WFI_Init + * @details The init function (sometimes called probe). + * It is invoked by register_netdev() + * @param[in] net_device *dev: + * @return NONE + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +void WILC_WFI_Init(struct net_device *dev) +{ + struct WILC_WFI_priv *priv; + + + /* + * Then, assign other fields in dev, using ether_setup() and some + * hand assignments + */ + ether_setup(dev); /* assign some of the fields */ + /* 1- Allocate space */ + + dev->netdev_ops = &WILC_WFI_netdev_ops; + dev->header_ops = &WILC_WFI_header_ops; + dev->watchdog_timeo = timeout; + /* keep the default flags, just add NOARP */ + dev->flags |= IFF_NOARP; + dev->features |= NETIF_F_NO_CSUM; + /* + * Then, initialize the priv field. This encloses the statistics + * and a few private fields. + */ + priv = netdev_priv(dev); + memset(priv, 0, sizeof(struct WILC_WFI_priv)); + priv->dev = dev; + netif_napi_add(dev, &priv->napi, WILC_WFI_Poll, 2); + /* The last parameter above is the NAPI "weight". */ + spin_lock_init(&priv->lock); + WILC_WFI_RxInts(dev, 1); /* enable receive interrupts */ + WILC_WFI_SetupPool(dev); +} + +/** + * @brief WILC_WFI_Stat + * @details Return statistics to the caller + * @param[in] net_device *dev: + * @return WILC_WFI_Stats : Return net_device_stats stucture with the + * network device driver private data contents. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ + +void WILC_WFI_Cleanup(void) +{ + int i; + struct WILC_WFI_priv *priv[2]; + + /*if(hwsim_mon!=NULL) + * { + * PRINT_D(RX_DBG, "Freeing monitor interface\n"); + * unregister_netdev(hwsim_mon); + * free_netdev(hwsim_mon); + * }*/ + for (i = 0; i < 2; i++) { + priv[i] = netdev_priv(WILC_WFI_devs[i]); + + if (WILC_WFI_devs[i]) { + PRINT_D(RX_DBG, "Unregistering\n"); + unregister_netdev(WILC_WFI_devs[i]); + WILC_WFI_TearDownPool(WILC_WFI_devs[i]); + free_netdev(WILC_WFI_devs[i]); + PRINT_D(RX_DBG, "[NETDEV]Stopping interface\n"); + WILC_WFI_DeInitHostInt(WILC_WFI_devs[i]); + WILC_WFI_WiphyFree(WILC_WFI_devs[i]); + } + + } + /* unregister_netdev(hwsim_mon); */ + WILC_WFI_deinit_mon_interface(); + return; +} + + +void StartConfigSim(void); + + + + + + + +/** + * @brief WILC_WFI_Stat + * @details Return statistics to the caller + * @param[in] net_device *dev: + * @return WILC_WFI_Stats : Return net_device_stats stucture with the + * network device driver private data contents. + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +int WILC_WFI_InitModule(void) +{ + + int result, i, ret = -ENOMEM; + struct WILC_WFI_priv *priv[2], *netpriv; + struct wireless_dev *wdev; + WILC_WFI_Interrupt = use_napi ? WILC_WFI_NapiInterrupt : WILC_WFI_RegularInterrupt; + char buf[IFNAMSIZ]; + + for (i = 0; i < 2; i++) { + + /* Allocate the net devices */ + WILC_WFI_devs[i] = alloc_netdev(sizeof(struct WILC_WFI_priv), "wlan%d", + WILC_WFI_Init); + if (WILC_WFI_devs[i] == NULL) + goto out; + /* priv[i] = netdev_priv(WILC_WFI_devs[i]); */ + + wdev = WILC_WFI_WiphyRegister(WILC_WFI_devs[i]); + WILC_WFI_devs[i]->ieee80211_ptr = wdev; + netpriv = netdev_priv(WILC_WFI_devs[i]); + netpriv->dev->ieee80211_ptr = wdev; + netpriv->dev->ml_priv = netpriv; + wdev->netdev = netpriv->dev; + + /*Registering the net device*/ + result = register_netdev(WILC_WFI_devs[i]); + if (result) + PRINT_D(RX_DBG, "WILC_WFI: error %i registering device \"%s\"\n", + result, WILC_WFI_devs[i]->name); + else + ret = 0; + } + + + /*init atmel driver */ + priv[0] = netdev_priv(WILC_WFI_devs[0]); + priv[1] = netdev_priv(WILC_WFI_devs[1]); + + if (priv[1]->dev->ieee80211_ptr->wiphy->interface_modes && BIT(NL80211_IFTYPE_MONITOR)) { + /* snprintf(buf, IFNAMSIZ, "mon.%s", priv[1]->dev->name); */ + /* WILC_WFI_init_mon_interface(); */ + /* priv[1]->monitor_flag = 1; */ + + } + priv[0]->bCfgScanning = WILC_FALSE; + priv[0]->u32RcvdChCount = 0; + + WILC_memset(priv[0]->au8AssociatedBss, 0xFF, ETH_ALEN); + + + /* ret = host_int_init(&priv[0]->hWILCWFIDrv); */ + /*copy handle to the other driver*/ + /* priv[1]->hWILCWFIDrv = priv[0]->hWILCWFIDrv; */ + if (ret) { + PRINT_ER("Error Init Driver\n"); + } + + +out: + if (ret) + WILC_WFI_Cleanup(); + return ret; + + +} + + +module_init(WILC_WFI_InitModule); +module_exit(WILC_WFI_Cleanup); + +#endif diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h new file mode 100644 index 000000000000..b322f0f956ea --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -0,0 +1,269 @@ +/*! + * @file wilc_wfi_netdevice.h + * @brief Definitions for the network module + * @author mdaftedar + * @date 01 MAR 2012 + * @version 1.0 + */ +#ifndef WILC_WFI_NETDEVICE +#define WILC_WFI_NETDEVICE + +/* These are the flags in the statusword */ +#define WILC_WFI_RX_INTR 0x0001 +#define WILC_WFI_TX_INTR 0x0002 + +/* Default timeout period */ +#define WILC_WFI_TIMEOUT 5 /* In jiffies */ +#define WILC_MAX_NUM_PMKIDS 16 +#define PMKID_LEN 16 +#define PMKID_FOUND 1 + #define NUM_STA_ASSOCIATED 8 + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/moduleparam.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/slab.h> /* kmalloc() */ +#include <linux/errno.h> /* error codes */ +#include <linux/types.h> /* size_t */ +#include <linux/interrupt.h> /* mark_bh */ +#include <linux/time.h> +#include <linux/in.h> +#include <linux/netdevice.h> /* struct device, and other headers */ +#include <linux/etherdevice.h> /* eth_type_trans */ +#include <linux/ip.h> /* struct iphdr */ +#include <linux/tcp.h> /* struct tcphdr */ +#include <linux/skbuff.h> + +#include <linux/ieee80211.h> +#include <net/cfg80211.h> + +#include <linux/ieee80211.h> +#include <net/cfg80211.h> +#include <net/ieee80211_radiotap.h> +#include <linux/if_arp.h> + + +#include <linux/in6.h> +#include <asm/checksum.h> +#include "host_interface.h" +#include "wilc_wlan.h" +#include <linux/wireless.h> /* tony, 2013-06-12 */ + +#define FLOW_CONTROL_LOWER_THRESHOLD 128 +#define FLOW_CONTROL_UPPER_THRESHOLD 256 + +/*iftype*/ + + +enum stats_flags { + WILC_WFI_RX_PKT = 1 << 0, + WILC_WFI_TX_PKT = 1 << 1, +}; + +struct WILC_WFI_stats { + + unsigned long rx_packets; + unsigned long tx_packets; + unsigned long rx_bytes; + unsigned long tx_bytes; + u64 rx_time; + u64 tx_time; + +}; + +/* + * This structure is private to each device. It is used to pass + * packets in and out, so there is place for a packet + */ + +#define RX_BH_KTHREAD 0 +#define RX_BH_WORK_QUEUE 1 +#define RX_BH_THREADED_IRQ 2 +#define num_reg_frame 2 +/* + * If you use RX_BH_WORK_QUEUE on LPC3131: You may lose the first interrupt on + * LPC3131 which is important to get the MAC start status when you are blocked inside + * linux_wlan_firmware_download() which blocks mac_open(). + */ +#if defined (NM73131_0_BOARD) + #define RX_BH_TYPE RX_BH_KTHREAD +#elif defined (PANDA_BOARD) + #define RX_BH_TYPE RX_BH_THREADED_IRQ +#else + #define RX_BH_TYPE RX_BH_KTHREAD +#endif + +struct wilc_wfi_key { + u8 *key; + u8 *seq; + int key_len; + int seq_len; + u32 cipher; +}; +struct wilc_wfi_wep_key { + u8 *key; + u8 key_len; + u8 key_idx; +}; + +struct sta_info { + u8 au8Sta_AssociatedBss[MAX_NUM_STA][ETH_ALEN]; +}; + +#ifdef WILC_P2P +/*Parameters needed for host interface for remaining on channel*/ +struct wilc_wfi_p2pListenParams { + struct ieee80211_channel *pstrListenChan; + enum nl80211_channel_type tenuChannelType; + WILC_Uint32 u32ListenDuration; + WILC_Uint64 u64ListenCookie; + WILC_Uint32 u32ListenSessionID; +}; + +#endif /*WILC_P2P*/ + +struct WILC_WFI_priv { + struct wireless_dev *wdev; + struct cfg80211_scan_request *pstrScanReq; + + #ifdef WILC_P2P + struct wilc_wfi_p2pListenParams strRemainOnChanParams; + WILC_Uint64 u64tx_cookie; + + #endif + + WILC_Bool bCfgScanning; + WILC_Uint32 u32RcvdChCount; + + + + u8 au8AssociatedBss[ETH_ALEN]; + struct sta_info assoc_stainfo; + struct net_device_stats stats; + u8 monitor_flag; + int status; + struct WILC_WFI_packet *ppool; + struct WILC_WFI_packet *rx_queue; /* List of incoming packets */ + int rx_int_enabled; + int tx_packetlen; + u8 *tx_packetdata; + struct sk_buff *skb; + spinlock_t lock; + struct net_device *dev; + struct napi_struct napi; + WILC_WFIDrvHandle hWILCWFIDrv; + WILC_WFIDrvHandle hWILCWFIDrv_2; + tstrHostIFpmkidAttr pmkid_list; + struct WILC_WFI_stats netstats; + u8 WILC_WFI_wep_default; + u8 WILC_WFI_wep_key[4][WLAN_KEY_LEN_WEP104]; + u8 WILC_WFI_wep_key_len[4]; + struct net_device *real_ndev; /* The real interface that the monitor is on */ + struct wilc_wfi_key *wilc_gtk[MAX_NUM_STA]; + struct wilc_wfi_key *wilc_ptk[MAX_NUM_STA]; + u8 wilc_groupkey; + /* semaphores */ + struct semaphore SemHandleUpdateStats; + struct semaphore hSemScanReq; + /* */ + WILC_Bool gbAutoRateAdjusted; + + WILC_Bool bInP2PlistenState; + +}; + +typedef struct { + WILC_Uint16 frame_type; + WILC_Bool reg; + +} struct_frame_reg; + + +#define NUM_CONCURRENT_IFC 2 +typedef struct { + uint8_t aSrcAddress[ETH_ALEN]; + uint8_t aBSSID[ETH_ALEN]; + uint32_t drvHandler; + struct net_device *wilc_netdev; +} tstrInterfaceInfo; +typedef struct { + int mac_status; + int wilc1000_initialized; + + + #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO) + unsigned short dev_irq_num; + #endif + wilc_wlan_oup_t oup; + int close; + uint8_t u8NoIfcs; + tstrInterfaceInfo strInterfaceInfo[NUM_CONCURRENT_IFC]; + uint8_t open_ifcs; + struct mutex txq_cs; + + /*Added by Amr - BugID_4720*/ + struct mutex txq_add_to_head_cs; + spinlock_t txq_spinlock; + + struct mutex rxq_cs; + struct mutex hif_cs; + + /* struct mutex txq_event; */ + struct semaphore rxq_event; + struct semaphore cfg_event; + struct semaphore sync_event; + + struct semaphore txq_event; + /* struct completion txq_event; */ + +#if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + struct work_struct rx_work_queue; +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + struct task_struct *rx_bh_thread; + struct semaphore rx_sem; +#endif + + + + struct semaphore rxq_thread_started; + struct semaphore txq_thread_started; + + struct task_struct *rxq_thread; + struct task_struct *txq_thread; + + unsigned char eth_src_address[NUM_CONCURRENT_IFC][6]; + /* unsigned char eth_dst_address[6]; */ + + const struct firmware *wilc_firmware; /* Bug 4703 */ + + struct net_device *real_ndev; +#ifdef WILC_SDIO + int already_claim; + struct sdio_func *wilc_sdio_func; +#else + struct spi_device *wilc_spidev; +#endif + +} linux_wlan_t; + +typedef struct { + uint8_t u8IfIdx; + u8 iftype; + int monitor_flag; + int mac_opened; + #ifdef WILC_P2P + struct_frame_reg g_struct_frame_reg[num_reg_frame]; + #endif + struct net_device *wilc_netdev; + struct net_device_stats netstats; + +} perInterface_wlan_t; + +struct WILC_WFI_mon_priv { + struct net_device *real_ndev; +}; +extern struct net_device *WILC_WFI_devs[]; + +#endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c new file mode 100644 index 000000000000..9edc851cb705 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -0,0 +1,2363 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_wlan.c */ +/* */ +/* */ +/* //////////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#define INLINE static __inline + +/******************************************** + * + * Global + * + ********************************************/ +extern unsigned int int_clrd; +extern wilc_hif_func_t hif_sdio; +extern wilc_hif_func_t hif_spi; +extern wilc_cfg_func_t mac_cfg; +#if defined(PLAT_RK3026_TCHIP) +extern u8 g_wilc_initialized; /* AMR : 0422 RK3026 Crash issue */ +#endif +extern void WILC_WFI_mgmt_rx(uint8_t *buff, uint32_t size); +extern void frmw_to_linux(uint8_t *buff, uint32_t size); +int sdio_xfer_cnt(void); +uint32_t wilc_get_chipid(uint8_t update); +WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue); + + + +typedef struct { + int quit; + + /** + * input interface functions + **/ + wilc_wlan_os_func_t os_func; + wilc_wlan_io_func_t io_func; + wilc_wlan_net_func_t net_func; + wilc_wlan_indicate_func_t indicate_func; + + /** + * host interface functions + **/ + wilc_hif_func_t hif_func; + void *hif_lock; + + /** + * configuration interface functions + **/ + wilc_cfg_func_t cif_func; + int cfg_frame_in_use; + wilc_cfg_frame_t cfg_frame; + uint32_t cfg_frame_offset; + int cfg_seq_no; + void *cfg_wait; + + /** + * RX buffer + **/ + #ifdef MEMORY_STATIC + uint32_t rx_buffer_size; + uint8_t *rx_buffer; + uint32_t rx_buffer_offset; + #endif + /** + * TX buffer + **/ + uint32_t tx_buffer_size; + uint8_t *tx_buffer; + uint32_t tx_buffer_offset; + + /** + * TX queue + **/ + void *txq_lock; + + /*Added by Amr - BugID_4720*/ + void *txq_add_to_head_lock; + void *txq_spinlock; + unsigned long txq_spinlock_flags; + + struct txq_entry_t *txq_head; + struct txq_entry_t *txq_tail; + int txq_entries; + void *txq_wait; + int txq_exit; + + /** + * RX queue + **/ + void *rxq_lock; + struct rxq_entry_t *rxq_head; + struct rxq_entry_t *rxq_tail; + int rxq_entries; + void *rxq_wait; + int rxq_exit; + + +} wilc_wlan_dev_t; + +static wilc_wlan_dev_t g_wlan; + +INLINE void chip_allow_sleep(void); +INLINE void chip_wakeup(void); +/******************************************** + * + * Debug + * + ********************************************/ + +static uint32_t dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ; + +static void wilc_debug(uint32_t flag, char *fmt, ...) +{ + char buf[256]; + va_list args; + int len; + + if (flag & dbgflag) { + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); + + if (g_wlan.os_func.os_debug) + g_wlan.os_func.os_debug(buf); + } + + return; +} + +static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP; + +/*BugID_5213*/ +/*acquire_bus() and release_bus() are made INLINE functions*/ +/*as a temporary workaround to fix a problem of receiving*/ +/*unknown interrupt from FW*/ +INLINE void acquire_bus(BUS_ACQUIRE_T acquire) +{ + + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + #ifndef WILC_OPTIMIZE_SLEEP_INT + if (genuChipPSstate != CHIP_WAKEDUP) + #endif + { + if (acquire == ACQUIRE_AND_WAKEUP) + chip_wakeup(); + } + +} +INLINE void release_bus(BUS_RELEASE_T release) +{ + #ifdef WILC_OPTIMIZE_SLEEP_INT + if (release == RELEASE_ALLOW_SLEEP) + chip_allow_sleep(); + #endif + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); +} +/******************************************** + * + * Queue + * + ********************************************/ + +static void wilc_wlan_txq_remove(struct txq_entry_t *tqe) +{ + + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + /* unsigned long flags; */ + if (tqe == p->txq_head) { + + p->txq_head = tqe->next; + if (p->txq_head) + p->txq_head->prev = NULL; + + + } else if (tqe == p->txq_tail) { + p->txq_tail = (tqe->prev); + if (p->txq_tail) + p->txq_tail->next = NULL; + } else { + tqe->prev->next = tqe->next; + tqe->next->prev = tqe->prev; + } + p->txq_entries -= 1; + +} + +static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void) +{ + struct txq_entry_t *tqe; + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + if (p->txq_head) { + tqe = p->txq_head; + p->txq_head = tqe->next; + if (p->txq_head) { + p->txq_head->prev = NULL; + } + p->txq_entries -= 1; + + /*Added by Amr - BugID_4720*/ + + + + } else { + tqe = NULL; + } + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + return tqe; +} + +static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + if (p->txq_head == NULL) { + tqe->next = NULL; + tqe->prev = NULL; + p->txq_head = tqe; + p->txq_tail = tqe; + } else { + tqe->next = NULL; + tqe->prev = p->txq_tail; + p->txq_tail->next = tqe; + p->txq_tail = tqe; + } + p->txq_entries += 1; + PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); + + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + + /** + * wake up TX queue + **/ + PRINT_D(TX_DBG, "Wake the txq_handling\n"); + + p->os_func.os_signal(p->txq_wait); + + +} + +static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + /*Added by Amr - BugID_4720*/ + if (p->os_func.os_wait(p->txq_add_to_head_lock, CFG_PKTS_TIMEOUT)) + return -1; + + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + if (p->txq_head == NULL) { + tqe->next = NULL; + tqe->prev = NULL; + p->txq_head = tqe; + p->txq_tail = tqe; + } else { + tqe->next = p->txq_head; + tqe->prev = NULL; + p->txq_head->prev = tqe; + p->txq_head = tqe; + } + p->txq_entries += 1; + PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries); + + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + p->os_func.os_signal(p->txq_add_to_head_lock); + + + /** + * wake up TX queue + **/ + p->os_func.os_signal(p->txq_wait); + PRINT_D(TX_DBG, "Wake up the txq_handler\n"); + + /*Added by Amr - BugID_4720*/ + return 0; + +} + +uint32_t Statisitcs_totalAcks = 0, Statisitcs_DroppedAcks = 0; + +#ifdef TCP_ACK_FILTER +struct Ack_session_info; +typedef struct Ack_session_info { + uint32_t Ack_seq_num; + uint32_t Bigger_Ack_num; + uint16_t src_port; + uint16_t dst_port; + uint16_t status; +} Ack_session_info_t; + +typedef struct { + uint32_t ack_num; + uint32_t Session_index; + struct txq_entry_t *txqe; +} Pending_Acks_info_t /*Ack_info_t*/; + + + + +struct Ack_session_info *Free_head; +struct Ack_session_info *Alloc_head; + +#define TCP_FIN_MASK (1 << 0) +#define TCP_SYN_MASK (1 << 1) +#define TCP_Ack_MASK (1 << 4) +#define NOT_TCP_ACK (-1) + +#define MAX_TCP_SESSION 25 +#define MAX_PENDING_ACKS 256 +Ack_session_info_t Acks_keep_track_info[2 * MAX_TCP_SESSION]; +Pending_Acks_info_t Pending_Acks_info[MAX_PENDING_ACKS]; + +uint32_t PendingAcks_arrBase; +uint32_t Opened_TCP_session; +uint32_t Pending_Acks; + + + +static __inline int Init_TCP_tracking(void) +{ + + return 0; + +} +static __inline int add_TCP_track_session(uint32_t src_prt, uint32_t dst_prt, uint32_t seq) +{ + Acks_keep_track_info[Opened_TCP_session].Ack_seq_num = seq; + Acks_keep_track_info[Opened_TCP_session].Bigger_Ack_num = 0; + Acks_keep_track_info[Opened_TCP_session].src_port = src_prt; + Acks_keep_track_info[Opened_TCP_session].dst_port = dst_prt; + Opened_TCP_session++; + + PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", Opened_TCP_session, seq); + return 0; +} + +static __inline int Update_TCP_track_session(uint32_t index, uint32_t Ack) +{ + + if (Ack > Acks_keep_track_info[index].Bigger_Ack_num) { + Acks_keep_track_info[index].Bigger_Ack_num = Ack; + } + return 0; + +} +static __inline int add_TCP_Pending_Ack(uint32_t Ack, uint32_t Session_index, struct txq_entry_t *txqe) +{ + Statisitcs_totalAcks++; + if (Pending_Acks < MAX_PENDING_ACKS) { + Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack; + Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe; + Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].Session_index = Session_index; + txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks; + Pending_Acks++; + + } else { + + } + return 0; +} +static __inline int remove_TCP_related(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + return 0; +} + +static __inline int tcp_process(struct txq_entry_t *tqe) +{ + int ret; + uint8_t *eth_hdr_ptr; + uint8_t *buffer = tqe->buffer; + unsigned short h_proto; + int i; + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + eth_hdr_ptr = &buffer[0]; + h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12])); + if (h_proto == 0x0800) { /* IP */ + uint8_t *ip_hdr_ptr; + uint8_t protocol; + + ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN]; + protocol = ip_hdr_ptr[9]; + + + if (protocol == 0x06) { + uint8_t *tcp_hdr_ptr; + uint32_t IHL, Total_Length, Data_offset; + tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN]; + IHL = (ip_hdr_ptr[0] & 0xf) << 2; + Total_Length = (((uint32_t)ip_hdr_ptr[2]) << 8) + ((uint32_t)ip_hdr_ptr[3]); + Data_offset = (((uint32_t)tcp_hdr_ptr[12] & 0xf0) >> 2); + if (Total_Length == (IHL + Data_offset)) { /*we want to recognize the clear Acks(packet only carry Ack infos not with data) so data size must be equal zero*/ + uint32_t seq_no, Ack_no; + seq_no = (((uint32_t)tcp_hdr_ptr[4]) << 24) + (((uint32_t)tcp_hdr_ptr[5]) << 16) + (((uint32_t)tcp_hdr_ptr[6]) << 8) + ((uint32_t)tcp_hdr_ptr[7]); + + Ack_no = (((uint32_t)tcp_hdr_ptr[8]) << 24) + (((uint32_t)tcp_hdr_ptr[9]) << 16) + (((uint32_t)tcp_hdr_ptr[10]) << 8) + ((uint32_t)tcp_hdr_ptr[11]); + + + for (i = 0; i < Opened_TCP_session; i++) { + if (Acks_keep_track_info[i].Ack_seq_num == seq_no) { + Update_TCP_track_session(i, Ack_no); + break; + } + } + if (i == Opened_TCP_session) { + add_TCP_track_session(0, 0, seq_no); + } + add_TCP_Pending_Ack(Ack_no, i, tqe); + + + } + + } else { + ret = 0; + } + } else { + ret = 0; + } + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + return ret; +} + + +static int wilc_wlan_txq_filter_dup_tcp_ack(void) +{ + + uint32_t i = 0; + uint32_t Dropped = 0; + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + + p->os_func.os_spin_lock(p->txq_spinlock, &p->txq_spinlock_flags); + for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) { + if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].Bigger_Ack_num) { + struct txq_entry_t *tqe; + PRINT_D(TCP_ENH, "DROP ACK: %u \n", Pending_Acks_info[i].ack_num); + tqe = Pending_Acks_info[i].txqe; + if (tqe) { + wilc_wlan_txq_remove(tqe); + Statisitcs_DroppedAcks++; + tqe->status = 1; /* mark the packet send */ + if (tqe->tx_complete_func) + tqe->tx_complete_func(tqe->priv, tqe->status); + p->os_func.os_free(tqe); + Dropped++; + } + } + } + Pending_Acks = 0; + Opened_TCP_session = 0; + + if (PendingAcks_arrBase == 0) { + PendingAcks_arrBase = MAX_TCP_SESSION; + } else { + PendingAcks_arrBase = 0; + } + + + p->os_func.os_spin_unlock(p->txq_spinlock, &p->txq_spinlock_flags); + + while (Dropped > 0) { + /*consume the semaphore count of the removed packet*/ + p->os_func.os_wait(p->txq_wait, 1); + Dropped--; + } + + return 1; +} +#endif + +#ifdef TCP_ENHANCEMENTS +WILC_Bool EnableTCPAckFilter = WILC_FALSE; + +void Enable_TCP_ACK_Filter(WILC_Bool value) +{ + EnableTCPAckFilter = value; +} + +WILC_Bool is_TCP_ACK_Filter_Enabled(void) +{ + return EnableTCPAckFilter; +} +#endif + +static int wilc_wlan_txq_add_cfg_pkt(uint8_t *buffer, uint32_t buffer_size) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + + PRINT_D(TX_DBG, "Adding config packet ...\n"); + if (p->quit) { + PRINT_D(TX_DBG, "Return due to clear function\n"); + p->os_func.os_signal(p->cfg_wait); + return 0; + } + + tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t)); + if (tqe == NULL) { + PRINT_ER("Failed to allocate memory\n"); + return 0; + } + + tqe->type = WILC_CFG_PKT; + tqe->buffer = buffer; + tqe->buffer_size = buffer_size; + tqe->tx_complete_func = NULL; + tqe->priv = NULL; +#ifdef TCP_ACK_FILTER + tqe->tcp_PendingAck_index = NOT_TCP_ACK; +#endif + /** + * Configuration packet always at the front + **/ + PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n"); + + /*Edited by Amr - BugID_4720*/ + if (wilc_wlan_txq_add_to_head(tqe)) + return 0; + return 1; +} + +static int wilc_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, wilc_tx_complete_func_t func) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + + if (p->quit) + return 0; + + tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t)); + + if (tqe == NULL) + return 0; + tqe->type = WILC_NET_PKT; + tqe->buffer = buffer; + tqe->buffer_size = buffer_size; + tqe->tx_complete_func = func; + tqe->priv = priv; + + PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n"); +#ifdef TCP_ACK_FILTER + tqe->tcp_PendingAck_index = NOT_TCP_ACK; +#ifdef TCP_ENHANCEMENTS + if (is_TCP_ACK_Filter_Enabled() == WILC_TRUE) +#endif + tcp_process(tqe); +#endif + wilc_wlan_txq_add_to_tail(tqe); + /*return number of itemes in the queue*/ + return p->txq_entries; +} +/*Bug3959: transmitting mgmt frames received from host*/ +#if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P) +int wilc_wlan_txq_add_mgmt_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, wilc_tx_complete_func_t func) +{ + + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + + if (p->quit) + return 0; + + tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t)); + + if (tqe == NULL) + return 0; + tqe->type = WILC_MGMT_PKT; + tqe->buffer = buffer; + tqe->buffer_size = buffer_size; + tqe->tx_complete_func = func; + tqe->priv = priv; +#ifdef TCP_ACK_FILTER + tqe->tcp_PendingAck_index = NOT_TCP_ACK; +#endif + PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n"); + wilc_wlan_txq_add_to_tail(tqe); + return 1; +} + +#ifdef WILC_FULLY_HOSTING_AP +int wilc_FH_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, wilc_tx_complete_func_t func) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + + if (p->quit) + return 0; + + tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t)); + + if (tqe == NULL) + return 0; + tqe->type = WILC_FH_DATA_PKT; + tqe->buffer = buffer; + tqe->buffer_size = buffer_size; + tqe->tx_complete_func = func; + tqe->priv = priv; + PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n"); + wilc_wlan_txq_add_to_tail(tqe); + /*return number of itemes in the queue*/ + return p->txq_entries; +} +#endif /* WILC_FULLY_HOSTING_AP*/ +#endif /*WILC_AP_EXTERNAL_MLME*/ +static struct txq_entry_t *wilc_wlan_txq_get_first(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + unsigned long flags; + + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + tqe = p->txq_head; + + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + + + return tqe; +} + +static struct txq_entry_t *wilc_wlan_txq_get_next(struct txq_entry_t *tqe) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + unsigned long flags; + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_lock(p->txq_spinlock, &flags); + + tqe = tqe->next; + /*Added by Amr - BugID_4720*/ + p->os_func.os_spin_unlock(p->txq_spinlock, &flags); + + + return tqe; +} + +static int wilc_wlan_rxq_add(struct rxq_entry_t *rqe) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + + if (p->quit) + return 0; + + p->os_func.os_enter_cs(p->rxq_lock); + if (p->rxq_head == NULL) { + PRINT_D(RX_DBG, "Add to Queue head\n"); + rqe->next = NULL; + p->rxq_head = rqe; + p->rxq_tail = rqe; + } else { + PRINT_D(RX_DBG, "Add to Queue tail\n"); + p->rxq_tail->next = rqe; + rqe->next = NULL; + p->rxq_tail = rqe; + } + p->rxq_entries += 1; + PRINT_D(RX_DBG, "Number of queue entries: %d\n", p->rxq_entries); + p->os_func.os_leave_cs(p->rxq_lock); + return p->rxq_entries; +} + +static struct rxq_entry_t *wilc_wlan_rxq_remove(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + + PRINT_D(RX_DBG, "Getting rxQ element\n"); + if (p->rxq_head) { + struct rxq_entry_t *rqe; + + p->os_func.os_enter_cs(p->rxq_lock); + rqe = p->rxq_head; + p->rxq_head = p->rxq_head->next; + p->rxq_entries -= 1; + PRINT_D(RX_DBG, "RXQ entries decreased\n"); + p->os_func.os_leave_cs(p->rxq_lock); + return rqe; + } + PRINT_D(RX_DBG, "Nothing to get from Q\n"); + return NULL; +} + + +/******************************************** + * + * Power Save handle functions + * + ********************************************/ + + + +#ifdef WILC_OPTIMIZE_SLEEP_INT + +INLINE void chip_allow_sleep(void) +{ + uint32_t reg = 0; + + /* Clear bit 1 */ + g_wlan.hif_func.hif_read_reg(0xf0, ®); + + g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0)); +} + +INLINE void chip_wakeup(void) +{ + uint32_t reg, clk_status_reg, trials = 0; + uint32_t sleep_time; + + if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { + do { + g_wlan.hif_func.hif_read_reg(1, ®); + /* Set bit 1 */ + g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1)); + + /* Clear bit 1*/ + g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1)); + + do { + /* Wait for the chip to stabilize*/ + WILC_Sleep(2); + /* Make sure chip is awake. This is an extra step that can be removed */ + /* later to avoid the bus access overhead */ + if ((wilc_get_chipid(WILC_TRUE) == 0)) { + wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); + } + } while ((wilc_get_chipid(WILC_TRUE) == 0) && ((++trials % 3) == 0)); + + } while (wilc_get_chipid(WILC_TRUE) == 0); + } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { + g_wlan.hif_func.hif_read_reg(0xf0, ®); + do { + /* Set bit 1 */ + g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0)); + + /* Check the clock status */ + g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); + + /* in case of clocks off, wait 2ms, and check it again. */ + /* if still off, wait for another 2ms, for a total wait of 6ms. */ + /* If still off, redo the wake up sequence */ + while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) { + /* Wait for the chip to stabilize*/ + WILC_Sleep(2); + + /* Make sure chip is awake. This is an extra step that can be removed */ + /* later to avoid the bus access overhead */ + g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg); + + if ((clk_status_reg & 0x1) == 0) { + wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n"); + } + } + /* in case of failure, Reset the wakeup bit to introduce a new edge on the next loop */ + if ((clk_status_reg & 0x1) == 0) { + /* Reset bit 0 */ + g_wlan.hif_func.hif_write_reg(0xf0, reg & (~(1 << 0))); + } + } while ((clk_status_reg & 0x1) == 0); + } + + + if (genuChipPSstate == CHIP_SLEEPING_MANUAL) { + g_wlan.hif_func.hif_read_reg(0x1C0C, ®); + reg &= ~(1 << 0); + g_wlan.hif_func.hif_write_reg(0x1C0C, reg); + + if (wilc_get_chipid(WILC_FALSE) >= 0x1002b0) { + /* Enable PALDO back right after wakeup */ + uint32_t val32; + g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); + val32 |= (1 << 6); + g_wlan.hif_func.hif_write_reg(0x1e1c, val32); + + g_wlan.hif_func.hif_read_reg(0x1e9c, &val32); + val32 |= (1 << 6); + g_wlan.hif_func.hif_write_reg(0x1e9c, val32); + } + } + genuChipPSstate = CHIP_WAKEDUP; +} +#else +INLINE void chip_wakeup(void) +{ + uint32_t reg, trials = 0; + do { + if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) { + g_wlan.hif_func.hif_read_reg(1, ®); + /* Make sure bit 1 is 0 before we start. */ + g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1)); + /* Set bit 1 */ + g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1)); + /* Clear bit 1*/ + g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1)); + } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO) { + /* Make sure bit 0 is 0 before we start. */ + g_wlan.hif_func.hif_read_reg(0xf0, ®); + g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0)); + /* Set bit 1 */ + g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0)); + /* Clear bit 1 */ + g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0)); + } + + do { + /* Wait for the chip to stabilize*/ + mdelay(3); + + /* Make sure chip is awake. This is an extra step that can be removed */ + /* later to avoid the bus access overhead */ + if ((wilc_get_chipid(WILC_TRUE) == 0)) { + wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n"); + } + } while ((wilc_get_chipid(WILC_TRUE) == 0) && ((++trials % 3) == 0)); + + } while (wilc_get_chipid(WILC_TRUE) == 0); + + if (genuChipPSstate == CHIP_SLEEPING_MANUAL) { + g_wlan.hif_func.hif_read_reg(0x1C0C, ®); + reg &= ~(1 << 0); + g_wlan.hif_func.hif_write_reg(0x1C0C, reg); + + if (wilc_get_chipid(WILC_FALSE) >= 0x1002b0) { + /* Enable PALDO back right after wakeup */ + uint32_t val32; + g_wlan.hif_func.hif_read_reg(0x1e1c, &val32); + val32 |= (1 << 6); + g_wlan.hif_func.hif_write_reg(0x1e1c, val32); + + g_wlan.hif_func.hif_read_reg(0x1e9c, &val32); + val32 |= (1 << 6); + g_wlan.hif_func.hif_write_reg(0x1e9c, val32); + } + } + genuChipPSstate = CHIP_WAKEDUP; +} +#endif +void chip_sleep_manually(WILC_Uint32 u32SleepTime) +{ + if (genuChipPSstate != CHIP_WAKEDUP) { + /* chip is already sleeping. Do nothing */ + return; + } + acquire_bus(ACQUIRE_ONLY); + +#ifdef WILC_OPTIMIZE_SLEEP_INT + chip_allow_sleep(); +#endif + + /* Trigger the manual sleep interrupt */ + g_wlan.hif_func.hif_write_reg(0x10a8, 1); + + genuChipPSstate = CHIP_SLEEPING_MANUAL; + release_bus(RELEASE_ONLY); + +} + + +/******************************************** + * + * Tx, Rx queue handle functions + * + ********************************************/ +static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + int i, entries = 0; + uint32_t sum; + uint32_t reg; + uint8_t *txb = p->tx_buffer; + uint32_t offset = 0; + int vmm_sz = 0; + struct txq_entry_t *tqe; + int ret = 0; + int counter; + int timeout; + uint32_t vmm_table[WILC_VMM_TBL_SIZE]; + p->txq_exit = 0; + do { + if (p->quit) + break; + + /*Added by Amr - BugID_4720*/ + p->os_func.os_wait(p->txq_add_to_head_lock, CFG_PKTS_TIMEOUT); +#ifdef TCP_ACK_FILTER + wilc_wlan_txq_filter_dup_tcp_ack(); +#endif + /** + * build the vmm list + **/ + PRINT_D(TX_DBG, "Getting the head of the TxQ\n"); + tqe = wilc_wlan_txq_get_first(); + i = 0; + sum = 0; + do { + /* if ((tqe != NULL) && (i < (8)) && */ + /* if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE-1)) && */ + if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1)) /* reserve last entry to 0 */) { + + if (tqe->type == WILC_CFG_PKT) { + vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET; + } + /*Bug3959: transmitting mgmt frames received from host*/ + /*vmm_sz will only be equal to tqe->buffer_size + 4 bytes (HOST_HDR_OFFSET)*/ + /* in other cases WILC_MGMT_PKT and WILC_DATA_PKT_MAC_HDR*/ + else if (tqe->type == WILC_NET_PKT) { + vmm_sz = ETH_ETHERNET_HDR_OFFSET; + } +#ifdef WILC_FULLY_HOSTING_AP + else if (tqe->type == WILC_FH_DATA_PKT) { + vmm_sz = FH_TX_HOST_HDR_OFFSET; + } +#endif +#ifdef WILC_AP_EXTERNAL_MLME + else { + vmm_sz = HOST_HDR_OFFSET; + } +#endif + vmm_sz += tqe->buffer_size; + PRINT_D(TX_DBG, "VMM Size before alignment = %d\n", vmm_sz); + if (vmm_sz & 0x3) { /* has to be word aligned */ + vmm_sz = (vmm_sz + 4) & ~0x3; + } + if ((sum + vmm_sz) > p->tx_buffer_size) { + break; + } + PRINT_D(TX_DBG, "VMM Size AFTER alignment = %d\n", vmm_sz); + vmm_table[i] = vmm_sz / 4; /* table take the word size */ + PRINT_D(TX_DBG, "VMMTable entry size = %d\n", vmm_table[i]); + + if (tqe->type == WILC_CFG_PKT) { + vmm_table[i] |= (1 << 10); + PRINT_D(TX_DBG, "VMMTable entry changed for CFG packet = %d\n", vmm_table[i]); + } +#ifdef BIG_ENDIAN + vmm_table[i] = BYTE_SWAP(vmm_table[i]); +#endif + + i++; + sum += vmm_sz; + PRINT_D(TX_DBG, "sum = %d\n", sum); + tqe = wilc_wlan_txq_get_next(tqe); + } else { + break; + } + } while (1); + + if (i == 0) { /* nothing in the queue */ + PRINT_D(TX_DBG, "Nothing in TX-Q\n"); + break; + } else { + PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i); + vmm_table[i] = 0x0; /* mark the last element to 0 */ + } + acquire_bus(ACQUIRE_AND_WAKEUP); + counter = 0; + do { + + ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n"); + break; + } + + if ((reg & 0x1) == 0) { + /** + * write to vmm table + **/ + PRINT_D(TX_DBG, "Writing VMM table ... with Size = %d\n", ((i + 1) * 4)); + break; + } else { + counter++; + if (counter > 200) { + counter = 0; + PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n"); + ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, 0); + break; + } + /** + * wait for vmm table is ready + **/ + PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait... \n"); + release_bus(RELEASE_ALLOW_SLEEP); + p->os_func.os_sleep(3); /* wait 3 ms */ + acquire_bus(ACQUIRE_AND_WAKEUP); + } + } while (!p->quit); + + if (!ret) { + goto _end_; + } + + timeout = 200; + do { + + /** + * write to vmm table + **/ + ret = p->hif_func.hif_block_tx(WILC_VMM_TBL_RX_SHADOW_BASE, (uint8_t *)vmm_table, ((i + 1) * 4)); /* Bug 4477 fix */ + if (!ret) { + wilc_debug(N_ERR, "ERR block TX of VMM table.\n"); + break; + } + + + /** + * interrupt firmware + **/ + ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x2); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n"); + break; + } + + /** + * wait for confirm... + **/ + + do { + ret = p->hif_func.hif_read_reg(WILC_HOST_VMM_CTL, ®); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n"); + break; + } + if ((reg >> 2) & 0x1) { + /** + * Get the entries + **/ + entries = ((reg >> 3) & 0x3f); + /* entries = ((reg>>3)&0x2f); */ + break; + } else { + release_bus(RELEASE_ALLOW_SLEEP); + p->os_func.os_sleep(3); /* wait 3 ms */ + acquire_bus(ACQUIRE_AND_WAKEUP); + PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg); + } + } while (--timeout); + if (timeout <= 0) { + ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x0); + break; + } + + if (!ret) { + break; + } + + if (entries == 0) { + PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]] \n", reg, i, vmm_table[i - 1]); + + /* undo the transaction. */ + ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, ®); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n"); + break; + } + reg &= ~(1ul << 0); + ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, reg); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n"); + break; + } + break; + } else { + break; + } + } while (1); + + if (!ret) { + goto _end_; + } + if (entries == 0) { + ret = WILC_TX_ERR_NO_BUF; + goto _end_; + } + + /* since copying data into txb takes some time, then + * allow the bus lock to be released let the RX task go. */ + release_bus(RELEASE_ALLOW_SLEEP); + + /** + * Copy data to the TX buffer + **/ + offset = 0; + i = 0; + do { + tqe = wilc_wlan_txq_remove_from_head(); + if (tqe != NULL && (vmm_table[i] != 0)) { + uint32_t header, buffer_offset; + +#ifdef BIG_ENDIAN + vmm_table[i] = BYTE_SWAP(vmm_table[i]); +#endif + vmm_sz = (vmm_table[i] & 0x3ff); /* in word unit */ + vmm_sz *= 4; + header = (tqe->type << 31) | (tqe->buffer_size << 15) | vmm_sz; + /*Bug3959: transmitting mgmt frames received from host*/ + /*setting bit 30 in the host header to indicate mgmt frame*/ +#ifdef WILC_AP_EXTERNAL_MLME + if (tqe->type == WILC_MGMT_PKT) { + header |= (1 << 30); + } else { + header &= ~(1 << 30); + } +#endif + +#ifdef BIG_ENDIAN + header = BYTE_SWAP(header); +#endif + memcpy(&txb[offset], &header, 4); + if (tqe->type == WILC_CFG_PKT) { + buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; + } + /*Bug3959: transmitting mgmt frames received from host*/ + /*buffer offset = HOST_HDR_OFFSET in other cases: WILC_MGMT_PKT*/ + /* and WILC_DATA_PKT_MAC_HDR*/ + else if (tqe->type == WILC_NET_PKT) { + char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid; + buffer_offset = ETH_ETHERNET_HDR_OFFSET; + /* copy the bssid at the sart of the buffer */ + memcpy(&txb[offset + 4], pBSSID, 6); + } +#ifdef WILC_FULLY_HOSTING_AP + else if (tqe->type == WILC_FH_DATA_PKT) { + buffer_offset = FH_TX_HOST_HDR_OFFSET; + } +#endif + else { + buffer_offset = HOST_HDR_OFFSET; + } + + memcpy(&txb[offset + buffer_offset], tqe->buffer, tqe->buffer_size); + offset += vmm_sz; + i++; + tqe->status = 1; /* mark the packet send */ + if (tqe->tx_complete_func) + tqe->tx_complete_func(tqe->priv, tqe->status); + #ifdef TCP_ACK_FILTER + if (tqe->tcp_PendingAck_index != NOT_TCP_ACK) { + Pending_Acks_info[tqe->tcp_PendingAck_index].txqe = NULL; + } + #endif + p->os_func.os_free(tqe); + } else { + break; + } + } while (--entries); + + /** + * lock the bus + **/ + acquire_bus(ACQUIRE_AND_WAKEUP); + + ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n"); + goto _end_; + } + + /** + * transfer + **/ + ret = p->hif_func.hif_block_tx_ext(0, txb, offset); + if (!ret) { + wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n"); + goto _end_; + } + +_end_: + + release_bus(RELEASE_ALLOW_SLEEP); + if (ret != 1) + break; + } while (0); + /*Added by Amr - BugID_4720*/ + p->os_func.os_signal(p->txq_add_to_head_lock); + + p->txq_exit = 1; + PRINT_D(TX_DBG, "THREAD: Exiting txq\n"); + /* return tx[]q count */ + *pu32TxqCount = p->txq_entries; + return ret; +} + +static void wilc_wlan_handle_rxq(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + int offset = 0, size, has_packet = 0; + uint8_t *buffer; + struct rxq_entry_t *rqe; + + p->rxq_exit = 0; + + + + + do { + if (p->quit) { + PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function \n"); + p->os_func.os_signal(p->cfg_wait); + break; + } + rqe = wilc_wlan_rxq_remove(); + if (rqe == NULL) { + PRINT_D(RX_DBG, "nothing in the queue - exit 1st do-while\n"); + break; + } + buffer = rqe->buffer; + size = rqe->buffer_size; + PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n", size, buffer); + offset = 0; + + + + do { + uint32_t header; + uint32_t pkt_len, pkt_offset, tp_len; + int is_cfg_packet; + PRINT_D(RX_DBG, "In the 2nd do-while\n"); + memcpy(&header, &buffer[offset], 4); +#ifdef BIG_ENDIAN + header = BYTE_SWAP(header); +#endif + PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", header, offset); + + + + is_cfg_packet = (header >> 31) & 0x1; + pkt_offset = (header >> 22) & 0x1ff; + tp_len = (header >> 11) & 0x7ff; + pkt_len = header & 0x7ff; + + if (pkt_len == 0 || tp_len == 0) { + wilc_debug(N_RXQ, "[wilc rxq]: data corrupt, packet len or tp_len is 0 [%d][%d]\n", pkt_len, tp_len); + break; + } + +/*bug 3887: [AP] Allow Management frames to be passed to the host*/ + #if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P) + #define IS_MANAGMEMENT 0x100 + #define IS_MANAGMEMENT_CALLBACK 0x080 + #define IS_MGMT_STATUS_SUCCES 0x040 + + + if (pkt_offset & IS_MANAGMEMENT) { + /* reset mgmt indicator bit, to use pkt_offeset in furthur calculations */ + pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES); + +#ifdef USE_WIRELESS + WILC_WFI_mgmt_rx(&buffer[offset + HOST_HDR_OFFSET], pkt_len); + +#endif + + } + /* BUG4530 fix */ + else + #endif + { + + if (!is_cfg_packet) { + + if (p->net_func.rx_indicate) { + if (pkt_len > 0) { + p->net_func.rx_indicate(&buffer[offset], pkt_len, pkt_offset); + has_packet = 1; + } + } + } else { + wilc_cfg_rsp_t rsp; + + + + p->cif_func.rx_indicate(&buffer[pkt_offset + offset], pkt_len, &rsp); + if (rsp.type == WILC_CFG_RSP) { + /** + * wake up the waiting task... + **/ + PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no); + if (p->cfg_seq_no == rsp.seq_no) { + p->os_func.os_signal(p->cfg_wait); + } + } else if (rsp.type == WILC_CFG_RSP_STATUS) { + /** + * Call back to indicate status... + **/ + if (p->indicate_func.mac_indicate) { + p->indicate_func.mac_indicate(WILC_MAC_INDICATE_STATUS); + } + + } else if (rsp.type == WILC_CFG_RSP_SCAN) { + if (p->indicate_func.mac_indicate) + p->indicate_func.mac_indicate(WILC_MAC_INDICATE_SCAN); + } + } + } + offset += tp_len; + if (offset >= size) + break; + } while (1); + + +#ifndef MEMORY_STATIC + if (buffer != NULL) + p->os_func.os_free((void *)buffer); +#endif + if (rqe != NULL) + p->os_func.os_free((void *)rqe); + + if (has_packet) { + if (p->net_func.rx_complete) + p->net_func.rx_complete(); + } + } while (1); + + p->rxq_exit = 1; + PRINT_D(RX_DBG, "THREAD: Exiting RX thread \n"); + return; +} + +/******************************************** + * + * Fast DMA Isr + * + ********************************************/ +static void wilc_unknown_isr_ext(void) +{ + g_wlan.hif_func.hif_clear_int_ext(0); +} +static void wilc_pllupdate_isr_ext(uint32_t int_stats) +{ + + int trials = 10; + + g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR); + + /* Waiting for PLL */ + g_wlan.os_func.os_atomic_sleep(WILC_PLL_TO); + + /* poll till read a valid data */ + while (!(ISWILC1000(wilc_get_chipid(WILC_TRUE)) && --trials)) { + PRINT_D(TX_DBG, "PLL update retrying\n"); + g_wlan.os_func.os_atomic_sleep(1); + } +} + +static void wilc_sleeptimer_isr_ext(uint32_t int_stats1) +{ + g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR); +#ifndef WILC_OPTIMIZE_SLEEP_INT + genuChipPSstate = CHIP_SLEEPING_AUTO; +#endif +} + +static void wilc_wlan_handle_isr_ext(uint32_t int_status) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; +#ifdef MEMORY_STATIC + uint32_t offset = p->rx_buffer_offset; +#endif + uint8_t *buffer = NULL; + uint32_t size; + uint32_t retries = 0; + int ret = 0; + struct rxq_entry_t *rqe; + + + /** + * Get the rx size + **/ + + size = ((int_status & 0x7fff) << 2); + + while (!size && retries < 10) { + uint32_t time = 0; + /*looping more secure*/ + /*zero size make a crashe because the dma will not happen and that will block the firmware*/ + wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++); + p->hif_func.hif_read_size(&size); + size = ((size & 0x7fff) << 2); + retries++; + + } + + if (size > 0) { +#ifdef MEMORY_STATIC + if (p->rx_buffer_size - offset < size) + offset = 0; + + if (p->rx_buffer) + buffer = &p->rx_buffer[offset]; + else { + wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size); + goto _end_; + } + +#else + buffer = p->os_func.os_malloc(size); + if (buffer == NULL) { + wilc_debug(N_ERR, "[wilc isr]: fail alloc host memory...drop the packets (%d)\n", size); + WILC_Sleep(100); + goto _end_; + } +#endif + + /** + * clear the chip's interrupt after getting size some register getting corrupted after clear the interrupt + **/ + p->hif_func.hif_clear_int_ext(DATA_INT_CLR | ENABLE_RX_VMM); + + + /** + * start transfer + **/ + ret = p->hif_func.hif_block_rx_ext(0, buffer, size); + + if (!ret) { + wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n"); + goto _end_; + } +_end_: + + + if (ret) { +#ifdef MEMORY_STATIC + offset += size; + p->rx_buffer_offset = offset; +#endif + /** + * add to rx queue + **/ + rqe = (struct rxq_entry_t *)p->os_func.os_malloc(sizeof(struct rxq_entry_t)); + if (rqe != NULL) { + rqe->buffer = buffer; + rqe->buffer_size = size; + PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer); + wilc_wlan_rxq_add(rqe); + p->os_func.os_signal(p->rxq_wait); + } + } else { +#ifndef MEMORY_STATIC + if (buffer != NULL) + p->os_func.os_free(buffer); +#endif + } + } +#ifdef TCP_ENHANCEMENTS + wilc_wlan_handle_rxq(); +#endif +} + +void wilc_handle_isr(void) +{ + uint32_t int_status; + + acquire_bus(ACQUIRE_AND_WAKEUP); + g_wlan.hif_func.hif_read_int(&int_status); + + if (int_status & PLL_INT_EXT) { + wilc_pllupdate_isr_ext(int_status); + } + if (int_status & DATA_INT_EXT) { + wilc_wlan_handle_isr_ext(int_status); + #ifndef WILC_OPTIMIZE_SLEEP_INT + /* Chip is up and talking*/ + genuChipPSstate = CHIP_WAKEDUP; + #endif + } + if (int_status & SLEEP_INT_EXT) { + wilc_sleeptimer_isr_ext(int_status); + } + + if (!(int_status & (ALL_INT_EXT))) { +#ifdef WILC_SDIO + PRINT_D(TX_DBG, ">> UNKNOWN_INTERRUPT - 0x%08x\n", int_status); +#endif + wilc_unknown_isr_ext(); + } +#if ((!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)) + linux_wlan_enable_irq(); +#endif + release_bus(RELEASE_ALLOW_SLEEP); +} + +/******************************************** + * + * Firmware download + * + ********************************************/ +static int wilc_wlan_firmware_download(const uint8_t *buffer, uint32_t buffer_size) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + uint32_t offset; + uint32_t addr, size, size2, blksz; + uint8_t *dma_buffer; + int ret = 0; + + blksz = (1ul << 12); /* Bug 4703: 4KB Good enough size for most platforms = PAGE_SIZE. */ + /* Allocate a DMA coherent buffer. */ + +#if (defined WILC_PREALLOC_AT_BOOT) + { + extern void *get_fw_buffer(void); + dma_buffer = (uint8_t *)get_fw_buffer(); + PRINT_D(TX_DBG, "fw_buffer = 0x%x\n", dma_buffer); + } +#else + dma_buffer = (uint8_t *)g_wlan.os_func.os_malloc(blksz); +#endif + if (dma_buffer == NULL) { + /*EIO 5*/ + ret = -5; + PRINT_ER("Can't allocate buffer for firmware download IO error\n "); + goto _fail_1; + } + + PRINT_D(INIT_DBG, "Downloading firmware size = %d ...\n", buffer_size); + /** + * load the firmware + **/ + offset = 0; + do { + memcpy(&addr, &buffer[offset], 4); + memcpy(&size, &buffer[offset + 4], 4); +#ifdef BIG_ENDIAN + addr = BYTE_SWAP(addr); + size = BYTE_SWAP(size); +#endif + acquire_bus(ACQUIRE_ONLY); + offset += 8; + while (((int)size) && (offset < buffer_size)) { + if (size <= blksz) { + size2 = size; + } else { + size2 = blksz; + } + /* Copy firmware into a DMA coherent buffer */ + memcpy(dma_buffer, &buffer[offset], size2); + ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2); + if (!ret) + break; + + addr += size2; + offset += size2; + size -= size2; + } + release_bus(RELEASE_ONLY); + + if (!ret) { + /*EIO 5*/ + ret = -5; + PRINT_ER("Can't download firmware IO error\n "); + goto _fail_; + } + PRINT_D(INIT_DBG, "Offset = %d\n", offset); + } while (offset < buffer_size); + +_fail_: + +#if (defined WILC_PREALLOC_AT_BOOT) + +#else + if (dma_buffer) + g_wlan.os_func.os_free(dma_buffer); +#endif + +_fail_1: + + return (ret < 0) ? ret : 0; +} + +/******************************************** + * + * Common + * + ********************************************/ +static int wilc_wlan_start(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + uint32_t reg = 0; + int ret; + uint32_t chipid; + + /** + * Set the host interface + **/ +#ifdef OLD_FPGA_BITFILE + acquire_bus(ACQUIRE_ONLY); + ret = p->hif_func.hif_read_reg(WILC_VMM_CORE_CTL, ®); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail read reg vmm_core_ctl...\n"); + release_bus(RELEASE_ALLOW_SLEEP); + return ret; + } + reg |= (p->io_func.io_type << 2); + ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CTL, reg); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_ctl...\n"); + release_bus(RELEASE_ONLY); + return ret; + } +#else + if (p->io_func.io_type == HIF_SDIO) { + reg = 0; + reg |= (1 << 3); /* bug 4456 and 4557 */ + } else if (p->io_func.io_type == HIF_SPI) { + reg = 1; + } + acquire_bus(ACQUIRE_ONLY); + ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CFG, reg); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n"); + release_bus(RELEASE_ONLY); + /* EIO 5*/ + ret = -5; + return ret; + } + reg = 0; +#ifdef WILC_SDIO_IRQ_GPIO + reg |= WILC_HAVE_SDIO_IRQ_GPIO; +#endif + +#ifdef WILC_DISABLE_PMU +#else + reg |= WILC_HAVE_USE_PMU; +#endif + +#ifdef WILC_SLEEP_CLK_SRC_XO + reg |= WILC_HAVE_SLEEP_CLK_SRC_XO; +#elif defined WILC_SLEEP_CLK_SRC_RTC + reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC; +#endif + +#ifdef WILC_EXT_PA_INV_TX_RX + reg |= WILC_HAVE_EXT_PA_INV_TX_RX; +#endif + + reg |= WILC_HAVE_LEGACY_RF_SETTINGS; + + +/*BugID_5257*/ +/*Set oscillator frequency*/ +#ifdef XTAL_24 + reg |= WILC_HAVE_XTAL_24; +#endif + +/*BugID_5271*/ +/*Enable/Disable GPIO configuration for FW logs*/ +#ifdef DISABLE_WILC_UART + reg |= WILC_HAVE_DISABLE_WILC_UART; +#endif + + ret = p->hif_func.hif_write_reg(WILC_GP_REG_1, reg); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n"); + release_bus(RELEASE_ONLY); + /* EIO 5*/ + ret = -5; + return ret; + } +#endif + + + /** + * Bus related + **/ + p->hif_func.hif_sync_ext(NUM_INT_EXT); + + ret = p->hif_func.hif_read_reg(0x1000, &chipid); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n"); + release_bus(RELEASE_ONLY); + /* EIO 5*/ + ret = -5; + return ret; + } + + /** + * Go... + **/ + + + p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + if ((reg & (1ul << 10)) == (1ul << 10)) { + reg &= ~(1ul << 10); + p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + } + + reg |= (1ul << 10); + ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + release_bus(RELEASE_ONLY); + + return (ret < 0) ? ret : 0; +} + +void wilc_wlan_global_reset(void) +{ + + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + acquire_bus(ACQUIRE_AND_WAKEUP); + p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0); + release_bus(RELEASE_ONLY); +} +static int wilc_wlan_stop(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + uint32_t reg = 0; + int ret; + uint8_t timeout = 10; + /** + * TODO: stop the firmware, need a re-download + **/ + acquire_bus(ACQUIRE_AND_WAKEUP); + + ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + return ret; + } + + reg &= ~(1 << 10); + + + ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + if (!ret) { + PRINT_ER("Error while writing reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + return ret; + } + + + + do { + ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + return ret; + } + PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout); + /*Workaround to ensure that the chip is actually reset*/ + if ((reg & (1 << 10))) { + PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout); + reg &= ~(1 << 10); + ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); + timeout--; + } else { + PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", timeout); + ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + return ret; + } + PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout); + break; + } + + } while (timeout); +#if 1 +/******************************************************************************/ +/* This was add at Bug 4595 to reset the chip while maintaining the bus state */ +/******************************************************************************/ + reg = ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 8) | (1 << 9) | (1 << 26) | (1 << 29) | (1 << 30) | (1 << 31)); /**/ + /**/ + ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); /**/ + reg = ~(1 << 10); /**/ + /**/ + ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg); /**/ +/******************************************************************************/ +#endif + + release_bus(RELEASE_ALLOW_SLEEP); + + return ret; +} + +static void wilc_wlan_cleanup(void) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + struct txq_entry_t *tqe; + struct rxq_entry_t *rqe; + uint32_t reg = 0; + int ret; + + p->quit = 1; + do { + tqe = wilc_wlan_txq_remove_from_head(); + if (tqe == NULL) + break; + if (tqe->tx_complete_func) + tqe->tx_complete_func(tqe->priv, 0); + p->os_func.os_free((void *)tqe); + } while (1); + + do { + rqe = wilc_wlan_rxq_remove(); + if (rqe == NULL) + break; +#ifdef MEMORY_DYNAMIC + p->os_func.os_free((void *)tqe->buffer); +#endif + p->os_func.os_free((void *)rqe); + } while (1); + + /** + * clean up buffer + **/ + +#if (defined WILC_PREALLOC_AT_BOOT) + +#else + #ifdef MEMORY_STATIC + if (p->rx_buffer) { + p->os_func.os_free(p->rx_buffer); + p->rx_buffer = NULL; + } + #endif + if (p->tx_buffer) { + p->os_func.os_free(p->tx_buffer); + p->tx_buffer = NULL; + } +#endif + + acquire_bus(ACQUIRE_AND_WAKEUP); + + + ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + } + PRINT_ER("Writing ABORT reg\n"); + ret = p->hif_func.hif_write_reg(WILC_GP_REG_0, (reg | ABORT_INT)); + if (!ret) { + PRINT_ER("Error while writing reg\n"); + release_bus(RELEASE_ALLOW_SLEEP); + } + release_bus(RELEASE_ALLOW_SLEEP); + /** + * io clean up + **/ + p->hif_func.hif_deinit(NULL); + +} + +static int wilc_wlan_cfg_commit(int type, uint32_t drvHandler) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + wilc_cfg_frame_t *cfg = &p->cfg_frame; + int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; + int seq_no = p->cfg_seq_no % 256; + int driver_handler = (WILC_Uint32)drvHandler; + + + /** + * Set up header + **/ + if (type == WILC_CFG_SET) { /* Set */ + cfg->wid_header[0] = 'W'; + } else { /* Query */ + cfg->wid_header[0] = 'Q'; + } + cfg->wid_header[1] = seq_no; /* sequence number */ + cfg->wid_header[2] = (uint8_t)total_len; + cfg->wid_header[3] = (uint8_t)(total_len >> 8); + cfg->wid_header[4] = (uint8_t)driver_handler; + cfg->wid_header[5] = (uint8_t)(driver_handler >> 8); + cfg->wid_header[6] = (uint8_t)(driver_handler >> 16); + cfg->wid_header[7] = (uint8_t)(driver_handler >> 24); + p->cfg_seq_no = seq_no; + + /** + * Add to TX queue + **/ + + /*Edited by Amr - BugID_4720*/ + if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len)) + return -1; + + return 0; +} + +static int wilc_wlan_cfg_set(int start, uint32_t wid, uint8_t *buffer, uint32_t buffer_size, int commit, uint32_t drvHandler) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + uint32_t offset; + int ret_size; + + + if (p->cfg_frame_in_use) + return 0; + + if (start) + p->cfg_frame_offset = 0; + + offset = p->cfg_frame_offset; + ret_size = p->cif_func.cfg_wid_set(p->cfg_frame.frame, offset, (uint16_t)wid, buffer, buffer_size); + offset += ret_size; + p->cfg_frame_offset = offset; + + if (commit) { + PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n", p->cfg_seq_no); + PRINT_D(RX_DBG, "Processing cfg_set()\n"); + p->cfg_frame_in_use = 1; + + /*Edited by Amr - BugID_4720*/ + if (wilc_wlan_cfg_commit(WILC_CFG_SET, drvHandler)) + ret_size = 0; /* BugID_5213 */ + + if (p->os_func.os_wait(p->cfg_wait, CFG_PKTS_TIMEOUT)) { + PRINT_D(TX_DBG, "Set Timed Out\n"); + ret_size = 0; + } + p->cfg_frame_in_use = 0; + p->cfg_frame_offset = 0; + p->cfg_seq_no += 1; + + } + + return ret_size; +} +static int wilc_wlan_cfg_get(int start, uint32_t wid, int commit, uint32_t drvHandler) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + uint32_t offset; + int ret_size; + + + if (p->cfg_frame_in_use) + return 0; + + if (start) + p->cfg_frame_offset = 0; + + offset = p->cfg_frame_offset; + ret_size = p->cif_func.cfg_wid_get(p->cfg_frame.frame, offset, (uint16_t)wid); + offset += ret_size; + p->cfg_frame_offset = offset; + + if (commit) { + p->cfg_frame_in_use = 1; + + /*Edited by Amr - BugID_4720*/ + if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drvHandler)) + ret_size = 0; /* BugID_5213 */ + + + if (p->os_func.os_wait(p->cfg_wait, CFG_PKTS_TIMEOUT)) { + PRINT_D(TX_DBG, "Get Timed Out\n"); + ret_size = 0; + } + PRINT_D(GENERIC_DBG, "[WILC]Get Response received\n"); + p->cfg_frame_in_use = 0; + p->cfg_frame_offset = 0; + p->cfg_seq_no += 1; + } + + return ret_size; +} + +static int wilc_wlan_cfg_get_val(uint32_t wid, uint8_t *buffer, uint32_t buffer_size) +{ + wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan; + int ret; + + ret = p->cif_func.cfg_wid_get_val((uint16_t)wid, buffer, buffer_size); + + return ret; +} + +void wilc_bus_set_max_speed(void) +{ + + /* Increase bus speed to max possible. */ + g_wlan.hif_func.hif_set_max_bus_speed(); +} + +void wilc_bus_set_default_speed(void) +{ + + /* Restore bus speed to default. */ + g_wlan.hif_func.hif_set_default_bus_speed(); +} +uint32_t init_chip(void) +{ + uint32_t chipid; + uint32_t reg, ret = 0; + +#if defined(PLAT_RK3026_TCHIP) + acquire_bus(ACQUIRE_AND_WAKEUP); /* AMR : 0422 RK3026 Crash issue */ +#else + acquire_bus(ACQUIRE_ONLY); +#endif + + chipid = wilc_get_chipid(WILC_TRUE); + + + + if ((chipid & 0xfff) != 0xa0) { + /** + * Avoid booting from boot ROM. Make sure that Drive IRQN [SDIO platform] + * or SD_DAT3 [SPI platform] to ?1? + **/ + /* Set cortus reset register to register control. */ + ret = g_wlan.hif_func.hif_read_reg(0x1118, ®); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n"); + return ret; + } + reg |= (1 << 0); + ret = g_wlan.hif_func.hif_write_reg(0x1118, reg); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n"); + return ret; + } + /** + * Write branch intruction to IRAM (0x71 trap) at location 0xFFFF0000 + * (Cortus map) or C0000 (AHB map). + **/ + ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71); + if (!ret) { + wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n"); + return ret; + } + } + + + #if 0 + if ((chipid & 0xfff) < 0xf0) { + /* Setting MUX to probe sleep signal on pin 6 of J216*/ + g_wlan.hif_func.hif_write_reg(0x1060, 0x1); + g_wlan.hif_func.hif_write_reg(0x1180, 0x33333333); + g_wlan.hif_func.hif_write_reg(0x1184, 0x33333333); + g_wlan.hif_func.hif_read_reg(0x1408, ®); + /* set MUX for GPIO_4 (pin 4) to cortus GPIO*/ + reg &= ~((0x7 << 16)); + g_wlan.hif_func.hif_write_reg(0x1408, (reg | (0x7 << 12))); + } else { + /* Enable test bus*/ + g_wlan.hif_func.hif_write_reg(0x1060, 0x1); + /* Rotate bus signals to get sleep signal on pin 6 like it was on previous chips*/ + g_wlan.hif_func.hif_write_reg(0x1188, 0x70); + /* Set output of pin 6 to test bus 0x1*/ + /* Set output of pin 9 to test bus 0x2*/ + g_wlan.hif_func.hif_write_reg(0x1180, 0x200100); + g_wlan.hif_func.hif_read_reg(0x1408, ®); + + /* set MUX for GPIO_4 (pin 4) to cortus GPIO*/ + reg &= ~((0x7 << 16)); + /* set MUX for GPIO_3 (pin 6) to test bus*/ + reg |= (0x7 << 12) | (0x7 << 24); + g_wlan.hif_func.hif_write_reg(0x1408, reg); + } + #endif + + + + release_bus(RELEASE_ONLY); + + return ret; + +} + +uint32_t wilc_get_chipid(uint8_t update) +{ + static uint32_t chipid; + /* SDIO can't read into global variables */ + /* Use this variable as a temp, then copy to the global */ + uint32_t tempchipid = 0; + uint32_t rfrevid; + + if (chipid == 0 || update != 0) { + g_wlan.hif_func.hif_read_reg(0x1000, &tempchipid); + g_wlan.hif_func.hif_read_reg(0x13f4, &rfrevid); + if (!ISWILC1000(tempchipid)) { + chipid = 0; + goto _fail_; + } + if (tempchipid == 0x1002a0) { + if (rfrevid == 0x1) { /* 1002A0 */ + } else { /* if (rfrevid == 0x2) */ /* 1002A1 */ + tempchipid = 0x1002a1; + } + } else if (tempchipid == 0x1002b0) { + if (rfrevid == 3) { /* 1002B0 */ + } else if (rfrevid == 4) { /* 1002B1 */ + tempchipid = 0x1002b1; + } else { /* if(rfrevid == 5) */ /* 1002B2 */ + tempchipid = 0x1002b2; + } + } else { + } + + chipid = tempchipid; + } +_fail_: + return chipid; +} + +#ifdef COMPLEMENT_BOOT +uint8_t core_11b_ready(void) +{ + uint32_t reg_val; + + acquire_bus(ACQUIRE_ONLY); + g_wlan.hif_func.hif_write_reg(0x16082c, 1); + g_wlan.hif_func.hif_write_reg(0x161600, 0x90); + g_wlan.hif_func.hif_read_reg(0x161600, ®_val); + release_bus(RELEASE_ONLY); + + if (reg_val == 0x90) + return 0; + else + return 1; +} +#endif + +int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup) +{ + + int ret = 0; + + PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n"); + + memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t)); + + /** + * store the input + **/ + memcpy((void *)&g_wlan.os_func, (void *)&inp->os_func, sizeof(wilc_wlan_os_func_t)); + memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(wilc_wlan_io_func_t)); + memcpy((void *)&g_wlan.net_func, (void *)&inp->net_func, sizeof(wilc_wlan_net_func_t)); + memcpy((void *)&g_wlan.indicate_func, (void *)&inp->indicate_func, sizeof(wilc_wlan_net_func_t)); + g_wlan.hif_lock = inp->os_context.hif_critical_section; + g_wlan.txq_lock = inp->os_context.txq_critical_section; + + /*Added by Amr - BugID_4720*/ + g_wlan.txq_add_to_head_lock = inp->os_context.txq_add_to_head_critical_section; + + /*Added by Amr - BugID_4720*/ + g_wlan.txq_spinlock = inp->os_context.txq_spin_lock; + + g_wlan.rxq_lock = inp->os_context.rxq_critical_section; + g_wlan.txq_wait = inp->os_context.txq_wait_event; + g_wlan.rxq_wait = inp->os_context.rxq_wait_event; + g_wlan.cfg_wait = inp->os_context.cfg_wait_event; + g_wlan.tx_buffer_size = inp->os_context.tx_buffer_size; +#if defined (MEMORY_STATIC) + g_wlan.rx_buffer_size = inp->os_context.rx_buffer_size; +#endif + /*** + * host interface init + **/ +#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */ + if (!g_wilc_initialized) { + custom_lock_bus(g_mac_open); + custom_wakeup(g_mac_open); + } +#endif + + if ((inp->io_func.io_type & 0x1) == HIF_SDIO) { + if (!hif_sdio.hif_init(inp, wilc_debug)) { + /* EIO 5 */ + ret = -5; + goto _fail_; + } + memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(wilc_hif_func_t)); + } else { + if ((inp->io_func.io_type & 0x1) == HIF_SPI) { + /** + * TODO: + **/ + if (!hif_spi.hif_init(inp, wilc_debug)) { + /* EIO 5 */ + ret = -5; + goto _fail_; + } + memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(wilc_hif_func_t)); + } else { + /* EIO 5 */ + ret = -5; + goto _fail_; + } + } + + /*** + * mac interface init + **/ + if (!mac_cfg.cfg_init(wilc_debug)) { + /* ENOBUFS 105 */ + ret = -105; + goto _fail_; + } + memcpy((void *)&g_wlan.cif_func, &mac_cfg, sizeof(wilc_cfg_func_t)); + + + /** + * alloc tx, rx buffer + **/ +#if (defined WILC_PREALLOC_AT_BOOT) + extern void *get_tx_buffer(void); + extern void *get_rx_buffer(void); + + PRINT_D(TX_DBG, "malloc before, g_wlan.tx_buffer = 0x%x, g_wlan.rx_buffer = 0x%x\n", g_wlan.tx_buffer, g_wlan.rx_buffer); +#endif + + + + if (g_wlan.tx_buffer == NULL) +#if (defined WILC_PREALLOC_AT_BOOT) + g_wlan.tx_buffer = (uint8_t *)get_tx_buffer(); +#else + g_wlan.tx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.tx_buffer_size); +#endif + PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer); + + if (g_wlan.tx_buffer == NULL) { + /* ENOBUFS 105 */ + ret = -105; + PRINT_ER("Can't allocate Tx Buffer"); + goto _fail_; + } + +/* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/ +#if defined (MEMORY_STATIC) + if (g_wlan.rx_buffer == NULL) + #if (defined WILC_PREALLOC_AT_BOOT) + g_wlan.rx_buffer = (uint8_t *)get_rx_buffer(); + #else + g_wlan.rx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.rx_buffer_size); + #endif + PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer); + if (g_wlan.rx_buffer == NULL) { + /* ENOBUFS 105 */ + ret = -105; + PRINT_ER("Can't allocate Rx Buffer"); + goto _fail_; + } +#endif + + /** + * export functions + **/ + oup->wlan_firmware_download = wilc_wlan_firmware_download; + oup->wlan_start = wilc_wlan_start; + oup->wlan_stop = wilc_wlan_stop; + oup->wlan_add_to_tx_que = wilc_wlan_txq_add_net_pkt; + oup->wlan_handle_tx_que = wilc_wlan_handle_txq; + oup->wlan_handle_rx_que = wilc_wlan_handle_rxq; + oup->wlan_handle_rx_isr = wilc_handle_isr; + oup->wlan_cleanup = wilc_wlan_cleanup; + oup->wlan_cfg_set = wilc_wlan_cfg_set; + oup->wlan_cfg_get = wilc_wlan_cfg_get; + oup->wlan_cfg_get_value = wilc_wlan_cfg_get_val; + + /*Bug3959: transmitting mgmt frames received from host*/ + #if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P) + oup->wlan_add_mgmt_to_tx_que = wilc_wlan_txq_add_mgmt_pkt; + + #ifdef WILC_FULLY_HOSTING_AP + oup->wlan_add_data_to_tx_que = wilc_FH_wlan_txq_add_net_pkt; + #endif + #endif + + if (!init_chip()) { + /* EIO 5 */ + ret = -5; + goto _fail_; + } +#ifdef TCP_ACK_FILTER + Init_TCP_tracking(); +#endif + +#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */ + if (!g_wilc_initialized) + custom_unlock_bus(g_mac_open); +#endif + + return 1; + +_fail_: + +#if (defined WILC_PREALLOC_AT_BOOT) + +#else + #ifdef MEMORY_STATIC + if (g_wlan.rx_buffer) { + g_wlan.os_func.os_free(g_wlan.rx_buffer); + g_wlan.rx_buffer = NULL; + } + #endif + if (g_wlan.tx_buffer) { + g_wlan.os_func.os_free(g_wlan.tx_buffer); + g_wlan.tx_buffer = NULL; + } +#endif + +#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */ + if (!g_wilc_initialized) + custom_unlock_bus(g_mac_open); +#endif + + return ret; + +} + +#define BIT31 (1 << 31) +WILC_Uint16 Set_machw_change_vir_if(WILC_Bool bValue) +{ + WILC_Uint16 ret; + WILC_Uint32 reg; + + /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/ + (&g_wlan)->os_func.os_enter_cs((&g_wlan)->hif_lock); + ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, ®); + if (!ret) { + PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n"); + } + + if (bValue == WILC_TRUE) { + reg |= (BIT31); + } else { + reg &= ~(BIT31); + } + + ret = (&g_wlan)->hif_func.hif_write_reg(WILC_CHANGING_VIR_IF, reg); + + if (!ret) { + PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n"); + } + (&g_wlan)->os_func.os_leave_cs((&g_wlan)->hif_lock); + + return ret; +} + +#ifdef WILC_FULLY_HOSTING_AP +wilc_wlan_dev_t *Get_wlan_context(WILC_Uint16 *pu16size) +{ + *pu16size = sizeof(wilc_wlan_dev_t); + return &g_wlan; +} +#endif + diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h new file mode 100644 index 000000000000..0ba7ec69e2b4 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -0,0 +1,321 @@ +#ifndef WILC_WLAN_H +#define WILC_WLAN_H + +#include "wilc_type.h" + + +#define ISWILC1000(id) (((id & 0xfffff000) == 0x100000) ? 1 : 0) + + +/******************************************** + * + * Mac eth header length + * + ********************************************/ +#define DRIVER_HANDLER_SIZE 4 +#define MAX_MAC_HDR_LEN 26 /* QOS_MAC_HDR_LEN */ +#define SUB_MSDU_HEADER_LENGTH 14 +#define SNAP_HDR_LEN 8 +#define ETHERNET_HDR_LEN 14 +#define WORD_ALIGNMENT_PAD 0 + +#define ETH_ETHERNET_HDR_OFFSET (MAX_MAC_HDR_LEN + SUB_MSDU_HEADER_LENGTH + \ + SNAP_HDR_LEN - ETHERNET_HDR_LEN + WORD_ALIGNMENT_PAD) + +/*Bug3959: transmitting mgmt frames received from host*/ +#define HOST_HDR_OFFSET 4 +#define ETHERNET_HDR_LEN 14 +#define IP_HDR_LEN 20 +#define IP_HDR_OFFSET ETHERNET_HDR_LEN +#define UDP_HDR_OFFSET (IP_HDR_LEN + IP_HDR_OFFSET) +#define UDP_HDR_LEN 8 +#define UDP_DATA_OFFSET (UDP_HDR_OFFSET + UDP_HDR_LEN) +#define ETH_CONFIG_PKT_HDR_LEN UDP_DATA_OFFSET + +#define ETH_CONFIG_PKT_HDR_OFFSET (ETH_ETHERNET_HDR_OFFSET + \ + ETH_CONFIG_PKT_HDR_LEN) +#define ACTION 0xD0 +#define PROBE_REQ 0x40 +#ifdef WILC_FULLY_HOSTING_AP +#define FH_TX_HOST_HDR_OFFSET 24 +#endif + +/******************************************** + * + * Endian Conversion + * + ********************************************/ + +#define BYTE_SWAP(val) ((((val) & 0x000000FF) << 24) + \ + (((val) & 0x0000FF00) << 8) + \ + (((val) & 0x00FF0000) >> 8) + \ + (((val) & 0xFF000000) >> 24)) + +/******************************************** + * + * Register Defines + * + ********************************************/ +#define WILC_PERIPH_REG_BASE 0x1000 +/*BugID_5137*/ +#define WILC_CHANGING_VIR_IF (0x108c) +#define WILC_CHIPID (WILC_PERIPH_REG_BASE) +#define WILC_GLB_RESET_0 (WILC_PERIPH_REG_BASE + 0x400) +#define WILC_PIN_MUX_0 (WILC_PERIPH_REG_BASE + 0x408) +#define WILC_HOST_TX_CTRL (WILC_PERIPH_REG_BASE + 0x6c) +#define WILC_HOST_RX_CTRL_0 (WILC_PERIPH_REG_BASE + 0x70) +#define WILC_HOST_RX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x74) +#define WILC_HOST_VMM_CTL (WILC_PERIPH_REG_BASE + 0x78) +#define WILC_HOST_RX_CTRL (WILC_PERIPH_REG_BASE + 0x80) +#define WILC_HOST_RX_EXTRA_SIZE (WILC_PERIPH_REG_BASE + 0x84) +#define WILC_HOST_TX_CTRL_1 (WILC_PERIPH_REG_BASE + 0x88) +#define WILC_MISC (WILC_PERIPH_REG_BASE + 0x428) +#define WILC_INTR_REG_BASE (WILC_PERIPH_REG_BASE + 0xa00) +#define WILC_INTR_ENABLE (WILC_INTR_REG_BASE) +#define WILC_INTR2_ENABLE (WILC_INTR_REG_BASE + 4) + +#define WILC_INTR_POLARITY (WILC_INTR_REG_BASE + 0x10) +#define WILC_INTR_TYPE (WILC_INTR_REG_BASE + 0x20) +#define WILC_INTR_CLEAR (WILC_INTR_REG_BASE + 0x30) +#define WILC_INTR_STATUS (WILC_INTR_REG_BASE + 0x40) + +#define WILC_VMM_TBL_SIZE 64 +#define WILC_VMM_TX_TBL_BASE (0x150400) +#define WILC_VMM_RX_TBL_BASE (0x150500) + +#define WILC_VMM_BASE 0x150000 +#define WILC_VMM_CORE_CTL (WILC_VMM_BASE) +#define WILC_VMM_TBL_CTL (WILC_VMM_BASE + 0x4) +#define WILC_VMM_TBL_ENTRY (WILC_VMM_BASE + 0x8) +#define WILC_VMM_TBL0_SIZE (WILC_VMM_BASE + 0xc) +#define WILC_VMM_TO_HOST_SIZE (WILC_VMM_BASE + 0x10) +#define WILC_VMM_CORE_CFG (WILC_VMM_BASE + 0x14) +#define WILC_VMM_TBL_ACTIVE (WILC_VMM_BASE + 040) +#define WILC_VMM_TBL_STATUS (WILC_VMM_BASE + 0x44) + +#define WILC_SPI_REG_BASE 0xe800 +#define WILC_SPI_CTL (WILC_SPI_REG_BASE) +#define WILC_SPI_MASTER_DMA_ADDR (WILC_SPI_REG_BASE + 0x4) +#define WILC_SPI_MASTER_DMA_COUNT (WILC_SPI_REG_BASE + 0x8) +#define WILC_SPI_SLAVE_DMA_ADDR (WILC_SPI_REG_BASE + 0xc) +#define WILC_SPI_SLAVE_DMA_COUNT (WILC_SPI_REG_BASE + 0x10) +#define WILC_SPI_TX_MODE (WILC_SPI_REG_BASE + 0x20) +#define WILC_SPI_PROTOCOL_CONFIG (WILC_SPI_REG_BASE + 0x24) +#define WILC_SPI_INTR_CTL (WILC_SPI_REG_BASE + 0x2c) + +#define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - WILC_SPI_REG_BASE) + +#define WILC_AHB_DATA_MEM_BASE 0x30000 +#define WILC_AHB_SHARE_MEM_BASE 0xd0000 + +#define WILC_VMM_TBL_RX_SHADOW_BASE WILC_AHB_SHARE_MEM_BASE /* Bug 4477 fix */ +#define WILC_VMM_TBL_RX_SHADOW_SIZE (256) /* Bug 4477 fix */ + +#define WILC_GP_REG_0 0x149c +#define WILC_GP_REG_1 0x14a0 + +#define rHAVE_SDIO_IRQ_GPIO_BIT (0) +#define rHAVE_USE_PMU_BIT (1) +#define rHAVE_SLEEP_CLK_SRC_RTC_BIT (2) +#define rHAVE_SLEEP_CLK_SRC_XO_BIT (3) +#define rHAVE_EXT_PA_INV_TX_RX_BIT (4) +#define rHAVE_LEGACY_RF_SETTINGS_BIT (5) +#define rHAVE_XTAL_24_BIT (6) +#define rHAVE_DISABLE_WILC_UART_BIT (7) + + +#define WILC_HAVE_SDIO_IRQ_GPIO (1 << rHAVE_SDIO_IRQ_GPIO_BIT) +#define WILC_HAVE_USE_PMU (1 << rHAVE_USE_PMU_BIT) +#define WILC_HAVE_SLEEP_CLK_SRC_RTC (1 << rHAVE_SLEEP_CLK_SRC_RTC_BIT) +#define WILC_HAVE_SLEEP_CLK_SRC_XO (1 << rHAVE_SLEEP_CLK_SRC_XO_BIT) +#define WILC_HAVE_EXT_PA_INV_TX_RX (1 << rHAVE_EXT_PA_INV_TX_RX_BIT) +#define WILC_HAVE_LEGACY_RF_SETTINGS (1 << rHAVE_LEGACY_RF_SETTINGS_BIT) +#define WILC_HAVE_XTAL_24 (1 << rHAVE_XTAL_24_BIT) +#define WILC_HAVE_DISABLE_WILC_UART (1 << rHAVE_DISABLE_WILC_UART_BIT) + + +/******************************************** + * + * Wlan Defines + * + ********************************************/ +#define WILC_CFG_PKT 1 +#define WILC_NET_PKT 0 +/*Bug3959: transmitting mgmt frames received from host*/ +#ifdef WILC_AP_EXTERNAL_MLME +#define WILC_MGMT_PKT 2 + +#ifdef WILC_FULLY_HOSTING_AP +#define WILC_FH_DATA_PKT 4 +#endif + +#endif /*WILC_AP_EXTERNAL_MLME*/ +#define WILC_CFG_SET 1 +#define WILC_CFG_QUERY 0 + +#define WILC_CFG_RSP 1 +#define WILC_CFG_RSP_STATUS 2 +#define WILC_CFG_RSP_SCAN 3 + +#ifdef WILC_SDIO +#define WILC_PLL_TO 4 +#else +#define WILC_PLL_TO 2 +#endif + + +#define ABORT_INT (1 << 31) + +/*******************************************/ +/* E0 and later Interrupt flags. */ +/*******************************************/ +/*******************************************/ +/* E0 and later Interrupt flags. */ +/* IRQ Status word */ +/* 15:0 = DMA count in words. */ +/* 16: INT0 flag */ +/* 17: INT1 flag */ +/* 18: INT2 flag */ +/* 19: INT3 flag */ +/* 20: INT4 flag */ +/* 21: INT5 flag */ +/*******************************************/ +#define IRG_FLAGS_OFFSET 16 +#define IRQ_DMA_WD_CNT_MASK ((1ul << IRG_FLAGS_OFFSET) - 1) +#define INT_0 (1 << (IRG_FLAGS_OFFSET)) +#define INT_1 (1 << (IRG_FLAGS_OFFSET + 1)) +#define INT_2 (1 << (IRG_FLAGS_OFFSET + 2)) +#define INT_3 (1 << (IRG_FLAGS_OFFSET + 3)) +#define INT_4 (1 << (IRG_FLAGS_OFFSET + 4)) +#define INT_5 (1 << (IRG_FLAGS_OFFSET + 5)) +#define MAX_NUM_INT (6) + +/*******************************************/ +/* E0 and later Interrupt flags. */ +/* IRQ Clear word */ +/* 0: Clear INT0 */ +/* 1: Clear INT1 */ +/* 2: Clear INT2 */ +/* 3: Clear INT3 */ +/* 4: Clear INT4 */ +/* 5: Clear INT5 */ +/* 6: Select VMM table 1 */ +/* 7: Select VMM table 2 */ +/* 8: Enable VMM */ +/*******************************************/ +#define CLR_INT0 (1 << 0) +#define CLR_INT1 (1 << 1) +#define CLR_INT2 (1 << 2) +#define CLR_INT3 (1 << 3) +#define CLR_INT4 (1 << 4) +#define CLR_INT5 (1 << 5) +#define SEL_VMM_TBL0 (1 << 6) +#define SEL_VMM_TBL1 (1 << 7) +#define EN_VMM (1 << 8) + +#define DATA_INT_EXT INT_0 +#define PLL_INT_EXT INT_1 +#define SLEEP_INT_EXT INT_2 +#define ALL_INT_EXT (DATA_INT_EXT | PLL_INT_EXT | SLEEP_INT_EXT) +#define NUM_INT_EXT (3) + +#define DATA_INT_CLR CLR_INT0 +#define PLL_INT_CLR CLR_INT1 +#define SLEEP_INT_CLR CLR_INT2 + +#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) +#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) + + +/*time for expiring the semaphores of cfg packets*/ +#define CFG_PKTS_TIMEOUT 2000 +/******************************************** + * + * Debug Type + * + ********************************************/ +typedef void (*wilc_debug_func)(uint32_t, char *, ...); + +/******************************************** + * + * Tx/Rx Queue Structure + * + ********************************************/ + +struct txq_entry_t { + struct txq_entry_t *next; + struct txq_entry_t *prev; + int type; + int tcp_PendingAck_index; + uint8_t *buffer; + int buffer_size; + void *priv; + int status; + void (*tx_complete_func)(void *, int); +}; + +struct rxq_entry_t { + struct rxq_entry_t *next; + uint8_t *buffer; + int buffer_size; +}; + +/******************************************** + * + * Host IF Structure + * + ********************************************/ + +typedef struct { + int (*hif_init)(wilc_wlan_inp_t *, wilc_debug_func); + int (*hif_deinit)(void *); + int (*hif_read_reg)(uint32_t, uint32_t *); + int (*hif_write_reg)(uint32_t, uint32_t); + int (*hif_block_rx)(uint32_t, uint8_t *, uint32_t); + int (*hif_block_tx)(uint32_t, uint8_t *, uint32_t); + int (*hif_sync)(void); + int (*hif_clear_int)(void); + int (*hif_read_int)(uint32_t *); + int (*hif_clear_int_ext)(uint32_t); + int (*hif_read_size)(uint32_t *); + int (*hif_block_tx_ext)(uint32_t, uint8_t *, uint32_t); + int (*hif_block_rx_ext)(uint32_t, uint8_t *, uint32_t); + int (*hif_sync_ext)(int); + void (*hif_set_max_bus_speed)(void); + void (*hif_set_default_bus_speed)(void); +} wilc_hif_func_t; + +/******************************************** + * + * Configuration Structure + * + ********************************************/ + +#define MAX_CFG_FRAME_SIZE 1468 + +typedef struct { + uint8_t ether_header[14]; + uint8_t ip_header[20]; + uint8_t udp_header[8]; + uint8_t wid_header[8]; + uint8_t frame[MAX_CFG_FRAME_SIZE]; +} wilc_cfg_frame_t; + +typedef struct { + int (*wlan_tx)(uint8_t *, uint32_t, wilc_tx_complete_func_t); +} wilc_wlan_cfg_func_t; + +typedef struct { + int type; + uint32_t seq_no; +} wilc_cfg_rsp_t; + +typedef struct { + int (*cfg_wid_set)(uint8_t *, uint32_t, uint16_t, uint8_t *, int); + int (*cfg_wid_get)(uint8_t *, uint32_t, uint16_t); + int (*cfg_wid_get_val)(uint16_t, uint8_t *, uint32_t); + int (*rx_indicate)(uint8_t *, int, wilc_cfg_rsp_t *); + int (*cfg_init)(wilc_debug_func); +} wilc_cfg_func_t; + +#endif diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c new file mode 100644 index 000000000000..a627c5870960 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -0,0 +1,643 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_wlan_cfg.c */ +/* */ +/* */ +/* ///////////////////////////////////////////////////////////////////////// */ + +#include "wilc_wlan_if.h" +#include "wilc_wlan.h" +#include "wilc_wlan_cfg.h" +#include "coreconfigurator.h" + +#ifdef WILC_FULLY_HOSTING_AP +#include "wilc_host_ap.h" +void WILC_mgm_HOSTAPD_ACK(void *priv, WILC_Bool bStatus); +#endif + +/******************************************** + * + * Global Data + * + ********************************************/ + +typedef struct { + wilc_debug_func dPrint; + + int mac_status; + uint8_t mac_address[7]; + uint8_t ip_address[5]; + uint8_t bssid[7]; + uint8_t ssid[34]; + uint8_t firmware_version[129]; + uint8_t supp_rate[24]; + uint8_t wep_key[28]; + uint8_t i_psk[66]; + uint8_t hardwareProductVersion[33]; + uint8_t phyversion[17]; + uint8_t supp_username[21]; + uint8_t supp_password[64]; + uint8_t assoc_req[256]; + uint8_t assoc_rsp[256]; + uint8_t firmware_info[8]; + uint8_t scan_result[256]; + uint8_t scan_result1[256]; +} wilc_mac_cfg_t; + +static wilc_mac_cfg_t g_mac; + +static wilc_cfg_byte_t g_cfg_byte[] = { + {WID_BSS_TYPE, 0}, + {WID_CURRENT_TX_RATE, 0}, + {WID_CURRENT_CHANNEL, 0}, + {WID_PREAMBLE, 0}, + {WID_11G_OPERATING_MODE, 0}, + {WID_STATUS, 0}, + {WID_SCAN_TYPE, 0}, + {WID_KEY_ID, 0}, + {WID_QOS_ENABLE, 0}, + {WID_POWER_MANAGEMENT, 0}, + {WID_11I_MODE, 0}, + {WID_AUTH_TYPE, 0}, + {WID_SITE_SURVEY, 0}, + {WID_LISTEN_INTERVAL, 0}, + {WID_DTIM_PERIOD, 0}, + {WID_ACK_POLICY, 0}, + {WID_BCAST_SSID, 0}, + {WID_REKEY_POLICY, 0}, + {WID_SHORT_SLOT_ALLOWED, 0}, + {WID_START_SCAN_REQ, 0}, + {WID_RSSI, 0}, + {WID_LINKSPEED, 0}, + {WID_AUTO_RX_SENSITIVITY, 0}, + {WID_DATAFLOW_CONTROL, 0}, + {WID_SCAN_FILTER, 0}, + {WID_11N_PROT_MECH, 0}, + {WID_11N_ERP_PROT_TYPE, 0}, + {WID_11N_ENABLE, 0}, + {WID_11N_OPERATING_MODE, 0}, + {WID_11N_OBSS_NONHT_DETECTION, 0}, + {WID_11N_HT_PROT_TYPE, 0}, + {WID_11N_RIFS_PROT_ENABLE, 0}, + {WID_11N_SMPS_MODE, 0}, + {WID_11N_CURRENT_TX_MCS, 0}, + {WID_11N_SHORT_GI_ENABLE, 0}, + {WID_RIFS_MODE, 0}, + {WID_TX_ABORT_CONFIG, 0}, + {WID_11N_IMMEDIATE_BA_ENABLED, 0}, + {WID_11N_TXOP_PROT_DISABLE, 0}, + {WID_NIL, 0} +}; + +static wilc_cfg_hword_t g_cfg_hword[] = { + {WID_LINK_LOSS_THRESHOLD, 0}, + {WID_RTS_THRESHOLD, 0}, + {WID_FRAG_THRESHOLD, 0}, + {WID_SHORT_RETRY_LIMIT, 0}, + {WID_LONG_RETRY_LIMIT, 0}, + {WID_BEACON_INTERVAL, 0}, + {WID_RX_SENSE, 0}, + {WID_ACTIVE_SCAN_TIME, 0}, + {WID_PASSIVE_SCAN_TIME, 0}, + {WID_SITE_SURVEY_SCAN_TIME, 0}, + {WID_JOIN_START_TIMEOUT, 0}, + {WID_AUTH_TIMEOUT, 0}, + {WID_ASOC_TIMEOUT, 0}, + {WID_11I_PROTOCOL_TIMEOUT, 0}, + {WID_EAPOL_RESPONSE_TIMEOUT, 0}, + {WID_11N_SIG_QUAL_VAL, 0}, + {WID_CCA_THRESHOLD, 0}, + {WID_NIL, 0} +}; + +static wilc_cfg_word_t g_cfg_word[] = { + {WID_FAILED_COUNT, 0}, + {WID_RETRY_COUNT, 0}, + {WID_MULTIPLE_RETRY_COUNT, 0}, + {WID_FRAME_DUPLICATE_COUNT, 0}, + {WID_ACK_FAILURE_COUNT, 0}, + {WID_RECEIVED_FRAGMENT_COUNT, 0}, + {WID_MCAST_RECEIVED_FRAME_COUNT, 0}, + {WID_FCS_ERROR_COUNT, 0}, + {WID_SUCCESS_FRAME_COUNT, 0}, + {WID_TX_FRAGMENT_COUNT, 0}, + {WID_TX_MULTICAST_FRAME_COUNT, 0}, + {WID_RTS_SUCCESS_COUNT, 0}, + {WID_RTS_FAILURE_COUNT, 0}, + {WID_WEP_UNDECRYPTABLE_COUNT, 0}, + {WID_REKEY_PERIOD, 0}, + {WID_REKEY_PACKET_COUNT, 0}, + {WID_HW_RX_COUNT, 0}, + {WID_GET_INACTIVE_TIME, 0}, + {WID_NIL, 0} + +}; + +static wilc_cfg_str_t g_cfg_str[] = { + {WID_SSID, g_mac.ssid}, /* 33 + 1 bytes */ + {WID_FIRMWARE_VERSION, g_mac.firmware_version}, + {WID_OPERATIONAL_RATE_SET, g_mac.supp_rate}, + {WID_BSSID, g_mac.bssid}, /* 6 bytes */ + {WID_WEP_KEY_VALUE, g_mac.wep_key}, /* 27 bytes */ + {WID_11I_PSK, g_mac.i_psk}, /* 65 bytes */ + /* {WID_11E_P_ACTION_REQ, g_mac.action_req}, */ + {WID_HARDWARE_VERSION, g_mac.hardwareProductVersion}, + {WID_MAC_ADDR, g_mac.mac_address}, + {WID_PHY_VERSION, g_mac.phyversion}, + {WID_SUPP_USERNAME, g_mac.supp_username}, + {WID_SUPP_PASSWORD, g_mac.supp_password}, + {WID_SITE_SURVEY_RESULTS, g_mac.scan_result}, + {WID_SITE_SURVEY_RESULTS, g_mac.scan_result1}, + /* {WID_RX_POWER_LEVEL, g_mac.channel_rssi}, */ + {WID_ASSOC_REQ_INFO, g_mac.assoc_req}, + {WID_ASSOC_RES_INFO, g_mac.assoc_rsp}, + /* {WID_11N_P_ACTION_REQ, g_mac.action_req}, */ + {WID_FIRMWARE_INFO, g_mac.firmware_version}, + {WID_IP_ADDRESS, g_mac.ip_address}, + {WID_NIL, NULL} +}; + +/******************************************** + * + * Configuration Functions + * + ********************************************/ + +static int wilc_wlan_cfg_set_byte(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t val8) +{ + uint8_t *buf; + + if ((offset + 4) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + buf[2] = 1; + buf[3] = val8; + return 4; +} + +static int wilc_wlan_cfg_set_hword(uint8_t *frame, uint32_t offset, uint16_t id, uint16_t val16) +{ + uint8_t *buf; + + if ((offset + 5) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + buf[2] = 2; + buf[3] = (uint8_t)val16; + buf[4] = (uint8_t)(val16 >> 8); + + return 5; +} + +static int wilc_wlan_cfg_set_word(uint8_t *frame, uint32_t offset, uint16_t id, uint32_t val32) +{ + uint8_t *buf; + + if ((offset + 7) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + buf[2] = 4; + buf[3] = (uint8_t)val32; + buf[4] = (uint8_t)(val32 >> 8); + buf[5] = (uint8_t)(val32 >> 16); + buf[6] = (uint8_t)(val32 >> 24); + + return 7; +} + +static int wilc_wlan_cfg_set_str(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *str, uint32_t size) +{ + uint8_t *buf; + + if ((offset + size + 3) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + buf[2] = (uint8_t)size; + + if ((str != NULL) && (size != 0)) + memcpy(&buf[3], str, size); + + return (size + 3); +} + +static int wilc_wlan_cfg_set_bin(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *b, uint32_t size) +{ + uint8_t *buf; + uint32_t i; + uint8_t checksum = 0; + + if ((offset + size + 5) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + buf[2] = (uint8_t)size; + buf[3] = (uint8_t)(size >> 8); + + if ((b != NULL) && (size != 0)) { + memcpy(&buf[4], b, size); + for (i = 0; i < size; i++) { + checksum += buf[i + 4]; + } + } + + buf[size + 4] = checksum; + + return (size + 5); +} + +/******************************************** + * + * Configuration Response Functions + * + ********************************************/ + +static void wilc_wlan_parse_response_frame(uint8_t *info, int size) +{ + uint32_t wid, len = 0, i = 0; + static int seq; + + while (size > 0) { + i = 0; + wid = info[0] | (info[1] << 8); +#ifdef BIG_ENDIAN + wid = BYTE_SWAP(wid); +#endif + PRINT_INFO(GENERIC_DBG, "Processing response for %d seq %d\n", wid, seq++); + switch ((wid >> 12) & 0x7) { + case WID_CHAR: + do { + if (g_cfg_byte[i].id == WID_NIL) + break; + + if (g_cfg_byte[i].id == wid) { + g_cfg_byte[i].val = info[3]; + break; + } + i++; + } while (1); + len = 2; + break; + + case WID_SHORT: + do { + if (g_cfg_hword[i].id == WID_NIL) + break; + + if (g_cfg_hword[i].id == wid) { +#ifdef BIG_ENDIAN + g_cfg_hword[i].val = (info[3] << 8) | (info[4]); +#else + g_cfg_hword[i].val = info[3] | (info[4] << 8); +#endif + break; + } + i++; + } while (1); + len = 3; + break; + + case WID_INT: + do { + if (g_cfg_word[i].id == WID_NIL) + break; + + if (g_cfg_word[i].id == wid) { +#ifdef BIG_ENDIAN + g_cfg_word[i].val = (info[3] << 24) | (info[4] << 16) | (info[5] << 8) | (info[6]); +#else + g_cfg_word[i].val = info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24); +#endif + break; + } + i++; + } while (1); + len = 5; + break; + + case WID_STR: + do { + if (g_cfg_str[i].id == WID_NIL) + break; + + if (g_cfg_str[i].id == wid) { + if (wid == WID_SITE_SURVEY_RESULTS) { + static int toggle; + PRINT_INFO(GENERIC_DBG, "Site survey results received[%d]\n", + size); + + PRINT_INFO(GENERIC_DBG, "Site survey results value[%d]toggle[%d]\n", size, toggle); + i += toggle; + toggle ^= 1; + } + memcpy(g_cfg_str[i].str, &info[2], (info[2] + 1)); + break; + } + i++; + } while (1); + len = 1 + info[2]; + break; + + default: + break; + } + size -= (2 + len); + info += (2 + len); + } + + return; +} + +static int wilc_wlan_parse_info_frame(uint8_t *info, int size) +{ + wilc_mac_cfg_t *pd = (wilc_mac_cfg_t *)&g_mac; + uint32_t wid, len; + int type = WILC_CFG_RSP_STATUS; + + wid = info[0] | (info[1] << 8); +#if 0 +#ifdef BIG_ENDIAN + wid = BYTE_SWAP(wid); +#endif +#endif + + len = info[2]; + PRINT_INFO(GENERIC_DBG, "Status Len = %d Id= %d\n", len, wid); + if ((len == 1) && (wid == WID_STATUS)) { + pd->mac_status = info[3]; + type = WILC_CFG_RSP_STATUS; + } + + return type; +} + +#if 0 +static int wilc_wlan_parse_network_frame(uint8_t *info, int size) +{ + wilc_mac_cfg_t *priv = (wilc_mac_cfg_t *)&g_mac; + uint32_t wid, len; + + wid = info[0] | (info[1] << 8); + len = info[2] | (info[3] << 8); + + /** + * Review: this message is only for AP mode. + * TBD + **/ + if (wid == WID_NETWORK_INFO) { /* not send by the firmware */ + + } + + return; +} +#endif + +/******************************************** + * + * Configuration Exported Functions + * + ********************************************/ + +static int wilc_wlan_cfg_set_wid(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *buf, int size) +{ + uint8_t type = (id >> 12) & 0xf; + int ret = 0; + + if (type == 0) { /* byte command */ + if (size >= 1) + ret = wilc_wlan_cfg_set_byte(frame, offset, id, *buf); + } else if (type == 1) { /* half word command */ + if (size >= 2) + ret = wilc_wlan_cfg_set_hword(frame, offset, id, *((uint16_t *)buf)); + } else if (type == 2) { /* word command */ + if (size >= 4) + ret = wilc_wlan_cfg_set_word(frame, offset, id, *((uint32_t *)buf)); + } else if (type == 3) { /* string command */ + ret = wilc_wlan_cfg_set_str(frame, offset, id, buf, size); + } else if (type == 4) { /* binary command */ + ret = wilc_wlan_cfg_set_bin(frame, offset, id, buf, size); + } else { + g_mac.dPrint(N_ERR, "illegal id\n"); + } + + return ret; +} + +static int wilc_wlan_cfg_get_wid(uint8_t *frame, uint32_t offset, uint16_t id) +{ + uint8_t *buf; + + if ((offset + 2) >= MAX_CFG_FRAME_SIZE) + return 0; + + buf = &frame[offset]; + + buf[0] = (uint8_t)id; + buf[1] = (uint8_t)(id >> 8); + + return 2; +} + +static int wilc_wlan_cfg_get_wid_value(uint16_t wid, uint8_t *buffer, uint32_t buffer_size) +{ + uint32_t type = (wid >> 12) & 0xf; + int i, ret = 0; + + if (wid == WID_STATUS) { + *((uint32_t *)buffer) = g_mac.mac_status; + return 4; + } + + i = 0; + if (type == 0) { /* byte command */ + do { + if (g_cfg_byte[i].id == WID_NIL) + break; + + if (g_cfg_byte[i].id == wid) { + memcpy(buffer, &g_cfg_byte[i].val, 1); + ret = 1; + break; + } + i++; + } while (1); + } else if (type == 1) { /* half word command */ + do { + if (g_cfg_hword[i].id == WID_NIL) + break; + + if (g_cfg_hword[i].id == wid) { + memcpy(buffer, &g_cfg_hword[i].val, 2); + ret = 2; + break; + } + i++; + } while (1); + } else if (type == 2) { /* word command */ + do { + if (g_cfg_word[i].id == WID_NIL) + break; + + if (g_cfg_word[i].id == wid) { + memcpy(buffer, &g_cfg_word[i].val, 4); + ret = 4; + break; + } + i++; + } while (1); + } else if (type == 3) { /* string command */ + do { + if (g_cfg_str[i].id == WID_NIL) + break; + + if (g_cfg_str[i].id == wid) { + uint32_t size = g_cfg_str[i].str[0]; + if (buffer_size >= size) { + if (g_cfg_str[i].id == WID_SITE_SURVEY_RESULTS) { + static int toggle; + PRINT_INFO(GENERIC_DBG, "Site survey results value[%d]\n", + size); + i += toggle; + toggle ^= 1; + + } + memcpy(buffer, &g_cfg_str[i].str[1], size); + ret = size; + } + break; + } + i++; + } while (1); + } else { + g_mac.dPrint(N_ERR, "[CFG]: illegal type (%08x)\n", wid); + } + + return ret; +} + +static int wilc_wlan_cfg_indicate_rx(uint8_t *frame, int size, wilc_cfg_rsp_t *rsp) +{ + int ret = 1; + uint8_t msg_type; + uint8_t msg_id; + uint16_t msg_len; + #ifdef WILC_FULLY_HOSTING_AP + WILC_Uint32 *ptru32Frame; + WILC_Bool bStatus = frame[2]; + + #ifdef BIG_ENDIAN + ptru32Frame = (frame[4] << 24) | (frame[5] << 16) | (frame[6] << 8) | frame[7]; + #else + ptru32Frame = (frame[7] << 24) | (frame[6] << 16) | (frame[5] << 8) | frame[4]; + #endif /* BIG_ENDIAN */ + + #endif /* WILC_FULLY_HOSTING_AP */ + + msg_type = frame[0]; + msg_id = frame[1]; /* seq no */ +#ifdef BIG_ENDIAN + msg_len = (frame[2] << 8) | frame[3]; +#else + msg_len = (frame[3] << 8) | frame[2]; +#endif + frame += 4; + size -= 4; + + /** + * The valid types of response messages are 'R' (Response), 'I' (Information), and 'N' (Network Information) + **/ + + switch (msg_type) { + case 'R': + wilc_wlan_parse_response_frame(frame, size); + rsp->type = WILC_CFG_RSP; + rsp->seq_no = msg_id; + break; + + case 'I': + rsp->type = wilc_wlan_parse_info_frame(frame, size); + rsp->seq_no = msg_id; + /*call host interface info parse as well*/ + PRINT_INFO(RX_DBG, "Info message received\n"); + GnrlAsyncInfoReceived(frame - 4, size + 4); + break; + + case 'L': +#ifndef SWITCH_LOG_TERMINAL + PRINT_ER("Unexpected firmware log message received \n"); +#else + PRINT_D(FIRM_DBG, "\nFIRMWARE LOGS :\n<<\n%s\n>>\n", frame); + break; + +#endif +#if 1 + case 'N': + NetworkInfoReceived(frame - 4, size + 4); + rsp->type = 0; + break; + +#endif +/*bug3819:*/ + case 'S': + PRINT_INFO(RX_DBG, "Scan Notification Received \n"); + host_int_ScanCompleteReceived(frame - 4, size + 4); + break; + +#ifdef WILC_FULLY_HOSTING_AP + case 'T': + PRINT_INFO(RX_DBG, "TBTT Notification Received \n"); + process_tbtt_isr(); + break; + + case 'A': + PRINT_INFO(RX_DBG, "HOSTAPD ACK Notification Received \n"); + WILC_mgm_HOSTAPD_ACK(ptru32Frame, bStatus); + break; +#endif + + default: + PRINT_INFO(RX_DBG, "Receive unknown message type[%d-%d-%d-%d-%d-%d-%d-%d]\n", + frame[0], frame[1], frame[2], frame[3], frame[4], + frame[5], frame[6], frame[7]); + rsp->type = 0; + rsp->seq_no = msg_id; + ret = 0; + break; + } + + return ret; +} + +static int wilc_wlan_cfg_init(wilc_debug_func func) +{ + memset((void *)&g_mac, 0, sizeof(wilc_mac_cfg_t)); + g_mac.dPrint = func; + return 1; +} + +wilc_cfg_func_t mac_cfg = { + wilc_wlan_cfg_set_wid, + wilc_wlan_cfg_get_wid, + wilc_wlan_cfg_get_wid_value, + wilc_wlan_cfg_indicate_rx, + wilc_wlan_cfg_init, +}; diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h new file mode 100644 index 000000000000..8906611b2930 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -0,0 +1,33 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_wlan_cfg.h */ +/* */ +/* */ +/* ///////////////////////////////////////////////////////////////////////// */ + +#ifndef WILC_WLAN_CFG_H +#define WILC_WLAN_CFG_H + +typedef struct { + uint16_t id; + uint16_t val; +} wilc_cfg_byte_t; + +typedef struct { + uint16_t id; + uint16_t val; +} wilc_cfg_hword_t; + +typedef struct { + uint32_t id; + uint32_t val; +} wilc_cfg_word_t; + +typedef struct { + uint32_t id; + uint8_t *str; +} wilc_cfg_str_t; + +#endif diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h new file mode 100644 index 000000000000..dd86ca7dd3f3 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -0,0 +1,991 @@ +/* ////////////////////////////////////////////////////////////////////////// */ +/* */ +/* Copyright (c) Atmel Corporation. All rights reserved. */ +/* */ +/* Module Name: wilc_wlan_if.h */ +/* */ +/* */ +/* ///////////////////////////////////////////////////////////////////////// */ + + +#ifndef WILC_WLAN_IF_H +#define WILC_WLAN_IF_H + +/*bug 3887: [AP] Allow Management frames to be passed to the host*/ +#define WILC_AP_EXTERNAL_MLME +#define WILC_P2P +#define TCP_ENHANCEMENTS +/* #define MEMORY_STATIC */ +/* #define WILC_FULLY_HOSTING_AP */ +/* #define USE_OLD_SPI_SW */ + + +#include "wilc_type.h" +#include "linux_wlan_common.h" + + +/******************************************** + * + * Debug Flags + * + ********************************************/ + +#define N_INIT 0x00000001 +#define N_ERR 0x00000002 +#define N_TXQ 0x00000004 +#define N_INTR 0x00000008 +#define N_RXQ 0x00000010 + +/******************************************** + * + * Host Interface Defines + * + ********************************************/ + +#define HIF_SDIO (0) +#define HIF_SPI (1 << 0) +#define HIF_SDIO_GPIO_IRQ (1 << 2) + + +/******************************************** + * + * Tx/Rx Buffer Size Defines + * + ********************************************/ + +#define CE_TX_BUFFER_SIZE (64 * 1024) +#define CE_RX_BUFFER_SIZE (384 * 1024) + +/******************************************** + * + * Wlan Interface Defines + * + ********************************************/ + +typedef struct { + uint32_t read_write: 1; + uint32_t function: 3; + uint32_t raw: 1; + uint32_t address: 17; + uint32_t data: 8; +} sdio_cmd52_t; + +typedef struct { + /* struct { */ + uint32_t read_write: 1; + uint32_t function: 3; + uint32_t block_mode: 1; + uint32_t increment: 1; + uint32_t address: 17; + uint32_t count: 9; + /* } bit; */ + uint8_t *buffer; + uint32_t block_size; +} sdio_cmd53_t; + +typedef struct { + void (*os_sleep)(uint32_t); + void (*os_atomic_sleep)(uint32_t); + void (*os_debug)(uint8_t *); + void *(*os_malloc)(uint32_t); + void *(*os_malloc_atomic)(uint32_t); + void (*os_free)(void *); + void (*os_lock)(void *); + void (*os_unlock)(void *); + int (*os_wait)(void *, WILC_Uint32); + void (*os_signal)(void *); + void (*os_enter_cs)(void *); + void (*os_leave_cs)(void *); + + /*Added by Amr - BugID_4720*/ + void (*os_spin_lock)(void *, unsigned long *); + void (*os_spin_unlock)(void *, unsigned long *); + +} wilc_wlan_os_func_t; + +typedef struct { + int io_type; + int (*io_init)(void *); + void (*io_deinit)(void *); + union { + struct { + int (*sdio_cmd52)(sdio_cmd52_t *); + int (*sdio_cmd53)(sdio_cmd53_t *); + int (*sdio_set_max_speed)(void); + int (*sdio_set_default_speed)(void); + } sdio; + struct { + int (*spi_max_speed)(void); + int (*spi_tx)(uint8_t *, uint32_t); + int (*spi_rx)(uint8_t *, uint32_t); + int (*spi_trx)(uint8_t *, uint8_t *, uint32_t); + } spi; + } u; +} wilc_wlan_io_func_t; + +typedef struct { + void (*rx_indicate)(uint8_t *, uint32_t, uint32_t); + void (*rx_complete)(void); +} wilc_wlan_net_func_t; + +typedef struct { + void (*mac_indicate)(int); +} wilc_wlan_indicate_func_t; +#define WILC_MAC_INDICATE_STATUS 0x1 +#define WILC_MAC_STATUS_INIT -1 +#define WILC_MAC_STATUS_READY 0 +#define WILC_MAC_STATUS_CONNECT 1 + +#define WILC_MAC_INDICATE_SCAN 0x2 + +typedef struct { + void *os_private; + + void *hif_critical_section; + + uint32_t tx_buffer_size; + void *txq_critical_section; + + /*Added by Amr - BugID_4720*/ + void *txq_add_to_head_critical_section; + void *txq_spin_lock; + + void *txq_wait_event; + +#if defined(MEMORY_STATIC) + uint32_t rx_buffer_size; +#endif + void *rxq_critical_section; + void *rxq_wait_event; + + void *cfg_wait_event; +} wilc_wlan_os_context_t; + +typedef struct { + wilc_wlan_os_context_t os_context; + wilc_wlan_os_func_t os_func; + wilc_wlan_io_func_t io_func; + wilc_wlan_net_func_t net_func; + wilc_wlan_indicate_func_t indicate_func; +} wilc_wlan_inp_t; + +#if 0 +typedef struct { + int start; + uint32_t id; + void *buffer; + uint32_t buffer_size; + int commit; +} wilc_wlan_cfg_set_t; + +typedef struct { + int start; + uint32_t id; + int commit; +} wilc_wlan_cfg_get_t; + +typedef struct { + uint32_t id; + void *buffer; + uint32_t buffer_size; +} wilc_wlan_cfg_val_t; +#endif + +struct tx_complete_data { + #ifdef WILC_FULLY_HOSTING_AP + struct tx_complete_data *next; + #endif + int size; + void *buff; + uint8_t *pBssid; + struct sk_buff *skb; +}; + + +typedef void (*wilc_tx_complete_func_t)(void *, int); + +#define WILC_TX_ERR_NO_BUF (-2) + +typedef struct { + int (*wlan_firmware_download)(const uint8_t *, uint32_t); + int (*wlan_start)(void); + int (*wlan_stop)(void); + int (*wlan_add_to_tx_que)(void *, uint8_t *, uint32_t, wilc_tx_complete_func_t); + int (*wlan_handle_tx_que)(uint32_t *); + void (*wlan_handle_rx_que)(void); + void (*wlan_handle_rx_isr)(void); + void (*wlan_cleanup)(void); + int (*wlan_cfg_set)(int, uint32_t, uint8_t *, uint32_t, int, uint32_t); + int (*wlan_cfg_get)(int, uint32_t, int, uint32_t); + int (*wlan_cfg_get_value)(uint32_t, uint8_t *, uint32_t); + /*Bug3959: transmitting mgmt frames received from host*/ + #if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P) + int (*wlan_add_mgmt_to_tx_que)(void *, uint8_t *, uint32_t, wilc_tx_complete_func_t); + + #ifdef WILC_FULLY_HOSTING_AP + int (*wlan_add_data_to_tx_que)(void *, uint8_t *, uint32_t, wilc_tx_complete_func_t); + #endif + + #endif +} wilc_wlan_oup_t; + +/******************************************** + * + * Wlan Configuration ID + * + ********************************************/ + +#define MAX_SSID_LEN 33 +#define MAX_RATES_SUPPORTED 12 + +#define INFINITE_SLEEP_TIME ((WILC_Uint32)0xFFFFFFFF) + +#ifdef WILC_PARSE_SCAN_IN_HOST +typedef enum { + SUPP_RATES_IE = 1, + EXT_SUPP_RATES_IE = 50, + HT_CAPABILITY_IE = 45, + RSN_IE = 48, + WPA_IE = 221, + WMM_IE = 221, + #ifdef WILC_P2P + P2P_IE = 221, + #endif +} BEACON_IE; +#endif +typedef enum { + INFRASTRUCTURE = 0, + INDEPENDENT, + AP, +} BSSTYPE_T; + +typedef enum { + RATE_AUTO = 0, + RATE_1MB = 1, + RATE_2MB = 2, + RATE_5MB = 5, + RATE_6MB = 6, + RATE_9MB = 9, + RATE_11MB = 11, + RATE_12MB = 12, + RATE_18MB = 18, + RATE_24MB = 24, + RATE_26MB = 36, + RATE_48MB = 48, + RATE_54MB = 54 +} TX_RATE_T; + +typedef enum { + B_ONLY_MODE = 0, /* basic rate: 1, 2 Mbps, otherwise: 5, 11 Mbps */ + G_ONLY_MODE, /* basic rate: 6, 12, 24 Mbps, otherwise: 9, 18, 36, 48, 54 Mbps */ + G_MIXED_11B_1_MODE, /* basic rate: 1, 2, 5.5, 11 Mbps, otherwise: all on */ + G_MIXED_11B_2_MODE, /* basic rate: 1, 2, 5, 11, 6, 12, 24 Mbps, otherwise: all on */ +} G_OPERATING_MODE_T; + +typedef enum { + G_SHORT_PREAMBLE = 0, /* Short Preamble */ + G_LONG_PREAMBLE = 1, /* Long Preamble */ + G_AUTO_PREAMBLE = 2, /* Auto Preamble Selection */ +} G_PREAMBLE_T; + +#define MAC_CONNECTED 1 +#define MAC_DISCONNECTED 0 + +/*bug3819: */ +#define SCAN_DONE TRUE +typedef enum { + PASSIVE_SCAN = 0, + ACTIVE_SCAN = 1, +} SCANTYPE_T; + +typedef enum { + NO_POWERSAVE = 0, + MIN_FAST_PS = 1, + MAX_FAST_PS = 2, + MIN_PSPOLL_PS = 3, + MAX_PSPOLL_PS = 4 +} USER_PS_MODE_T; + +typedef enum { + CHIP_WAKEDUP = 0, + CHIP_SLEEPING_AUTO = 1, + CHIP_SLEEPING_MANUAL = 2 +} CHIP_PS_STATE_T; + +typedef enum { + ACQUIRE_ONLY = 0, + ACQUIRE_AND_WAKEUP = 1, +} BUS_ACQUIRE_T; + +typedef enum { + RELEASE_ONLY = 0, + RELEASE_ALLOW_SLEEP = 1, +} BUS_RELEASE_T; + +typedef enum { + NO_SECURITY = 0, + WEP_40 = 0x3, + WEP_104 = 0x7, + WPA_AES = 0x29, + WPA_TKIP = 0x49, + WPA_AES_TKIP = 0x69, /* Aes or Tkip */ + WPA2_AES = 0x31, + WPA2_TKIP = 0x51, + WPA2_AES_TKIP = 0x71, /* Aes or Tkip */ +} SECURITY_T; + +typedef enum { + OPEN_SYSTEM = 1, + SHARED_KEY = 2, + ANY = 3, + IEEE8021 = 5 +} AUTHTYPE_T; + +typedef enum { + SITE_SURVEY_1CH = 0, + SITE_SURVEY_ALL_CH = 1, + SITE_SURVEY_OFF = 2 +} SITE_SURVEY_T; + +typedef enum { + NORMAL_ACK = 0, + NO_ACK, +} ACK_POLICY_T; + +typedef enum { + DONT_RESET = 0, + DO_RESET = 1, + NO_REQUEST = 2, +} RESET_REQ_T; + +typedef enum { + REKEY_DISABLE = 1, + REKEY_TIME_BASE, + REKEY_PKT_BASE, + REKEY_TIME_PKT_BASE +} RSNA_REKEY_POLICY_T; + +typedef enum { + FILTER_NO = 0x00, + FILTER_AP_ONLY = 0x01, + FILTER_STA_ONLY = 0x02 +} SCAN_CLASS_FITLER_T; + +typedef enum { + PRI_HIGH_RSSI = 0x00, + PRI_LOW_RSSI = 0x04, + PRI_DETECT = 0x08 +} SCAN_PRI_T; + +typedef enum { + CH_FILTER_OFF = 0x00, + CH_FILTER_ON = 0x10 +} CH_FILTER_T; + +typedef enum { + AUTO_PROT = 0, /* Auto */ + NO_PROT, /* Do not use any protection */ + ERP_PROT, /* Protect all ERP frame exchanges */ + HT_PROT, /* Protect all HT frame exchanges */ + GF_PROT, /* Protect all GF frame exchanges */ +} N_PROTECTION_MODE_T; + +typedef enum { + G_SELF_CTS_PROT, + G_RTS_CTS_PROT, +} G_PROTECTION_MODE_T; + +typedef enum { + HT_MIXED_MODE = 1, + HT_ONLY_20MHZ_MODE, + HT_ONLY_20_40MHZ_MODE, +} N_OPERATING_MODE_T; + +typedef enum { + NO_DETECT = 0, + DETECT_ONLY = 1, + DETECT_PROTECT = 2, + DETECT_PROTECT_REPORT = 3, +} N_OBSS_DETECTION_T; + +typedef enum { + RTS_CTS_NONHT_PROT = 0, /* RTS-CTS at non-HT rate */ + FIRST_FRAME_NONHT_PROT, /* First frame at non-HT rate */ + LSIG_TXOP_PROT, /* LSIG TXOP Protection */ + FIRST_FRAME_MIXED_PROT, /* First frame at Mixed format */ +} N_PROTECTION_TYPE_T; + +typedef enum { + STATIC_MODE = 1, + DYNAMIC_MODE = 2, + MIMO_MODE = 3, /* power save disable */ +} N_SMPS_MODE_T; + +typedef enum { + DISABLE_SELF_CTS, + ENABLE_SELF_CTS, + DISABLE_TX_ABORT, + ENABLE_TX_ABORT, + HW_TRIGGER_ABORT, + SW_TRIGGER_ABORT, +} TX_ABORT_OPTION_T; + +typedef enum { + WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_BIN_DATA = 4, + WID_BIN = 5, + WID_IP = 6, + WID_ADR = 7, + WID_UNDEF = 8, + WID_TYPE_FORCE_32BIT = 0xFFFFFFFF + +} WID_TYPE_T, tenuWIDtype; + +typedef enum { + WID_NIL = 0xffff, + + + /* BSS Type */ + /* -------------------------------------------------------------- */ + /* Configuration : Infrastructure Independent Access Point */ + /* Values to set : 0 1 2 */ + /* -------------------------------------------------------------- */ + WID_BSS_TYPE = 0x0000, + + /* Transmit Rate */ + /* -------------------------------------------------------------- */ + /* Configuration : 1 2 5.5 11 6 9 12 18 24 36 48 54 */ + /* Values to set : 1 2 5 11 6 9 12 18 24 36 48 54 */ + /* -------------------------------------------------------------- */ + WID_CURRENT_TX_RATE = 0x0001, + + /* Channel */ + /* ------------------------------------------------------------------- */ + /* Configuration(g) : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + /* Values to set : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + /* -------------------------------------------------------------------- */ + WID_CURRENT_CHANNEL = 0x0002, + + /* Preamble */ + /* -------------------------------------------------------------- */ + /* Configuration : short long Auto */ + /* Values to set : 0 1 2 */ + /* -------------------------------------------------------------- */ + WID_PREAMBLE = 0x0003, + + /* 11g operating mode (ignored if 11g not present) */ + /* -------------------------------------------------------------- */ + /* Configuration : HighPerf Compat(RSet #1) Compat(RSet #2) */ + /* Values to set : 1 2 3 */ + /* -------------------------------------------------------------- */ + WID_11G_OPERATING_MODE = 0x0004, + + /* Mac status (response only) */ + /* -------------------------------------------------------------- */ + /* Configuration : disconnect connect */ + /* Values to get : 0 1 */ + /* -------------------------------------------------------------- */ + WID_STATUS = 0x0005, + + /* Scan type */ + /* -------------------------------------------------------------- */ + /* Configuration : Passive Scanning Active Scanning */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_SCAN_TYPE = 0x0007, + + /* Key Id (WEP default key Id) */ + /* -------------------------------------------------------------- */ + /* Configuration : Any value between 0 to 3 */ + /* Values to set : Same value. Default is 0 */ + /* -------------------------------------------------------------- */ + WID_KEY_ID = 0x0009, + + /* QoS Enable */ + /* -------------------------------------------------------------- */ + /* Configuration : QoS Disable WMM Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_QOS_ENABLE = 0x000A, + + /* Power Management */ + /* ------------------------------------------------------------------ */ + /* Configuration : NO_POWERSAVE MIN_POWERSAVE MAX_POWERSAVE */ + /* Values to set : 0 1 2 */ + /* ------------------------------------------------------------------ */ + WID_POWER_MANAGEMENT = 0x000B, + + /* WEP/802 11I Configuration */ + /* ------------------------------------------------------------------ */ + /* Configuration : Disable WP40 WP104 WPA-AES WPA-TKIP RSN-AES RSN-TKIP */ + /* Values (0x) : 00 03 07 29 49 31 51 */ + /* */ + /* Configuration : WPA-AES+TKIP RSN-AES+TKIP */ + /* Values (0x) : 69 71 */ + /* ------------------------------------------------------------------ */ + WID_11I_MODE = 0x000C, + + /* WEP Configuration: Used in BSS STA mode only when WEP is enabled */ + /* ------------------------------------------------------------------ */ + /* Configuration : Open System Shared Key Any Type | 802.1x Auth */ + /* Values (0x) : 01 02 03 | BIT2 */ + /* ------------------------------------------------------------------ */ + WID_AUTH_TYPE = 0x000D, + + /* Site Survey Type */ + /* -------------------------------------------------------------- */ + /* Configuration : Values to set */ + /* Survey 1 Channel : 0 */ + /* survey all Channels : 1 */ + /* Disable Site Survey : 2 */ + /* -------------------------------------------------------------- */ + WID_SITE_SURVEY = 0x000E, + + /* Listen Interval */ + /* -------------------------------------------------------------- */ + /* Configuration : Any value between 1 to 255 */ + /* Values to set : Same value. Default is 3 */ + /* -------------------------------------------------------------- */ + WID_LISTEN_INTERVAL = 0x000F, + + /* DTIM Period */ + /* -------------------------------------------------------------- */ + /* Configuration : Any value between 1 to 255 */ + /* Values to set : Same value. Default is 3 */ + /* -------------------------------------------------------------- */ + WID_DTIM_PERIOD = 0x0010, + + /* ACK Policy */ + /* -------------------------------------------------------------- */ + /* Configuration : Normal Ack No Ack */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_ACK_POLICY = 0x0011, + + /* Reset MAC (Set only) */ + /* -------------------------------------------------------------- */ + /* Configuration : Don't Reset Reset No Request */ + /* Values to set : 0 1 2 */ + /* -------------------------------------------------------------- */ + WID_RESET = 0x0012, + + /* Broadcast SSID Option: Setting this will adhere to "" SSID element */ + /* ------------------------------------------------------------------ */ + /* Configuration : Enable Disable */ + /* Values to set : 1 0 */ + /* ------------------------------------------------------------------ */ + WID_BCAST_SSID = 0x0015, + + /* Disconnect (Station) */ + /* ------------------------------------------------------------------ */ + /* Configuration : Association ID */ + /* Values to set : Association ID */ + /* ------------------------------------------------------------------ */ + WID_DISCONNECT = 0x0016, + + /* 11a Tx Power Level */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets TX Power (Higher the value greater the power) */ + /* Values to set : Any value between 0 and 63 (inclusive; Default is 48)*/ + /* -------------------------------------------------------------------- */ + WID_TX_POWER_LEVEL_11A = 0x0018, + + /* Group Key Update Policy Selection */ + /* -------------------------------------------------------------------- */ + /* Configuration : Disabled timeBased packetBased timePacketBased */ + /* Values to set : 1 2 3 4 */ + /* -------------------------------------------------------------------- */ + WID_REKEY_POLICY = 0x0019, + + /* Allow Short Slot */ + /* -------------------------------------------------------------- */ + /* Configuration : Disallow Short Slot Allow Short Slot */ + /* (Enable Only Long Slot) (Enable Short Slot if applicable)*/ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_SHORT_SLOT_ALLOWED = 0x001A, + + WID_PHY_ACTIVE_REG = 0x001B, + + /* 11b Tx Power Level */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets TX Power (Higher the value greater the power) */ + /* Values to set : Any value between 0 and 63 (inclusive; Default is 48)*/ + /* -------------------------------------------------------------------- */ + WID_TX_POWER_LEVEL_11B = 0x001D, + + /* Scan Request */ + /* -------------------------------------------------------------------- */ + /* Configuration : Request default scan */ + /* Values to set : 0 */ + /* -------------------------------------------------------------------- */ + WID_START_SCAN_REQ = 0x001E, + + /* Rssi (get only) */ + /* -------------------------------------------------------------------- */ + /* Configuration : */ + /* Values to get : Rssi value */ + /* -------------------------------------------------------------------- */ + WID_RSSI = 0x001F, + + /* Join Request */ + /* -------------------------------------------------------------------- */ + /* Configuration : Request to join */ + /* Values to set : index of scan result */ + /* -------------------------------------------------------------------- */ + WID_JOIN_REQ = 0x0020, + + WID_LINKSPEED = 0x0026, + + /* Enable User Control of TX Power */ + /* -------------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------------- */ + WID_USER_CONTROL_ON_TX_POWER = 0x0027, + + WID_MEMORY_ACCESS_8BIT = 0x0029, + + /* Enable Auto RX Sensitivity feature */ + /* -------------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------------- */ + WID_AUTO_RX_SENSITIVITY = 0x0032, + + /* Receive Buffer Based Ack */ + /* -------------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------------- */ + WID_DATAFLOW_CONTROL = 0x0033, + + /* Scan Filter */ + /* -------------------------------------------------------------------- */ + /* Configuration : Class No filter AP only Station Only */ + /* Values to set : 0 1 2 */ + /* Configuration : Priority High Rssi Low Rssi Detect */ + /* Values to set : 0 0x4 0x08 */ + /* Configuration : Channel filter off filter on */ + /* Values to set : 0 0x10 */ + /* -------------------------------------------------------------------- */ + WID_SCAN_FILTER = 0x0036, + + /* Link Loss Threshold (measure in the beacon period) */ + /* -------------------------------------------------------------------- */ + /* Configuration : Any value between 10 and 254 (Set to 255 to disable it) */ + /* Values to set : Same value. Default is 10 */ + /* -------------------------------------------------------------------- */ + WID_LINK_LOSS_THRESHOLD = 0x0037, + + /*BugID_4978*/ + WID_ABORT_RUNNING_SCAN = 0x003E, + + /* NMAC Character WID list */ + WID_WPS_START = 0x0043, + + /* Protection mode for MAC */ + /* -------------------------------------------------------------- */ + /* Configuration : Auto No protection ERP HT GF */ + /* Values to set : 0 1 2 3 4 */ + /* -------------------------------------------------------------- */ + WID_11N_PROT_MECH = 0x0080, + + /* ERP Protection type for MAC */ + /* -------------------------------------------------------------- */ + /* Configuration : Self-CTS RTS-CTS */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_11N_ERP_PROT_TYPE = 0x0081, + + /* HT Option Enable */ + /* -------------------------------------------------------------- */ + /* Configuration : HT Enable HT Disable */ + /* Values to set : 1 0 */ + /* -------------------------------------------------------------- */ + WID_11N_ENABLE = 0x0082, + + /* 11n Operating mode (Note that 11g operating mode will also be */ + /* used in addition to this, if this is set to HT Mixed mode) */ + /* -------------------------------------------------------------- */ + /* Configuration : HT Mixed HT Only-20MHz HT Only-20/40MHz */ + /* Values to set : 1 2 3 */ + /* -------------------------------------------------------------- */ + WID_11N_OPERATING_MODE = 0x0083, + + /* 11n OBSS non-HT STA Detection flag */ + /* -------------------------------------------------------------- */ + /* Configuration : Do not detect */ + /* Values to set : 0 */ + /* Configuration : Detect, do not protect or report */ + /* Values to set : 1 */ + /* Configuration : Detect, protect and do not report */ + /* Values to set : 2 */ + /* Configuration : Detect, protect and report to other BSS */ + /* Values to set : 3 */ + /* -------------------------------------------------------------- */ + WID_11N_OBSS_NONHT_DETECTION = 0x0084, + + /* 11n HT Protection Type */ + /* -------------------------------------------------------------- */ + /* Configuration : RTS-CTS First Frame Exchange at non-HT-rate */ + /* Values to set : 0 1 */ + /* Configuration : LSIG TXOP First Frame Exchange in Mixed Fmt */ + /* Values to set : 2 3 */ + /* -------------------------------------------------------------- */ + WID_11N_HT_PROT_TYPE = 0x0085, + + /* 11n RIFS Protection Enable Flag */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_11N_RIFS_PROT_ENABLE = 0x0086, + + /* SMPS Mode */ + /* -------------------------------------------------------------- */ + /* Configuration : Static Dynamic MIMO (Power Save Disabled) */ + /* Values to set : 1 2 3 */ + /* -------------------------------------------------------------- */ + WID_11N_SMPS_MODE = 0x0087, + + /* Current transmit MCS */ + /* -------------------------------------------------------------- */ + /* Configuration : MCS Index for data rate */ + /* Values to set : 0 to 7 */ + /* -------------------------------------------------------------- */ + WID_11N_CURRENT_TX_MCS = 0x0088, + + WID_11N_PRINT_STATS = 0x0089, + + /* 11n Short GI Enable Flag */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_11N_SHORT_GI_ENABLE = 0x008D, + + /* 11n RIFS Enable Flag */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_RIFS_MODE = 0x0094, + + /* TX Abort Feature */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Self CTS Enable Self CTS */ + /* Values to set : 0 1 */ + /* Configuration : Disable TX Abort Enable TX Abort */ + /* Values to set : 2 3 */ + /* Configuration : Enable HW TX Abort Enable SW TX Abort */ + /* Values to set : 4 5 */ + /* -------------------------------------------------------------- */ + WID_TX_ABORT_CONFIG = 0x00A1, + + WID_REG_TSSI_11B_VALUE = 0x00A6, + WID_REG_TSSI_11G_VALUE = 0x00A7, + WID_REG_TSSI_11N_VALUE = 0x00A8, + WID_TX_CALIBRATION = 0x00A9, + WID_DSCR_TSSI_11B_VALUE = 0x00AA, + WID_DSCR_TSSI_11G_VALUE = 0x00AB, + WID_DSCR_TSSI_11N_VALUE = 0x00AC, + + /* Immediate Block-Ack Support */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 0 1 */ + /* -------------------------------------------------------------- */ + WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF, + + /* TXOP Disable Flag */ + /* -------------------------------------------------------------- */ + /* Configuration : Disable Enable */ + /* Values to set : 1 0 */ + /* -------------------------------------------------------------- */ + WID_11N_TXOP_PROT_DISABLE = 0x00B0, + + + WID_TX_POWER_LEVEL_11N = 0x00B1, + + /* Custom Character WID list */ + WID_PC_TEST_MODE = 0x00C8, + /*bug3819: */ + /* SCAN Complete notification WID*/ + WID_SCAN_COMPLETE = 0x00C9, + +#ifdef WILC_AP_EXTERNAL_MLME + WID_DEL_BEACON = 0x00CA, +#endif + + WID_LOGTerminal_Switch = 0x00CD, + /* EMAC Short WID list */ + /* RTS Threshold */ + /* -------------------------------------------------------------- */ + /* Configuration : Any value between 256 to 2347 */ + /* Values to set : Same value. Default is 2347 */ + /* -------------------------------------------------------------- */ + WID_RTS_THRESHOLD = 0x1000, + + /* Fragmentation Threshold */ + /* -------------------------------------------------------------- */ + /* Configuration : Any value between 256 to 2346 */ + /* Values to set : Same value. Default is 2346 */ + /* -------------------------------------------------------------- */ + WID_FRAG_THRESHOLD = 0x1001, + + WID_SHORT_RETRY_LIMIT = 0x1002, + WID_LONG_RETRY_LIMIT = 0x1003, + WID_BEACON_INTERVAL = 0x1006, + WID_MEMORY_ACCESS_16BIT = 0x1008, + WID_RX_SENSE = 0x100B, + WID_ACTIVE_SCAN_TIME = 0x100C, + WID_PASSIVE_SCAN_TIME = 0x100D, + + WID_SITE_SURVEY_SCAN_TIME = 0x100E, + WID_JOIN_START_TIMEOUT = 0x100F, + WID_AUTH_TIMEOUT = 0x1010, + WID_ASOC_TIMEOUT = 0x1011, + WID_11I_PROTOCOL_TIMEOUT = 0x1012, + WID_EAPOL_RESPONSE_TIMEOUT = 0x1013, + + /* NMAC Short WID list */ + WID_11N_SIG_QUAL_VAL = 0x1085, + WID_CCA_THRESHOLD = 0x1087, + + /* Custom Short WID list */ + + /* EMAC Integer WID list */ + WID_FAILED_COUNT = 0x2000, + WID_RETRY_COUNT = 0x2001, + WID_MULTIPLE_RETRY_COUNT = 0x2002, + WID_FRAME_DUPLICATE_COUNT = 0x2003, + WID_ACK_FAILURE_COUNT = 0x2004, + WID_RECEIVED_FRAGMENT_COUNT = 0x2005, + WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006, + WID_FCS_ERROR_COUNT = 0x2007, + WID_SUCCESS_FRAME_COUNT = 0x2008, + WID_HUT_TX_COUNT = 0x200A, + WID_TX_FRAGMENT_COUNT = 0x200B, + WID_TX_MULTICAST_FRAME_COUNT = 0x200C, + WID_RTS_SUCCESS_COUNT = 0x200D, + WID_RTS_FAILURE_COUNT = 0x200E, + WID_WEP_UNDECRYPTABLE_COUNT = 0x200F, + WID_REKEY_PERIOD = 0x2010, + WID_REKEY_PACKET_COUNT = 0x2011, + WID_1X_SERV_ADDR = 0x2012, + WID_STACK_IP_ADDR = 0x2013, + WID_STACK_NETMASK_ADDR = 0x2014, + WID_HW_RX_COUNT = 0x2015, + WID_MEMORY_ADDRESS = 0x201E, + WID_MEMORY_ACCESS_32BIT = 0x201F, + WID_RF_REG_VAL = 0x2021, + + + /* NMAC Integer WID list */ + WID_11N_PHY_ACTIVE_REG_VAL = 0x2080, + + /* Custom Integer WID list */ + WID_GET_INACTIVE_TIME = 0x2084, + WID_SET_DRV_HANDLER = 0X2085, + WID_SET_OPERATION_MODE = 0X2086, + /* EMAC String WID list */ + WID_SSID = 0x3000, + WID_FIRMWARE_VERSION = 0x3001, + WID_OPERATIONAL_RATE_SET = 0x3002, + WID_BSSID = 0x3003, + WID_WEP_KEY_VALUE = 0x3004, + WID_11I_PSK = 0x3008, + WID_11E_P_ACTION_REQ = 0x3009, + WID_1X_KEY = 0x300A, + WID_HARDWARE_VERSION = 0x300B, + WID_MAC_ADDR = 0x300C, + WID_HUT_DEST_ADDR = 0x300D, + WID_PHY_VERSION = 0x300F, + WID_SUPP_USERNAME = 0x3010, + WID_SUPP_PASSWORD = 0x3011, + WID_SITE_SURVEY_RESULTS = 0x3012, + WID_RX_POWER_LEVEL = 0x3013, + WID_DEL_ALL_RX_BA = 0x3014, + WID_SET_STA_MAC_INACTIVE_TIME = 0x3017, + WID_ADD_WEP_KEY = 0x3019, + WID_REMOVE_WEP_KEY = 0x301A, + WID_ADD_PTK = 0x301B, + WID_ADD_RX_GTK = 0x301C, + WID_ADD_TX_GTK = 0x301D, + WID_REMOVE_KEY = 0x301E, + WID_ASSOC_REQ_INFO = 0x301F, + WID_ASSOC_RES_INFO = 0x3020, + WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */ + WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */ + WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */ + WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */ + + /* NMAC String WID list */ + WID_11N_P_ACTION_REQ = 0x3080, + WID_HUT_TEST_ID = 0x3081, + WID_PMKID_INFO = 0x3082, + WID_FIRMWARE_INFO = 0x3083, + #ifdef WILC_P2P + WID_REGISTER_FRAME = 0x3084, + #endif + WID_DEL_ALL_STA = 0x3085, + #ifdef WILC_P2P + WID_REMAIN_ON_CHAN = 0x3996, + #endif + /*BugID_4156*/ + WID_SSID_PROBE_REQ = 0x3997, + /*BugID_4124 WID to trigger modified Join Request using SSID and BSSID instead of bssListIdx (used by WID_JOIN_REQ)*/ + WID_JOIN_REQ_EXTENDED = 0x3998, + + /* BugID 4951: WID toset IP address in firmware */ + WID_IP_ADDRESS = 0x3999, + + + + /* Custom String WID list */ + + /* EMAC Binary WID list */ + WID_UAPSD_CONFIG = 0x4001, + WID_UAPSD_STATUS = 0x4002, + WID_WMM_AP_AC_PARAMS = 0x4003, + WID_WMM_STA_AC_PARAMS = 0x4004, + WID_NETWORK_INFO = 0x4005, + WID_STA_JOIN_INFO = 0x4006, + WID_CONNECTED_STA_LIST = 0x4007, + + /* NMAC Binary WID list */ + WID_11N_AUTORATE_TABLE = 0x4080, + + + /*Added here by Amr - BugID 4134*/ + WID_SCAN_CHANNEL_LIST = 0x4084, + + /*BugID_3746 WID to add IE to be added in next probe request*/ + WID_INFO_ELEMENT_PROBE = 0x4085, + /*BugID_3746 WID to add IE to be added in next associate request*/ + WID_INFO_ELEMENT_ASSOCIATE = 0x4086, + WID_ADD_STA = 0X4087, + WID_REMOVE_STA = 0X4088, + WID_EDIT_STA = 0X4089, + WID_ADD_BEACON = 0x408a, + + /* BugID 5108 */ + WID_SETUP_MULTICAST_FILTER = 0x408b, + + /* Miscellaneous WIDs */ + WID_ALL = 0x7FFE, + WID_MAX = 0xFFFF +} WID_T; + +int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup); + +void wilc_bus_set_max_speed(void); +void wilc_bus_set_default_speed(void); +uint32_t wilc_get_chipid(uint8_t update); + + +#endif diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index bd69e8cf200f..c0e6ac8a28eb 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -207,6 +207,8 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, /* XXXX need to pick keynum other than default? */ p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); + if (!p80211_wep->data) + return -ENOMEM; foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, skb->len, (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK), diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 9408644cc8b8..fe36613589ae 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -708,7 +708,10 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, continue; } - /* Validate plug address against chunk data and identify chunk */ + /* + * Validate plug address against + * chunk data and identify chunk + */ for (c = 0; c < nfchunks; c++) { cstart = fchunk[c].addr; cend = fchunk[c].addr + fchunk[c].len; @@ -923,7 +926,8 @@ static int read_fwfile(const struct ihex_binrec *record) rcnt, s3info[ns3info].len, s3info[ns3info].type); - if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) { + if (((s3info[ns3info].len - 1) * sizeof(u16)) > + sizeof(s3info[ns3info].info)) { pr_err("S3 inforec length too long - aborting\n"); return 1; } diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index ddb294e7044f..0329c521d17c 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -428,7 +428,8 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) result = hfa384x_drvr_start(hw); if (result) { netdev_err(wlandev->netdev, - "hfa384x_drvr_start() failed,result=%d\n", (int)result); + "hfa384x_drvr_start() failed,result=%d\n", + (int)result); result = P80211ENUM_resultcode_implementation_failure; wlandev->msdstate = WLAN_MSD_HWPRESENT; @@ -471,7 +472,8 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) result = hfa384x_drvr_start(hw); if (result) { netdev_err(wlandev->netdev, - "hfa384x_drvr_start() failed,result=%d\n", (int)result); + "hfa384x_drvr_start() failed,result=%d\n", + (int)result); result = P80211ENUM_resultcode_implementation_failure; wlandev->msdstate = WLAN_MSD_HWPRESENT; @@ -481,7 +483,8 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) result = prism2sta_getcardinfo(wlandev); if (result) { netdev_err(wlandev->netdev, - "prism2sta_getcardinfo() failed,result=%d\n", (int)result); + "prism2sta_getcardinfo() failed,result=%d\n", + (int)result); result = P80211ENUM_resultcode_implementation_failure; hfa384x_drvr_stop(hw); @@ -491,7 +494,8 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) result = prism2sta_globalsetup(wlandev); if (result) { netdev_err(wlandev->netdev, - "prism2sta_globalsetup() failed,result=%d\n", (int)result); + "prism2sta_globalsetup() failed,result=%d\n", + (int)result); result = P80211ENUM_resultcode_implementation_failure; hfa384x_drvr_stop(hw); @@ -1244,9 +1248,9 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); return; } - prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, - (p80211pstrd_t *) & - wlandev->ssid); + prism2mgmt_bytestr2pstr( + (struct hfa384x_bytestr *) &ssid, + (p80211pstrd_t *) &wlandev->ssid); /* Collect the port status */ result = hfa384x_drvr_getconfig16(hw, @@ -1658,8 +1662,9 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, if (hw->authlist.cnt >= WLAN_AUTH_MAX) { rec.status = P80211ENUM_status_ap_full; } else { - ether_addr_copy(hw->authlist.addr[hw->authlist.cnt], - rec.address); + ether_addr_copy( + hw->authlist.addr[hw->authlist.cnt], + rec.address); hw->authlist.cnt++; added = 1; } diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 74e88200726c..943d463cf193 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -8,10 +8,7 @@ #include <linux/sizes.h> #include <linux/module.h> - -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif +#include <linux/pci.h> #include "XGI_main.h" #include "vb_init.h" @@ -1770,7 +1767,7 @@ static int xgifb_probe(struct pci_dev *pdev, } xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress = - ioremap(xgifb_info->video_base, xgifb_info->video_size); + ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); @@ -2014,12 +2011,8 @@ static int xgifb_probe(struct pci_dev *pdev, fb_alloc_cmap(&fb_info->cmap, 256, 0); -#ifdef CONFIG_MTRR - xgifb_info->mtrr = mtrr_add(xgifb_info->video_base, - xgifb_info->video_size, MTRR_TYPE_WRCOMB, 1); - if (xgifb_info->mtrr >= 0) - dev_info(&pdev->dev, "Added MTRR\n"); -#endif + xgifb_info->mtrr = arch_phys_wc_add(xgifb_info->video_base, + xgifb_info->video_size); if (register_framebuffer(fb_info) < 0) { ret = -EINVAL; @@ -2031,11 +2024,7 @@ static int xgifb_probe(struct pci_dev *pdev, return 0; error_mtrr: -#ifdef CONFIG_MTRR - if (xgifb_info->mtrr >= 0) - mtrr_del(xgifb_info->mtrr, xgifb_info->video_base, - xgifb_info->video_size); -#endif /* CONFIG_MTRR */ + arch_phys_wc_del(xgifb_info->mtrr); error_1: iounmap(xgifb_info->mmio_vbase); iounmap(xgifb_info->video_vbase); @@ -2059,11 +2048,7 @@ static void xgifb_remove(struct pci_dev *pdev) struct fb_info *fb_info = xgifb_info->fb_info; unregister_framebuffer(fb_info); -#ifdef CONFIG_MTRR - if (xgifb_info->mtrr >= 0) - mtrr_del(xgifb_info->mtrr, xgifb_info->video_base, - xgifb_info->video_size); -#endif /* CONFIG_MTRR */ + arch_phys_wc_del(xgifb_info->mtrr); iounmap(xgifb_info->mmio_vbase); iounmap(xgifb_info->video_vbase); release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index a47395e92d20..c886dd2892a4 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -940,7 +940,7 @@ static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension, data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); data &= 0xfe; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ + xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* disable auto-threshold */ xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); data = xgifb_reg_get(pVBInfo->P3c4, 0x09); @@ -1081,24 +1081,17 @@ static void XGI_WriteDAC(unsigned short dl, unsigned short dh, struct vb_device_info *pVBInfo) { - unsigned short temp, bh, bl; + unsigned short bh, bl; bh = ah; bl = al; if (dl != 0) { - temp = bh; - bh = dh; - dh = temp; - if (dl == 1) { - temp = bl; - bl = dh; - dh = temp; - } else { - temp = bl; - bl = bh; - bh = temp; - } + swap(bh, dh); + if (dl == 1) + swap(bl, dh); + else + swap(bl, bh); } outb((unsigned short) dh, pVBInfo->P3c9); outb((unsigned short) bh, pVBInfo->P3c9); diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 34871a628b11..74e6114ff18f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -230,7 +230,7 @@ int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) * Here we serialize access across the TIQN+TPG Tuple. */ ret = down_interruptible(&tpg->np_login_sem); - if ((ret != 0) || signal_pending(current)) + if (ret != 0) return -1; spin_lock_bh(&tpg->tpg_state_lock); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 8ce94ff744e6..70d799dfab03 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -346,6 +346,7 @@ static int iscsi_login_zero_tsih_s1( if (IS_ERR(sess->se_sess)) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); + kfree(sess->sess_ops); kfree(sess); return -ENOMEM; } diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index e8a240818353..5e3295fe404d 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -161,10 +161,7 @@ struct iscsi_portal_group *iscsit_get_tpg_from_np( int iscsit_get_tpg( struct iscsi_portal_group *tpg) { - int ret; - - ret = mutex_lock_interruptible(&tpg->tpg_access_lock); - return ((ret != 0) || signal_pending(current)) ? -1 : 0; + return mutex_lock_interruptible(&tpg->tpg_access_lock); } void iscsit_put_tpg(struct iscsi_portal_group *tpg) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 75cbde1f7c5b..4f8d4d459aa4 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -704,7 +704,7 @@ target_alua_state_check(struct se_cmd *cmd) if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) return 0; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; if (!port) @@ -2377,7 +2377,7 @@ ssize_t core_alua_store_secondary_write_metadata( int core_setup_alua(struct se_device *dev) { - if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && + if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { struct t10_alua_lu_gp_member *lu_gp_mem; diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index ddaf76a4ac2a..e7b0430a0575 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -212,10 +212,6 @@ static struct config_group *target_core_register_fabric( pr_debug("Target_Core_ConfigFS: REGISTER -> Allocated Fabric:" " %s\n", tf->tf_group.cg_item.ci_name); - /* - * Setup tf_ops.tf_subsys pointer for usage with configfs_depend_item() - */ - tf->tf_ops.tf_subsys = tf->tf_subsys; tf->tf_fabric = &tf->tf_group.cg_item; pr_debug("Target_Core_ConfigFS: REGISTER -> Set tf->tf_fabric" " for %s\n", name); @@ -291,10 +287,17 @@ static struct configfs_subsystem target_core_fabrics = { }, }; -struct configfs_subsystem *target_core_subsystem[] = { - &target_core_fabrics, - NULL, -}; +int target_depend_item(struct config_item *item) +{ + return configfs_depend_item(&target_core_fabrics, item); +} +EXPORT_SYMBOL(target_depend_item); + +void target_undepend_item(struct config_item *item) +{ + return configfs_undepend_item(&target_core_fabrics, item); +} +EXPORT_SYMBOL(target_undepend_item); /*############################################################################## // Start functions called by external Target Fabrics Modules @@ -467,7 +470,6 @@ int target_register_template(const struct target_core_fabric_ops *fo) * struct target_fabric_configfs->tf_cit_tmpl */ tf->tf_module = fo->module; - tf->tf_subsys = target_core_subsystem[0]; snprintf(tf->tf_name, TARGET_FABRIC_NAME_SIZE, "%s", fo->name); tf->tf_ops = *fo; @@ -809,7 +811,7 @@ static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev, { int ret; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return sprintf(page, "Passthrough\n"); spin_lock(&dev->dev_reservation_lock); @@ -960,7 +962,7 @@ SE_DEV_PR_ATTR_RO(res_pr_type); static ssize_t target_core_dev_pr_show_attr_res_type( struct se_device *dev, char *page) { - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return sprintf(page, "SPC_PASSTHROUGH\n"); else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) return sprintf(page, "SPC2_RESERVATIONS\n"); @@ -973,7 +975,7 @@ SE_DEV_PR_ATTR_RO(res_type); static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( struct se_device *dev, char *page) { - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; return sprintf(page, "APTPL Bit Status: %s\n", @@ -988,7 +990,7 @@ SE_DEV_PR_ATTR_RO(res_aptpl_active); static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( struct se_device *dev, char *page) { - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; return sprintf(page, "Ready to process PR APTPL metadata..\n"); @@ -1035,7 +1037,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( u16 port_rpti = 0, tpgt = 0; u8 type = 0, scope; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) return 0; @@ -2870,7 +2872,7 @@ static int __init target_core_init_configfs(void) { struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; struct config_group *lu_gp_cg = NULL; - struct configfs_subsystem *subsys; + struct configfs_subsystem *subsys = &target_core_fabrics; struct t10_alua_lu_gp *lu_gp; int ret; @@ -2878,7 +2880,6 @@ static int __init target_core_init_configfs(void) " Engine: %s on %s/%s on "UTS_RELEASE"\n", TARGET_CORE_VERSION, utsname()->sysname, utsname()->machine); - subsys = target_core_subsystem[0]; config_group_init(&subsys->su_group); mutex_init(&subsys->su_mutex); @@ -3008,13 +3009,10 @@ out_global: static void __exit target_core_exit_configfs(void) { - struct configfs_subsystem *subsys; struct config_group *hba_cg, *alua_cg, *lu_gp_cg; struct config_item *item; int i; - subsys = target_core_subsystem[0]; - lu_gp_cg = &alua_lu_gps_group; for (i = 0; lu_gp_cg->default_groups[i]; i++) { item = &lu_gp_cg->default_groups[i]->cg_item; @@ -3045,8 +3043,8 @@ static void __exit target_core_exit_configfs(void) * We expect subsys->su_group.default_groups to be released * by configfs subsystem provider logic.. */ - configfs_unregister_subsystem(subsys); - kfree(subsys->su_group.default_groups); + configfs_unregister_subsystem(&target_core_fabrics); + kfree(target_core_fabrics.su_group.default_groups); core_alua_free_lu_gp(default_lu_gp); default_lu_gp = NULL; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7faa6aef9a4d..ce5f768181ff 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -33,6 +33,7 @@ #include <linux/kthread.h> #include <linux/in.h> #include <linux/export.h> +#include <asm/unaligned.h> #include <net/sock.h> #include <net/tcp.h> #include <scsi/scsi.h> @@ -527,7 +528,7 @@ static void core_export_port( list_add_tail(&port->sep_list, &dev->dev_sep_list); spin_unlock(&dev->se_port_lock); - if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && + if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { @@ -1603,7 +1604,7 @@ int target_configure_device(struct se_device *dev) * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI * passthrough because this is being provided by the backend LLD. */ - if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { + if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)) { strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); strncpy(&dev->t10_wwn.model[0], dev->transport->inquiry_prod, 16); @@ -1707,3 +1708,76 @@ void core_dev_release_virtual_lun0(void) target_free_device(g_lun0_dev); core_delete_hba(hba); } + +/* + * Common CDB parsing for kernel and user passthrough. + */ +sense_reason_t +passthrough_parse_cdb(struct se_cmd *cmd, + sense_reason_t (*exec_cmd)(struct se_cmd *cmd)) +{ + unsigned char *cdb = cmd->t_task_cdb; + + /* + * Clear a lun set in the cdb if the initiator talking to use spoke + * and old standards version, as we can't assume the underlying device + * won't choke up on it. + */ + switch (cdb[0]) { + case READ_10: /* SBC - RDProtect */ + case READ_12: /* SBC - RDProtect */ + case READ_16: /* SBC - RDProtect */ + case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ + case VERIFY: /* SBC - VRProtect */ + case VERIFY_16: /* SBC - VRProtect */ + case WRITE_VERIFY: /* SBC - VRProtect */ + case WRITE_VERIFY_12: /* SBC - VRProtect */ + case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ + break; + default: + cdb[1] &= 0x1f; /* clear logical unit number */ + break; + } + + /* + * For REPORT LUNS we always need to emulate the response, for everything + * else, pass it up. + */ + if (cdb[0] == REPORT_LUNS) { + cmd->execute_cmd = spc_emulate_report_luns; + return TCM_NO_SENSE; + } + + /* Set DATA_CDB flag for ops that should have it */ + switch (cdb[0]) { + case READ_6: + case READ_10: + case READ_12: + case READ_16: + case WRITE_6: + case WRITE_10: + case WRITE_12: + case WRITE_16: + case WRITE_VERIFY: + case WRITE_VERIFY_12: + case 0x8e: /* WRITE_VERIFY_16 */ + case COMPARE_AND_WRITE: + case XDWRITEREAD_10: + cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; + break; + case VARIABLE_LENGTH_CMD: + switch (get_unaligned_be16(&cdb[8])) { + case READ_32: + case WRITE_32: + case 0x0c: /* WRITE_VERIFY_32 */ + case XDWRITEREAD_32: + cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; + break; + } + } + + cmd->execute_cmd = exec_cmd; + + return TCM_NO_SENSE; +} +EXPORT_SYMBOL(passthrough_parse_cdb); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index f7e6e51aed36..3f27bfd816d8 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -958,7 +958,6 @@ static struct se_subsystem_api fileio_template = { .inquiry_prod = "FILEIO", .inquiry_rev = FD_VERSION, .owner = THIS_MODULE, - .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, .attach_hba = fd_attach_hba, .detach_hba = fd_detach_hba, .alloc_device = fd_alloc_device, diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 1b7947c2510f..8c965683789f 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -904,7 +904,6 @@ static struct se_subsystem_api iblock_template = { .inquiry_prod = "IBLOCK", .inquiry_rev = IBLOCK_VERSION, .owner = THIS_MODULE, - .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, .attach_hba = iblock_attach_hba, .detach_hba = iblock_detach_hba, .alloc_device = iblock_alloc_device, diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 874a9bc988d8..68bd7f5d9f73 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -4,9 +4,6 @@ /* target_core_alua.c */ extern struct t10_alua_lu_gp *default_lu_gp; -/* target_core_configfs.c */ -extern struct configfs_subsystem *target_core_subsystem[]; - /* target_core_device.c */ extern struct mutex g_device_mutex; extern struct list_head g_device_list; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index c1aa9655e96e..a15411c79ae9 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1367,41 +1367,26 @@ void core_scsi3_free_all_registrations( static int core_scsi3_tpg_depend_item(struct se_portal_group *tpg) { - return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys, - &tpg->tpg_group.cg_item); + return target_depend_item(&tpg->tpg_group.cg_item); } static void core_scsi3_tpg_undepend_item(struct se_portal_group *tpg) { - configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys, - &tpg->tpg_group.cg_item); - + target_undepend_item(&tpg->tpg_group.cg_item); atomic_dec_mb(&tpg->tpg_pr_ref_count); } static int core_scsi3_nodeacl_depend_item(struct se_node_acl *nacl) { - struct se_portal_group *tpg = nacl->se_tpg; - if (nacl->dynamic_node_acl) return 0; - - return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys, - &nacl->acl_group.cg_item); + return target_depend_item(&nacl->acl_group.cg_item); } static void core_scsi3_nodeacl_undepend_item(struct se_node_acl *nacl) { - struct se_portal_group *tpg = nacl->se_tpg; - - if (nacl->dynamic_node_acl) { - atomic_dec_mb(&nacl->acl_pr_ref_count); - return; - } - - configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys, - &nacl->acl_group.cg_item); - + if (!nacl->dynamic_node_acl) + target_undepend_item(&nacl->acl_group.cg_item); atomic_dec_mb(&nacl->acl_pr_ref_count); } @@ -1419,8 +1404,7 @@ static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve) nacl = lun_acl->se_lun_nacl; tpg = nacl->se_tpg; - return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys, - &lun_acl->se_lun_group.cg_item); + return target_depend_item(&lun_acl->se_lun_group.cg_item); } static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) @@ -1438,9 +1422,7 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) nacl = lun_acl->se_lun_nacl; tpg = nacl->se_tpg; - configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys, - &lun_acl->se_lun_group.cg_item); - + target_undepend_item(&lun_acl->se_lun_group.cg_item); atomic_dec_mb(&se_deve->pr_ref_count); } @@ -4111,7 +4093,7 @@ target_check_reservation(struct se_cmd *cmd) return 0; if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) return 0; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; spin_lock(&dev->dev_reservation_lock); diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index f6c954c4635f..ecc5eaef13d6 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -521,6 +521,7 @@ static int pscsi_configure_device(struct se_device *dev) " pdv_host_id: %d\n", pdv->pdv_host_id); return -EINVAL; } + pdv->pdv_lld_host = sh; } } else { if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) { @@ -603,6 +604,8 @@ static void pscsi_free_device(struct se_device *dev) if ((phv->phv_mode == PHV_LLD_SCSI_HOST_NO) && (phv->phv_lld_host != NULL)) scsi_host_put(phv->phv_lld_host); + else if (pdv->pdv_lld_host) + scsi_host_put(pdv->pdv_lld_host); if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) scsi_device_put(sd); @@ -970,64 +973,13 @@ fail: return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } -/* - * Clear a lun set in the cdb if the initiator talking to use spoke - * and old standards version, as we can't assume the underlying device - * won't choke up on it. - */ -static inline void pscsi_clear_cdb_lun(unsigned char *cdb) -{ - switch (cdb[0]) { - case READ_10: /* SBC - RDProtect */ - case READ_12: /* SBC - RDProtect */ - case READ_16: /* SBC - RDProtect */ - case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ - case VERIFY: /* SBC - VRProtect */ - case VERIFY_16: /* SBC - VRProtect */ - case WRITE_VERIFY: /* SBC - VRProtect */ - case WRITE_VERIFY_12: /* SBC - VRProtect */ - case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ - break; - default: - cdb[1] &= 0x1f; /* clear logical unit number */ - break; - } -} - static sense_reason_t pscsi_parse_cdb(struct se_cmd *cmd) { - unsigned char *cdb = cmd->t_task_cdb; - if (cmd->se_cmd_flags & SCF_BIDI) return TCM_UNSUPPORTED_SCSI_OPCODE; - pscsi_clear_cdb_lun(cdb); - - /* - * For REPORT LUNS we always need to emulate the response, for everything - * else the default for pSCSI is to pass the command to the underlying - * LLD / physical hardware. - */ - switch (cdb[0]) { - case REPORT_LUNS: - cmd->execute_cmd = spc_emulate_report_luns; - return 0; - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - case WRITE_VERIFY: - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - /* FALLTHROUGH*/ - default: - cmd->execute_cmd = pscsi_execute_cmd; - return 0; - } + return passthrough_parse_cdb(cmd, pscsi_execute_cmd); } static sense_reason_t @@ -1189,7 +1141,7 @@ static struct configfs_attribute *pscsi_backend_dev_attrs[] = { static struct se_subsystem_api pscsi_template = { .name = "pscsi", .owner = THIS_MODULE, - .transport_type = TRANSPORT_PLUGIN_PHBA_PDEV, + .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, .attach_hba = pscsi_attach_hba, .detach_hba = pscsi_detach_hba, .pmode_enable_hba = pscsi_pmode_enable_hba, diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h index 1bd757dff8ee..820d3052b775 100644 --- a/drivers/target/target_core_pscsi.h +++ b/drivers/target/target_core_pscsi.h @@ -45,6 +45,7 @@ struct pscsi_dev_virt { int pdv_lun_id; struct block_device *pdv_bd; struct scsi_device *pdv_sd; + struct Scsi_Host *pdv_lld_host; } ____cacheline_aligned; typedef enum phv_modes { diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index a263bf5fab8d..d16489b6a1a4 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -733,7 +733,6 @@ static struct se_subsystem_api rd_mcp_template = { .name = "rd_mcp", .inquiry_prod = "RAMDISK-MCP", .inquiry_rev = RD_MCP_VERSION, - .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, .attach_hba = rd_attach_hba, .detach_hba = rd_detach_hba, .alloc_device = rd_alloc_device, diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 8855781ac653..733824e3825f 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -568,7 +568,7 @@ sbc_compare_and_write(struct se_cmd *cmd) * comparision using SGLs at cmd->t_bidi_data_sg.. */ rc = down_interruptible(&dev->caw_sem); - if ((rc != 0) || signal_pending(current)) { + if (rc != 0) { cmd->transport_complete_callback = NULL; return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3fe5cb240b6f..675f2d9d1f14 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1196,7 +1196,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd) * Check if SAM Task Attribute emulation is enabled for this * struct se_device storage object */ - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return 0; if (cmd->sam_task_attr == TCM_ACA_TAG) { @@ -1770,7 +1770,7 @@ static int target_write_prot_action(struct se_cmd *cmd) sectors, 0, NULL, 0); if (unlikely(cmd->pi_err)) { spin_lock_irq(&cmd->t_state_lock); - cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT; + cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); spin_unlock_irq(&cmd->t_state_lock); transport_generic_request_failure(cmd, cmd->pi_err); return -1; @@ -1787,7 +1787,7 @@ static bool target_handle_task_attr(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return false; /* @@ -1868,7 +1868,7 @@ void target_execute_cmd(struct se_cmd *cmd) if (target_handle_task_attr(cmd)) { spin_lock_irq(&cmd->t_state_lock); - cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT; + cmd->transport_state &= ~(CMD_T_BUSY | CMD_T_SENT); spin_unlock_irq(&cmd->t_state_lock); return; } @@ -1912,7 +1912,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) return; if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { @@ -1957,8 +1957,7 @@ static void transport_complete_qf(struct se_cmd *cmd) case DMA_TO_DEVICE: if (cmd->se_cmd_flags & SCF_BIDI) { ret = cmd->se_tfo->queue_data_in(cmd); - if (ret < 0) - break; + break; } /* Fall through for DMA_TO_DEVICE */ case DMA_NONE: diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index dbc872a6c981..07d2996d8c1f 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -71,13 +71,6 @@ struct tcmu_hba { u32 host_id; }; -/* User wants all cmds or just some */ -enum passthru_level { - TCMU_PASS_ALL = 0, - TCMU_PASS_IO, - TCMU_PASS_INVALID, -}; - #define TCMU_CONFIG_LEN 256 struct tcmu_dev { @@ -89,7 +82,6 @@ struct tcmu_dev { #define TCMU_DEV_BIT_OPEN 0 #define TCMU_DEV_BIT_BROKEN 1 unsigned long flags; - enum passthru_level pass_level; struct uio_info uio_info; @@ -683,8 +675,6 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) setup_timer(&udev->timeout, tcmu_device_timedout, (unsigned long)udev); - udev->pass_level = TCMU_PASS_ALL; - return &udev->se_dev; } @@ -948,13 +938,13 @@ static void tcmu_free_device(struct se_device *dev) } enum { - Opt_dev_config, Opt_dev_size, Opt_err, Opt_pass_level, + Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_err, }; static match_table_t tokens = { {Opt_dev_config, "dev_config=%s"}, {Opt_dev_size, "dev_size=%u"}, - {Opt_pass_level, "pass_level=%u"}, + {Opt_hw_block_size, "hw_block_size=%u"}, {Opt_err, NULL} }; @@ -965,7 +955,7 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, char *orig, *ptr, *opts, *arg_p; substring_t args[MAX_OPT_ARGS]; int ret = 0, token; - int arg; + unsigned long tmp_ul; opts = kstrdup(page, GFP_KERNEL); if (!opts) @@ -998,15 +988,23 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, if (ret < 0) pr_err("kstrtoul() failed for dev_size=\n"); break; - case Opt_pass_level: - match_int(args, &arg); - if (arg >= TCMU_PASS_INVALID) { - pr_warn("TCMU: Invalid pass_level: %d\n", arg); + case Opt_hw_block_size: + arg_p = match_strdup(&args[0]); + if (!arg_p) { + ret = -ENOMEM; break; } - - pr_debug("TCMU: Setting pass_level to %d\n", arg); - udev->pass_level = arg; + ret = kstrtoul(arg_p, 0, &tmp_ul); + kfree(arg_p); + if (ret < 0) { + pr_err("kstrtoul() failed for hw_block_size=\n"); + break; + } + if (!tmp_ul) { + pr_err("hw_block_size must be nonzero\n"); + break; + } + dev->dev_attrib.hw_block_size = tmp_ul; break; default: break; @@ -1024,8 +1022,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) bl = sprintf(b + bl, "Config: %s ", udev->dev_config[0] ? udev->dev_config : "NULL"); - bl += sprintf(b + bl, "Size: %zu PassLevel: %u\n", - udev->dev_size, udev->pass_level); + bl += sprintf(b + bl, "Size: %zu\n", udev->dev_size); return bl; } @@ -1039,20 +1036,6 @@ static sector_t tcmu_get_blocks(struct se_device *dev) } static sense_reason_t -tcmu_execute_rw(struct se_cmd *se_cmd, struct scatterlist *sgl, u32 sgl_nents, - enum dma_data_direction data_direction) -{ - int ret; - - ret = tcmu_queue_cmd(se_cmd); - - if (ret != 0) - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - else - return TCM_NO_SENSE; -} - -static sense_reason_t tcmu_pass_op(struct se_cmd *se_cmd) { int ret = tcmu_queue_cmd(se_cmd); @@ -1063,91 +1046,29 @@ tcmu_pass_op(struct se_cmd *se_cmd) return TCM_NO_SENSE; } -static struct sbc_ops tcmu_sbc_ops = { - .execute_rw = tcmu_execute_rw, - .execute_sync_cache = tcmu_pass_op, - .execute_write_same = tcmu_pass_op, - .execute_write_same_unmap = tcmu_pass_op, - .execute_unmap = tcmu_pass_op, -}; - static sense_reason_t tcmu_parse_cdb(struct se_cmd *cmd) { - unsigned char *cdb = cmd->t_task_cdb; - struct tcmu_dev *udev = TCMU_DEV(cmd->se_dev); - sense_reason_t ret; - - switch (udev->pass_level) { - case TCMU_PASS_ALL: - /* We're just like pscsi, then */ - /* - * For REPORT LUNS we always need to emulate the response, for everything - * else, pass it up. - */ - switch (cdb[0]) { - case REPORT_LUNS: - cmd->execute_cmd = spc_emulate_report_luns; - break; - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - case WRITE_VERIFY: - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - /* FALLTHROUGH */ - default: - cmd->execute_cmd = tcmu_pass_op; - } - ret = TCM_NO_SENSE; - break; - case TCMU_PASS_IO: - ret = sbc_parse_cdb(cmd, &tcmu_sbc_ops); - break; - default: - pr_err("Unknown tcm-user pass level %d\n", udev->pass_level); - ret = TCM_CHECK_CONDITION_ABORT_CMD; - } - - return ret; + return passthrough_parse_cdb(cmd, tcmu_pass_op); } -DEF_TB_DEFAULT_ATTRIBS(tcmu); +DEF_TB_DEV_ATTRIB_RO(tcmu, hw_pi_prot_type); +TB_DEV_ATTR_RO(tcmu, hw_pi_prot_type); + +DEF_TB_DEV_ATTRIB_RO(tcmu, hw_block_size); +TB_DEV_ATTR_RO(tcmu, hw_block_size); + +DEF_TB_DEV_ATTRIB_RO(tcmu, hw_max_sectors); +TB_DEV_ATTR_RO(tcmu, hw_max_sectors); + +DEF_TB_DEV_ATTRIB_RO(tcmu, hw_queue_depth); +TB_DEV_ATTR_RO(tcmu, hw_queue_depth); static struct configfs_attribute *tcmu_backend_dev_attrs[] = { - &tcmu_dev_attrib_emulate_model_alias.attr, - &tcmu_dev_attrib_emulate_dpo.attr, - &tcmu_dev_attrib_emulate_fua_write.attr, - &tcmu_dev_attrib_emulate_fua_read.attr, - &tcmu_dev_attrib_emulate_write_cache.attr, - &tcmu_dev_attrib_emulate_ua_intlck_ctrl.attr, - &tcmu_dev_attrib_emulate_tas.attr, - &tcmu_dev_attrib_emulate_tpu.attr, - &tcmu_dev_attrib_emulate_tpws.attr, - &tcmu_dev_attrib_emulate_caw.attr, - &tcmu_dev_attrib_emulate_3pc.attr, - &tcmu_dev_attrib_pi_prot_type.attr, &tcmu_dev_attrib_hw_pi_prot_type.attr, - &tcmu_dev_attrib_pi_prot_format.attr, - &tcmu_dev_attrib_enforce_pr_isids.attr, - &tcmu_dev_attrib_is_nonrot.attr, - &tcmu_dev_attrib_emulate_rest_reord.attr, - &tcmu_dev_attrib_force_pr_aptpl.attr, &tcmu_dev_attrib_hw_block_size.attr, - &tcmu_dev_attrib_block_size.attr, &tcmu_dev_attrib_hw_max_sectors.attr, - &tcmu_dev_attrib_optimal_sectors.attr, &tcmu_dev_attrib_hw_queue_depth.attr, - &tcmu_dev_attrib_queue_depth.attr, - &tcmu_dev_attrib_max_unmap_lba_count.attr, - &tcmu_dev_attrib_max_unmap_block_desc_count.attr, - &tcmu_dev_attrib_unmap_granularity.attr, - &tcmu_dev_attrib_unmap_granularity_alignment.attr, - &tcmu_dev_attrib_max_write_same_len.attr, NULL, }; @@ -1156,7 +1077,7 @@ static struct se_subsystem_api tcmu_template = { .inquiry_prod = "USER", .inquiry_rev = TCMU_VERSION, .owner = THIS_MODULE, - .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, + .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, .attach_hba = tcmu_attach_hba, .detach_hba = tcmu_detach_hba, .alloc_device = tcmu_alloc_device, diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index a600ff15dcfd..8fd680ac941b 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -58,7 +58,6 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op bool src) { struct se_device *se_dev; - struct configfs_subsystem *subsys = target_core_subsystem[0]; unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN], *dev_wwn; int rc; @@ -90,8 +89,7 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op " se_dev\n", xop->src_dev); } - rc = configfs_depend_item(subsys, - &se_dev->dev_group.cg_item); + rc = target_depend_item(&se_dev->dev_group.cg_item); if (rc != 0) { pr_err("configfs_depend_item attempt failed:" " %d for se_dev: %p\n", rc, se_dev); @@ -99,8 +97,8 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op return rc; } - pr_debug("Called configfs_depend_item for subsys: %p se_dev: %p" - " se_dev->se_dev_group: %p\n", subsys, se_dev, + pr_debug("Called configfs_depend_item for se_dev: %p" + " se_dev->se_dev_group: %p\n", se_dev, &se_dev->dev_group); mutex_unlock(&g_device_mutex); @@ -373,7 +371,6 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd) static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) { - struct configfs_subsystem *subsys = target_core_subsystem[0]; struct se_device *remote_dev; if (xop->op_origin == XCOL_SOURCE_RECV_OP) @@ -381,11 +378,11 @@ static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) else remote_dev = xop->src_dev; - pr_debug("Calling configfs_undepend_item for subsys: %p" + pr_debug("Calling configfs_undepend_item for" " remote_dev: %p remote_dev->dev_group: %p\n", - subsys, remote_dev, &remote_dev->dev_group.cg_item); + remote_dev, &remote_dev->dev_group.cg_item); - configfs_undepend_item(subsys, &remote_dev->dev_group.cg_item); + target_undepend_item(&remote_dev->dev_group.cg_item); } static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index c2556cf5186b..01255fd65135 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -224,9 +224,9 @@ static const struct armada_thermal_data armada380_data = { .is_valid_shift = 10, .temp_shift = 0, .temp_mask = 0x3ff, - .coef_b = 1169498786UL, - .coef_m = 2000000UL, - .coef_div = 4289, + .coef_b = 2931108200UL, + .coef_m = 5000000UL, + .coef_div = 10502, .inverted = true, }; diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 12623bc02f46..725718e97a0b 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -206,51 +206,57 @@ static void find_target_mwait(void) } +struct pkg_cstate_info { + bool skip; + int msr_index; + int cstate_id; +}; + +#define PKG_CSTATE_INIT(id) { \ + .msr_index = MSR_PKG_C##id##_RESIDENCY, \ + .cstate_id = id \ + } + +static struct pkg_cstate_info pkg_cstates[] = { + PKG_CSTATE_INIT(2), + PKG_CSTATE_INIT(3), + PKG_CSTATE_INIT(6), + PKG_CSTATE_INIT(7), + PKG_CSTATE_INIT(8), + PKG_CSTATE_INIT(9), + PKG_CSTATE_INIT(10), + {NULL}, +}; + static bool has_pkg_state_counter(void) { - u64 tmp; - return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || - !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) || - !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || - !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); + u64 val; + struct pkg_cstate_info *info = pkg_cstates; + + /* check if any one of the counter msrs exists */ + while (info->msr_index) { + if (!rdmsrl_safe(info->msr_index, &val)) + return true; + info++; + } + + return false; } static u64 pkg_state_counter(void) { u64 val; u64 count = 0; - - static bool skip_c2; - static bool skip_c3; - static bool skip_c6; - static bool skip_c7; - - if (!skip_c2) { - if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) - count += val; - else - skip_c2 = true; - } - - if (!skip_c3) { - if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val)) - count += val; - else - skip_c3 = true; - } - - if (!skip_c6) { - if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val)) - count += val; - else - skip_c6 = true; - } - - if (!skip_c7) { - if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val)) - count += val; - else - skip_c7 = true; + struct pkg_cstate_info *info = pkg_cstates; + + while (info->msr_index) { + if (!info->skip) { + if (!rdmsrl_safe(info->msr_index, &val)) + count += val; + else + info->skip = true; + } + info++; } return count; @@ -667,7 +673,7 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = { }; /* runs on Nehalem and later */ -static const struct x86_cpu_id intel_powerclamp_ids[] = { +static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = { { X86_VENDOR_INTEL, 6, 0x1a}, { X86_VENDOR_INTEL, 6, 0x1c}, { X86_VENDOR_INTEL, 6, 0x1e}, @@ -689,12 +695,13 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { { X86_VENDOR_INTEL, 6, 0x46}, { X86_VENDOR_INTEL, 6, 0x4c}, { X86_VENDOR_INTEL, 6, 0x4d}, + { X86_VENDOR_INTEL, 6, 0x4f}, { X86_VENDOR_INTEL, 6, 0x56}, {} }; MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); -static int powerclamp_probe(void) +static int __init powerclamp_probe(void) { if (!x86_match_cpu(intel_powerclamp_ids)) { pr_err("Intel powerclamp does not run on family %d model %d\n", @@ -760,7 +767,7 @@ file_error: debugfs_remove_recursive(debug_dir); } -static int powerclamp_init(void) +static int __init powerclamp_init(void) { int retval; int bitmap_size; @@ -809,7 +816,7 @@ exit_free: } module_init(powerclamp_init); -static void powerclamp_exit(void) +static void __exit powerclamp_exit(void) { unregister_hotcpu_notifier(&powerclamp_cpu_notifier); end_power_clamp(); diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 3aa46ac7cdbc..cd8f5f93b42c 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -529,7 +529,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev) thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); if (IS_ERR(thermal->pclk)) { - error = PTR_ERR(thermal->clk); + error = PTR_ERR(thermal->pclk); dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", error); return error; diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 0531c752fbbb..8e391812e503 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -103,7 +103,7 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) { - return 0; + return false; } static inline const struct thermal_trip * of_thermal_get_trip_points(struct thermal_zone_device *tz) diff --git a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c index a4929272074f..58b5c6694cd4 100644 --- a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c +++ b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c @@ -420,7 +420,8 @@ const struct ti_bandgap_data dra752_data = { TI_BANDGAP_FEATURE_FREEZE_BIT | TI_BANDGAP_FEATURE_TALERT | TI_BANDGAP_FEATURE_COUNTER_DELAY | - TI_BANDGAP_FEATURE_HISTORY_BUFFER, + TI_BANDGAP_FEATURE_HISTORY_BUFFER | + TI_BANDGAP_FEATURE_ERRATA_814, .fclock_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div", .conv_table = dra752_adc_to_temp, diff --git a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c index eff0c80fd4af..79ff70c446ba 100644 --- a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c +++ b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c @@ -319,7 +319,8 @@ const struct ti_bandgap_data omap5430_data = { TI_BANDGAP_FEATURE_FREEZE_BIT | TI_BANDGAP_FEATURE_TALERT | TI_BANDGAP_FEATURE_COUNTER_DELAY | - TI_BANDGAP_FEATURE_HISTORY_BUFFER, + TI_BANDGAP_FEATURE_HISTORY_BUFFER | + TI_BANDGAP_FEATURE_ERRATA_813, .fclock_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div", .conv_table = omap5430_adc_to_temp, diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index 62a5d449c388..bc14dc874594 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -119,6 +119,37 @@ exit: } /** + * ti_errata814_bandgap_read_temp() - helper function to read dra7 sensor temperature + * @bgp: pointer to ti_bandgap structure + * @reg: desired register (offset) to be read + * + * Function to read dra7 bandgap sensor temperature. This is done separately + * so as to workaround the errata "Bandgap Temperature read Dtemp can be + * corrupted" - Errata ID: i814". + * Read accesses to registers listed below can be corrupted due to incorrect + * resynchronization between clock domains. + * Read access to registers below can be corrupted : + * CTRL_CORE_DTEMP_MPU/GPU/CORE/DSPEVE/IVA_n (n = 0 to 4) + * CTRL_CORE_TEMP_SENSOR_MPU/GPU/CORE/DSPEVE/IVA_n + * + * Return: the register value. + */ +static u32 ti_errata814_bandgap_read_temp(struct ti_bandgap *bgp, u32 reg) +{ + u32 val1, val2; + + val1 = ti_bandgap_readl(bgp, reg); + val2 = ti_bandgap_readl(bgp, reg); + + /* If both times we read the same value then that is right */ + if (val1 == val2) + return val1; + + /* if val1 and val2 are different read it third time */ + return ti_bandgap_readl(bgp, reg); +} + +/** * ti_bandgap_read_temp() - helper function to read sensor temperature * @bgp: pointer to ti_bandgap structure * @id: bandgap sensor id @@ -148,7 +179,11 @@ static u32 ti_bandgap_read_temp(struct ti_bandgap *bgp, int id) } /* read temperature */ - temp = ti_bandgap_readl(bgp, reg); + if (TI_BANDGAP_HAS(bgp, ERRATA_814)) + temp = ti_errata814_bandgap_read_temp(bgp, reg); + else + temp = ti_bandgap_readl(bgp, reg); + temp &= tsr->bgap_dtemp_mask; if (TI_BANDGAP_HAS(bgp, FREEZE_BIT)) @@ -410,7 +445,7 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id, { struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data; struct temp_sensor_registers *tsr; - u32 thresh_val, reg_val, t_hot, t_cold; + u32 thresh_val, reg_val, t_hot, t_cold, ctrl; int err = 0; tsr = bgp->conf->sensors[id].registers; @@ -442,8 +477,47 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id, ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask); reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) | (t_cold << __ffs(tsr->threshold_tcold_mask)); + + /** + * Errata i813: + * Spurious Thermal Alert: Talert can happen randomly while the device + * remains under the temperature limit defined for this event to trig. + * This spurious event is caused by a incorrect re-synchronization + * between clock domains. The comparison between configured threshold + * and current temperature value can happen while the value is + * transitioning (metastable), thus causing inappropriate event + * generation. No spurious event occurs as long as the threshold value + * stays unchanged. Spurious event can be generated while a thermal + * alert threshold is modified in + * CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n. + */ + + if (TI_BANDGAP_HAS(bgp, ERRATA_813)) { + /* Mask t_hot and t_cold events at the IP Level */ + ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl); + + if (hot) + ctrl &= ~tsr->mask_hot_mask; + else + ctrl &= ~tsr->mask_cold_mask; + + ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl); + } + + /* Write the threshold value */ ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold); + if (TI_BANDGAP_HAS(bgp, ERRATA_813)) { + /* Unmask t_hot and t_cold events at the IP Level */ + ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl); + if (hot) + ctrl |= tsr->mask_hot_mask; + else + ctrl |= tsr->mask_cold_mask; + + ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl); + } + if (err) { dev_err(bgp->dev, "failed to reprogram thot threshold\n"); err = -EIO; diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.h b/drivers/thermal/ti-soc-thermal/ti-bandgap.h index b3adf72f252d..0c52f7afba00 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.h +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.h @@ -318,6 +318,10 @@ struct ti_temp_sensor { * TI_BANDGAP_FEATURE_HISTORY_BUFFER - used when the bandgap device features * a history buffer of temperatures. * + * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device + * has Errata 814 + * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device + * has Errata 813 * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a * specific feature (above) or not. Return non-zero, if yes. */ @@ -331,6 +335,8 @@ struct ti_temp_sensor { #define TI_BANDGAP_FEATURE_FREEZE_BIT BIT(7) #define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8) #define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9) +#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10) +#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11) #define TI_BANDGAP_HAS(b, f) \ ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f) diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 0655fecf8240..0f82c0b146f6 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -59,7 +59,7 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count) struct goldfish_tty *qtty = &goldfish_ttys[line]; void __iomem *base = qtty->base; spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, + gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, base + GOLDFISH_TTY_DATA_PTR_HIGH); writel(count, base + GOLDFISH_TTY_DATA_LEN); writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD); @@ -81,7 +81,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) count = tty_prepare_flip_string(&qtty->port, &buf, count); spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, + gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, base + GOLDFISH_TTY_DATA_PTR_HIGH); writel(count, base + GOLDFISH_TTY_DATA_LEN); writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD); diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index f1e57425e39f..7a3d146a5f0e 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -289,7 +289,7 @@ static int xen_initial_domain_console_init(void) return -ENOMEM; } - info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); + info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); info->vtermno = HVC_COOKIE; spin_lock(&xencons_lock); @@ -299,11 +299,27 @@ static int xen_initial_domain_console_init(void) return 0; } +static void xen_console_update_evtchn(struct xencons_info *info) +{ + if (xen_hvm_domain()) { + uint64_t v; + int err; + + err = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); + if (!err && v) + info->evtchn = v; + } else + info->evtchn = xen_start_info->console.domU.evtchn; +} + void xen_console_resume(void) { struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); - if (info != NULL && info->irq) + if (info != NULL && info->irq) { + if (!xen_initial_domain()) + xen_console_update_evtchn(info); rebind_evtchn_irq(info->evtchn, info->irq); + } } static void xencons_disconnect_backend(struct xencons_info *info) diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index 04d9e23d1ee1..358323c83b4f 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -174,13 +174,13 @@ struct mips_ejtag_fdc_tty { static inline void mips_ejtag_fdc_write(struct mips_ejtag_fdc_tty *priv, unsigned int offs, unsigned int data) { - iowrite32(data, priv->reg + offs); + __raw_writel(data, priv->reg + offs); } static inline unsigned int mips_ejtag_fdc_read(struct mips_ejtag_fdc_tty *priv, unsigned int offs) { - return ioread32(priv->reg + offs); + return __raw_readl(priv->reg + offs); } /* Encoding of byte stream in FDC words */ @@ -347,9 +347,9 @@ static void mips_ejtag_fdc_console_write(struct console *c, const char *s, s += inc[word.bytes - 1]; /* Busy wait until there's space in fifo */ - while (ioread32(regs + REG_FDSTAT) & REG_FDSTAT_TXF) + while (__raw_readl(regs + REG_FDSTAT) & REG_FDSTAT_TXF) ; - iowrite32(word.word, regs + REG_FDTX(c->index)); + __raw_writel(word.word, regs + REG_FDTX(c->index)); } out: local_irq_restore(flags); @@ -1227,7 +1227,7 @@ static int kgdbfdc_read_char(void) /* Read next word from KGDB channel */ do { - stat = ioread32(regs + REG_FDSTAT); + stat = __raw_readl(regs + REG_FDSTAT); /* No data waiting? */ if (stat & REG_FDSTAT_RXE) @@ -1236,7 +1236,7 @@ static int kgdbfdc_read_char(void) /* Read next word */ channel = (stat & REG_FDSTAT_RXCHAN) >> REG_FDSTAT_RXCHAN_SHIFT; - data = ioread32(regs + REG_FDRX); + data = __raw_readl(regs + REG_FDRX); } while (channel != CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN); /* Decode into rbuf */ @@ -1266,9 +1266,10 @@ static void kgdbfdc_push_one(void) return; /* Busy wait until there's space in fifo */ - while (ioread32(regs + REG_FDSTAT) & REG_FDSTAT_TXF) + while (__raw_readl(regs + REG_FDSTAT) & REG_FDSTAT_TXF) ; - iowrite32(word.word, regs + REG_FDTX(CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN)); + __raw_writel(word.word, + regs + REG_FDTX(CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN)); } /* flush the whole write buffer to the TX FIFO */ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 91abc00aa833..2c34c3249972 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3170,7 +3170,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) return gsmtty_modem_update(dlci, encode); } -static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty) +static void gsmtty_cleanup(struct tty_struct *tty) { struct gsm_dlci *dlci = tty->driver_data; struct gsm_mux *gsm = dlci->gsm; @@ -3178,7 +3178,6 @@ static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty) dlci_put(dlci); dlci_put(gsm->dlci[0]); mux_put(gsm); - driver->ttys[tty->index] = NULL; } /* Virtual ttys for the demux */ @@ -3199,7 +3198,7 @@ static const struct tty_operations gsmtty_ops = { .tiocmget = gsmtty_tiocmget, .tiocmset = gsmtty_tiocmset, .break_ctl = gsmtty_break_ctl, - .remove = gsmtty_remove, + .cleanup = gsmtty_cleanup, }; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 644ddb841d9f..bbc4ce66c2c1 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -600,7 +600,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, add_wait_queue(&tty->read_wait, &wait); for (;;) { - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { + if (test_bit(TTY_OTHER_DONE, &tty->flags)) { ret = -EIO; break; } @@ -828,7 +828,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, /* set bits for operations that won't block */ if (n_hdlc->rx_buf_list.head) mask |= POLLIN | POLLRDNORM; /* readable */ - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + if (test_bit(TTY_OTHER_DONE, &tty->flags)) mask |= POLLHUP; if (tty_hung_up_p(filp)) mask |= POLLHUP; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index cf6e0f2e1331..396344cb011f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -162,6 +162,17 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, return put_user(x, ptr); } +static inline int tty_copy_to_user(struct tty_struct *tty, + void __user *to, + const void *from, + unsigned long n) +{ + struct n_tty_data *ldata = tty->disc_data; + + tty_audit_add_data(tty, to, n, ldata->icanon); + return copy_to_user(to, from, n); +} + /** * n_tty_kick_worker - start input worker (if required) * @tty: terminal @@ -1949,6 +1960,18 @@ static inline int input_available_p(struct tty_struct *tty, int poll) return ldata->commit_head - ldata->read_tail >= amt; } +static inline int check_other_done(struct tty_struct *tty) +{ + int done = test_bit(TTY_OTHER_DONE, &tty->flags); + if (done) { + /* paired with cmpxchg() in check_other_closed(); ensures + * read buffer head index is not stale + */ + smp_mb__after_atomic(); + } + return done; +} + /** * copy_from_read_buf - copy read data directly * @tty: terminal device @@ -2058,8 +2081,8 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, size = N_TTY_BUF_SIZE - tail; n = eol - tail; - if (n > 4096) - n += 4096; + if (n > N_TTY_BUF_SIZE) + n += N_TTY_BUF_SIZE; n += found; c = n; @@ -2072,12 +2095,12 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, __func__, eol, found, n, c, size, more); if (n > size) { - ret = copy_to_user(*b, read_buf_addr(ldata, tail), size); + ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), size); if (ret) return -EFAULT; - ret = copy_to_user(*b + size, ldata->read_buf, n - size); + ret = tty_copy_to_user(tty, *b + size, ldata->read_buf, n - size); } else - ret = copy_to_user(*b, read_buf_addr(ldata, tail), n); + ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), n); if (ret) return -EFAULT; @@ -2167,7 +2190,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, struct n_tty_data *ldata = tty->disc_data; unsigned char __user *b = buf; DEFINE_WAIT_FUNC(wait, woken_wake_function); - int c; + int c, done; int minimum, time; ssize_t retval = 0; long timeout; @@ -2235,8 +2258,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, ((minimum - (b - buf)) >= 1)) ldata->minimum_to_wake = (minimum - (b - buf)); + done = check_other_done(tty); + if (!input_available_p(tty, 0)) { - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { + if (done) { retval = -EIO; break; } @@ -2443,12 +2468,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, poll_wait(file, &tty->read_wait, wait); poll_wait(file, &tty->write_wait, wait); + if (check_other_done(tty)) + mask |= POLLHUP; if (input_available_p(tty, 1)) mask |= POLLIN | POLLRDNORM; if (tty->packet && tty->link->ctrl_status) mask |= POLLPRI | POLLIN | POLLRDNORM; - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) - mask |= POLLHUP; if (tty_hung_up_p(file)) mask |= POLLHUP; if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e72ee629cead..4d5e8409769c 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -53,9 +53,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp) /* Review - krefs on tty_link ?? */ if (!tty->link) return; - tty_flush_to_ldisc(tty->link); set_bit(TTY_OTHER_CLOSED, &tty->link->flags); - wake_up_interruptible(&tty->link->read_wait); + tty_flip_buffer_push(tty->link->port); wake_up_interruptible(&tty->link->write_wait); if (tty->driver->subtype == PTY_TYPE_MASTER) { set_bit(TTY_OTHER_CLOSED, &tty->flags); @@ -243,7 +242,9 @@ static int pty_open(struct tty_struct *tty, struct file *filp) goto out; clear_bit(TTY_IO_ERROR, &tty->flags); + /* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */ clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); + clear_bit(TTY_OTHER_DONE, &tty->link->flags); set_bit(TTY_THROTTLED, &tty->flags); return 0; diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 9289999cb7c6..dce1a23706e8 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -562,12 +562,36 @@ static irqreturn_t omap_wake_irq(int irq, void *dev_id) return IRQ_NONE; } +#ifdef CONFIG_SERIAL_8250_DMA +static int omap_8250_dma_handle_irq(struct uart_port *port); +#endif + +static irqreturn_t omap8250_irq(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + struct uart_8250_port *up = up_to_u8250p(port); + unsigned int iir; + int ret; + +#ifdef CONFIG_SERIAL_8250_DMA + if (up->dma) { + ret = omap_8250_dma_handle_irq(port); + return IRQ_RETVAL(ret); + } +#endif + + serial8250_rpm_get(up); + iir = serial_port_in(port, UART_IIR); + ret = serial8250_handle_irq(port, iir); + serial8250_rpm_put(up); + + return IRQ_RETVAL(ret); +} + static int omap_8250_startup(struct uart_port *port) { - struct uart_8250_port *up = - container_of(port, struct uart_8250_port, port); + struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = port->private_data; - int ret; if (priv->wakeirq) { @@ -580,10 +604,31 @@ static int omap_8250_startup(struct uart_port *port) pm_runtime_get_sync(port->dev); - ret = serial8250_do_startup(port); - if (ret) + up->mcr = 0; + serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + + serial_out(up, UART_LCR, UART_LCR_WLEN8); + + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + + if (up->dma) { + ret = serial8250_request_dma(up); + if (ret) { + dev_warn_ratelimited(port->dev, + "failed to request DMA\n"); + up->dma = NULL; + } + } + + ret = request_irq(port->irq, omap8250_irq, IRQF_SHARED, + dev_name(port->dev), port); + if (ret < 0) goto err; + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + #ifdef CONFIG_PM up->capabilities |= UART_CAP_RPM; #endif @@ -610,8 +655,7 @@ err: static void omap_8250_shutdown(struct uart_port *port) { - struct uart_8250_port *up = - container_of(port, struct uart_8250_port, port); + struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = port->private_data; flush_work(&priv->qos_work); @@ -621,11 +665,24 @@ static void omap_8250_shutdown(struct uart_port *port) pm_runtime_get_sync(port->dev); serial_out(up, UART_OMAP_WER, 0); - serial8250_do_shutdown(port); + + up->ier = 0; + serial_out(up, UART_IER, 0); + + if (up->dma) + serial8250_release_dma(up); + + /* + * Disable break condition and FIFOs + */ + if (up->lcr & UART_LCR_SBC) + serial_out(up, UART_LCR, up->lcr & ~UART_LCR_SBC); + serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); + free_irq(port->irq, port); if (priv->wakeirq) free_irq(priv->wakeirq, port); } @@ -974,6 +1031,13 @@ static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) } #endif +static int omap8250_no_handle_irq(struct uart_port *port) +{ + /* IRQ has not been requested but handling irq? */ + WARN_ONCE(1, "Unexpected irq handling before port startup\n"); + return 0; +} + static int omap8250_probe(struct platform_device *pdev) { struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1075,6 +1139,7 @@ static int omap8250_probe(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(&up, priv); + up.port.handle_irq = omap8250_no_handle_irq; #ifdef CONFIG_SERIAL_8250_DMA if (pdev->dev.of_node) { /* @@ -1088,7 +1153,6 @@ static int omap8250_probe(struct platform_device *pdev) ret = of_property_count_strings(pdev->dev.of_node, "dma-names"); if (ret == 2) { up.dma = &priv->omap8250_dma; - up.port.handle_irq = omap_8250_dma_handle_irq; priv->omap8250_dma.fn = the_no_dma_filter_fn; priv->omap8250_dma.tx_dma = omap_8250_tx_dma; priv->omap8250_dma.rx_dma = omap_8250_rx_dma; diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 5a4e9d579585..763eb20fe321 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1249,20 +1249,19 @@ __acquires(&uap->port.lock) /* * Transmit a character - * There must be at least one free entry in the TX FIFO to accept the char. * - * Returns true if the FIFO might have space in it afterwards; - * returns false if the FIFO definitely became full. + * Returns true if the character was successfully queued to the FIFO. + * Returns false otherwise. */ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) { + if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + return false; /* unable to transmit character */ + writew(c, uap->port.membase + UART01x_DR); uap->port.icount.tx++; - if (likely(uap->tx_irq_seen > 1)) - return true; - - return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); + return true; } static bool pl011_tx_chars(struct uart_amba_port *uap) @@ -1296,7 +1295,8 @@ static bool pl011_tx_chars(struct uart_amba_port *uap) return false; if (uap->port.x_char) { - pl011_tx_char(uap, uap->port.x_char); + if (!pl011_tx_char(uap, uap->port.x_char)) + goto done; uap->port.x_char = 0; --count; } @@ -1639,6 +1639,9 @@ static int pl011_startup(struct uart_port *port) writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); + /* Assume that TX IRQ doesn't work until we see one: */ + uap->tx_irq_seen = 0; + spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ @@ -1702,7 +1705,7 @@ static void pl011_shutdown(struct uart_port *port) spin_lock_irq(&uap->port.lock); uap->im = 0; writew(uap->im, uap->port.membase + UART011_IMSC); - writew(0xffff & ~UART011_TXIS, uap->port.membase + UART011_ICR); + writew(0xffff, uap->port.membase + UART011_ICR); spin_unlock_irq(&uap->port.lock); pl011_dma_shutdown(uap); diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 5fdc9f3ecd64..6dc471e30e79 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -187,13 +187,8 @@ static int __init param_setup_earlycon(char *buf) return 0; err = setup_earlycon(buf); - if (err == -ENOENT) { - pr_warn("no match for %s\n", buf); - err = 0; - } else if (err == -EALREADY) { - pr_warn("already registered\n"); - err = 0; - } + if (err == -ENOENT || err == -EALREADY) + return 0; return err; } early_param("earlycon", param_setup_earlycon); diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index c8cfa0637128..88250395b0ce 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -911,6 +911,14 @@ static void dma_rx_callback(void *data) status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state); count = RX_BUF_SIZE - state.residue; + + if (readl(sport->port.membase + USR2) & USR2_IDLE) { + /* In condition [3] the SDMA counted up too early */ + count--; + + writel(USR2_IDLE, sport->port.membase + USR2); + } + dev_dbg(sport->port.dev, "We get %d bytes.\n", count); if (count) { diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 211479aa34bb..7f49172ccd86 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1735,6 +1735,8 @@ static int serial_omap_probe(struct platform_device *pdev) err_add_port: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_qos_remove_request(&up->pm_qos_request); + device_init_wakeup(up->dev, false); err_rs485: err_port_line: return ret; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 75661641f5fe..2f78b77f0f81 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -37,6 +37,28 @@ #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) +/* + * If all tty flip buffers have been processed by flush_to_ldisc() or + * dropped by tty_buffer_flush(), check if the linked pty has been closed. + * If so, wake the reader/poll to process + */ +static inline void check_other_closed(struct tty_struct *tty) +{ + unsigned long flags, old; + + /* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */ + for (flags = ACCESS_ONCE(tty->flags); + test_bit(TTY_OTHER_CLOSED, &flags); + ) { + old = flags; + __set_bit(TTY_OTHER_DONE, &flags); + flags = cmpxchg(&tty->flags, old, flags); + if (old == flags) { + wake_up_interruptible(&tty->read_wait); + break; + } + } +} /** * tty_buffer_lock_exclusive - gain exclusive access to buffer @@ -229,6 +251,8 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) if (ld && ld->ops->flush_buffer) ld->ops->flush_buffer(tty); + check_other_closed(tty); + atomic_dec(&buf->priority); mutex_unlock(&buf->lock); } @@ -471,8 +495,10 @@ static void flush_to_ldisc(struct work_struct *work) smp_rmb(); count = head->commit - head->read; if (!count) { - if (next == NULL) + if (next == NULL) { + check_other_closed(tty); break; + } buf->head = next; tty_buffer_free(port, head); continue; @@ -489,19 +515,6 @@ static void flush_to_ldisc(struct work_struct *work) } /** - * tty_flush_to_ldisc - * @tty: tty to push - * - * Push the terminal flip buffers to the line discipline. - * - * Must not be called from IRQ context. - */ -void tty_flush_to_ldisc(struct tty_struct *tty) -{ - flush_work(&tty->port->buf.work); -} - -/** * tty_flip_buffer_push - terminal * @port: tty port to push * diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index dfb05edcdb96..5b7061a33103 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -88,9 +88,13 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf, char buf[32]; int ret; - if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + count = min_t(size_t, sizeof(buf) - 1, count); + if (copy_from_user(buf, ubuf, count)) return -EFAULT; + /* sscanf requires a zero terminated string */ + buf[count] = '\0'; + if (sscanf(buf, "%u", &mode) != 1) return -EINVAL; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 41e510ae8c83..d85abfed84cc 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -106,6 +106,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04f3, 0x010c), .driver_info = USB_QUIRK_DEVICE_QUALIFIER }, + { USB_DEVICE(0x04f3, 0x0125), .driver_info = + USB_QUIRK_DEVICE_QUALIFIER }, + { USB_DEVICE(0x04f3, 0x016f), .driver_info = USB_QUIRK_DEVICE_QUALIFIER }, diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fdab715a0631..c0eafa6fd403 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -339,7 +339,7 @@ #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 -#define DWC3_DGCMD_STATUS(n) (((n) >> 15) & 1) +#define DWC3_DGCMD_STATUS(n) (((n) >> 12) & 0x0F) #define DWC3_DGCMD_CMDACT (1 << 10) #define DWC3_DGCMD_CMDIOC (1 << 8) @@ -355,7 +355,7 @@ #define DWC3_DEPCMD_PARAM_SHIFT 16 #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) -#define DWC3_DEPCMD_STATUS(x) (((x) >> 15) & 1) +#define DWC3_DEPCMD_STATUS(x) (((x) >> 12) & 0x0F) #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) #define DWC3_DEPCMD_CMDACT (1 << 10) #define DWC3_DEPCMD_CMDIOC (1 << 8) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index edba5348be18..6b486a36863c 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -65,8 +65,8 @@ #define USBOTGSS_IRQENABLE_SET_MISC 0x003c #define USBOTGSS_IRQENABLE_CLR_MISC 0x0040 #define USBOTGSS_IRQMISC_OFFSET 0x03fc -#define USBOTGSS_UTMI_OTG_CTRL 0x0080 -#define USBOTGSS_UTMI_OTG_STATUS 0x0084 +#define USBOTGSS_UTMI_OTG_STATUS 0x0080 +#define USBOTGSS_UTMI_OTG_CTRL 0x0084 #define USBOTGSS_UTMI_OTG_OFFSET 0x0480 #define USBOTGSS_TXFIFO_DEPTH 0x0508 #define USBOTGSS_RXFIFO_DEPTH 0x050c @@ -98,20 +98,20 @@ #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL (1 << 3) #define USBOTGSS_IRQMISC_IDPULLUP_FALL (1 << 0) -/* UTMI_OTG_CTRL REGISTER */ -#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5) -#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4) -#define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS (1 << 3) -#define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP (1 << 0) - /* UTMI_OTG_STATUS REGISTER */ -#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE (1 << 31) -#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT (1 << 9) -#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8) -#define USBOTGSS_UTMI_OTG_STATUS_IDDIG (1 << 4) -#define USBOTGSS_UTMI_OTG_STATUS_SESSEND (1 << 3) -#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID (1 << 2) -#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID (1 << 1) +#define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS (1 << 5) +#define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS (1 << 4) +#define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS (1 << 3) +#define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP (1 << 0) + +/* UTMI_OTG_CTRL REGISTER */ +#define USBOTGSS_UTMI_OTG_CTRL_SW_MODE (1 << 31) +#define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT (1 << 9) +#define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE (1 << 8) +#define USBOTGSS_UTMI_OTG_CTRL_IDDIG (1 << 4) +#define USBOTGSS_UTMI_OTG_CTRL_SESSEND (1 << 3) +#define USBOTGSS_UTMI_OTG_CTRL_SESSVALID (1 << 2) +#define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID (1 << 1) struct dwc3_omap { struct device *dev; @@ -119,7 +119,7 @@ struct dwc3_omap { int irq; void __iomem *base; - u32 utmi_otg_status; + u32 utmi_otg_ctrl; u32 utmi_otg_offset; u32 irqmisc_offset; u32 irq_eoi_offset; @@ -153,15 +153,15 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) writel(value, base + offset); } -static u32 dwc3_omap_read_utmi_status(struct dwc3_omap *omap) +static u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap) { - return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS + + return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL + omap->utmi_otg_offset); } -static void dwc3_omap_write_utmi_status(struct dwc3_omap *omap, u32 value) +static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value) { - dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS + + dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL + omap->utmi_otg_offset, value); } @@ -235,25 +235,25 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap, } } - val = dwc3_omap_read_utmi_status(omap); - val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG - | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID - | USBOTGSS_UTMI_OTG_STATUS_SESSEND); - val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID - | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; - dwc3_omap_write_utmi_status(omap, val); + val = dwc3_omap_read_utmi_ctrl(omap); + val &= ~(USBOTGSS_UTMI_OTG_CTRL_IDDIG + | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID + | USBOTGSS_UTMI_OTG_CTRL_SESSEND); + val |= USBOTGSS_UTMI_OTG_CTRL_SESSVALID + | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT; + dwc3_omap_write_utmi_ctrl(omap, val); break; case OMAP_DWC3_VBUS_VALID: dev_dbg(omap->dev, "VBUS Connect\n"); - val = dwc3_omap_read_utmi_status(omap); - val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND; - val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG - | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID - | USBOTGSS_UTMI_OTG_STATUS_SESSVALID - | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; - dwc3_omap_write_utmi_status(omap, val); + val = dwc3_omap_read_utmi_ctrl(omap); + val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND; + val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG + | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID + | USBOTGSS_UTMI_OTG_CTRL_SESSVALID + | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT; + dwc3_omap_write_utmi_ctrl(omap, val); break; case OMAP_DWC3_ID_FLOAT: @@ -263,13 +263,13 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap, case OMAP_DWC3_VBUS_OFF: dev_dbg(omap->dev, "VBUS Disconnect\n"); - val = dwc3_omap_read_utmi_status(omap); - val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID - | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID - | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT); - val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND - | USBOTGSS_UTMI_OTG_STATUS_IDDIG; - dwc3_omap_write_utmi_status(omap, val); + val = dwc3_omap_read_utmi_ctrl(omap); + val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID + | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID + | USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT); + val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND + | USBOTGSS_UTMI_OTG_CTRL_IDDIG; + dwc3_omap_write_utmi_ctrl(omap, val); break; default: @@ -422,22 +422,22 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) struct device_node *node = omap->dev->of_node; int utmi_mode = 0; - reg = dwc3_omap_read_utmi_status(omap); + reg = dwc3_omap_read_utmi_ctrl(omap); of_property_read_u32(node, "utmi-mode", &utmi_mode); switch (utmi_mode) { case DWC3_OMAP_UTMI_MODE_SW: - reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE; break; case DWC3_OMAP_UTMI_MODE_HW: - reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE; break; default: dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode); } - dwc3_omap_write_utmi_status(omap, reg); + dwc3_omap_write_utmi_ctrl(omap, reg); } static int dwc3_omap_extcon_register(struct dwc3_omap *omap) @@ -614,7 +614,7 @@ static int dwc3_omap_suspend(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); - omap->utmi_otg_status = dwc3_omap_read_utmi_status(omap); + omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap); dwc3_omap_disable_irqs(omap); return 0; @@ -624,7 +624,7 @@ static int dwc3_omap_resume(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); - dwc3_omap_write_utmi_status(omap, omap->utmi_otg_status); + dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl); dwc3_omap_enable_irqs(omap); pm_runtime_disable(dev); diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index c42765b3a060..0495c94a23d7 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1295,6 +1295,7 @@ static void purge_configs_funcs(struct gadget_info *gi) } } c->next_interface_id = 0; + memset(c->interface, 0, sizeof(c->interface)); c->superspeed = 0; c->highspeed = 0; c->fullspeed = 0; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 6bdb57069044..3507f880eb74 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -315,7 +315,6 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, return ret; } - set_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags); return len; } break; @@ -847,7 +846,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) ret = ep->status; if (io_data->read && ret > 0) { ret = copy_to_iter(data, ret, &io_data->data); - if (unlikely(iov_iter_count(&io_data->data))) + if (!ret) ret = -EFAULT; } } @@ -1463,8 +1462,7 @@ static void ffs_data_clear(struct ffs_data *ffs) { ENTER(); - if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags)) - ffs_closed(ffs); + ffs_closed(ffs); BUG_ON(ffs->gadget); @@ -3422,9 +3420,13 @@ static int ffs_ready(struct ffs_data *ffs) ffs_obj->desc_ready = true; ffs_obj->ffs_data = ffs; - if (ffs_obj->ffs_ready_callback) + if (ffs_obj->ffs_ready_callback) { ret = ffs_obj->ffs_ready_callback(ffs); + if (ret) + goto done; + } + set_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags); done: ffs_dev_unlock(); return ret; @@ -3443,7 +3445,8 @@ static void ffs_closed(struct ffs_data *ffs) ffs_obj->desc_ready = false; - if (ffs_obj->ffs_closed_callback) + if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) && + ffs_obj->ffs_closed_callback) ffs_obj->ffs_closed_callback(ffs); if (!ffs_obj->opts || ffs_obj->opts->no_configfs diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 13dfc9915b1d..f7f35a36c09a 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -437,12 +437,20 @@ static int hidg_setup(struct usb_function *f, | USB_REQ_GET_DESCRIPTOR): switch (value >> 8) { case HID_DT_HID: + { + struct hid_descriptor hidg_desc_copy = hidg_desc; + VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n"); + hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT; + hidg_desc_copy.desc[0].wDescriptorLength = + cpu_to_le16(hidg->report_desc_length); + length = min_t(unsigned short, length, - hidg_desc.bLength); - memcpy(req->buf, &hidg_desc, length); + hidg_desc_copy.bLength); + memcpy(req->buf, &hidg_desc_copy, length); goto respond; break; + } case HID_DT_REPORT: VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n"); length = min_t(unsigned short, length, @@ -632,6 +640,10 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + /* + * We can use hidg_desc struct here but we should not relay + * that its content won't change after returning from this function. + */ hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; hidg_desc.desc[0].wDescriptorLength = cpu_to_le16(hidg->report_desc_length); diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 259b656c0b3e..6316aa5b1c49 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -973,7 +973,13 @@ static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = strlcpy(page, opts->id, PAGE_SIZE); + if (opts->id) { + result = strlcpy(page, opts->id, PAGE_SIZE); + } else { + page[0] = 0; + result = 0; + } + mutex_unlock(&opts->lock); return result; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 9719abfb6145..7856b3394494 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -588,7 +588,10 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (intf == 1) { if (alt == 1) { - config_ep_by_speed(cdev->gadget, f, out_ep); + err = config_ep_by_speed(cdev->gadget, f, out_ep); + if (err) + return err; + usb_ep_enable(out_ep); out_ep->driver_data = audio; audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 89179ab20c10..7ee057930ae7 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -113,6 +113,7 @@ struct gs_port { int write_allocated; struct gs_buf port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ + bool write_busy; /* REVISIT this state ... */ struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ @@ -363,7 +364,7 @@ __acquires(&port->port_lock) int status = 0; bool do_tty_wake = false; - while (!list_empty(pool)) { + while (!port->write_busy && !list_empty(pool)) { struct usb_request *req; int len; @@ -393,9 +394,11 @@ __acquires(&port->port_lock) * NOTE that we may keep sending data for a while after * the TTY closed (dev->ioport->port_tty is NULL). */ + port->write_busy = true; spin_unlock(&port->port_lock); status = usb_ep_queue(in, req, GFP_ATOMIC); spin_lock(&port->port_lock); + port->write_busy = false; if (status) { pr_debug("%s: %s %s err %d\n", diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c index c30b7b572465..1194b09ae746 100644 --- a/drivers/usb/gadget/legacy/acm_ms.c +++ b/drivers/usb/gadget/legacy/acm_ms.c @@ -121,7 +121,7 @@ static struct usb_function *f_msg; /* * We _always_ have both ACM and mass storage functions. */ -static int __init acm_ms_do_config(struct usb_configuration *c) +static int acm_ms_do_config(struct usb_configuration *c) { struct fsg_opts *opts; int status; @@ -174,7 +174,7 @@ static struct usb_configuration acm_ms_config_driver = { /*-------------------------------------------------------------------------*/ -static int __init acm_ms_bind(struct usb_composite_dev *cdev) +static int acm_ms_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct fsg_opts *opts; @@ -249,7 +249,7 @@ fail_get_msg: return status; } -static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) +static int acm_ms_unbind(struct usb_composite_dev *cdev) { usb_put_function(f_msg); usb_put_function_instance(fi_msg); @@ -258,13 +258,13 @@ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver acm_ms_driver = { +static struct usb_composite_driver acm_ms_driver = { .name = "g_acm_ms", .dev = &device_desc, .max_speed = USB_SPEED_SUPER, .strings = dev_strings, .bind = acm_ms_bind, - .unbind = __exit_p(acm_ms_unbind), + .unbind = acm_ms_unbind, }; module_usb_composite_driver(acm_ms_driver); diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index f46a3956e43d..f289caf18a45 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -167,7 +167,7 @@ static const struct usb_descriptor_header *otg_desc[] = { /*-------------------------------------------------------------------------*/ -static int __init audio_do_config(struct usb_configuration *c) +static int audio_do_config(struct usb_configuration *c) { int status; @@ -216,7 +216,7 @@ static struct usb_configuration audio_config_driver = { /*-------------------------------------------------------------------------*/ -static int __init audio_bind(struct usb_composite_dev *cdev) +static int audio_bind(struct usb_composite_dev *cdev) { #ifndef CONFIG_GADGET_UAC1 struct f_uac2_opts *uac2_opts; @@ -276,7 +276,7 @@ fail: return status; } -static int __exit audio_unbind(struct usb_composite_dev *cdev) +static int audio_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_GADGET_UAC1 if (!IS_ERR_OR_NULL(f_uac1)) @@ -292,13 +292,13 @@ static int __exit audio_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver audio_driver = { +static struct usb_composite_driver audio_driver = { .name = "g_audio", .dev = &device_desc, .strings = audio_strings, .max_speed = USB_SPEED_HIGH, .bind = audio_bind, - .unbind = __exit_p(audio_unbind), + .unbind = audio_unbind, }; module_usb_composite_driver(audio_driver); diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c index 2e85d9473478..afd3e37921a7 100644 --- a/drivers/usb/gadget/legacy/cdc2.c +++ b/drivers/usb/gadget/legacy/cdc2.c @@ -104,7 +104,7 @@ static struct usb_function_instance *fi_ecm; /* * We _always_ have both CDC ECM and CDC ACM functions. */ -static int __init cdc_do_config(struct usb_configuration *c) +static int cdc_do_config(struct usb_configuration *c) { int status; @@ -153,7 +153,7 @@ static struct usb_configuration cdc_config_driver = { /*-------------------------------------------------------------------------*/ -static int __init cdc_bind(struct usb_composite_dev *cdev) +static int cdc_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct f_ecm_opts *ecm_opts; @@ -211,7 +211,7 @@ fail: return status; } -static int __exit cdc_unbind(struct usb_composite_dev *cdev) +static int cdc_unbind(struct usb_composite_dev *cdev) { usb_put_function(f_acm); usb_put_function_instance(fi_serial); @@ -222,13 +222,13 @@ static int __exit cdc_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver cdc_driver = { +static struct usb_composite_driver cdc_driver = { .name = "g_cdc", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = cdc_bind, - .unbind = __exit_p(cdc_unbind), + .unbind = cdc_unbind, }; module_usb_composite_driver(cdc_driver); diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 633683a72a11..204b10b1a7e7 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -284,7 +284,7 @@ fail_1: return -ENODEV; } -static int __init dbgp_bind(struct usb_gadget *gadget, +static int dbgp_bind(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { int err, stp; @@ -406,7 +406,7 @@ fail: return err; } -static __refdata struct usb_gadget_driver dbgp_driver = { +static struct usb_gadget_driver dbgp_driver = { .function = "dbgp", .max_speed = USB_SPEED_HIGH, .bind = dbgp_bind, diff --git a/drivers/usb/gadget/legacy/ether.c b/drivers/usb/gadget/legacy/ether.c index c5fdc61cdc4a..a3323dca218f 100644 --- a/drivers/usb/gadget/legacy/ether.c +++ b/drivers/usb/gadget/legacy/ether.c @@ -222,7 +222,7 @@ static struct usb_function *f_rndis; * the first one present. That's to make Microsoft's drivers happy, * and to follow DOCSIS 1.0 (cable modem standard). */ -static int __init rndis_do_config(struct usb_configuration *c) +static int rndis_do_config(struct usb_configuration *c) { int status; @@ -264,7 +264,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode"); /* * We _always_ have an ECM, CDC Subset, or EEM configuration. */ -static int __init eth_do_config(struct usb_configuration *c) +static int eth_do_config(struct usb_configuration *c) { int status = 0; @@ -318,7 +318,7 @@ static struct usb_configuration eth_config_driver = { /*-------------------------------------------------------------------------*/ -static int __init eth_bind(struct usb_composite_dev *cdev) +static int eth_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct f_eem_opts *eem_opts = NULL; @@ -447,7 +447,7 @@ fail: return status; } -static int __exit eth_unbind(struct usb_composite_dev *cdev) +static int eth_unbind(struct usb_composite_dev *cdev) { if (has_rndis()) { usb_put_function(f_rndis); @@ -466,13 +466,13 @@ static int __exit eth_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver eth_driver = { +static struct usb_composite_driver eth_driver = { .name = "g_ether", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_SUPER, .bind = eth_bind, - .unbind = __exit_p(eth_unbind), + .unbind = eth_unbind, }; module_usb_composite_driver(eth_driver); diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index b01b88e1b716..e821931c965c 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c @@ -163,7 +163,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev); static int gfs_do_config(struct usb_configuration *c); -static __refdata struct usb_composite_driver gfs_driver = { +static struct usb_composite_driver gfs_driver = { .name = DRIVER_NAME, .dev = &gfs_dev_desc, .strings = gfs_dev_strings, @@ -304,8 +304,10 @@ static int functionfs_ready_callback(struct ffs_data *ffs) gfs_registered = true; ret = usb_composite_probe(&gfs_driver); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + ++missing_funcs; gfs_registered = false; + } return ret; } diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index e02a095294ac..da19c486b61e 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -118,7 +118,7 @@ static struct usb_gadget_strings *dev_strings[] = { static struct usb_function_instance *fi_midi; static struct usb_function *f_midi; -static int __exit midi_unbind(struct usb_composite_dev *dev) +static int midi_unbind(struct usb_composite_dev *dev) { usb_put_function(f_midi); usb_put_function_instance(fi_midi); @@ -133,7 +133,7 @@ static struct usb_configuration midi_config = { .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW, }; -static int __init midi_bind_config(struct usb_configuration *c) +static int midi_bind_config(struct usb_configuration *c) { int status; @@ -150,7 +150,7 @@ static int __init midi_bind_config(struct usb_configuration *c) return 0; } -static int __init midi_bind(struct usb_composite_dev *cdev) +static int midi_bind(struct usb_composite_dev *cdev) { struct f_midi_opts *midi_opts; int status; @@ -185,13 +185,13 @@ put: return status; } -static __refdata struct usb_composite_driver midi_driver = { +static struct usb_composite_driver midi_driver = { .name = (char *) longname, .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = midi_bind, - .unbind = __exit_p(midi_unbind), + .unbind = midi_unbind, }; module_usb_composite_driver(midi_driver); diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 614b06d80b41..2baa572686c6 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -106,7 +106,7 @@ static struct usb_gadget_strings *dev_strings[] = { /****************************** Configurations ******************************/ -static int __init do_config(struct usb_configuration *c) +static int do_config(struct usb_configuration *c) { struct hidg_func_node *e, *n; int status = 0; @@ -147,7 +147,7 @@ static struct usb_configuration config_driver = { /****************************** Gadget Bind ******************************/ -static int __init hid_bind(struct usb_composite_dev *cdev) +static int hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct list_head *tmp; @@ -205,7 +205,7 @@ put: return status; } -static int __exit hid_unbind(struct usb_composite_dev *cdev) +static int hid_unbind(struct usb_composite_dev *cdev) { struct hidg_func_node *n; @@ -216,7 +216,7 @@ static int __exit hid_unbind(struct usb_composite_dev *cdev) return 0; } -static int __init hidg_plat_driver_probe(struct platform_device *pdev) +static int hidg_plat_driver_probe(struct platform_device *pdev) { struct hidg_func_descriptor *func = dev_get_platdata(&pdev->dev); struct hidg_func_node *entry; @@ -252,13 +252,13 @@ static int hidg_plat_driver_remove(struct platform_device *pdev) /****************************** Some noise ******************************/ -static __refdata struct usb_composite_driver hidg_driver = { +static struct usb_composite_driver hidg_driver = { .name = "g_hid", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = hid_bind, - .unbind = __exit_p(hid_unbind), + .unbind = hid_unbind, }; static struct platform_driver hidg_plat_driver = { diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index 8e27a8c96444..e7bfb081f111 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -130,7 +130,7 @@ static int msg_thread_exits(struct fsg_common *common) return 0; } -static int __init msg_do_config(struct usb_configuration *c) +static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; int ret; @@ -170,7 +170,7 @@ static struct usb_configuration msg_config_driver = { /****************************** Gadget Bind ******************************/ -static int __init msg_bind(struct usb_composite_dev *cdev) +static int msg_bind(struct usb_composite_dev *cdev) { static const struct fsg_operations ops = { .thread_exits = msg_thread_exits, @@ -248,7 +248,7 @@ static int msg_unbind(struct usb_composite_dev *cdev) /****************************** Some noise ******************************/ -static __refdata struct usb_composite_driver msg_driver = { +static struct usb_composite_driver msg_driver = { .name = "g_mass_storage", .dev = &msg_device_desc, .max_speed = USB_SPEED_SUPER, diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c index 39d27bb343b4..b21b51f0c9fa 100644 --- a/drivers/usb/gadget/legacy/multi.c +++ b/drivers/usb/gadget/legacy/multi.c @@ -149,7 +149,7 @@ static struct usb_function *f_acm_rndis; static struct usb_function *f_rndis; static struct usb_function *f_msg_rndis; -static __init int rndis_do_config(struct usb_configuration *c) +static int rndis_do_config(struct usb_configuration *c) { struct fsg_opts *fsg_opts; int ret; @@ -237,7 +237,7 @@ static struct usb_function *f_acm_multi; static struct usb_function *f_ecm; static struct usb_function *f_msg_multi; -static __init int cdc_do_config(struct usb_configuration *c) +static int cdc_do_config(struct usb_configuration *c) { struct fsg_opts *fsg_opts; int ret; @@ -466,7 +466,7 @@ fail: return status; } -static int __exit multi_unbind(struct usb_composite_dev *cdev) +static int multi_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_msg_multi); @@ -497,13 +497,13 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev) /****************************** Some noise ******************************/ -static __refdata struct usb_composite_driver multi_driver = { +static struct usb_composite_driver multi_driver = { .name = "g_multi", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = multi_bind, - .unbind = __exit_p(multi_unbind), + .unbind = multi_unbind, .needs_serial = 1, }; diff --git a/drivers/usb/gadget/legacy/ncm.c b/drivers/usb/gadget/legacy/ncm.c index e90e23db2acb..6ce7421412e9 100644 --- a/drivers/usb/gadget/legacy/ncm.c +++ b/drivers/usb/gadget/legacy/ncm.c @@ -107,7 +107,7 @@ static struct usb_function *f_ncm; /*-------------------------------------------------------------------------*/ -static int __init ncm_do_config(struct usb_configuration *c) +static int ncm_do_config(struct usb_configuration *c) { int status; @@ -143,7 +143,7 @@ static struct usb_configuration ncm_config_driver = { /*-------------------------------------------------------------------------*/ -static int __init gncm_bind(struct usb_composite_dev *cdev) +static int gncm_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct f_ncm_opts *ncm_opts; @@ -186,7 +186,7 @@ fail: return status; } -static int __exit gncm_unbind(struct usb_composite_dev *cdev) +static int gncm_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_ncm)) usb_put_function(f_ncm); @@ -195,13 +195,13 @@ static int __exit gncm_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver ncm_driver = { +static struct usb_composite_driver ncm_driver = { .name = "g_ncm", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = gncm_bind, - .unbind = __exit_p(gncm_unbind), + .unbind = gncm_unbind, }; module_usb_composite_driver(ncm_driver); diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c index 9b8fd701648c..4bb498a38a1c 100644 --- a/drivers/usb/gadget/legacy/nokia.c +++ b/drivers/usb/gadget/legacy/nokia.c @@ -118,7 +118,7 @@ static struct usb_function_instance *fi_obex1; static struct usb_function_instance *fi_obex2; static struct usb_function_instance *fi_phonet; -static int __init nokia_bind_config(struct usb_configuration *c) +static int nokia_bind_config(struct usb_configuration *c) { struct usb_function *f_acm; struct usb_function *f_phonet = NULL; @@ -224,7 +224,7 @@ err_get_acm: return status; } -static int __init nokia_bind(struct usb_composite_dev *cdev) +static int nokia_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int status; @@ -307,7 +307,7 @@ err_usb: return status; } -static int __exit nokia_unbind(struct usb_composite_dev *cdev) +static int nokia_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_obex1_cfg2)) usb_put_function(f_obex1_cfg2); @@ -338,13 +338,13 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver nokia_driver = { +static struct usb_composite_driver nokia_driver = { .name = "g_nokia", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = nokia_bind, - .unbind = __exit_p(nokia_unbind), + .unbind = nokia_unbind, }; module_usb_composite_driver(nokia_driver); diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index d5b6ee725a2a..1ce7df1060a5 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -126,7 +126,7 @@ static struct usb_configuration printer_cfg_driver = { .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int __init printer_do_config(struct usb_configuration *c) +static int printer_do_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; int status = 0; @@ -152,7 +152,7 @@ static int __init printer_do_config(struct usb_configuration *c) return status; } -static int __init printer_bind(struct usb_composite_dev *cdev) +static int printer_bind(struct usb_composite_dev *cdev) { struct f_printer_opts *opts; int ret, len; @@ -191,7 +191,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev) return ret; } -static int __exit printer_unbind(struct usb_composite_dev *cdev) +static int printer_unbind(struct usb_composite_dev *cdev) { usb_put_function(f_printer); usb_put_function_instance(fi_printer); @@ -199,7 +199,7 @@ static int __exit printer_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver printer_driver = { +static struct usb_composite_driver printer_driver = { .name = shortname, .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c index 1f5f978d35d5..8b7528f9b78e 100644 --- a/drivers/usb/gadget/legacy/serial.c +++ b/drivers/usb/gadget/legacy/serial.c @@ -174,7 +174,7 @@ out: return ret; } -static int __init gs_bind(struct usb_composite_dev *cdev) +static int gs_bind(struct usb_composite_dev *cdev) { int status; @@ -230,7 +230,7 @@ static int gs_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver gserial_driver = { +static struct usb_composite_driver gserial_driver = { .name = "g_serial", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 8b80addc4ce6..f9b4882fce52 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -2397,7 +2397,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver usbg_driver = { +static struct usb_composite_driver usbg_driver = { .name = "g_target", .dev = &usbg_device_desc, .strings = usbg_strings, diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index 04a3da20f742..72c976bf3530 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -334,7 +334,7 @@ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { * USB configuration */ -static int __init +static int webcam_config_bind(struct usb_configuration *c) { int status = 0; @@ -358,7 +358,7 @@ static struct usb_configuration webcam_config_driver = { .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW, }; -static int /* __init_or_exit */ +static int webcam_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_uvc)) @@ -368,7 +368,7 @@ webcam_unbind(struct usb_composite_dev *cdev) return 0; } -static int __init +static int webcam_bind(struct usb_composite_dev *cdev) { struct f_uvc_opts *uvc_opts; @@ -422,7 +422,7 @@ error: * Driver */ -static __refdata struct usb_composite_driver webcam_driver = { +static struct usb_composite_driver webcam_driver = { .name = "g_webcam", .dev = &webcam_device_descriptor, .strings = webcam_device_strings, diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index 5ee95152493c..c986e8addb90 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -272,7 +272,7 @@ static struct usb_function_instance *func_inst_lb; module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(qlen, "depth of loopback queue"); -static int __init zero_bind(struct usb_composite_dev *cdev) +static int zero_bind(struct usb_composite_dev *cdev) { struct f_ss_opts *ss_opts; struct f_lb_opts *lb_opts; @@ -400,7 +400,7 @@ static int zero_unbind(struct usb_composite_dev *cdev) return 0; } -static __refdata struct usb_composite_driver zero_driver = { +static struct usb_composite_driver zero_driver = { .name = "zero", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 2fbedca3c2b4..fc4226462f8f 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1942,7 +1942,7 @@ err_unprepare_fclk: return retval; } -static int __exit at91udc_remove(struct platform_device *pdev) +static int at91udc_remove(struct platform_device *pdev) { struct at91_udc *udc = platform_get_drvdata(pdev); unsigned long flags; @@ -2018,7 +2018,7 @@ static int at91udc_resume(struct platform_device *pdev) #endif static struct platform_driver at91_udc_driver = { - .remove = __exit_p(at91udc_remove), + .remove = at91udc_remove, .shutdown = at91udc_shutdown, .suspend = at91udc_suspend, .resume = at91udc_resume, diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 4c01953a0869..351d48550c33 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -2186,7 +2186,7 @@ static int usba_udc_probe(struct platform_device *pdev) return 0; } -static int __exit usba_udc_remove(struct platform_device *pdev) +static int usba_udc_remove(struct platform_device *pdev) { struct usba_udc *udc; int i; @@ -2258,7 +2258,7 @@ static int usba_udc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(usba_udc_pm_ops, usba_udc_suspend, usba_udc_resume); static struct platform_driver udc_driver = { - .remove = __exit_p(usba_udc_remove), + .remove = usba_udc_remove, .driver = { .name = "atmel_usba_udc", .pm = &usba_udc_pm_ops, diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 55fcb930f92e..c60022b46a48 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2525,7 +2525,7 @@ err_kfree: /* Driver removal function * Free resources and finish pending transactions */ -static int __exit fsl_udc_remove(struct platform_device *pdev) +static int fsl_udc_remove(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -2663,7 +2663,7 @@ static const struct platform_device_id fsl_udc_devtype[] = { }; MODULE_DEVICE_TABLE(platform, fsl_udc_devtype); static struct platform_driver udc_driver = { - .remove = __exit_p(fsl_udc_remove), + .remove = fsl_udc_remove, /* Just for FSL i.mx SoC currently */ .id_table = fsl_udc_devtype, /* these suspend and resume are not usb suspend and resume */ diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index fb4df159d32d..3970f453de49 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1342,7 +1342,7 @@ static const struct usb_gadget_ops fusb300_gadget_ops = { .udc_stop = fusb300_udc_stop, }; -static int __exit fusb300_remove(struct platform_device *pdev) +static int fusb300_remove(struct platform_device *pdev) { struct fusb300 *fusb300 = platform_get_drvdata(pdev); @@ -1492,7 +1492,7 @@ clean_up: } static struct platform_driver fusb300_driver = { - .remove = __exit_p(fusb300_remove), + .remove = fusb300_remove, .driver = { .name = (char *) udc_name, }, diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 8c7c83c93713..309706fe4bf0 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1528,7 +1528,7 @@ static const struct usb_gadget_ops m66592_gadget_ops = { .pullup = m66592_pullup, }; -static int __exit m66592_remove(struct platform_device *pdev) +static int m66592_remove(struct platform_device *pdev) { struct m66592 *m66592 = platform_get_drvdata(pdev); @@ -1695,7 +1695,7 @@ clean_up: /*-------------------------------------------------------------------------*/ static struct platform_driver m66592_driver = { - .remove = __exit_p(m66592_remove), + .remove = m66592_remove, .driver = { .name = (char *) udc_name, }, diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 2495fe9c95c5..0293f7169dee 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1820,7 +1820,7 @@ static const struct usb_gadget_ops r8a66597_gadget_ops = { .set_selfpowered = r8a66597_set_selfpowered, }; -static int __exit r8a66597_remove(struct platform_device *pdev) +static int r8a66597_remove(struct platform_device *pdev) { struct r8a66597 *r8a66597 = platform_get_drvdata(pdev); @@ -1974,7 +1974,7 @@ clean_up2: /*-------------------------------------------------------------------------*/ static struct platform_driver r8a66597_driver = { - .remove = __exit_p(r8a66597_remove), + .remove = r8a66597_remove, .driver = { .name = (char *) udc_name, }, diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index b808951491cc..99fd9a5667df 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -1487,7 +1487,7 @@ static int s3c2410_udc_pullup(struct usb_gadget *gadget, int is_on) dprintk(DEBUG_NORMAL, "%s()\n", __func__); - s3c2410_udc_set_pullup(udc, is_on ? 0 : 1); + s3c2410_udc_set_pullup(udc, is_on); return 0; } diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index dd3e9fd31b80..1f24274477ab 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -2071,8 +2071,8 @@ static int xudc_probe(struct platform_device *pdev) /* Map the registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); udc->addr = devm_ioremap_resource(&pdev->dev, res); - if (!udc->addr) - return -ENOMEM; + if (IS_ERR(udc->addr)) + return PTR_ERR(udc->addr); irq = platform_get_irq(pdev, 0); if (irq < 0) { diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f5397a517c54..7d34cbfaf373 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2026,8 +2026,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, break; case COMP_DEV_ERR: case COMP_STALL: + frame->status = -EPROTO; + skip_td = true; + break; case COMP_TX_ERR: frame->status = -EPROTO; + if (event_trb != td->last_trb) + return 0; skip_td = true; break; case COMP_STOP: @@ -2640,7 +2645,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) xhci_halt(xhci); hw_died: spin_unlock(&xhci->lock); - return -ESHUTDOWN; + return IRQ_HANDLED; } /* diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac1674854..36bf089b708f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3682,18 +3682,21 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); unsigned long flags; - int ret; + int ret, slot_id; struct xhci_command *command; command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); if (!command) return 0; + /* xhci->slot_id and xhci->addr_dev are not thread-safe */ + mutex_lock(&xhci->mutex); spin_lock_irqsave(&xhci->lock, flags); command->completion = &xhci->addr_dev; ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); + mutex_unlock(&xhci->mutex); xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); kfree(command); return 0; @@ -3702,8 +3705,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) spin_unlock_irqrestore(&xhci->lock, flags); wait_for_completion(command->completion); + slot_id = xhci->slot_id; + mutex_unlock(&xhci->mutex); - if (!xhci->slot_id || command->status != COMP_SUCCESS) { + if (!slot_id || command->status != COMP_SUCCESS) { xhci_err(xhci, "Error while assigning device slot ID\n"); xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", HCS_MAX_SLOTS( @@ -3728,11 +3733,11 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) * xhci_discover_or_reset_device(), which may be called as part of * mass storage driver error handling. */ - if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { + if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) { xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); goto disable_slot; } - udev->slot_id = xhci->slot_id; + udev->slot_id = slot_id; #ifndef CONFIG_USB_DEFAULT_PERSIST /* @@ -3778,12 +3783,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; u64 temp_64; - struct xhci_command *command; + struct xhci_command *command = NULL; + + mutex_lock(&xhci->mutex); if (!udev->slot_id) { xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Bad Slot ID %d", udev->slot_id); - return -EINVAL; + ret = -EINVAL; + goto out; } virt_dev = xhci->devs[udev->slot_id]; @@ -3796,7 +3804,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, */ xhci_warn(xhci, "Virt dev invalid for slot_id 0x%x!\n", udev->slot_id); - return -EINVAL; + ret = -EINVAL; + goto out; } if (setup == SETUP_CONTEXT_ONLY) { @@ -3804,13 +3813,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == SLOT_STATE_DEFAULT) { xhci_dbg(xhci, "Slot already in default state\n"); - return 0; + goto out; } } command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); - if (!command) - return -ENOMEM; + if (!command) { + ret = -ENOMEM; + goto out; + } command->in_ctx = virt_dev->in_ctx; command->completion = &xhci->addr_dev; @@ -3820,8 +3831,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); - kfree(command); - return -EINVAL; + ret = -EINVAL; + goto out; } /* * If this is the first Set Address since device plug-in or @@ -3848,8 +3859,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg_trace(xhci, trace_xhci_dbg_address, "FIXME: allocate a command ring segment"); - kfree(command); - return ret; + goto out; } xhci_ring_cmd_db(xhci); spin_unlock_irqrestore(&xhci->lock, flags); @@ -3896,10 +3906,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, ret = -EINVAL; break; } - if (ret) { - kfree(command); - return ret; - } + if (ret) + goto out; temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Op regs DCBAA ptr = %#016llx", temp_64); @@ -3932,8 +3940,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Internal device address = %d", le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); +out: + mutex_unlock(&xhci->mutex); kfree(command); - return 0; + return ret; } int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) @@ -4855,6 +4865,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) return 0; } + mutex_init(&xhci->mutex); xhci->cap_regs = hcd->regs; xhci->op_regs = hcd->regs + HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)); @@ -5011,4 +5022,12 @@ static int __init xhci_hcd_init(void) BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); return 0; } + +/* + * If an init function is provided, an exit function must also be provided + * to allow module unload. + */ +static void __exit xhci_hcd_fini(void) { } + module_init(xhci_hcd_init); +module_exit(xhci_hcd_fini); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8e421b89632d..6977f8491fa7 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1267,7 +1267,7 @@ union xhci_trb { * since the command ring is 64-byte aligned. * It must also be greater than 16. */ -#define TRBS_PER_SEGMENT 64 +#define TRBS_PER_SEGMENT 256 /* Allow two commands + a link TRB, along with any reserved command TRBs */ #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) @@ -1497,6 +1497,8 @@ struct xhci_hcd { struct list_head lpm_failed_devs; /* slot enabling and address device helpers */ + /* these are not thread safe so use mutex */ + struct mutex mutex; struct completion addr_dev; int slot_id; /* For USB 3.0 LPM enable/disable. */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3789b08ef67b..6dca3d794ced 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2021,13 +2021,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (musb->ops->quirks) musb->io.quirks = musb->ops->quirks; - /* At least tusb6010 has it's own offsets.. */ - if (musb->ops->ep_offset) - musb->io.ep_offset = musb->ops->ep_offset; - if (musb->ops->ep_select) - musb->io.ep_select = musb->ops->ep_select; - - /* ..and some devices use indexed offset or flat offset */ + /* Most devices use indexed offset or flat offset */ if (musb->io.quirks & MUSB_INDEXED_EP) { musb->io.ep_offset = musb_indexed_ep_offset; musb->io.ep_select = musb_indexed_ep_select; @@ -2036,6 +2030,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->io.ep_select = musb_flat_ep_select; } + /* At least tusb6010 has its own offsets */ + if (musb->ops->ep_offset) + musb->io.ep_offset = musb->ops->ep_offset; + if (musb->ops->ep_select) + musb->io.ep_select = musb->ops->ep_select; + if (musb->ops->fifo_mode) fifo_mode = musb->ops->fifo_mode; else diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 7225d526df04..03ab0c699f74 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -1179,7 +1179,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, } err = devm_request_threaded_irq(&pdev->dev, irq, NULL, ab8500_usb_link_status_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, + IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, "usb-link-status", ab); if (err < 0) { dev_err(ab->dev, "request_irq failed for link status irq\n"); @@ -1195,7 +1195,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, } err = devm_request_threaded_irq(&pdev->dev, irq, NULL, ab8500_usb_disconnect_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, + IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, "usb-id-fall", ab); if (err < 0) { dev_err(ab->dev, "request_irq failed for ID fall irq\n"); @@ -1211,7 +1211,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, } err = devm_request_threaded_irq(&pdev->dev, irq, NULL, ab8500_usb_disconnect_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, + IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, "usb-vbus-fall", ab); if (err < 0) { dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 1e0e10dd6ba5..3af263cc0caa 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -94,7 +94,7 @@ struct isp1301 { #if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) -#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) +#if defined(CONFIG_TPS65010) || (defined(CONFIG_TPS65010_MODULE) && defined(MODULE)) #include <linux/i2c/tps65010.h> diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index 845f658276b1..2b28443d07b9 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -401,7 +401,8 @@ static int tahvo_usb_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, tu); tu->irq = platform_get_irq(pdev, 0); - ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, 0, + ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, + IRQF_ONESHOT, "tahvo-vbus", tu); if (ret) { dev_err(&pdev->dev, "could not register tahvo-vbus irq: %d\n", diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 8597cf9cfceb..c0f5c652d272 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -611,6 +611,8 @@ struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) { struct usbhs_pipe *pipe = pkt->pipe; + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); if (usbhs_pipe_is_busy(pipe)) return 0; @@ -624,6 +626,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) usbhs_pipe_data_sequence(pipe, pkt->sequence); pkt->sequence = -1; /* -1 sequence will be ignored */ + if (usbhs_pipe_is_dcp(pipe)) + usbhsf_fifo_clear(pipe, fifo); + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); usbhs_pipe_enable(pipe); usbhs_pipe_running(pipe, 1); @@ -673,7 +678,14 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) *is_done = 1; usbhsf_rx_irq_ctrl(pipe, 0); usbhs_pipe_running(pipe, 0); - usbhs_pipe_disable(pipe); /* disable pipe first */ + /* + * If function mode, since this controller is possible to enter + * Control Write status stage at this timing, this driver + * should not disable the pipe. If such a case happens, this + * controller is not able to complete the status stage. + */ + if (!usbhs_mod_is_host(priv) && !usbhs_pipe_is_dcp(pipe)) + usbhs_pipe_disable(pipe); /* disable pipe first */ } /* @@ -1227,15 +1239,21 @@ static void usbhsf_dma_init_dt(struct device *dev, struct usbhs_fifo *fifo, { char name[16]; - snprintf(name, sizeof(name), "tx%d", channel); - fifo->tx_chan = dma_request_slave_channel_reason(dev, name); - if (IS_ERR(fifo->tx_chan)) - fifo->tx_chan = NULL; - - snprintf(name, sizeof(name), "rx%d", channel); - fifo->rx_chan = dma_request_slave_channel_reason(dev, name); - if (IS_ERR(fifo->rx_chan)) - fifo->rx_chan = NULL; + /* + * To avoid complex handing for DnFIFOs, the driver uses each + * DnFIFO as TX or RX direction (not bi-direction). + * So, the driver uses odd channels for TX, even channels for RX. + */ + snprintf(name, sizeof(name), "ch%d", channel); + if (channel & 1) { + fifo->tx_chan = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(fifo->tx_chan)) + fifo->tx_chan = NULL; + } else { + fifo->rx_chan = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(fifo->rx_chan)) + fifo->rx_chan = NULL; + } } static void usbhsf_dma_init(struct usbhs_priv *priv, struct usbhs_fifo *fifo, diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 84ce2d74894c..ffd739e31bfc 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -127,6 +127,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8eb68a31cab6..4c8b3b82103d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -699,6 +699,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4e4f46f3c89c..792e054126de 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -155,6 +155,7 @@ #define XSENS_AWINDA_STATION_PID 0x0101 #define XSENS_AWINDA_DONGLE_PID 0x0102 #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ +#define XSENS_MTDEVBOARD_PID 0x0300 /* Motion Tracker Development Board */ #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ /* Xsens devices using FTDI VID */ diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 829604d11f3f..f5257af33ecf 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -61,7 +61,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1), .driver_info = PL2303_QUIRK_UART_STATE_IDX0 }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65), diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 71fd9da1d6e7..e3b7af8adfb7 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -62,10 +62,6 @@ #define ALCATEL_VENDOR_ID 0x11f7 #define ALCATEL_PRODUCT_ID 0x02df -/* Samsung I330 phone cradle */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_ID 0x8001 - #define SIEMENS_VENDOR_ID 0x11f5 #define SIEMENS_PRODUCT_ID_SX1 0x0001 #define SIEMENS_PRODUCT_ID_X65 0x0003 diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index bf2bd40e5f2a..60afb39eb73c 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -95,7 +95,7 @@ static const struct usb_device_id id_table[] = { .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), + { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d684b4b8108f..caf188800c67 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -766,6 +766,13 @@ UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_GO_SLOW ), +/* Reported by Christian Schaller <cschalle@redhat.com> */ +UNUSUAL_DEV( 0x059f, 0x0651, 0x0000, 0x0000, + "LaCie", + "External HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + /* Submitted by Joel Bourquard <numlock@freesurf.ch> * Some versions of this device need the SubClass and Protocol overrides * while others don't. diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 69fab0fd15ae..e9851add6f4e 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -907,8 +907,14 @@ static void vfio_pci_request(void *device_data, unsigned int count) mutex_lock(&vdev->igate); if (vdev->req_trigger) { - dev_dbg(&vdev->pdev->dev, "Requesting device from user\n"); + if (!(count % 10)) + dev_notice_ratelimited(&vdev->pdev->dev, + "Relaying device request to user (#%u)\n", + count); eventfd_signal(vdev->req_trigger, 1); + } else if (count == 0) { + dev_warn(&vdev->pdev->dev, + "No device request channel registered, blocked until released by user\n"); } mutex_unlock(&vdev->igate); diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 0d336625ac71..e1278fe04b1e 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -710,6 +710,8 @@ void *vfio_del_group_dev(struct device *dev) void *device_data = device->device_data; struct vfio_unbound_dev *unbound; unsigned int i = 0; + long ret; + bool interrupted = false; /* * The group exists so long as we have a device reference. Get @@ -755,9 +757,22 @@ void *vfio_del_group_dev(struct device *dev) vfio_device_put(device); - } while (wait_event_interruptible_timeout(vfio.release_q, - !vfio_dev_present(group, dev), - HZ * 10) <= 0); + if (interrupted) { + ret = wait_event_timeout(vfio.release_q, + !vfio_dev_present(group, dev), HZ * 10); + } else { + ret = wait_event_interruptible_timeout(vfio.release_q, + !vfio_dev_present(group, dev), HZ * 10); + if (ret == -ERESTARTSYS) { + interrupted = true; + dev_warn(dev, + "Device is currently in use, task" + " \"%s\" (%d) " + "blocked until device is released", + current->comm, task_pid_nr(current)); + } + } + } while (ret <= 0); vfio_group_put(group); diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 5e19bb53b3a9..ea32b386797f 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -1409,8 +1409,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs, * dependency now. */ se_tpg = &tpg->se_tpg; - ret = configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys, - &se_tpg->tpg_group.cg_item); + ret = target_depend_item(&se_tpg->tpg_group.cg_item); if (ret) { pr_warn("configfs_depend_item() failed: %d\n", ret); kfree(vs_tpg); @@ -1513,8 +1512,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs, * to allow vhost-scsi WWPN se_tpg->tpg_group shutdown to occur. */ se_tpg = &tpg->se_tpg; - configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys, - &se_tpg->tpg_group.cg_item); + target_undepend_item(&se_tpg->tpg_group.cg_item); } if (match) { for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 3a145a643e0d..6897f1c1bc73 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -274,6 +274,10 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(pb->pwm)) { + ret = PTR_ERR(pb->pwm); + if (ret == -EPROBE_DEFER) + goto err_alloc; + dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); pb->legacy = true; pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c index 5db43fc100a4..7dd46312c180 100644 --- a/drivers/xen/events/events_2l.c +++ b/drivers/xen/events/events_2l.c @@ -345,6 +345,15 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static void evtchn_2l_resume(void) +{ + int i; + + for_each_online_cpu(i) + memset(per_cpu(cpu_evtchn_mask, i), 0, sizeof(xen_ulong_t) * + EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); +} + static const struct evtchn_ops evtchn_ops_2l = { .max_channels = evtchn_2l_max_channels, .nr_channels = evtchn_2l_max_channels, @@ -356,6 +365,7 @@ static const struct evtchn_ops evtchn_ops_2l = { .mask = evtchn_2l_mask, .unmask = evtchn_2l_unmask, .handle_events = evtchn_2l_handle_events, + .resume = evtchn_2l_resume, }; void __init xen_evtchn_2l_init(void) diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 70fba973a107..38387950490e 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -529,8 +529,8 @@ static unsigned int __startup_pirq(unsigned int irq) if (rc) goto err; - bind_evtchn_to_cpu(evtchn, 0); info->evtchn = evtchn; + bind_evtchn_to_cpu(evtchn, 0); rc = xen_evtchn_port_setup(info); if (rc) @@ -957,7 +957,7 @@ unsigned xen_evtchn_nr_channels(void) } EXPORT_SYMBOL_GPL(xen_evtchn_nr_channels); -int bind_virq_to_irq(unsigned int virq, unsigned int cpu) +int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu) { struct evtchn_bind_virq bind_virq; int evtchn, irq, ret; @@ -971,8 +971,12 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) if (irq < 0) goto out; - irq_set_chip_and_handler_name(irq, &xen_percpu_chip, - handle_percpu_irq, "virq"); + if (percpu) + irq_set_chip_and_handler_name(irq, &xen_percpu_chip, + handle_percpu_irq, "virq"); + else + irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, + handle_edge_irq, "virq"); bind_virq.virq = virq; bind_virq.vcpu = cpu; @@ -1062,7 +1066,7 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, { int irq, retval; - irq = bind_virq_to_irq(virq, cpu); + irq = bind_virq_to_irq(virq, cpu, irqflags & IRQF_PERCPU); if (irq < 0) return irq; retval = request_irq(irq, handler, irqflags, devname, dev_id); @@ -1279,8 +1283,9 @@ void rebind_evtchn_irq(int evtchn, int irq) mutex_unlock(&irq_mapping_update_lock); - /* new event channels are always bound to cpu 0 */ - irq_set_affinity(irq, cpumask_of(0)); + bind_evtchn_to_cpu(evtchn, info->cpu); + /* This will be deferred until interrupt is processed */ + irq_set_affinity(irq, cpumask_of(info->cpu)); /* Unmask the event channel. */ enable_irq(irq); diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index d5bb1a33d0a3..89274850741b 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -327,30 +327,10 @@ static int map_grant_pages(struct grant_map *map) return err; } -struct unmap_grant_pages_callback_data -{ - struct completion completion; - int result; -}; - -static void unmap_grant_callback(int result, - struct gntab_unmap_queue_data *data) -{ - struct unmap_grant_pages_callback_data* d = data->data; - - d->result = result; - complete(&d->completion); -} - static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) { int i, err = 0; struct gntab_unmap_queue_data unmap_data; - struct unmap_grant_pages_callback_data data; - - init_completion(&data.completion); - unmap_data.data = &data; - unmap_data.done= &unmap_grant_callback; if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { int pgno = (map->notify.addr >> PAGE_SHIFT); @@ -367,11 +347,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) unmap_data.pages = map->pages + offset; unmap_data.count = pages; - gnttab_unmap_refs_async(&unmap_data); - - wait_for_completion(&data.completion); - if (data.result) - return data.result; + err = gnttab_unmap_refs_sync(&unmap_data); + if (err) + return err; for (i = 0; i < pages; i++) { if (map->unmap_ops[offset+i].status) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 17972fbacddc..b1c7170e5c9e 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -123,6 +123,11 @@ struct gnttab_ops { int (*query_foreign_access)(grant_ref_t ref); }; +struct unmap_refs_callback_data { + struct completion completion; + int result; +}; + static struct gnttab_ops *gnttab_interface; static int grant_table_version; @@ -863,6 +868,29 @@ void gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item) } EXPORT_SYMBOL_GPL(gnttab_unmap_refs_async); +static void unmap_refs_callback(int result, + struct gntab_unmap_queue_data *data) +{ + struct unmap_refs_callback_data *d = data->data; + + d->result = result; + complete(&d->completion); +} + +int gnttab_unmap_refs_sync(struct gntab_unmap_queue_data *item) +{ + struct unmap_refs_callback_data data; + + init_completion(&data.completion); + item->data = &data; + item->done = &unmap_refs_callback; + gnttab_unmap_refs_async(item); + wait_for_completion(&data.completion); + + return data.result; +} +EXPORT_SYMBOL_GPL(gnttab_unmap_refs_sync); + static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) { int rc; diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index bf1940706422..9e6a85104a20 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -131,6 +131,8 @@ static void do_suspend(void) goto out_resume; } + xen_arch_suspend(); + si.cancelled = 1; err = stop_machine(xen_suspend, &si, cpumask_of(0)); @@ -148,11 +150,12 @@ static void do_suspend(void) si.cancelled = 1; } + xen_arch_resume(); + out_resume: - if (!si.cancelled) { - xen_arch_resume(); + if (!si.cancelled) xs_resume(); - } else + else xs_suspend_cancel(); dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 810ad419e34c..4c549323c605 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -235,7 +235,7 @@ retry: #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { - xen_io_tlb_start = (void *)__get_free_pages(__GFP_NOWARN, order); + xen_io_tlb_start = (void *)xen_get_swiotlb_free_pages(order); if (xen_io_tlb_start) break; order--; diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c index 75fe3d466515..9c234209d8b5 100644 --- a/drivers/xen/xen-pciback/conf_space.c +++ b/drivers/xen/xen-pciback/conf_space.c @@ -16,8 +16,8 @@ #include "conf_space.h" #include "conf_space_quirks.h" -bool permissive; -module_param(permissive, bool, 0644); +bool xen_pcibk_permissive; +module_param_named(permissive, xen_pcibk_permissive, bool, 0644); /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, * xen_pcibk_write_config_word, and xen_pcibk_write_config_byte are created. */ @@ -262,7 +262,7 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) * This means that some fields may still be read-only because * they have entries in the config_field list that intercept * the write and do nothing. */ - if (dev_data->permissive || permissive) { + if (dev_data->permissive || xen_pcibk_permissive) { switch (size) { case 1: err = pci_write_config_byte(dev, offset, diff --git a/drivers/xen/xen-pciback/conf_space.h b/drivers/xen/xen-pciback/conf_space.h index 2e1d73d1d5d0..62461a8ba1d6 100644 --- a/drivers/xen/xen-pciback/conf_space.h +++ b/drivers/xen/xen-pciback/conf_space.h @@ -64,7 +64,7 @@ struct config_field_entry { void *data; }; -extern bool permissive; +extern bool xen_pcibk_permissive; #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index c2260a0456c9..ad3d17d29c81 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c @@ -118,7 +118,7 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) cmd->val = value; - if (!permissive && (!dev_data || !dev_data->permissive)) + if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive)) return 0; /* Only allow the guest to control certain bits. */ diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 564b31584860..5390a674b5e3 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -57,6 +57,7 @@ #include <xen/xen.h> #include <xen/xenbus.h> #include <xen/events.h> +#include <xen/xen-ops.h> #include <xen/page.h> #include <xen/hvm.h> @@ -735,6 +736,30 @@ static int __init xenstored_local_init(void) return err; } +static int xenbus_resume_cb(struct notifier_block *nb, + unsigned long action, void *data) +{ + int err = 0; + + if (xen_hvm_domain()) { + uint64_t v; + + err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); + if (!err && v) + xen_store_evtchn = v; + else + pr_warn("Cannot update xenstore event channel: %d\n", + err); + } else + xen_store_evtchn = xen_start_info->store_evtchn; + + return err; +} + +static struct notifier_block xenbus_resume_nb = { + .notifier_call = xenbus_resume_cb, +}; + static int __init xenbus_init(void) { int err = 0; @@ -793,6 +818,10 @@ static int __init xenbus_init(void) goto out_error; } + if ((xen_store_domain_type != XS_LOCAL) && + (xen_store_domain_type != XS_UNKNOWN)) + xen_resume_notifier_register(&xenbus_resume_nb); + #ifdef CONFIG_XEN_COMPAT_XENFS /* * Create xenfs mountpoint in /proc for compatibility with diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 241ef68d2893..cd46e4158830 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -918,7 +918,7 @@ static int load_elf_binary(struct linux_binprm *bprm) total_size = total_mapping_size(elf_phdata, loc->elf_ex.e_phnum); if (!total_size) { - error = -EINVAL; + retval = -EINVAL; goto out_free_dentry; } } diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 9de772ee0031..614aaa1969bd 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -880,6 +880,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, * indirect refs to their parent bytenr. * When roots are found, they're added to the roots list * + * NOTE: This can return values > 0 + * * FIXME some caching might speed things up */ static int find_parent_nodes(struct btrfs_trans_handle *trans, @@ -1198,6 +1200,19 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, return ret; } +/** + * btrfs_check_shared - tell us whether an extent is shared + * + * @trans: optional trans handle + * + * btrfs_check_shared uses the backref walking code but will short + * circuit as soon as it finds a root or inode that doesn't match the + * one passed in. This provides a significant performance benefit for + * callers (such as fiemap) which want to know whether the extent is + * shared but do not need a ref count. + * + * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error. + */ int btrfs_check_shared(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 root_objectid, u64 inum, u64 bytenr) @@ -1226,11 +1241,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans, ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp, roots, NULL, root_objectid, inum); if (ret == BACKREF_FOUND_SHARED) { + /* this is the only condition under which we return 1 */ ret = 1; break; } if (ret < 0 && ret != -ENOENT) break; + ret = 0; node = ulist_next(tmp, &uiter); if (!node) break; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0ec8e228b89f..0ec3acd14cbf 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3180,8 +3180,6 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); fail: btrfs_release_path(path); - if (ret) - btrfs_abort_transaction(trans, root, ret); return ret; } @@ -3487,8 +3485,30 @@ again: ret = 0; } } - if (!ret) + if (!ret) { ret = write_one_cache_group(trans, root, path, cache); + /* + * Our block group might still be attached to the list + * of new block groups in the transaction handle of some + * other task (struct btrfs_trans_handle->new_bgs). This + * means its block group item isn't yet in the extent + * tree. If this happens ignore the error, as we will + * try again later in the critical section of the + * transaction commit. + */ + if (ret == -ENOENT) { + ret = 0; + spin_lock(&cur_trans->dirty_bgs_lock); + if (list_empty(&cache->dirty_list)) { + list_add_tail(&cache->dirty_list, + &cur_trans->dirty_bgs); + btrfs_get_block_group(cache); + } + spin_unlock(&cur_trans->dirty_bgs_lock); + } else if (ret) { + btrfs_abort_transaction(trans, root, ret); + } + } /* if its not on the io list, we need to put the block group */ if (should_put) @@ -3597,8 +3617,11 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, ret = 0; } } - if (!ret) + if (!ret) { ret = write_one_cache_group(trans, root, path, cache); + if (ret) + btrfs_abort_transaction(trans, root, ret); + } /* if its not on the io list, we need to put the block group */ if (should_put) @@ -8806,6 +8829,24 @@ again: goto again; } + /* + * if we are changing raid levels, try to allocate a corresponding + * block group with the new raid level. + */ + alloc_flags = update_block_group_flags(root, cache->flags); + if (alloc_flags != cache->flags) { + ret = do_chunk_alloc(trans, root, alloc_flags, + CHUNK_ALLOC_FORCE); + /* + * ENOSPC is allowed here, we may have enough space + * already allocated at the new raid level to + * carry on + */ + if (ret == -ENOSPC) + ret = 0; + if (ret < 0) + goto out; + } ret = set_block_group_ro(cache, 0); if (!ret) @@ -8819,7 +8860,9 @@ again: out: if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) { alloc_flags = update_block_group_flags(root, cache->flags); + lock_chunks(root->fs_info->chunk_root); check_system_chunk(trans, root, alloc_flags); + unlock_chunks(root->fs_info->chunk_root); } mutex_unlock(&root->fs_info->ro_block_group_mutex); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 43af5a61ad25..c32d226bfecc 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4772,6 +4772,25 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, start >> PAGE_CACHE_SHIFT); if (eb && atomic_inc_not_zero(&eb->refs)) { rcu_read_unlock(); + /* + * Lock our eb's refs_lock to avoid races with + * free_extent_buffer. When we get our eb it might be flagged + * with EXTENT_BUFFER_STALE and another task running + * free_extent_buffer might have seen that flag set, + * eb->refs == 2, that the buffer isn't under IO (dirty and + * writeback flags not set) and it's still in the tree (flag + * EXTENT_BUFFER_TREE_REF set), therefore being in the process + * of decrementing the extent buffer's reference count twice. + * So here we could race and increment the eb's reference count, + * clear its stale flag, mark it as dirty and drop our reference + * before the other task finishes executing free_extent_buffer, + * which would later result in an attempt to free an extent + * buffer that is dirty. + */ + if (test_bit(EXTENT_BUFFER_STALE, &eb->bflags)) { + spin_lock(&eb->refs_lock); + spin_unlock(&eb->refs_lock); + } mark_extent_buffer_accessed(eb, NULL); return eb; } diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 41c510b7cc11..9dbe5b548fa6 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -86,7 +86,7 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, mapping_set_gfp_mask(inode->i_mapping, mapping_gfp_mask(inode->i_mapping) & - ~(GFP_NOFS & ~__GFP_HIGHMEM)); + ~(__GFP_FS | __GFP_HIGHMEM)); return inode; } @@ -3466,6 +3466,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; int ret; struct btrfs_io_ctl io_ctl; + bool release_metadata = true; if (!btrfs_test_opt(root, INODE_MAP_CACHE)) return 0; @@ -3473,11 +3474,20 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, memset(&io_ctl, 0, sizeof(io_ctl)); ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, trans, path, 0); - if (!ret) + if (!ret) { + /* + * At this point writepages() didn't error out, so our metadata + * reservation is released when the writeback finishes, at + * inode.c:btrfs_finish_ordered_io(), regardless of it finishing + * with or without an error. + */ + release_metadata = false; ret = btrfs_wait_cache_io(root, trans, NULL, &io_ctl, path, 0); + } if (ret) { - btrfs_delalloc_release_metadata(inode, inode->i_size); + if (release_metadata) + btrfs_delalloc_release_metadata(inode, inode->i_size); #ifdef DEBUG btrfs_err(root->fs_info, "failed to write free ino cache for root %llu", diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 157cc54fc634..760c4a5e096b 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -722,6 +722,7 @@ void btrfs_start_ordered_extent(struct inode *inode, int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) { int ret = 0; + int ret_wb = 0; u64 end; u64 orig_end; struct btrfs_ordered_extent *ordered; @@ -741,9 +742,14 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) if (ret) return ret; - ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end); - if (ret) - return ret; + /* + * If we have a writeback error don't return immediately. Wait first + * for any ordered extents that haven't completed yet. This is to make + * sure no one can dirty the same page ranges and call writepages() + * before the ordered extents complete - to avoid failures (-EEXIST) + * when adding the new ordered extents to the ordered tree. + */ + ret_wb = filemap_fdatawait_range(inode->i_mapping, start, orig_end); end = orig_end; while (1) { @@ -767,7 +773,7 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) break; end--; } - return ret; + return ret_wb ? ret_wb : ret; } /* diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 96aebf3bcd5b..174f5e1e00ab 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -4625,6 +4625,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, { u64 chunk_offset; + ASSERT(mutex_is_locked(&extent_root->fs_info->chunk_mutex)); chunk_offset = find_next_chunk(extent_root->fs_info); return __btrfs_alloc_chunk(trans, extent_root, chunk_offset, type); } diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 430e0348c99e..7dc886c9a78f 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -24,6 +24,7 @@ #include "cifsfs.h" #include "dns_resolve.h" #include "cifs_debug.h" +#include "cifs_unicode.h" static LIST_HEAD(cifs_dfs_automount_list); @@ -312,7 +313,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) xid = get_xid(); rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, &num_referrals, &referrals, - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_remap(cifs_sb)); free_xid(xid); cifs_put_tlink(tlink); diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 0303c6793d90..5a53ac6b1e02 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -27,41 +27,6 @@ #include "cifsglob.h" #include "cifs_debug.h" -/* - * cifs_utf16_bytes - how long will a string be after conversion? - * @utf16 - pointer to input string - * @maxbytes - don't go past this many bytes of input string - * @codepage - destination codepage - * - * Walk a utf16le string and return the number of bytes that the string will - * be after being converted to the given charset, not including any null - * termination required. Don't walk past maxbytes in the source buffer. - */ -int -cifs_utf16_bytes(const __le16 *from, int maxbytes, - const struct nls_table *codepage) -{ - int i; - int charlen, outlen = 0; - int maxwords = maxbytes / 2; - char tmp[NLS_MAX_CHARSET_SIZE]; - __u16 ftmp; - - for (i = 0; i < maxwords; i++) { - ftmp = get_unaligned_le16(&from[i]); - if (ftmp == 0) - break; - - charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); - if (charlen > 0) - outlen += charlen; - else - outlen++; - } - - return outlen; -} - int cifs_remap(struct cifs_sb_info *cifs_sb) { int map_type; @@ -155,10 +120,13 @@ convert_sfm_char(const __u16 src_char, char *target) * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE). */ static int -cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, +cifs_mapchar(char *target, const __u16 *from, const struct nls_table *cp, int maptype) { int len = 1; + __u16 src_char; + + src_char = *from; if ((maptype == SFM_MAP_UNI_RSVD) && convert_sfm_char(src_char, target)) return len; @@ -168,10 +136,23 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, /* if character not one of seven in special remap set */ len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); - if (len <= 0) { - *target = '?'; - len = 1; - } + if (len <= 0) + goto surrogate_pair; + + return len; + +surrogate_pair: + /* convert SURROGATE_PAIR and IVS */ + if (strcmp(cp->charset, "utf8")) + goto unknown; + len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6); + if (len <= 0) + goto unknown; + return len; + +unknown: + *target = '?'; + len = 1; return len; } @@ -206,7 +187,7 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, int nullsize = nls_nullsize(codepage); int fromwords = fromlen / 2; char tmp[NLS_MAX_CHARSET_SIZE]; - __u16 ftmp; + __u16 ftmp[3]; /* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */ /* * because the chars can be of varying widths, we need to take care @@ -217,9 +198,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize); for (i = 0; i < fromwords; i++) { - ftmp = get_unaligned_le16(&from[i]); - if (ftmp == 0) + ftmp[0] = get_unaligned_le16(&from[i]); + if (ftmp[0] == 0) break; + if (i + 1 < fromwords) + ftmp[1] = get_unaligned_le16(&from[i + 1]); + else + ftmp[1] = 0; + if (i + 2 < fromwords) + ftmp[2] = get_unaligned_le16(&from[i + 2]); + else + ftmp[2] = 0; /* * check to see if converting this character might make the @@ -234,6 +223,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, /* put converted char into 'to' buffer */ charlen = cifs_mapchar(&to[outlen], ftmp, codepage, map_type); outlen += charlen; + + /* charlen (=bytes of UTF-8 for 1 character) + * 4bytes UTF-8(surrogate pair) is charlen=4 + * (4bytes UTF-16 code) + * 7-8bytes UTF-8(IVS) is charlen=3+4 or 4+4 + * (2 UTF-8 pairs divided to 2 UTF-16 pairs) */ + if (charlen == 4) + i++; + else if (charlen >= 5) + /* 5-6bytes UTF-8 */ + i += 2; } /* properly null-terminate string */ @@ -296,6 +296,46 @@ success: } /* + * cifs_utf16_bytes - how long will a string be after conversion? + * @utf16 - pointer to input string + * @maxbytes - don't go past this many bytes of input string + * @codepage - destination codepage + * + * Walk a utf16le string and return the number of bytes that the string will + * be after being converted to the given charset, not including any null + * termination required. Don't walk past maxbytes in the source buffer. + */ +int +cifs_utf16_bytes(const __le16 *from, int maxbytes, + const struct nls_table *codepage) +{ + int i; + int charlen, outlen = 0; + int maxwords = maxbytes / 2; + char tmp[NLS_MAX_CHARSET_SIZE]; + __u16 ftmp[3]; + + for (i = 0; i < maxwords; i++) { + ftmp[0] = get_unaligned_le16(&from[i]); + if (ftmp[0] == 0) + break; + if (i + 1 < maxwords) + ftmp[1] = get_unaligned_le16(&from[i + 1]); + else + ftmp[1] = 0; + if (i + 2 < maxwords) + ftmp[2] = get_unaligned_le16(&from[i + 2]); + else + ftmp[2] = 0; + + charlen = cifs_mapchar(tmp, ftmp, codepage, NO_MAP_UNI_RSVD); + outlen += charlen; + } + + return outlen; +} + +/* * cifs_strndup_from_utf16 - copy a string from wire format to the local * codepage * @src - source string @@ -409,10 +449,15 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, char src_char; __le16 dst_char; wchar_t tmp; + wchar_t *wchar_to; /* UTF-16 */ + int ret; + unicode_t u; if (map_chars == NO_MAP_UNI_RSVD) return cifs_strtoUTF16(target, source, PATH_MAX, cp); + wchar_to = kzalloc(6, GFP_KERNEL); + for (i = 0; i < srclen; j++) { src_char = source[i]; charlen = 1; @@ -441,11 +486,55 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, * if no match, use question mark, which at least in * some cases serves as wild card */ - if (charlen < 1) { - dst_char = cpu_to_le16(0x003f); - charlen = 1; + if (charlen > 0) + goto ctoUTF16; + + /* convert SURROGATE_PAIR */ + if (strcmp(cp->charset, "utf8") || !wchar_to) + goto unknown; + if (*(source + i) & 0x80) { + charlen = utf8_to_utf32(source + i, 6, &u); + if (charlen < 0) + goto unknown; + } else + goto unknown; + ret = utf8s_to_utf16s(source + i, charlen, + UTF16_LITTLE_ENDIAN, + wchar_to, 6); + if (ret < 0) + goto unknown; + + i += charlen; + dst_char = cpu_to_le16(*wchar_to); + if (charlen <= 3) + /* 1-3bytes UTF-8 to 2bytes UTF-16 */ + put_unaligned(dst_char, &target[j]); + else if (charlen == 4) { + /* 4bytes UTF-8(surrogate pair) to 4bytes UTF-16 + * 7-8bytes UTF-8(IVS) divided to 2 UTF-16 + * (charlen=3+4 or 4+4) */ + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 1)); + j++; + put_unaligned(dst_char, &target[j]); + } else if (charlen >= 5) { + /* 5-6bytes UTF-8 to 6bytes UTF-16 */ + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 1)); + j++; + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 2)); + j++; + put_unaligned(dst_char, &target[j]); } + continue; + +unknown: + dst_char = cpu_to_le16(0x003f); + charlen = 1; } + +ctoUTF16: /* * character may take more than one byte in the source string, * but will take exactly two bytes in the target string @@ -456,6 +545,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, ctoUTF16_out: put_unaligned(0, &target[j]); /* Null terminate target unicode string */ + kfree(wchar_to); return j; } diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f5089bde3635..0a9fb6b53126 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -469,6 +469,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_puts(s, ",nouser_xattr"); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) seq_puts(s, ",mapchars"); + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR) + seq_puts(s, ",mapposix"); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) seq_puts(s, ",sfu"); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c31ce98c1704..c63fd1dde25b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -361,11 +361,11 @@ extern int CIFSUnixCreateHardLink(const unsigned int xid, extern int CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, - const struct nls_table *nls_codepage); + const struct nls_table *nls_codepage, int remap); extern int CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, char **syminfo, - const struct nls_table *nls_codepage); + const struct nls_table *nls_codepage, int remap); extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, char **symlinkinfo, const struct nls_table *nls_codepage); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 84650a51c7c4..f26ffbfc64d8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2784,7 +2784,7 @@ copyRetry: int CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_RSP *pSMBr = NULL; @@ -2804,9 +2804,9 @@ createSymLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName, - /* find define for this maxpathcomponent */ - PATH_MAX, nls_codepage); + cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, + /* find define for this maxpathcomponent */ + PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; @@ -2828,9 +2828,9 @@ createSymLinkRetry: data_offset = (char *) (&pSMB->hdr.Protocol) + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len_target = - cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX - /* find define for this maxpathcomponent */ - , nls_codepage); + cifsConvertToUTF16((__le16 *) data_offset, toName, + /* find define for this maxpathcomponent */ + PATH_MAX, nls_codepage, remap); name_len_target++; /* trailing null */ name_len_target *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -3034,7 +3034,7 @@ winCreateHardLinkRetry: int CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, char **symlinkinfo, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { /* SMB_QUERY_FILE_UNIX_LINK */ TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -3055,8 +3055,9 @@ querySymLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName, - PATH_MAX, nls_codepage); + cifsConvertToUTF16((__le16 *) pSMB->FileName, + searchName, PATH_MAX, nls_codepage, + remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -4917,7 +4918,7 @@ getDFSRetry: strncpy(pSMB->RequestFileName, search_name, name_len); } - if (ses->server && ses->server->sign) + if (ses->server->sign) pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->hdr.Uid = ses->Suid; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f3bfe08e177b..8383d5ea4202 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -386,6 +386,7 @@ cifs_reconnect(struct TCP_Server_Info *server) rc = generic_ip_connect(server); if (rc) { cifs_dbg(FYI, "reconnect error %d\n", rc); + mutex_unlock(&server->srv_mutex); msleep(3000); } else { atomic_inc(&tcpSesReconnectCount); @@ -393,8 +394,8 @@ cifs_reconnect(struct TCP_Server_Info *server) if (server->tcpStatus != CifsExiting) server->tcpStatus = CifsNeedNegotiate; spin_unlock(&GlobalMid_Lock); + mutex_unlock(&server->srv_mutex); } - mutex_unlock(&server->srv_mutex); } while (server->tcpStatus == CifsNeedReconnect); return rc; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 338d56936f6a..c3eb998a99bd 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -620,8 +620,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, } rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_remap(cifs_sb)); if (rc) goto mknod_out; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cafbf10521d5..3f50cee79df9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -140,8 +140,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, posix_flags = cifs_posix_convert_flags(f_flags); rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data, poplock, full_path, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_remap(cifs_sb)); cifs_put_tlink(tlink); if (rc) @@ -1553,8 +1552,8 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, rc = server->ops->mand_unlock_range(cfile, flock, xid); out: - if (flock->fl_flags & FL_POSIX) - posix_lock_file_wait(file, flock); + if (flock->fl_flags & FL_POSIX && !rc) + rc = posix_lock_file_wait(file, flock); return rc; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 55b58112d122..f621b44cb800 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -373,8 +373,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* could have done a find first instead but this returns more info */ rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_sb->local_nls, cifs_remap(cifs_sb)); cifs_put_tlink(tlink); if (!rc) { @@ -402,9 +401,25 @@ int cifs_get_inode_info_unix(struct inode **pinode, rc = -ENOMEM; } else { /* we already have inode, update it */ + + /* if uniqueid is different, return error */ + if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && + CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { + rc = -ESTALE; + goto cgiiu_exit; + } + + /* if filetype is different, return error */ + if (unlikely(((*pinode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { + rc = -ESTALE; + goto cgiiu_exit; + } + cifs_fattr_to_inode(*pinode, &fattr); } +cgiiu_exit: return rc; } @@ -839,6 +854,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, if (!*inode) rc = -ENOMEM; } else { + /* we already have inode, update it */ + + /* if filetype is different, return error */ + if (unlikely(((*inode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { + rc = -ESTALE; + goto cgii_exit; + } + cifs_fattr_to_inode(*inode, &fattr); } @@ -2215,8 +2239,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) pTcon = tlink_tcon(tlink); rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); + cifs_remap(cifs_sb)); cifs_put_tlink(tlink); } diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 252e672d5604..e6c707cc62b3 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -717,7 +717,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); else if (pTcon->unix_ext) rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_remap(cifs_sb)); /* else rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName, cifs_sb_target->local_nls); */ diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b4a47237486b..b1eede3678a9 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -90,6 +90,8 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, if (dentry) { inode = d_inode(dentry); if (inode) { + if (d_mountpoint(dentry)) + goto out; /* * If we're generating inode numbers, then we don't * want to clobber the existing one with the one that diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 7bfdd6066276..fc537c29044e 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -960,7 +960,8 @@ cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, /* Check for unix extensions */ if (cap_unix(tcon->ses)) { rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_remap(cifs_sb)); if (rc == -EREMOTE) rc = cifs_unix_dfs_readlink(xid, tcon, full_path, target_path, diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 65cd7a84c8bc..54cbe19d9c08 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -110,7 +110,7 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ , /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */ /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */ - if ((tcon->ses) && + if ((tcon->ses) && (tcon->ses->server) && (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) hdr->CreditCharge = cpu_to_le16(1); /* else CreditCharge MBZ */ diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index da94e41bdbf6..537356742091 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c @@ -173,5 +173,5 @@ MODULE_LICENSE("GPL"); MODULE_VERSION("0.0.2"); MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration."); -module_init(configfs_init); +core_initcall(configfs_init); module_exit(configfs_exit); diff --git a/fs/dcache.c b/fs/dcache.c index 656ce522a218..37b5afdaf698 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1239,13 +1239,13 @@ ascend: /* might go back up the wrong parent if we have had a rename. */ if (need_seqretry(&rename_lock, seq)) goto rename_retry; - next = child->d_child.next; - while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { + /* go into the first sibling still alive */ + do { + next = child->d_child.next; if (next == &this_parent->d_subdirs) goto ascend; child = list_entry(next, struct dentry, d_child); - next = next->next; - } + } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); rcu_read_unlock(); goto resume; } diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 59fedbcf8798..86a2121828c3 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -121,7 +121,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, int len, i; int err = -ENOMEM; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return err; diff --git a/fs/exec.c b/fs/exec.c index 49a1c61433b7..1977c2a553ac 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -659,6 +659,9 @@ int setup_arg_pages(struct linux_binprm *bprm, if (stack_base > STACK_SIZE_MAX) stack_base = STACK_SIZE_MAX; + /* Add space for stack randomization. */ + stack_base += (STACK_RND_MASK << PAGE_SHIFT); + /* Make sure we didn't let the argument array grow too large. */ if (vma->vm_end - vma->vm_start > stack_base) return -ENOMEM; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 009a0590b20f..9a83f149ac85 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2889,7 +2889,6 @@ extern int ext4_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags); extern int ext4_ext_calc_metadata_amount(struct inode *inode, ext4_lblk_t lblocks); -extern int ext4_extent_tree_init(handle_t *, struct inode *); extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int num, struct ext4_ext_path *path); diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index 3445035c7e01..d41843181818 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -87,6 +87,12 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) ext4_put_nojournal(handle); return 0; } + + if (!handle->h_transaction) { + err = jbd2_journal_stop(handle); + return handle->h_err ? handle->h_err : err; + } + sb = handle->h_transaction->t_journal->j_private; err = handle->h_err; rc = jbd2_journal_stop(handle); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index d74e08029643..e003a1e81dc3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -377,7 +377,7 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) ext4_lblk_t lblock = le32_to_cpu(ext->ee_block); ext4_lblk_t last = lblock + len - 1; - if (lblock > last) + if (len == 0 || lblock > last) return 0; return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); } @@ -5396,6 +5396,14 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) loff_t new_size, ioffset; int ret; + /* + * We need to test this early because xfstests assumes that a + * collapse range of (0, 1) will return EOPNOTSUPP if the file + * system does not support collapse range. + */ + if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) + return -EOPNOTSUPP; + /* Collapse range works only on fs block size aligned offsets. */ if (offset & (EXT4_CLUSTER_SIZE(sb) - 1) || len & (EXT4_CLUSTER_SIZE(sb) - 1)) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 55b187c3bac1..0554b0b5957b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4345,7 +4345,7 @@ static void ext4_update_other_inodes_time(struct super_block *sb, int inode_size = EXT4_INODE_SIZE(sb); oi.orig_ino = orig_ino; - ino = orig_ino & ~(inodes_per_block - 1); + ino = (orig_ino & ~(inodes_per_block - 1)) + 1; for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { if (ino == orig_ino) continue; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f06d0589ddba..ca9d4a2fed41 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -294,6 +294,8 @@ static void __save_error_info(struct super_block *sb, const char *func, struct ext4_super_block *es = EXT4_SB(sb)->s_es; EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; + if (bdev_read_only(sb->s_bdev)) + return; es->s_state |= cpu_to_le16(EXT4_ERROR_FS); es->s_last_error_time = cpu_to_le32(get_seconds()); strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func)); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index b91b0e10678e..1e1aae669fa8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1513,6 +1513,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, { struct inode *inode = mapping->host; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + bool locked = false; int ret; long diff; @@ -1533,7 +1534,13 @@ static int f2fs_write_data_pages(struct address_space *mapping, diff = nr_pages_to_write(sbi, DATA, wbc); + if (!S_ISDIR(inode->i_mode)) { + mutex_lock(&sbi->writepages); + locked = true; + } ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); + if (locked) + mutex_unlock(&sbi->writepages); f2fs_submit_merged_bio(sbi, DATA, WRITE); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d8921cf2ba9a..8de34ab6d5b1 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -625,6 +625,7 @@ struct f2fs_sb_info { struct mutex cp_mutex; /* checkpoint procedure lock */ struct rw_semaphore cp_rwsem; /* blocking FS operations */ struct rw_semaphore node_write; /* locking node writes */ + struct mutex writepages; /* mutex for writepages() */ wait_queue_head_t cp_wait; struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 7e3794edae42..658e8079aaf9 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -298,16 +298,14 @@ fail: static void *f2fs_follow_link(struct dentry *dentry, struct nameidata *nd) { - struct page *page; + struct page *page = page_follow_link_light(dentry, nd); - page = page_follow_link_light(dentry, nd); - if (IS_ERR(page)) + if (IS_ERR_OR_NULL(page)) return page; /* this is broken symlink case */ if (*nd_get_link(nd) == 0) { - kunmap(page); - page_cache_release(page); + page_put_link(dentry, nd, page); return ERR_PTR(-ENOENT); } return page; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 160b88346b24..b2dd1b01f076 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1035,6 +1035,7 @@ try_onemore: sbi->raw_super = raw_super; sbi->raw_super_buf = raw_super_buf; mutex_init(&sbi->gc_mutex); + mutex_init(&sbi->writepages); mutex_init(&sbi->cp_mutex); init_rwsem(&sbi->node_write); clear_sbi_flag(sbi, SBI_POR_DOING); diff --git a/fs/fhandle.c b/fs/fhandle.c index 999ff5c3cab0..d59712dfa3e7 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -195,8 +195,9 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, goto out_err; } /* copy the full handle */ - if (copy_from_user(handle, ufh, - sizeof(struct file_handle) + + *handle = f_handle; + if (copy_from_user(&handle->f_handle, + &ufh->f_handle, f_handle.handle_bytes)) { retval = -EFAULT; goto out_handle; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index ef263174acd2..07d8d8f52faf 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -581,7 +581,7 @@ static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, if (name == NULL) goto out_put; - fd = file_create(name, mode & S_IFMT); + fd = file_create(name, mode & 0777); if (fd < 0) error = fd; else diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index b5128c6e63ad..a9079d035ae5 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -842,15 +842,23 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, { jbd2_journal_revoke_header_t *header; int offset, max; + int csum_size = 0; + __u32 rcount; int record_len = 4; header = (jbd2_journal_revoke_header_t *) bh->b_data; offset = sizeof(jbd2_journal_revoke_header_t); - max = be32_to_cpu(header->r_count); + rcount = be32_to_cpu(header->r_count); if (!jbd2_revoke_block_csum_verify(journal, header)) return -EINVAL; + if (jbd2_journal_has_csum_v2or3(journal)) + csum_size = sizeof(struct jbd2_journal_revoke_tail); + if (rcount > journal->j_blocksize - csum_size) + return -EINVAL; + max = rcount; + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) record_len = 8; diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index c6cbaef2bda1..14214da80eb8 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c @@ -577,7 +577,7 @@ static void write_one_revoke_record(journal_t *journal, { int csum_size = 0; struct buffer_head *descriptor; - int offset; + int sz, offset; journal_header_t *header; /* If we are already aborting, this all becomes a noop. We @@ -594,9 +594,14 @@ static void write_one_revoke_record(journal_t *journal, if (jbd2_journal_has_csum_v2or3(journal)) csum_size = sizeof(struct jbd2_journal_revoke_tail); + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) + sz = 8; + else + sz = 4; + /* Make sure we have a descriptor with space left for the record */ if (descriptor) { - if (offset >= journal->j_blocksize - csum_size) { + if (offset + sz > journal->j_blocksize - csum_size) { flush_descriptor(journal, descriptor, offset, write_op); descriptor = NULL; } @@ -619,16 +624,13 @@ static void write_one_revoke_record(journal_t *journal, *descriptorp = descriptor; } - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) { + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) * ((__be64 *)(&descriptor->b_data[offset])) = cpu_to_be64(record->blocknr); - offset += 8; - - } else { + else * ((__be32 *)(&descriptor->b_data[offset])) = cpu_to_be32(record->blocknr); - offset += 4; - } + offset += sz; *offsetp = offset; } diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 5f09370c90a8..ff2f2e6ad311 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -551,7 +551,6 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) int result; int wanted; - WARN_ON(!transaction); if (is_handle_aborted(handle)) return -EROFS; journal = transaction->t_journal; @@ -627,7 +626,6 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask) tid_t tid; int need_to_start, ret; - WARN_ON(!transaction); /* If we've had an abort of any type, don't even think about * actually doing the restart! */ if (is_handle_aborted(handle)) @@ -785,7 +783,6 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, int need_copy = 0; unsigned long start_lock, time_lock; - WARN_ON(!transaction); if (is_handle_aborted(handle)) return -EROFS; journal = transaction->t_journal; @@ -1051,7 +1048,6 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) int err; jbd_debug(5, "journal_head %p\n", jh); - WARN_ON(!transaction); err = -EROFS; if (is_handle_aborted(handle)) goto out; @@ -1266,7 +1262,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) struct journal_head *jh; int ret = 0; - WARN_ON(!transaction); if (is_handle_aborted(handle)) return -EROFS; journal = transaction->t_journal; @@ -1397,7 +1392,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) int err = 0; int was_modified = 0; - WARN_ON(!transaction); if (is_handle_aborted(handle)) return -EROFS; journal = transaction->t_journal; @@ -1530,8 +1524,22 @@ int jbd2_journal_stop(handle_t *handle) tid_t tid; pid_t pid; - if (!transaction) - goto free_and_exit; + if (!transaction) { + /* + * Handle is already detached from the transaction so + * there is nothing to do other than decrease a refcount, + * or free the handle if refcount drops to zero + */ + if (--handle->h_ref > 0) { + jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, + handle->h_ref); + return err; + } else { + if (handle->h_rsv_handle) + jbd2_free_handle(handle->h_rsv_handle); + goto free_and_exit; + } + } journal = transaction->t_journal; J_ASSERT(journal_current_handle() == handle); @@ -2373,7 +2381,6 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) transaction_t *transaction = handle->h_transaction; journal_t *journal; - WARN_ON(!transaction); if (is_handle_aborted(handle)) return -EROFS; journal = transaction->t_journal; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index f131fc23ffc4..fffca9517321 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -518,7 +518,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, if (!kn) goto err_out1; - ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); + /* + * If the ino of the sysfs entry created for a kmem cache gets + * allocated from an ida layer, which is accounted to the memcg that + * owns the cache, the memcg will get pinned forever. So do not account + * ino ida allocations. + */ + ret = ida_simple_get(&root->ino_ida, 1, 0, + GFP_KERNEL | __GFP_NOACCOUNT); if (ret < 0) goto err_out2; kn->ino = ret; diff --git a/fs/namei.c b/fs/namei.c index 4a8d998b7274..fe30d3be43a8 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1415,6 +1415,7 @@ static int lookup_fast(struct nameidata *nd, */ if (nd->flags & LOOKUP_RCU) { unsigned seq; + bool negative; dentry = __d_lookup_rcu(parent, &nd->last, &seq); if (!dentry) goto unlazy; @@ -1424,8 +1425,11 @@ static int lookup_fast(struct nameidata *nd, * the dentry name information from lookup. */ *inode = dentry->d_inode; + negative = d_is_negative(dentry); if (read_seqcount_retry(&dentry->d_seq, seq)) return -ECHILD; + if (negative) + return -ENOENT; /* * This sequence count validates that the parent had no @@ -1472,6 +1476,10 @@ unlazy: goto need_lookup; } + if (unlikely(d_is_negative(dentry))) { + dput(dentry); + return -ENOENT; + } path->mnt = mnt; path->dentry = dentry; err = follow_managed(path, nd->flags); @@ -1583,10 +1591,10 @@ static inline int walk_component(struct nameidata *nd, struct path *path, goto out_err; inode = path->dentry->d_inode; + err = -ENOENT; + if (d_is_negative(path->dentry)) + goto out_path_put; } - err = -ENOENT; - if (d_is_negative(path->dentry)) - goto out_path_put; if (should_follow_link(path->dentry, follow)) { if (nd->flags & LOOKUP_RCU) { @@ -3036,14 +3044,13 @@ retry_lookup: BUG_ON(nd->flags & LOOKUP_RCU); inode = path->dentry->d_inode; -finish_lookup: - /* we _can_ be in RCU mode here */ error = -ENOENT; if (d_is_negative(path->dentry)) { path_to_nameidata(path, nd); goto out; } - +finish_lookup: + /* we _can_ be in RCU mode here */ if (should_follow_link(path->dentry, !symlink_ok)) { if (nd->flags & LOOKUP_RCU) { if (unlikely(nd->path.mnt != path->mnt || @@ -3226,7 +3233,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, if (unlikely(file->f_flags & __O_TMPFILE)) { error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); - goto out; + goto out2; } error = path_init(dfd, pathname, flags, nd); @@ -3256,6 +3263,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, } out: path_cleanup(nd); +out2: if (!(opened & FILE_OPENED)) { BUG_ON(!error); put_filp(file); diff --git a/fs/namespace.c b/fs/namespace.c index 1f4f9dac6e5a..1b9e11167bae 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3179,6 +3179,12 @@ bool fs_fully_visible(struct file_system_type *type) if (mnt->mnt.mnt_sb->s_type != type) continue; + /* This mount is not fully visible if it's root directory + * is not the root directory of the filesystem. + */ + if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) + continue; + /* This mount is not fully visible if there are any child mounts * that cover anything except for empty directories. */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 45b35b9b1e36..55e1e3af23a3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -38,6 +38,7 @@ #include <linux/mm.h> #include <linux/delay.h> #include <linux/errno.h> +#include <linux/file.h> #include <linux/string.h> #include <linux/ratelimit.h> #include <linux/printk.h> @@ -5604,6 +5605,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, p->server = server; atomic_inc(&lsp->ls_count); p->ctx = get_nfs_open_context(ctx); + get_file(fl->fl_file); memcpy(&p->fl, fl, sizeof(p->fl)); return p; out_free_seqid: @@ -5716,6 +5718,7 @@ static void nfs4_lock_release(void *calldata) nfs_free_seqid(data->arg.lock_seqid); nfs4_put_lock_state(data->lsp); put_nfs_open_context(data->ctx); + fput(data->fl.fl_file); kfree(data); dprintk("%s: done!\n", __func__); } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index d12a4be613a5..dfc19f1575a1 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1845,12 +1845,15 @@ int nfs_wb_all(struct inode *inode) trace_nfs_writeback_inode_enter(inode); ret = filemap_write_and_wait(inode->i_mapping); - if (!ret) { - ret = nfs_commit_inode(inode, FLUSH_SYNC); - if (!ret) - pnfs_sync_inode(inode, true); - } + if (ret) + goto out; + ret = nfs_commit_inode(inode, FLUSH_SYNC); + if (ret < 0) + goto out; + pnfs_sync_inode(inode, true); + ret = 0; +out: trace_nfs_writeback_inode_exit(inode, ret); return ret; } diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 03d647bf195d..cdefaa331a07 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -181,6 +181,17 @@ nfsd4_block_proc_layoutcommit(struct inode *inode, } const struct nfsd4_layout_ops bl_layout_ops = { + /* + * Pretend that we send notification to the client. This is a blatant + * lie to force recent Linux clients to cache our device IDs. + * We rarely ever change the device ID, so the harm of leaking deviceids + * for a while isn't too bad. Unfortunately RFC5661 is a complete mess + * in this regard, but I filed errata 4119 for this a while ago, and + * hopefully the Linux client will eventually start caching deviceids + * without this again. + */ + .notify_types = + NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE, .proc_getdeviceinfo = nfsd4_block_proc_getdeviceinfo, .encode_getdeviceinfo = nfsd4_block_encode_getdeviceinfo, .proc_layoutget = nfsd4_block_proc_layoutget, diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 58277859a467..5694cfb7a47b 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -224,7 +224,7 @@ static int nfs_cb_stat_to_errno(int status) } static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected, - enum nfsstat4 *status) + int *status) { __be32 *p; u32 op; @@ -235,7 +235,7 @@ static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected, op = be32_to_cpup(p++); if (unlikely(op != expected)) goto out_unexpected; - *status = be32_to_cpup(p); + *status = nfs_cb_stat_to_errno(be32_to_cpup(p)); return 0; out_overflow: print_overflow_msg(__func__, xdr); @@ -446,22 +446,16 @@ out_overflow: static int decode_cb_sequence4res(struct xdr_stream *xdr, struct nfsd4_callback *cb) { - enum nfsstat4 nfserr; int status; if (cb->cb_minorversion == 0) return 0; - status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &nfserr); - if (unlikely(status)) - goto out; - if (unlikely(nfserr != NFS4_OK)) - goto out_default; - status = decode_cb_sequence4resok(xdr, cb); -out: - return status; -out_default: - return nfs_cb_stat_to_errno(nfserr); + status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &cb->cb_status); + if (unlikely(status || cb->cb_status)) + return status; + + return decode_cb_sequence4resok(xdr, cb); } /* @@ -524,26 +518,19 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, struct nfsd4_callback *cb) { struct nfs4_cb_compound_hdr hdr; - enum nfsstat4 nfserr; int status; status = decode_cb_compound4res(xdr, &hdr); if (unlikely(status)) - goto out; + return status; if (cb != NULL) { status = decode_cb_sequence4res(xdr, cb); - if (unlikely(status)) - goto out; + if (unlikely(status || cb->cb_status)) + return status; } - status = decode_cb_op_status(xdr, OP_CB_RECALL, &nfserr); - if (unlikely(status)) - goto out; - if (unlikely(nfserr != NFS4_OK)) - status = nfs_cb_stat_to_errno(nfserr); -out: - return status; + return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status); } #ifdef CONFIG_NFSD_PNFS @@ -621,24 +608,18 @@ static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp, struct nfsd4_callback *cb) { struct nfs4_cb_compound_hdr hdr; - enum nfsstat4 nfserr; int status; status = decode_cb_compound4res(xdr, &hdr); if (unlikely(status)) - goto out; + return status; + if (cb) { status = decode_cb_sequence4res(xdr, cb); - if (unlikely(status)) - goto out; + if (unlikely(status || cb->cb_status)) + return status; } - status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr); - if (unlikely(status)) - goto out; - if (unlikely(nfserr != NFS4_OK)) - status = nfs_cb_stat_to_errno(nfserr); -out: - return status; + return decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &cb->cb_status); } #endif /* CONFIG_NFSD_PNFS */ @@ -898,13 +879,6 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) if (!nfsd41_cb_get_slot(clp, task)) return; } - spin_lock(&clp->cl_lock); - if (list_empty(&cb->cb_per_client)) { - /* This is the first call, not a restart */ - cb->cb_done = false; - list_add(&cb->cb_per_client, &clp->cl_callbacks); - } - spin_unlock(&clp->cl_lock); rpc_call_start(task); } @@ -918,22 +892,33 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) if (clp->cl_minorversion) { /* No need for lock, access serialized in nfsd4_cb_prepare */ - ++clp->cl_cb_session->se_cb_seq_nr; + if (!task->tk_status) + ++clp->cl_cb_session->se_cb_seq_nr; clear_bit(0, &clp->cl_cb_slot_busy); rpc_wake_up_next(&clp->cl_cb_waitq); dprintk("%s: freed slot, new seqid=%d\n", __func__, clp->cl_cb_session->se_cb_seq_nr); } - if (clp->cl_cb_client != task->tk_client) { - /* We're shutting down or changing cl_cb_client; leave - * it to nfsd4_process_cb_update to restart the call if - * necessary. */ + /* + * If the backchannel connection was shut down while this + * task was queued, we need to resubmit it after setting up + * a new backchannel connection. + * + * Note that if we lost our callback connection permanently + * the submission code will error out, so we don't need to + * handle that case here. + */ + if (task->tk_flags & RPC_TASK_KILLED) { + task->tk_status = 0; + cb->cb_need_restart = true; return; } - if (cb->cb_done) - return; + if (cb->cb_status) { + WARN_ON_ONCE(task->tk_status); + task->tk_status = cb->cb_status; + } switch (cb->cb_ops->done(cb, task)) { case 0: @@ -949,21 +934,17 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) default: BUG(); } - cb->cb_done = true; } static void nfsd4_cb_release(void *calldata) { struct nfsd4_callback *cb = calldata; - struct nfs4_client *clp = cb->cb_clp; - - if (cb->cb_done) { - spin_lock(&clp->cl_lock); - list_del(&cb->cb_per_client); - spin_unlock(&clp->cl_lock); + if (cb->cb_need_restart) + nfsd4_run_cb(cb); + else cb->cb_ops->release(cb); - } + } static const struct rpc_call_ops nfsd4_cb_ops = { @@ -1058,9 +1039,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb) nfsd4_mark_cb_down(clp, err); return; } - /* Yay, the callback channel's back! Restart any callbacks: */ - list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client) - queue_work(callback_wq, &cb->cb_work); } static void @@ -1071,8 +1049,12 @@ nfsd4_run_cb_work(struct work_struct *work) struct nfs4_client *clp = cb->cb_clp; struct rpc_clnt *clnt; - if (cb->cb_ops && cb->cb_ops->prepare) - cb->cb_ops->prepare(cb); + if (cb->cb_need_restart) { + cb->cb_need_restart = false; + } else { + if (cb->cb_ops && cb->cb_ops->prepare) + cb->cb_ops->prepare(cb); + } if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK) nfsd4_process_cb_update(cb); @@ -1084,6 +1066,15 @@ nfsd4_run_cb_work(struct work_struct *work) cb->cb_ops->release(cb); return; } + + /* + * Don't send probe messages for 4.1 or later. + */ + if (!cb->cb_ops && clp->cl_minorversion) { + clp->cl_cb_state = NFSD4_CB_UP; + return; + } + cb->cb_msg.rpc_cred = clp->cl_cb_cred; rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN, cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb); @@ -1098,8 +1089,8 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp, cb->cb_msg.rpc_resp = cb; cb->cb_ops = ops; INIT_WORK(&cb->cb_work, nfsd4_run_cb_work); - INIT_LIST_HEAD(&cb->cb_per_client); - cb->cb_done = true; + cb->cb_status = 0; + cb->cb_need_restart = false; } void nfsd4_run_cb(struct nfsd4_callback *cb) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 38f2d7abe3a7..039f9c8a95e8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -94,6 +94,7 @@ static struct kmem_cache *lockowner_slab; static struct kmem_cache *file_slab; static struct kmem_cache *stateid_slab; static struct kmem_cache *deleg_slab; +static struct kmem_cache *odstate_slab; static void free_session(struct nfsd4_session *); @@ -281,6 +282,7 @@ put_nfs4_file(struct nfs4_file *fi) if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { hlist_del_rcu(&fi->fi_hash); spin_unlock(&state_lock); + WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate)); WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); } @@ -471,6 +473,86 @@ static void nfs4_file_put_access(struct nfs4_file *fp, u32 access) __nfs4_file_put_access(fp, O_RDONLY); } +/* + * Allocate a new open/delegation state counter. This is needed for + * pNFS for proper return on close semantics. + * + * Note that we only allocate it for pNFS-enabled exports, otherwise + * all pointers to struct nfs4_clnt_odstate are always NULL. + */ +static struct nfs4_clnt_odstate * +alloc_clnt_odstate(struct nfs4_client *clp) +{ + struct nfs4_clnt_odstate *co; + + co = kmem_cache_zalloc(odstate_slab, GFP_KERNEL); + if (co) { + co->co_client = clp; + atomic_set(&co->co_odcount, 1); + } + return co; +} + +static void +hash_clnt_odstate_locked(struct nfs4_clnt_odstate *co) +{ + struct nfs4_file *fp = co->co_file; + + lockdep_assert_held(&fp->fi_lock); + list_add(&co->co_perfile, &fp->fi_clnt_odstate); +} + +static inline void +get_clnt_odstate(struct nfs4_clnt_odstate *co) +{ + if (co) + atomic_inc(&co->co_odcount); +} + +static void +put_clnt_odstate(struct nfs4_clnt_odstate *co) +{ + struct nfs4_file *fp; + + if (!co) + return; + + fp = co->co_file; + if (atomic_dec_and_lock(&co->co_odcount, &fp->fi_lock)) { + list_del(&co->co_perfile); + spin_unlock(&fp->fi_lock); + + nfsd4_return_all_file_layouts(co->co_client, fp); + kmem_cache_free(odstate_slab, co); + } +} + +static struct nfs4_clnt_odstate * +find_or_hash_clnt_odstate(struct nfs4_file *fp, struct nfs4_clnt_odstate *new) +{ + struct nfs4_clnt_odstate *co; + struct nfs4_client *cl; + + if (!new) + return NULL; + + cl = new->co_client; + + spin_lock(&fp->fi_lock); + list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) { + if (co->co_client == cl) { + get_clnt_odstate(co); + goto out; + } + } + co = new; + co->co_file = fp; + hash_clnt_odstate_locked(new); +out: + spin_unlock(&fp->fi_lock); + return co; +} + struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab) { @@ -606,7 +688,8 @@ static void block_delegations(struct knfsd_fh *fh) } static struct nfs4_delegation * -alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh) +alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh, + struct nfs4_clnt_odstate *odstate) { struct nfs4_delegation *dp; long n; @@ -631,6 +714,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh) INIT_LIST_HEAD(&dp->dl_perfile); INIT_LIST_HEAD(&dp->dl_perclnt); INIT_LIST_HEAD(&dp->dl_recall_lru); + dp->dl_clnt_odstate = odstate; + get_clnt_odstate(odstate); dp->dl_type = NFS4_OPEN_DELEGATE_READ; dp->dl_retries = 1; nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, @@ -714,6 +799,7 @@ static void destroy_delegation(struct nfs4_delegation *dp) spin_lock(&state_lock); unhash_delegation_locked(dp); spin_unlock(&state_lock); + put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } @@ -724,6 +810,7 @@ static void revoke_delegation(struct nfs4_delegation *dp) WARN_ON(!list_empty(&dp->dl_recall_lru)); + put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_deleg_lease(dp->dl_stid.sc_file); if (clp->cl_minorversion == 0) @@ -933,6 +1020,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid) { struct nfs4_ol_stateid *stp = openlockstateid(stid); + put_clnt_odstate(stp->st_clnt_odstate); release_all_access(stp); if (stp->st_stateowner) nfs4_put_stateowner(stp->st_stateowner); @@ -1538,7 +1626,6 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) INIT_LIST_HEAD(&clp->cl_openowners); INIT_LIST_HEAD(&clp->cl_delegations); INIT_LIST_HEAD(&clp->cl_lru); - INIT_LIST_HEAD(&clp->cl_callbacks); INIT_LIST_HEAD(&clp->cl_revoked); #ifdef CONFIG_NFSD_PNFS INIT_LIST_HEAD(&clp->cl_lo_states); @@ -1634,6 +1721,7 @@ __destroy_client(struct nfs4_client *clp) while (!list_empty(&reaplist)) { dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); list_del_init(&dp->dl_recall_lru); + put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } @@ -3057,6 +3145,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, spin_lock_init(&fp->fi_lock); INIT_LIST_HEAD(&fp->fi_stateids); INIT_LIST_HEAD(&fp->fi_delegations); + INIT_LIST_HEAD(&fp->fi_clnt_odstate); fh_copy_shallow(&fp->fi_fhandle, fh); fp->fi_deleg_file = NULL; fp->fi_had_conflict = false; @@ -3073,6 +3162,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, void nfsd4_free_slabs(void) { + kmem_cache_destroy(odstate_slab); kmem_cache_destroy(openowner_slab); kmem_cache_destroy(lockowner_slab); kmem_cache_destroy(file_slab); @@ -3103,8 +3193,14 @@ nfsd4_init_slabs(void) sizeof(struct nfs4_delegation), 0, 0, NULL); if (deleg_slab == NULL) goto out_free_stateid_slab; + odstate_slab = kmem_cache_create("nfsd4_odstate", + sizeof(struct nfs4_clnt_odstate), 0, 0, NULL); + if (odstate_slab == NULL) + goto out_free_deleg_slab; return 0; +out_free_deleg_slab: + kmem_cache_destroy(deleg_slab); out_free_stateid_slab: kmem_cache_destroy(stateid_slab); out_free_file_slab: @@ -3581,6 +3677,14 @@ alloc_stateid: open->op_stp = nfs4_alloc_open_stateid(clp); if (!open->op_stp) return nfserr_jukebox; + + if (nfsd4_has_session(cstate) && + (cstate->current_fh.fh_export->ex_flags & NFSEXP_PNFS)) { + open->op_odstate = alloc_clnt_odstate(clp); + if (!open->op_odstate) + return nfserr_jukebox; + } + return nfs_ok; } @@ -3869,7 +3973,7 @@ out_fput: static struct nfs4_delegation * nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, - struct nfs4_file *fp) + struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) { int status; struct nfs4_delegation *dp; @@ -3877,7 +3981,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, if (fp->fi_had_conflict) return ERR_PTR(-EAGAIN); - dp = alloc_init_deleg(clp, fh); + dp = alloc_init_deleg(clp, fh, odstate); if (!dp) return ERR_PTR(-ENOMEM); @@ -3903,6 +4007,7 @@ out_unlock: spin_unlock(&state_lock); out: if (status) { + put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_stid(&dp->dl_stid); return ERR_PTR(status); } @@ -3980,7 +4085,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, default: goto out_no_deleg; } - dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file); + dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file, stp->st_clnt_odstate); if (IS_ERR(dp)) goto out_no_deleg; @@ -4069,6 +4174,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf release_open_stateid(stp); goto out; } + + stp->st_clnt_odstate = find_or_hash_clnt_odstate(fp, + open->op_odstate); + if (stp->st_clnt_odstate == open->op_odstate) + open->op_odstate = NULL; } update_stateid(&stp->st_stid.sc_stateid); memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); @@ -4129,6 +4239,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, kmem_cache_free(file_slab, open->op_file); if (open->op_stp) nfs4_put_stid(&open->op_stp->st_stid); + if (open->op_odstate) + kmem_cache_free(odstate_slab, open->op_odstate); } __be32 @@ -4385,10 +4497,17 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s return nfserr_old_stateid; } +static __be32 nfsd4_check_openowner_confirmed(struct nfs4_ol_stateid *ols) +{ + if (ols->st_stateowner->so_is_open_owner && + !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) + return nfserr_bad_stateid; + return nfs_ok; +} + static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) { struct nfs4_stid *s; - struct nfs4_ol_stateid *ols; __be32 status = nfserr_bad_stateid; if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) @@ -4418,13 +4537,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) break; case NFS4_OPEN_STID: case NFS4_LOCK_STID: - ols = openlockstateid(s); - if (ols->st_stateowner->so_is_open_owner - && !(openowner(ols->st_stateowner)->oo_flags - & NFS4_OO_CONFIRMED)) - status = nfserr_bad_stateid; - else - status = nfs_ok; + status = nfsd4_check_openowner_confirmed(openlockstateid(s)); break; default: printk("unknown stateid type %x\n", s->sc_type); @@ -4516,8 +4629,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate, status = nfs4_check_fh(current_fh, stp); if (status) goto out; - if (stp->st_stateowner->so_is_open_owner - && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) + status = nfsd4_check_openowner_confirmed(stp); + if (status) goto out; status = nfs4_check_openmode(stp, flags); if (status) @@ -4852,9 +4965,6 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, update_stateid(&stp->st_stid.sc_stateid); memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); - nfsd4_return_all_file_layouts(stp->st_stateowner->so_client, - stp->st_stid.sc_file); - nfsd4_close_open_stateid(stp); /* put reference from nfs4_preprocess_seqid_op */ @@ -6488,6 +6598,7 @@ nfs4_state_shutdown_net(struct net *net) list_for_each_safe(pos, next, &reaplist) { dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); list_del_init(&dp->dl_recall_lru); + put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 4f3bfeb11766..dbc4f85a5008 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -63,12 +63,12 @@ typedef struct { struct nfsd4_callback { struct nfs4_client *cb_clp; - struct list_head cb_per_client; u32 cb_minorversion; struct rpc_message cb_msg; struct nfsd4_callback_ops *cb_ops; struct work_struct cb_work; - bool cb_done; + int cb_status; + bool cb_need_restart; }; struct nfsd4_callback_ops { @@ -126,6 +126,7 @@ struct nfs4_delegation { struct list_head dl_perfile; struct list_head dl_perclnt; struct list_head dl_recall_lru; /* delegation recalled */ + struct nfs4_clnt_odstate *dl_clnt_odstate; u32 dl_type; time_t dl_time; /* For recall: */ @@ -332,7 +333,6 @@ struct nfs4_client { int cl_cb_state; struct nfsd4_callback cl_cb_null; struct nfsd4_session *cl_cb_session; - struct list_head cl_callbacks; /* list of in-progress callbacks */ /* for all client information that callback code might need: */ spinlock_t cl_lock; @@ -465,6 +465,17 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so) } /* + * Per-client state indicating no. of opens and outstanding delegations + * on a file from a particular client.'od' stands for 'open & delegation' + */ +struct nfs4_clnt_odstate { + struct nfs4_client *co_client; + struct nfs4_file *co_file; + struct list_head co_perfile; + atomic_t co_odcount; +}; + +/* * nfs4_file: a file opened by some number of (open) nfs4_stateowners. * * These objects are global. nfsd keeps one instance of a nfs4_file per @@ -485,6 +496,7 @@ struct nfs4_file { struct list_head fi_delegations; struct rcu_head fi_rcu; }; + struct list_head fi_clnt_odstate; /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ struct file * fi_fds[3]; /* @@ -526,6 +538,7 @@ struct nfs4_ol_stateid { struct list_head st_perstateowner; struct list_head st_locks; struct nfs4_stateowner * st_stateowner; + struct nfs4_clnt_odstate * st_clnt_odstate; unsigned char st_access_bmap; unsigned char st_deny_bmap; struct nfs4_ol_stateid * st_openstp; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index f982ae84f0cd..2f8c092be2b3 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -247,6 +247,7 @@ struct nfsd4_open { struct nfs4_openowner *op_openowner; /* used during processing */ struct nfs4_file *op_file; /* used during processing */ struct nfs4_ol_stateid *op_stp; /* used during processing */ + struct nfs4_clnt_odstate *op_odstate; /* used during processing */ struct nfs4_acl *op_acl; struct xdr_netobj op_label; }; diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 059f37137f9a..919fd5bb14a8 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c @@ -388,7 +388,7 @@ static int nilfs_btree_root_broken(const struct nilfs_btree_node *node, nchildren = nilfs_btree_node_get_nchildren(node); if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN || - level > NILFS_BTREE_LEVEL_MAX || + level >= NILFS_BTREE_LEVEL_MAX || nchildren < 0 || nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) { pr_crit("NILFS: bad btree root (inode number=%lu): level = %d, flags = 0x%x, nchildren = %d\n", diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a6944b25fd5b..fdf4b41d0609 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -757,6 +757,19 @@ lookup: if (tmpres) { spin_unlock(&dlm->spinlock); spin_lock(&tmpres->spinlock); + + /* + * Right after dlm spinlock was released, dlm_thread could have + * purged the lockres. Check if lockres got unhashed. If so + * start over. + */ + if (hlist_unhashed(&tmpres->hash_node)) { + spin_unlock(&tmpres->spinlock); + dlm_lockres_put(tmpres); + tmpres = NULL; + goto lookup; + } + /* Wait on the thread that is mastering the resource */ if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { __dlm_wait_on_lockres(tmpres); diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c index 082234581d05..83f4e76511c2 100644 --- a/fs/omfs/bitmap.c +++ b/fs/omfs/bitmap.c @@ -159,7 +159,7 @@ int omfs_allocate_range(struct super_block *sb, goto out; found: - *return_block = i * bits_per_entry + bit; + *return_block = (u64) i * bits_per_entry + bit; *return_size = run; ret = set_run(sb, i, bits_per_entry, bit, run, 1); diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index 138321b0c6c2..3d935c81789a 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c @@ -306,7 +306,8 @@ static const struct super_operations omfs_sops = { */ static int omfs_get_imap(struct super_block *sb) { - unsigned int bitmap_size, count, array_size; + unsigned int bitmap_size, array_size; + int count; struct omfs_sb_info *sbi = OMFS_SB(sb); struct buffer_head *bh; unsigned long **ptr; @@ -359,7 +360,7 @@ nomem: } enum { - Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask + Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask, Opt_err }; static const match_table_t tokens = { @@ -368,6 +369,7 @@ static const match_table_t tokens = { {Opt_umask, "umask=%o"}, {Opt_dmask, "dmask=%o"}, {Opt_fmask, "fmask=%o"}, + {Opt_err, NULL}, }; static int parse_options(char *options, struct omfs_sb_info *sbi) @@ -548,8 +550,10 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) } sb->s_root = d_make_root(root); - if (!sb->s_root) + if (!sb->s_root) { + ret = -ENOMEM; goto out_brelse_bh2; + } printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name); ret = 0; diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 24f640441bd9..84d693d37428 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -299,6 +299,9 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, struct cred *override_cred; char *link = NULL; + if (WARN_ON(!workdir)) + return -EROFS; + ovl_path_upper(parent, &parentpath); upperdir = parentpath.dentry; diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index d139405d2bfa..692ceda3bc21 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, struct kstat stat; int err; + if (WARN_ON(!workdir)) + return ERR_PTR(-EROFS); + err = ovl_lock_rename_workdir(workdir, upperdir); if (err) goto out; @@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, struct dentry *newdentry; int err; + if (WARN_ON(!workdir)) + return -EROFS; + err = ovl_lock_rename_workdir(workdir, upperdir); if (err) goto out; @@ -506,11 +512,28 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) struct dentry *opaquedir = NULL; int err; - if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { - opaquedir = ovl_check_empty_and_clear(dentry); - err = PTR_ERR(opaquedir); - if (IS_ERR(opaquedir)) - goto out; + if (WARN_ON(!workdir)) + return -EROFS; + + if (is_dir) { + if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { + opaquedir = ovl_check_empty_and_clear(dentry); + err = PTR_ERR(opaquedir); + if (IS_ERR(opaquedir)) + goto out; + } else { + LIST_HEAD(list); + + /* + * When removing an empty opaque directory, then it + * makes no sense to replace it with an exact replica of + * itself. But emptiness still needs to be checked. + */ + err = ovl_check_empty_dir(dentry, &list); + ovl_cache_free(&list); + if (err) + goto out; + } } err = ovl_lock_rename_workdir(workdir, upperdir); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5f0d1993e6e3..bf8537c7f455 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) { struct ovl_fs *ufs = sb->s_fs_info; - if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) + if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) return -EROFS; return 0; @@ -925,9 +925,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); err = PTR_ERR(ufs->workdir); if (IS_ERR(ufs->workdir)) { - pr_err("overlayfs: failed to create directory %s/%s\n", - ufs->config.workdir, OVL_WORKDIR_NAME); - goto out_put_upper_mnt; + pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", + ufs->config.workdir, OVL_WORKDIR_NAME, -err); + sb->s_flags |= MS_RDONLY; + ufs->workdir = NULL; } } @@ -997,7 +998,6 @@ out_put_lower_mnt: kfree(ufs->lower_mnt); out_put_workdir: dput(ufs->workdir); -out_put_upper_mnt: mntput(ufs->upper_mnt); out_put_lowerpath: for (i = 0; i < numlower; i++) diff --git a/fs/splice.c b/fs/splice.c index 476024bb6546..bfe62ae40f40 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1161,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, long ret, bytes; umode_t i_mode; size_t len; - int i, flags; + int i, flags, more; /* * We require the input being a regular file, as we don't want to @@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, * Don't block on output, we have to drain the direct pipe. */ sd->flags &= ~SPLICE_F_NONBLOCK; + more = sd->flags & SPLICE_F_MORE; while (len) { size_t read_len; @@ -1217,6 +1218,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, sd->total_len = read_len; /* + * If more data is pending, set SPLICE_F_MORE + * If this is the last data and SPLICE_F_MORE was not set + * initially, clears it. + */ + if (read_len < len) + sd->flags |= SPLICE_F_MORE; + else if (!more) + sd->flags &= ~SPLICE_F_MORE; + /* * NOTE: nonblocking mode only applies to the input. We * must not do the output in nonblocking mode as then we * could get stuck data in the internal pipe: diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 04e79d57bca6..e9d401ce93bb 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -574,8 +574,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) * After the last attribute is removed revert to original inode format, * making all literal area available to the data fork once more. */ -STATIC void -xfs_attr_fork_reset( +void +xfs_attr_fork_remove( struct xfs_inode *ip, struct xfs_trans *tp) { @@ -641,7 +641,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) (mp->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && !(args->op_flags & XFS_DA_OP_ADDNAME)) { - xfs_attr_fork_reset(dp, args->trans); + xfs_attr_fork_remove(dp, args->trans); } else { xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); @@ -905,7 +905,7 @@ xfs_attr3_leaf_to_shortform( if (forkoff == -1) { ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); - xfs_attr_fork_reset(dp, args->trans); + xfs_attr_fork_remove(dp, args->trans); goto out; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index 025c4b820c03..882c8d338891 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -53,7 +53,7 @@ int xfs_attr_shortform_remove(struct xfs_da_args *args); int xfs_attr_shortform_list(struct xfs_attr_list_context *context); int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); - +void xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp); /* * Internal routines when attribute fork size == XFS_LBSIZE(mp). diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index aeffeaaac0ec..f1026e86dabc 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3224,12 +3224,24 @@ xfs_bmap_extsize_align( align_alen += temp; align_off -= temp; } + + /* Same adjustment for the end of the requested area. */ + temp = (align_alen % extsz); + if (temp) + align_alen += extsz - temp; + /* - * Same adjustment for the end of the requested area. + * For large extent hint sizes, the aligned extent might be larger than + * MAXEXTLEN. In that case, reduce the size by an extsz so that it pulls + * the length back under MAXEXTLEN. The outer allocation loops handle + * short allocation just fine, so it is safe to do this. We only want to + * do it when we are forced to, though, because it means more allocation + * operations are required. */ - if ((temp = (align_alen % extsz))) { - align_alen += extsz - temp; - } + while (align_alen > MAXEXTLEN) + align_alen -= extsz; + ASSERT(align_alen <= MAXEXTLEN); + /* * If the previous block overlaps with this proposed allocation * then move the start forward without adjusting the length. @@ -3318,7 +3330,9 @@ xfs_bmap_extsize_align( return -EINVAL; } else { ASSERT(orig_off >= align_off); - ASSERT(orig_end <= align_off + align_alen); + /* see MAXEXTLEN handling above */ + ASSERT(orig_end <= align_off + align_alen || + align_alen + extsz > MAXEXTLEN); } #ifdef DEBUG @@ -4099,13 +4113,6 @@ xfs_bmapi_reserve_delalloc( /* Figure out the extent size, adjust alen */ extsz = xfs_get_extsz_hint(ip); if (extsz) { - /* - * Make sure we don't exceed a single extent length when we - * align the extent by reducing length we are going to - * allocate by the maximum amount extent size aligment may - * require. - */ - alen = XFS_FILBLKS_MIN(len, MAXEXTLEN - (2 * extsz - 1)); error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, 1, 0, &aoff, &alen); ASSERT(!error); diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 07349a183a11..1c9e75521250 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -376,7 +376,7 @@ xfs_ialloc_ag_alloc( */ newlen = args.mp->m_ialloc_inos; if (args.mp->m_maxicount && - percpu_counter_read(&args.mp->m_icount) + newlen > + percpu_counter_read_positive(&args.mp->m_icount) + newlen > args.mp->m_maxicount) return -ENOSPC; args.minlen = args.maxlen = args.mp->m_ialloc_blks; @@ -1339,10 +1339,13 @@ xfs_dialloc( * If we have already hit the ceiling of inode blocks then clear * okalloc so we scan all available agi structures for a free * inode. + * + * Read rough value of mp->m_icount by percpu_counter_read_positive, + * which will sacrifice the preciseness but improve the performance. */ if (mp->m_maxicount && - percpu_counter_read(&mp->m_icount) + mp->m_ialloc_inos > - mp->m_maxicount) { + percpu_counter_read_positive(&mp->m_icount) + mp->m_ialloc_inos + > mp->m_maxicount) { noroom = 1; okalloc = 0; } diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index f9c1c64782d3..3fbf167cfb4c 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -380,23 +380,31 @@ xfs_attr3_root_inactive( return error; } +/* + * xfs_attr_inactive kills all traces of an attribute fork on an inode. It + * removes both the on-disk and in-memory inode fork. Note that this also has to + * handle the condition of inodes without attributes but with an attribute fork + * configured, so we can't use xfs_inode_hasattr() here. + * + * The in-memory attribute fork is removed even on error. + */ int -xfs_attr_inactive(xfs_inode_t *dp) +xfs_attr_inactive( + struct xfs_inode *dp) { - xfs_trans_t *trans; - xfs_mount_t *mp; - int error; + struct xfs_trans *trans; + struct xfs_mount *mp; + int cancel_flags = 0; + int lock_mode = XFS_ILOCK_SHARED; + int error = 0; mp = dp->i_mount; ASSERT(! XFS_NOT_DQATTACHED(mp, dp)); - xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!xfs_inode_hasattr(dp) || - dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return 0; - } - xfs_iunlock(dp, XFS_ILOCK_SHARED); + xfs_ilock(dp, lock_mode); + if (!XFS_IFORK_Q(dp)) + goto out_destroy_fork; + xfs_iunlock(dp, lock_mode); /* * Start our first transaction of the day. @@ -408,13 +416,18 @@ xfs_attr_inactive(xfs_inode_t *dp) * the inode in every transaction to let it float upward through * the log. */ + lock_mode = 0; trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL); error = xfs_trans_reserve(trans, &M_RES(mp)->tr_attrinval, 0, 0); - if (error) { - xfs_trans_cancel(trans, 0); - return error; - } - xfs_ilock(dp, XFS_ILOCK_EXCL); + if (error) + goto out_cancel; + + lock_mode = XFS_ILOCK_EXCL; + cancel_flags = XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT; + xfs_ilock(dp, lock_mode); + + if (!XFS_IFORK_Q(dp)) + goto out_cancel; /* * No need to make quota reservations here. We expect to release some @@ -422,29 +435,31 @@ xfs_attr_inactive(xfs_inode_t *dp) */ xfs_trans_ijoin(trans, dp, 0); - /* - * Decide on what work routines to call based on the inode size. - */ - if (!xfs_inode_hasattr(dp) || - dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { - error = 0; - goto out; + /* invalidate and truncate the attribute fork extents */ + if (dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { + error = xfs_attr3_root_inactive(&trans, dp); + if (error) + goto out_cancel; + + error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0); + if (error) + goto out_cancel; } - error = xfs_attr3_root_inactive(&trans, dp); - if (error) - goto out; - error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0); - if (error) - goto out; + /* Reset the attribute fork - this also destroys the in-core fork */ + xfs_attr_fork_remove(dp, trans); error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES); - xfs_iunlock(dp, XFS_ILOCK_EXCL); - + xfs_iunlock(dp, lock_mode); return error; -out: - xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); - xfs_iunlock(dp, XFS_ILOCK_EXCL); +out_cancel: + xfs_trans_cancel(trans, cancel_flags); +out_destroy_fork: + /* kill the in-core attr fork before we drop the inode lock */ + if (dp->i_afp) + xfs_idestroy_fork(dp, XFS_ATTR_FORK); + if (lock_mode) + xfs_iunlock(dp, lock_mode); return error; } diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 8121e75352ee..3b7591224f4a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -124,7 +124,7 @@ xfs_iozero( status = 0; } while (count); - return (-status); + return status; } int diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d6ebc85192b7..539a85fddbc2 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1946,21 +1946,17 @@ xfs_inactive( /* * If there are attributes associated with the file then blow them away * now. The code calls a routine that recursively deconstructs the - * attribute fork. We need to just commit the current transaction - * because we can't use it for xfs_attr_inactive(). + * attribute fork. If also blows away the in-core attribute fork. */ - if (ip->i_d.di_anextents > 0) { - ASSERT(ip->i_d.di_forkoff != 0); - + if (XFS_IFORK_Q(ip)) { error = xfs_attr_inactive(ip); if (error) return; } - if (ip->i_afp) - xfs_idestroy_fork(ip, XFS_ATTR_FORK); - + ASSERT(!ip->i_afp); ASSERT(ip->i_d.di_anextents == 0); + ASSERT(ip->i_d.di_forkoff == 0); /* * Free the inode. @@ -2883,7 +2879,13 @@ xfs_rename_alloc_whiteout( if (error) return error; - /* Satisfy xfs_bumplink that this is a real tmpfile */ + /* + * Prepare the tmpfile inode as if it were created through the VFS. + * Otherwise, the link increment paths will complain about nlink 0->1. + * Drop the link count as done by d_tmpfile(), complete the inode setup + * and flag it as linkable. + */ + drop_nlink(VFS_I(tmpfile)); xfs_finish_inode_setup(tmpfile); VFS_I(tmpfile)->i_state |= I_LINKABLE; @@ -3151,7 +3153,7 @@ xfs_rename( * intermediate state on disk. */ if (wip) { - ASSERT(wip->i_d.di_nlink == 0); + ASSERT(VFS_I(wip)->i_nlink == 0 && wip->i_d.di_nlink == 0); error = xfs_bumplink(tp, wip); if (error) goto out_trans_abort; diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 2ce7ee3b4ec1..6f23fbdfb365 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1084,14 +1084,18 @@ xfs_log_sbcount(xfs_mount_t *mp) return xfs_sync_sb(mp, true); } +/* + * Deltas for the inode count are +/-64, hence we use a large batch size + * of 128 so we don't need to take the counter lock on every update. + */ +#define XFS_ICOUNT_BATCH 128 int xfs_mod_icount( struct xfs_mount *mp, int64_t delta) { - /* deltas are +/-64, hence the large batch size of 128. */ - __percpu_counter_add(&mp->m_icount, delta, 128); - if (percpu_counter_compare(&mp->m_icount, 0) < 0) { + __percpu_counter_add(&mp->m_icount, delta, XFS_ICOUNT_BATCH); + if (__percpu_counter_compare(&mp->m_icount, 0, XFS_ICOUNT_BATCH) < 0) { ASSERT(0); percpu_counter_add(&mp->m_icount, -delta); return -EINVAL; @@ -1113,6 +1117,14 @@ xfs_mod_ifree( return 0; } +/* + * Deltas for the block count can vary from 1 to very large, but lock contention + * only occurs on frequent small block count updates such as in the delayed + * allocation path for buffered writes (page a time updates). Hence we set + * a large batch count (1024) to minimise global counter updates except when + * we get near to ENOSPC and we have to be very accurate with our updates. + */ +#define XFS_FDBLOCKS_BATCH 1024 int xfs_mod_fdblocks( struct xfs_mount *mp, @@ -1151,25 +1163,19 @@ xfs_mod_fdblocks( * Taking blocks away, need to be more accurate the closer we * are to zero. * - * batch size is set to a maximum of 1024 blocks - if we are - * allocating of freeing extents larger than this then we aren't - * going to be hammering the counter lock so a lock per update - * is not a problem. - * * If the counter has a value of less than 2 * max batch size, * then make everything serialise as we are real close to * ENOSPC. */ -#define __BATCH 1024 - if (percpu_counter_compare(&mp->m_fdblocks, 2 * __BATCH) < 0) + if (__percpu_counter_compare(&mp->m_fdblocks, 2 * XFS_FDBLOCKS_BATCH, + XFS_FDBLOCKS_BATCH) < 0) batch = 1; else - batch = __BATCH; -#undef __BATCH + batch = XFS_FDBLOCKS_BATCH; __percpu_counter_add(&mp->m_fdblocks, delta, batch); - if (percpu_counter_compare(&mp->m_fdblocks, - XFS_ALLOC_SET_ASIDE(mp)) >= 0) { + if (__percpu_counter_compare(&mp->m_fdblocks, XFS_ALLOC_SET_ASIDE(mp), + XFS_FDBLOCKS_BATCH) >= 0) { /* we had space! */ return 0; } diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 2dd405c9be78..45c39a37f924 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -186,6 +186,7 @@ {0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ {0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ {0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x665f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index aff923ae8c4b..d87d8eced064 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -116,7 +116,6 @@ __printf(3, 4) int bdi_register(struct backing_dev_info *bdi, struct device *parent, const char *fmt, ...); int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); -void bdi_unregister(struct backing_dev_info *bdi); int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, enum wb_reason reason); diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index a1b25e35ea5f..b7299febc4b4 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -220,7 +220,7 @@ enum rq_flag_bits { /* This mask is used for both bio and request merge checking */ #define REQ_NOMERGE_FLAGS \ - (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) + (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ) #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) #define REQ_THROTTLED (1ULL << __REQ_THROTTLED) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 7f9a516f24de..5d93a6645e88 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -821,8 +821,6 @@ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, struct scsi_ioctl_command __user *); -extern void blk_queue_bio(struct request_queue *q, struct bio *bio); - /* * A queue has just exitted congestion. Note this in the global counter of * congested queues, and wake up anyone who was waiting for requests to be diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index ae2982c0f7a6..656da2a12ffe 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -17,7 +17,7 @@ #define PHY_ID_BCM7250 0xae025280 #define PHY_ID_BCM7364 0xae025260 #define PHY_ID_BCM7366 0x600d8490 -#define PHY_ID_BCM7425 0x03625e60 +#define PHY_ID_BCM7425 0x600d86b0 #define PHY_ID_BCM7429 0x600d8730 #define PHY_ID_BCM7439 0x600d8480 #define PHY_ID_BCM7439_2 0xae025080 diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index cdf13ca7cac3..371e560d13cf 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -9,10 +9,24 @@ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) - /* Optimization barrier */ + /* The "volatile" is due to gcc bugs */ #define barrier() __asm__ __volatile__("": : :"memory") +/* + * This version is i.e. to prevent dead stores elimination on @ptr + * where gcc and llvm may behave differently when otherwise using + * normal barrier(): while gcc behavior gets along with a normal + * barrier(), llvm needs an explicit input variable to be assumed + * clobbered. The issue is as follows: while the inline asm might + * access any memory it wants, the compiler could have fit all of + * @ptr into memory registers instead, and since @ptr never escaped + * from that, it proofed that the inline asm wasn't touching any of + * it. This version works well with both compilers, i.e. we're telling + * the compiler that the inline asm absolutely may see the contents + * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495 + */ +#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory") /* * This macro obfuscates arithmetic on a variable address so that gcc diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index ba147a1727e6..0c9a2f2c2802 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -13,9 +13,12 @@ /* Intel ECC compiler doesn't support gcc specific asm stmts. * It uses intrinsics to do the equivalent things. */ +#undef barrier_data #undef RELOC_HIDE #undef OPTIMIZER_HIDE_VAR +#define barrier_data(ptr) barrier() + #define RELOC_HIDE(ptr, off) \ ({ unsigned long __ptr; \ __ptr = (unsigned long) (ptr); \ diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 0e41ca0e5927..867722591be2 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -169,6 +169,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); # define barrier() __memory_barrier() #endif +#ifndef barrier_data +# define barrier_data(ptr) barrier() +#endif + /* Unreachable code */ #ifndef unreachable # define unreachable() do { } while (1) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 27e285b92b5f..59915ea5373c 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -151,10 +151,8 @@ static inline unsigned int cpumask_any_but(const struct cpumask *mask, return 1; } -static inline int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp) +static inline unsigned int cpumask_local_spread(unsigned int i, int node) { - set_bit(0, cpumask_bits(dstp)); - return 0; } @@ -208,7 +206,7 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) int cpumask_next_and(int n, const struct cpumask *, const struct cpumask *); int cpumask_any_but(const struct cpumask *mask, unsigned int cpu); -int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp); +unsigned int cpumask_local_spread(unsigned int i, int node); /** * for_each_cpu - iterate over every cpu in a mask diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 46e83c2156c6..f9ecf63d47f1 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -46,7 +46,7 @@ const char *ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int len); const char *ftrace_print_array_seq(struct trace_seq *p, - const void *buf, int buf_len, + const void *buf, int count, size_t el_size); struct trace_iterator; diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 97a9373e61e8..15928f0647e4 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -30,6 +30,7 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_RECLAIMABLE 0x80000u +#define ___GFP_NOACCOUNT 0x100000u #define ___GFP_NOTRACK 0x200000u #define ___GFP_NO_KSWAPD 0x400000u #define ___GFP_OTHER_NODE 0x800000u @@ -87,6 +88,7 @@ struct vm_area_struct; #define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */ #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */ +#define __GFP_NOACCOUNT ((__force gfp_t)___GFP_NOACCOUNT) /* Don't account to kmemcg */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */ #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD) diff --git a/include/linux/goldfish.h b/include/linux/goldfish.h index 569236e6b2bc..93e080b39cf6 100644 --- a/include/linux/goldfish.h +++ b/include/linux/goldfish.h @@ -3,13 +3,24 @@ /* Helpers for Goldfish virtual platform */ -static inline void gf_write64(unsigned long data, - void __iomem *portl, void __iomem *porth) +static inline void gf_write_ptr(const void *ptr, void __iomem *portl, + void __iomem *porth) { - writel((u32)data, portl); + writel((u32)(unsigned long)ptr, portl); #ifdef CONFIG_64BIT - writel(data>>32, porth); + writel((unsigned long)ptr >> 32, porth); #endif } +static inline void gf_write_dma_addr(const dma_addr_t addr, + void __iomem *portl, + void __iomem *porth) +{ + writel((u32)addr, portl); +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + writel(addr >> 32, porth); +#endif +} + + #endif /* __LINUX_GOLDFISH_H */ diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index 0408421d885f..0042bf330b99 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h @@ -74,7 +74,7 @@ struct sensor_hub_pending { * @usage: Usage id for this hub device instance. * @start_collection_index: Starting index for a phy type collection * @end_collection_index: Last index for a phy type collection - * @mutex: synchronizing mutex. + * @mutex_ptr: synchronizing mutex pointer. * @pending: Holds information of pending sync read request. */ struct hid_sensor_hub_device { @@ -84,7 +84,7 @@ struct hid_sensor_hub_device { u32 usage; int start_collection_index; int end_collection_index; - struct mutex mutex; + struct mutex *mutex_ptr; struct sensor_hub_pending pending; }; diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 36ec4ae74634..9de976b4f9a7 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -95,8 +95,6 @@ struct device_node; -extern struct irq_chip gic_arch_extn; - void gic_set_irqchip_flags(unsigned long flags); void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 5fc3d1083071..2b6a204bd8d4 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -166,19 +166,34 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) } #if BITS_PER_LONG < 64 -extern u64 __ktime_divns(const ktime_t kt, s64 div); -static inline u64 ktime_divns(const ktime_t kt, s64 div) +extern s64 __ktime_divns(const ktime_t kt, s64 div); +static inline s64 ktime_divns(const ktime_t kt, s64 div) { + /* + * Negative divisors could cause an inf loop, + * so bug out here. + */ + BUG_ON(div < 0); if (__builtin_constant_p(div) && !(div >> 32)) { - u64 ns = kt.tv64; - do_div(ns, div); - return ns; + s64 ns = kt.tv64; + u64 tmp = ns < 0 ? -ns : ns; + + do_div(tmp, div); + return ns < 0 ? -tmp : tmp; } else { return __ktime_divns(kt, div); } } #else /* BITS_PER_LONG < 64 */ -# define ktime_divns(kt, div) (u64)((kt).tv64 / (div)) +static inline s64 ktime_divns(const ktime_t kt, s64 div) +{ + /* + * 32-bit implementation cannot handle negative divisors, + * so catch them on 64bit as well. + */ + WARN_ON(div < 0); + return kt.tv64 / div; +} #endif static inline s64 ktime_to_us(const ktime_t kt) diff --git a/include/linux/libata.h b/include/linux/libata.h index 8dad4a307bb8..28aeae46f355 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -205,6 +205,7 @@ enum { ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ + ATA_LFLAG_CHANGED = (1 << 10), /* LPM state changed on this link */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ @@ -309,6 +310,12 @@ enum { */ ATA_TMOUT_PMP_SRST_WAIT = 5000, + /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might + * be a spurious PHY event, so ignore the first PHY event that + * occurs within 10s after the policy change. + */ + ATA_TMOUT_SPURIOUS_PHY = 10000, + /* ATA bus states */ BUS_UNKNOWN = 0, BUS_DMA = 1, @@ -788,6 +795,8 @@ struct ata_link { struct ata_eh_context eh_context; struct ata_device device[ATA_MAX_DEVICES]; + + unsigned long last_lpm_change; /* when last LPM change happened */ }; #define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag) #define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0]) @@ -1201,6 +1210,7 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q); +extern bool sata_lpm_ignore_phy_events(struct ata_link *link); extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 72dff5fb0d0c..6c8918114804 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -463,6 +463,8 @@ memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **memcg, int order) if (!memcg_kmem_enabled()) return true; + if (gfp & __GFP_NOACCOUNT) + return true; /* * __GFP_NOFAIL allocations will move on even if charging is not * possible. Therefore we don't even try, and have this allocation @@ -522,6 +524,8 @@ memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) { if (!memcg_kmem_enabled()) return cachep; + if (gfp & __GFP_NOACCOUNT) + return cachep; if (gfp & __GFP_NOFAIL) return cachep; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1899c74a7127..05b9a694e213 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -25,7 +25,6 @@ #ifndef _LINUX_NETDEVICE_H #define _LINUX_NETDEVICE_H -#include <linux/pm_qos.h> #include <linux/timer.h> #include <linux/bug.h> #include <linux/delay.h> @@ -1499,8 +1498,6 @@ enum netdev_priv_flags { * * @qdisc_tx_busylock: XXX: need comments on this one * - * @pm_qos_req: Power Management QoS object - * * FIXME: cleanup struct net_device such that network protocol info * moves out. */ diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index ff3fea3194c6..9abb763e4b86 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h @@ -460,7 +460,7 @@ struct nilfs_btree_node { /* level */ #define NILFS_BTREE_LEVEL_DATA 0 #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) -#define NILFS_BTREE_LEVEL_MAX 14 +#define NILFS_BTREE_LEVEL_MAX 14 /* Max level (exclusive) */ /** * struct nilfs_palloc_group_desc - block group descriptor diff --git a/include/linux/of.h b/include/linux/of.h index ddeaae6d2083..b871ff9d81d7 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -121,6 +121,8 @@ extern struct device_node *of_stdout; extern raw_spinlock_t devtree_lock; #ifdef CONFIG_OF +void of_core_init(void); + static inline bool is_of_node(struct fwnode_handle *fwnode) { return fwnode && fwnode->type == FWNODE_OF; @@ -376,6 +378,10 @@ bool of_console_check(struct device_node *dn, char *name, int index); #else /* CONFIG_OF */ +static inline void of_core_init(void) +{ +} + static inline bool is_of_node(struct fwnode_handle *fwnode) { return false; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 38cff8f6716d..2f7b9a40f627 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2541,10 +2541,6 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 -#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 -#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154 -#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150 -#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 50e50095c8d1..84a109449610 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -41,7 +41,12 @@ void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); s64 __percpu_counter_sum(struct percpu_counter *fbc); -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs); +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch); + +static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +{ + return __percpu_counter_compare(fbc, rhs, percpu_counter_batch); +} static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -116,6 +121,12 @@ static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) return 0; } +static inline int +__percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) +{ + return percpu_counter_compare(fbc, rhs); +} + static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 61992cf2e977..d8a82a89f35a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -92,8 +92,6 @@ struct hw_perf_event_extra { int idx; /* index in shared_regs->regs[] */ }; -struct event_constraint; - /** * struct hw_perf_event - performance event hardware details: */ @@ -112,8 +110,6 @@ struct hw_perf_event { struct hw_perf_event_extra extra_reg; struct hw_perf_event_extra branch_reg; - - struct event_constraint *constraint; }; struct { /* software */ struct hrtimer hrtimer; diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h index a947ab8b441a..533d9807e543 100644 --- a/include/linux/platform_data/si5351.h +++ b/include/linux/platform_data/si5351.h @@ -5,8 +5,6 @@ #ifndef __LINUX_PLATFORM_DATA_SI5351_H__ #define __LINUX_PLATFORM_DATA_SI5351_H__ -struct clk; - /** * enum si5351_pll_src - Si5351 pll clock source * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config @@ -107,8 +105,6 @@ struct si5351_clkout_config { * @clkout: array of clkout configuration */ struct si5351_platform_data { - struct clk *clk_xtal; - struct clk *clk_clkin; enum si5351_pll_src pll_src[2]; struct si5351_clkout_config clkout[8]; }; diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index dbcbcc59aa92..843ceca9a21e 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -17,6 +17,7 @@ #ifndef _LINUX_RHASHTABLE_H #define _LINUX_RHASHTABLE_H +#include <linux/atomic.h> #include <linux/compiler.h> #include <linux/errno.h> #include <linux/jhash.h> @@ -100,6 +101,7 @@ struct rhashtable; * @key_len: Length of key * @key_offset: Offset of key in struct to be hashed * @head_offset: Offset of rhash_head in struct to be hashed + * @insecure_max_entries: Maximum number of entries (may be exceeded) * @max_size: Maximum size while expanding * @min_size: Minimum size while shrinking * @nulls_base: Base value to generate nulls marker @@ -115,6 +117,7 @@ struct rhashtable_params { size_t key_len; size_t key_offset; size_t head_offset; + unsigned int insecure_max_entries; unsigned int max_size; unsigned int min_size; u32 nulls_base; @@ -286,6 +289,18 @@ static inline bool rht_grow_above_100(const struct rhashtable *ht, (!ht->p.max_size || tbl->size < ht->p.max_size); } +/** + * rht_grow_above_max - returns true if table is above maximum + * @ht: hash table + * @tbl: current table + */ +static inline bool rht_grow_above_max(const struct rhashtable *ht, + const struct bucket_table *tbl) +{ + return ht->p.insecure_max_entries && + atomic_read(&ht->nelems) >= ht->p.insecure_max_entries; +} + /* The bucket lock is selected based on the hash and protects mutations * on a group of hash buckets. * @@ -589,6 +604,10 @@ restart: goto out; } + err = -E2BIG; + if (unlikely(rht_grow_above_max(ht, tbl))) + goto out; + if (unlikely(rht_grow_above_100(ht, tbl))) { slow_path: spin_unlock_bh(lock); diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h index 6341f5be6e24..a30b172df6e1 100644 --- a/include/linux/sched/rt.h +++ b/include/linux/sched/rt.h @@ -18,7 +18,7 @@ static inline int rt_task(struct task_struct *p) #ifdef CONFIG_RT_MUTEXES extern int rt_mutex_getprio(struct task_struct *p); extern void rt_mutex_setprio(struct task_struct *p, int prio); -extern int rt_mutex_check_prio(struct task_struct *task, int newprio); +extern int rt_mutex_get_effective_prio(struct task_struct *task, int newprio); extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task); extern void rt_mutex_adjust_pi(struct task_struct *p); static inline bool tsk_is_pi_blocked(struct task_struct *tsk) @@ -31,9 +31,10 @@ static inline int rt_mutex_getprio(struct task_struct *p) return p->normal_prio; } -static inline int rt_mutex_check_prio(struct task_struct *task, int newprio) +static inline int rt_mutex_get_effective_prio(struct task_struct *task, + int newprio) { - return 0; + return newprio; } static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 66e374d62f64..f15154a879c7 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -176,6 +176,7 @@ struct nf_bridge_info { struct net_device *physindev; struct net_device *physoutdev; char neigh_header[8]; + __be32 ipv4_daddr; }; #endif diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 0caa3a2d4106..e8bbf403618f 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -145,11 +145,21 @@ struct tcp_sock { * read the code and the spec side by side (and laugh ...) * See RFC793 and RFC1122. The RFC writes these in capitals. */ + u64 bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived + * sum(delta(rcv_nxt)), or how many bytes + * were acked. + */ u32 rcv_nxt; /* What we want to receive next */ u32 copied_seq; /* Head of yet unread data */ u32 rcv_wup; /* rcv_nxt on last window update sent */ u32 snd_nxt; /* Next sequence we send */ + u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked + * sum(delta(snd_una)), or how many bytes + * were acked. + */ + struct u64_stats_sync syncp; /* protects 64bit vars (cf tcp_get_info()) */ + u32 snd_una; /* First byte we want an ack for */ u32 snd_sml; /* Last byte of the most recently transmitted small packet */ u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ diff --git a/include/linux/tty.h b/include/linux/tty.h index fe5623c9af71..d76631f615c2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -339,6 +339,7 @@ struct tty_file_private { #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ #define TTY_DEBUG 4 /* Debugging */ #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ +#define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */ #define TTY_LDISC_OPEN 11 /* Line discipline is open */ #define TTY_PTY_LOCK 16 /* pty private */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ @@ -462,7 +463,6 @@ extern int tty_hung_up_p(struct file *filp); extern void do_SAK(struct tty_struct *tty); extern void __do_SAK(struct tty_struct *tty); extern void no_tty(void); -extern void tty_flush_to_ldisc(struct tty_struct *tty); extern void tty_buffer_free_all(struct tty_port *port); extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); extern void tty_buffer_init(struct tty_port *port); diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h index 0ee05da38899..03835522dfcb 100644 --- a/include/linux/uidgid.h +++ b/include/linux/uidgid.h @@ -109,12 +109,12 @@ static inline bool gid_lte(kgid_t left, kgid_t right) static inline bool uid_valid(kuid_t uid) { - return !uid_eq(uid, INVALID_UID); + return __kuid_val(uid) != (uid_t) -1; } static inline bool gid_valid(kgid_t gid) { - return !gid_eq(gid, INVALID_GID); + return __kgid_val(gid) != (gid_t) -1; } #ifdef CONFIG_USER_NS diff --git a/include/linux/util_macros.h b/include/linux/util_macros.h index d5f4fb69dba3..f9b2ce58039b 100644 --- a/include/linux/util_macros.h +++ b/include/linux/util_macros.h @@ -5,7 +5,7 @@ ({ \ typeof(as) __fc_i, __fc_as = (as) - 1; \ typeof(x) __fc_x = (x); \ - typeof(*a) *__fc_a = (a); \ + typeof(*a) const *__fc_a = (a); \ for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ __fc_a[__fc_i + 1], 2)) \ diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index eeda67652766..6ea16c84293b 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -30,11 +30,13 @@ struct wpan_phy_cca; struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, + unsigned char name_assign_type, int type); void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, struct net_device *dev); int (*add_virtual_intf)(struct wpan_phy *wpan_phy, const char *name, + unsigned char name_assign_type, enum nl802154_iftype type, __le64 extended_addr); int (*del_virtual_intf)(struct wpan_phy *wpan_phy, diff --git a/include/net/codel.h b/include/net/codel.h index aeee28081245..1e18005f7f65 100644 --- a/include/net/codel.h +++ b/include/net/codel.h @@ -120,11 +120,13 @@ static inline u32 codel_time_to_us(codel_time_t val) * struct codel_params - contains codel parameters * @target: target queue size (in time units) * @interval: width of moving time window + * @mtu: device mtu, or minimal queue backlog in bytes. * @ecn: is Explicit Congestion Notification enabled */ struct codel_params { codel_time_t target; codel_time_t interval; + u32 mtu; bool ecn; }; @@ -166,10 +168,12 @@ struct codel_stats { u32 ecn_mark; }; -static void codel_params_init(struct codel_params *params) +static void codel_params_init(struct codel_params *params, + const struct Qdisc *sch) { params->interval = MS2TIME(100); params->target = MS2TIME(5); + params->mtu = psched_mtu(qdisc_dev(sch)); params->ecn = false; } @@ -180,7 +184,7 @@ static void codel_vars_init(struct codel_vars *vars) static void codel_stats_init(struct codel_stats *stats) { - stats->maxpacket = 256; + stats->maxpacket = 0; } /* @@ -234,7 +238,7 @@ static bool codel_should_drop(const struct sk_buff *skb, stats->maxpacket = qdisc_pkt_len(skb); if (codel_time_before(vars->ldelay, params->target) || - sch->qstats.backlog <= stats->maxpacket) { + sch->qstats.backlog <= params->mtu) { /* went below - stay below for at least interval */ vars->first_above_time = 0; return false; diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 48a815823587..0320bbb7d7b5 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -98,7 +98,8 @@ struct inet_connection_sock { const struct tcp_congestion_ops *icsk_ca_ops; const struct inet_connection_sock_af_ops *icsk_af_ops; unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); - __u8 icsk_ca_state:7, + __u8 icsk_ca_state:6, + icsk_ca_setsockopt:1, icsk_ca_dst_locked:1; __u8 icsk_retransmits; __u8 icsk_pending; @@ -129,9 +130,10 @@ struct inet_connection_sock { u32 probe_timestamp; } icsk_mtup; - u32 icsk_ca_priv[16]; u32 icsk_user_timeout; -#define ICSK_CA_PRIV_SIZE (16 * sizeof(u32)) + + u64 icsk_ca_priv[64 / sizeof(u64)]; +#define ICSK_CA_PRIV_SIZE (8 * sizeof(u64)) }; #define ICSK_TIME_RETRANS 1 /* Retransmit timer */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b4bef1152c05..fc57f6b82fc5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -354,7 +354,7 @@ enum ieee80211_rssi_event_data { }; /** - * enum ieee80211_rssi_event - data attached to an %RSSI_EVENT + * struct ieee80211_rssi_event - data attached to an %RSSI_EVENT * @data: See &enum ieee80211_rssi_event_data */ struct ieee80211_rssi_event { @@ -388,7 +388,7 @@ enum ieee80211_mlme_event_status { }; /** - * enum ieee80211_mlme_event - data attached to an %MLME_EVENT + * struct ieee80211_mlme_event - data attached to an %MLME_EVENT * @data: See &enum ieee80211_mlme_event_data * @status: See &enum ieee80211_mlme_event_status * @reason: the reason code if applicable @@ -401,9 +401,10 @@ struct ieee80211_mlme_event { /** * struct ieee80211_event - event to be sent to the driver - * @type The event itself. See &enum ieee80211_event_type. + * @type: The event itself. See &enum ieee80211_event_type. * @rssi: relevant if &type is %RSSI_EVENT * @mlme: relevant if &type is %AUTH_EVENT + * @u: union holding the above two fields */ struct ieee80211_event { enum ieee80211_event_type type; @@ -1666,6 +1667,8 @@ struct ieee80211_tx_control { * @sta: station table entry, %NULL for per-vif queue * @tid: the TID for this queue (unused for per-vif queue) * @ac: the AC for this queue + * @drv_priv: data area for driver use, will always be aligned to + * sizeof(void *). * * The driver can obtain packets from this queue by calling * ieee80211_tx_dequeue(). diff --git a/include/net/mac802154.h b/include/net/mac802154.h index e18e7fd43f47..7df28a4c23f9 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -247,19 +247,109 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) __put_unaligned_memmove64(swab64p(le64_src), be64_dst); } -/* Basic interface to register ieee802154 device */ +/** + * ieee802154_alloc_hw - Allocate a new hardware device + * + * This must be called once for each hardware device. The returned pointer + * must be used to refer to this device when calling other functions. + * mac802154 allocates a private data area for the driver pointed to by + * @priv in &struct ieee802154_hw, the size of this area is given as + * @priv_data_len. + * + * @priv_data_len: length of private data + * @ops: callbacks for this device + * + * Return: A pointer to the new hardware device, or %NULL on error. + */ struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); + +/** + * ieee802154_free_hw - free hardware descriptor + * + * This function frees everything that was allocated, including the + * private data for the driver. You must call ieee802154_unregister_hw() + * before calling this function. + * + * @hw: the hardware to free + */ void ieee802154_free_hw(struct ieee802154_hw *hw); + +/** + * ieee802154_register_hw - Register hardware device + * + * You must call this function before any other functions in + * mac802154. Note that before a hardware can be registered, you + * need to fill the contained wpan_phy's information. + * + * @hw: the device to register as returned by ieee802154_alloc_hw() + * + * Return: 0 on success. An error code otherwise. + */ int ieee802154_register_hw(struct ieee802154_hw *hw); + +/** + * ieee802154_unregister_hw - Unregister a hardware device + * + * This function instructs mac802154 to free allocated resources + * and unregister netdevices from the networking subsystem. + * + * @hw: the hardware to unregister + */ void ieee802154_unregister_hw(struct ieee802154_hw *hw); +/** + * ieee802154_rx - receive frame + * + * Use this function to hand received frames to mac802154. The receive + * buffer in @skb must start with an IEEE 802.15.4 header. In case of a + * paged @skb is used, the driver is recommended to put the ieee802154 + * header of the frame on the linear part of the @skb to avoid memory + * allocation and/or memcpy by the stack. + * + * This function may not be called in IRQ context. Calls to this function + * for a single hardware must be synchronized against each other. + * + * @hw: the hardware this frame came in on + * @skb: the buffer to receive, owned by mac802154 after this call + */ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb); + +/** + * ieee802154_rx_irqsafe - receive frame + * + * Like ieee802154_rx() but can be called in IRQ context + * (internally defers to a tasklet.) + * + * @hw: the hardware this frame came in on + * @skb: the buffer to receive, owned by mac802154 after this call + * @lqi: link quality indicator + */ void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); - +/** + * ieee802154_wake_queue - wake ieee802154 queue + * @hw: pointer as obtained from ieee802154_alloc_hw(). + * + * Drivers should use this function instead of netif_wake_queue. + */ void ieee802154_wake_queue(struct ieee802154_hw *hw); + +/** + * ieee802154_stop_queue - stop ieee802154 queue + * @hw: pointer as obtained from ieee802154_alloc_hw(). + * + * Drivers should use this function instead of netif_stop_queue. + */ void ieee802154_stop_queue(struct ieee802154_hw *hw); + +/** + * ieee802154_xmit_complete - frame transmission complete + * + * @hw: pointer as obtained from ieee802154_alloc_hw(). + * @skb: buffer for transmission + * @ifs_handling: indicate interframe space handling + */ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb, bool ifs_handling); diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index c56a438c3a1e..ce13cf20f625 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -574,11 +574,14 @@ static inline void sctp_v6_map_v4(union sctp_addr *addr) /* Map v4 address to v4-mapped v6 address */ static inline void sctp_v4_map_v6(union sctp_addr *addr) { + __be16 port; + + port = addr->v4.sin_port; + addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; + addr->v6.sin6_port = port; addr->v6.sin6_family = AF_INET6; addr->v6.sin6_flowinfo = 0; addr->v6.sin6_scope_id = 0; - addr->v6.sin6_port = addr->v4.sin_port; - addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; addr->v6.sin6_addr.s6_addr32[0] = 0; addr->v6.sin6_addr.s6_addr32[1] = 0; addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff); diff --git a/include/net/tcp.h b/include/net/tcp.h index 051dc5c2802d..6d204f3f9df8 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -576,7 +576,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) } /* tcp.c */ -void tcp_get_info(const struct sock *, struct tcp_info *); +void tcp_get_info(struct sock *, struct tcp_info *); /* Read 'sendfile()'-style from a TCP socket */ typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, @@ -804,6 +804,8 @@ enum tcp_ca_ack_event_flags { /* Requires ECN/ECT set on all packets */ #define TCP_CONG_NEEDS_ECN 0x2 +union tcp_cc_info; + struct tcp_congestion_ops { struct list_head list; u32 key; @@ -829,7 +831,8 @@ struct tcp_congestion_ops { /* hook for packet ack accounting (optional) */ void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us); /* get info for inet_diag (optional) */ - int (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); + size_t (*get_info)(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info); char name[TCP_CA_NAME_MAX]; struct module *owner; diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index ce55906b54a0..ac54c27a2bfd 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -160,7 +160,7 @@ static inline int rdma_ip2gid(struct sockaddr *addr, union ib_gid *gid) } /* Important - sockaddr should be a union of sockaddr_in and sockaddr_in6 */ -static inline int rdma_gid2ip(struct sockaddr *out, union ib_gid *gid) +static inline void rdma_gid2ip(struct sockaddr *out, union ib_gid *gid) { if (ipv6_addr_v4mapped((struct in6_addr *)gid)) { struct sockaddr_in *out_in = (struct sockaddr_in *)out; @@ -173,7 +173,6 @@ static inline int rdma_gid2ip(struct sockaddr *out, union ib_gid *gid) out_in->sin6_family = AF_INET6; memcpy(&out_in->sin6_addr.s6_addr, gid->raw, 16); } - return 0; } static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h index 0e3ff30647d5..39ed2d2fbd51 100644 --- a/include/rdma/ib_cm.h +++ b/include/rdma/ib_cm.h @@ -105,7 +105,8 @@ enum ib_cm_data_size { IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE = 216, IB_CM_SIDR_REP_PRIVATE_DATA_SIZE = 136, IB_CM_SIDR_REP_INFO_LENGTH = 72, - IB_CM_COMPARE_SIZE = 64 + /* compare done u32 at a time */ + IB_CM_COMPARE_SIZE = (64 / sizeof(u32)) }; struct ib_cm_id; @@ -337,8 +338,8 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id); #define IB_SDP_SERVICE_ID_MASK cpu_to_be64(0xFFFFFFFFFFFF0000ULL) struct ib_cm_compare_data { - u8 data[IB_CM_COMPARE_SIZE]; - u8 mask[IB_CM_COMPARE_SIZE]; + u32 data[IB_CM_COMPARE_SIZE]; + u32 mask[IB_CM_COMPARE_SIZE]; }; /** diff --git a/include/rdma/iw_portmap.h b/include/rdma/iw_portmap.h index 928b2775e992..fda31673a562 100644 --- a/include/rdma/iw_portmap.h +++ b/include/rdma/iw_portmap.h @@ -148,6 +148,16 @@ int iwpm_add_mapping_cb(struct sk_buff *, struct netlink_callback *); int iwpm_add_and_query_mapping_cb(struct sk_buff *, struct netlink_callback *); /** + * iwpm_remote_info_cb - Process remote connecting peer address info, which + * the port mapper has received from the connecting peer + * + * @cb: Contains the received message (payload and netlink header) + * + * Stores the IPv4/IPv6 address info in a hash table + */ +int iwpm_remote_info_cb(struct sk_buff *, struct netlink_callback *); + +/** * iwpm_mapping_error_cb - Process port mapper notification for error * * @skb: @@ -175,6 +185,21 @@ int iwpm_mapping_info_cb(struct sk_buff *, struct netlink_callback *); int iwpm_ack_mapping_info_cb(struct sk_buff *, struct netlink_callback *); /** + * iwpm_get_remote_info - Get the remote connecting peer address info + * + * @mapped_loc_addr: Mapped local address of the listening peer + * @mapped_rem_addr: Mapped remote address of the connecting peer + * @remote_addr: To store the remote address of the connecting peer + * @nl_client: The index of the netlink client + * + * The remote address info is retrieved and provided to the client in + * the remote_addr. After that it is removed from the hash table + */ +int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, + struct sockaddr_storage *mapped_rem_addr, + struct sockaddr_storage *remote_addr, u8 nl_client); + +/** * iwpm_create_mapinfo - Store local and mapped IPv4/IPv6 address * info in a hash table * @local_addr: Local ip/tcp address diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index d61be7297b2c..5f1225706993 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -1,9 +1,7 @@ #ifndef TARGET_CORE_BACKEND_H #define TARGET_CORE_BACKEND_H -#define TRANSPORT_PLUGIN_PHBA_PDEV 1 -#define TRANSPORT_PLUGIN_VHBA_PDEV 2 -#define TRANSPORT_PLUGIN_VHBA_VDEV 3 +#define TRANSPORT_FLAG_PASSTHROUGH 1 struct target_backend_cits { struct config_item_type tb_dev_cit; @@ -22,7 +20,7 @@ struct se_subsystem_api { char inquiry_rev[4]; struct module *owner; - u8 transport_type; + u8 transport_flags; int (*attach_hba)(struct se_hba *, u32); void (*detach_hba)(struct se_hba *); @@ -138,5 +136,7 @@ int se_dev_set_queue_depth(struct se_device *, u32); int se_dev_set_max_sectors(struct se_device *, u32); int se_dev_set_optimal_sectors(struct se_device *, u32); int se_dev_set_block_size(struct se_device *, u32); +sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd, + sense_reason_t (*exec_cmd)(struct se_cmd *cmd)); #endif /* TARGET_CORE_BACKEND_H */ diff --git a/include/target/target_core_configfs.h b/include/target/target_core_configfs.h index 25bb04c4209e..b99c01170392 100644 --- a/include/target/target_core_configfs.h +++ b/include/target/target_core_configfs.h @@ -40,8 +40,6 @@ struct target_fabric_configfs { struct config_item *tf_fabric; /* Passed from fabric modules */ struct config_item_type *tf_fabric_cit; - /* Pointer to target core subsystem */ - struct configfs_subsystem *tf_subsys; /* Pointer to fabric's struct module */ struct module *tf_module; struct target_core_fabric_ops tf_ops; diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 17c7f5ac7ea0..0f4dc3768587 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -4,7 +4,6 @@ struct target_core_fabric_ops { struct module *module; const char *name; - struct configfs_subsystem *tf_subsys; char *(*get_fabric_name)(void); u8 (*get_fabric_proto_ident)(struct se_portal_group *); char *(*tpg_get_wwn)(struct se_portal_group *); @@ -109,6 +108,9 @@ struct target_core_fabric_ops { int target_register_template(const struct target_core_fabric_ops *fo); void target_unregister_template(const struct target_core_fabric_ops *fo); +int target_depend_item(struct config_item *item); +void target_undepend_item(struct config_item *item); + struct se_session *transport_init_session(enum target_prot_op); int transport_alloc_session_tags(struct se_session *, unsigned int, unsigned int); diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 81ea59812117..f7554fd7fc62 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h @@ -140,19 +140,42 @@ DEFINE_EVENT(kmem_free, kfree, TP_ARGS(call_site, ptr) ); -DEFINE_EVENT(kmem_free, kmem_cache_free, +DEFINE_EVENT_CONDITION(kmem_free, kmem_cache_free, TP_PROTO(unsigned long call_site, const void *ptr), - TP_ARGS(call_site, ptr) + TP_ARGS(call_site, ptr), + + /* + * This trace can be potentially called from an offlined cpu. + * Since trace points use RCU and RCU should not be used from + * offline cpus, filter such calls out. + * While this trace can be called from a preemptable section, + * it has no impact on the condition since tasks can migrate + * only from online cpus to other online cpus. Thus its safe + * to use raw_smp_processor_id. + */ + TP_CONDITION(cpu_online(raw_smp_processor_id())) ); -TRACE_EVENT(mm_page_free, +TRACE_EVENT_CONDITION(mm_page_free, TP_PROTO(struct page *page, unsigned int order), TP_ARGS(page, order), + + /* + * This trace can be potentially called from an offlined cpu. + * Since trace points use RCU and RCU should not be used from + * offline cpus, filter such calls out. + * While this trace can be called from a preemptable section, + * it has no impact on the condition since tasks can migrate + * only from online cpus to other online cpus. Thus its safe + * to use raw_smp_processor_id. + */ + TP_CONDITION(cpu_online(raw_smp_processor_id())), + TP_STRUCT__entry( __field( unsigned long, pfn ) __field( unsigned int, order ) @@ -253,12 +276,35 @@ DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, TP_ARGS(page, order, migratetype) ); -DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, +TRACE_EVENT_CONDITION(mm_page_pcpu_drain, TP_PROTO(struct page *page, unsigned int order, int migratetype), TP_ARGS(page, order, migratetype), + /* + * This trace can be potentially called from an offlined cpu. + * Since trace points use RCU and RCU should not be used from + * offline cpus, filter such calls out. + * While this trace can be called from a preemptable section, + * it has no impact on the condition since tasks can migrate + * only from online cpus to other online cpus. Thus its safe + * to use raw_smp_processor_id. + */ + TP_CONDITION(cpu_online(raw_smp_processor_id())), + + TP_STRUCT__entry( + __field( unsigned long, pfn ) + __field( unsigned int, order ) + __field( int, migratetype ) + ), + + TP_fast_assign( + __entry->pfn = page ? page_to_pfn(page) : -1UL; + __entry->order = order; + __entry->migratetype = migratetype; + ), + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", pfn_to_page(__entry->pfn), __entry->pfn, __entry->order, __entry->migratetype) diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 880dd7437172..c178d13d6f4c 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h @@ -250,7 +250,6 @@ DEFINE_EVENT(writeback_class, name, \ DEFINE_WRITEBACK_EVENT(writeback_nowork); DEFINE_WRITEBACK_EVENT(writeback_wake_background); DEFINE_WRITEBACK_EVENT(writeback_bdi_register); -DEFINE_WRITEBACK_EVENT(writeback_bdi_unregister); DECLARE_EVENT_CLASS(wbc_class, TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi), diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index d65c0a09efd3..c7093c75bdd6 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h @@ -143,4 +143,8 @@ struct tcp_dctcp_info { __u32 dctcp_ab_tot; }; +union tcp_cc_info { + struct tcpvegas_info vegas; + struct tcp_dctcp_info dctcp; +}; #endif /* _UAPI_INET_DIAG_H_ */ diff --git a/include/uapi/linux/mpls.h b/include/uapi/linux/mpls.h index bc9abfe88c9a..139d4dd1cab8 100644 --- a/include/uapi/linux/mpls.h +++ b/include/uapi/linux/mpls.h @@ -31,4 +31,14 @@ struct mpls_label { #define MPLS_LS_TTL_MASK 0x000000FF #define MPLS_LS_TTL_SHIFT 0 +/* Reserved labels */ +#define MPLS_LABEL_IPV4NULL 0 /* RFC3032 */ +#define MPLS_LABEL_RTALERT 1 /* RFC3032 */ +#define MPLS_LABEL_IPV6NULL 2 /* RFC3032 */ +#define MPLS_LABEL_IMPLNULL 3 /* RFC3032 */ +#define MPLS_LABEL_ENTROPY 7 /* RFC6790 */ +#define MPLS_LABEL_GAL 13 /* RFC5586 */ +#define MPLS_LABEL_OAMALERT 14 /* RFC3429 */ +#define MPLS_LABEL_EXTENSION 15 /* RFC7274 */ + #endif /* _UAPI_MPLS_H */ diff --git a/include/uapi/linux/netfilter/nf_conntrack_tcp.h b/include/uapi/linux/netfilter/nf_conntrack_tcp.h index 9993a421201c..ef9f80f0f529 100644 --- a/include/uapi/linux/netfilter/nf_conntrack_tcp.h +++ b/include/uapi/linux/netfilter/nf_conntrack_tcp.h @@ -42,6 +42,9 @@ enum tcp_conntrack { /* The field td_maxack has been set */ #define IP_CT_TCP_FLAG_MAXACK_SET 0x20 +/* Marks possibility for expected RFC5961 challenge ACK */ +#define IP_CT_EXP_CHALLENGE_ACK 0x40 + struct nf_ct_tcp_flags { __u8 flags; __u8 mask; diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index 974db03f7b1a..17fb02f488da 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -337,7 +337,7 @@ struct rtnexthop { #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ #define RTNH_F_ONLINK 4 /* Gateway is forced on link */ -#define RTNH_F_EXTERNAL 8 /* Route installed externally */ +#define RTNH_F_OFFLOAD 8 /* offloaded route */ /* Macros to handle hexthops */ diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index 3b9718328d8b..faa72f4fa547 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -112,6 +112,7 @@ enum { #define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ #define TCP_TIMESTAMP 24 #define TCP_NOTSENT_LOWAT 25 /* limit number of unsent bytes in write queue */ +#define TCP_CC_INFO 26 /* Get Congestion Control (optional) info */ struct tcp_repair_opt { __u32 opt_code; @@ -189,6 +190,8 @@ struct tcp_info { __u64 tcpi_pacing_rate; __u64 tcpi_max_pacing_rate; + __u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ + __u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ }; /* for TCP_MD5SIG socket option */ diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h index 984169a819ee..d7f1cbc3766c 100644 --- a/include/uapi/linux/virtio_balloon.h +++ b/include/uapi/linux/virtio_balloon.h @@ -26,6 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include <linux/types.h> +#include <linux/virtio_types.h> #include <linux/virtio_ids.h> #include <linux/virtio_config.h> diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h index de69170a30ce..6e4bb4270ca2 100644 --- a/include/uapi/rdma/rdma_netlink.h +++ b/include/uapi/rdma/rdma_netlink.h @@ -37,6 +37,7 @@ enum { RDMA_NL_IWPM_ADD_MAPPING, RDMA_NL_IWPM_QUERY_MAPPING, RDMA_NL_IWPM_REMOVE_MAPPING, + RDMA_NL_IWPM_REMOTE_INFO, RDMA_NL_IWPM_HANDLE_ERR, RDMA_NL_IWPM_MAPINFO, RDMA_NL_IWPM_MAPINFO_NUM, diff --git a/include/xen/events.h b/include/xen/events.h index 5321cd9636e6..7d95fdf9cf3e 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -17,7 +17,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id); -int bind_virq_to_irq(unsigned int virq, unsigned int cpu); +int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu); int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler, unsigned long irqflags, const char *devname, diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 143ca5ffab7a..4478f4b4aae2 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -191,6 +191,7 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, struct gnttab_unmap_grant_ref *kunmap_ops, struct page **pages, unsigned int count); void gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item); +int gnttab_unmap_refs_sync(struct gntab_unmap_queue_data *item); /* Perform a batch of grant map/copy operations. Retry every batch slot diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index c643e6a94c9a..0ce4f32017ea 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -13,6 +13,7 @@ void xen_arch_post_suspend(int suspend_cancelled); void xen_timer_resume(void); void xen_arch_resume(void); +void xen_arch_suspend(void); void xen_resume_notifier_register(struct notifier_block *nb); void xen_resume_notifier_unregister(struct notifier_block *nb); diff --git a/init/do_mounts.c b/init/do_mounts.c index 8369ffa5f33d..a95bbdb2a502 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -225,10 +225,11 @@ dev_t name_to_dev_t(const char *name) #endif if (strncmp(name, "/dev/", 5) != 0) { - unsigned maj, min; + unsigned maj, min, offset; char dummy; - if (sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) { + if ((sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) || + (sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3)) { res = MKDEV(maj, min); if (maj != MAJOR(res) || min != MINOR(res)) goto fail; diff --git a/kernel/compat.c b/kernel/compat.c index 24f00610c575..333d364be29d 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -912,7 +912,8 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, * bitmap. We must however ensure the end of the * kernel bitmap is zeroed. */ - if (nr_compat_longs-- > 0) { + if (nr_compat_longs) { + nr_compat_longs--; if (__get_user(um, umask)) return -EFAULT; } else { @@ -954,7 +955,8 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, * We dont want to write past the end of the userspace * bitmap. */ - if (nr_compat_longs-- > 0) { + if (nr_compat_longs) { + nr_compat_longs--; if (__put_user(um, umask)) return -EFAULT; } diff --git a/kernel/events/core.c b/kernel/events/core.c index 81aa3a4ece9f..eddf1ed4155e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -913,10 +913,30 @@ static void put_ctx(struct perf_event_context *ctx) * Those places that change perf_event::ctx will hold both * perf_event_ctx::mutex of the 'old' and 'new' ctx value. * - * Lock ordering is by mutex address. There is one other site where - * perf_event_context::mutex nests and that is put_event(). But remember that - * that is a parent<->child context relation, and migration does not affect - * children, therefore these two orderings should not interact. + * Lock ordering is by mutex address. There are two other sites where + * perf_event_context::mutex nests and those are: + * + * - perf_event_exit_task_context() [ child , 0 ] + * __perf_event_exit_task() + * sync_child_event() + * put_event() [ parent, 1 ] + * + * - perf_event_init_context() [ parent, 0 ] + * inherit_task_group() + * inherit_group() + * inherit_event() + * perf_event_alloc() + * perf_init_event() + * perf_try_init_event() [ child , 1 ] + * + * While it appears there is an obvious deadlock here -- the parent and child + * nesting levels are inverted between the two. This is in fact safe because + * life-time rules separate them. That is an exiting task cannot fork, and a + * spawning task cannot (yet) exit. + * + * But remember that that these are parent<->child context relations, and + * migration does not affect children, therefore these two orderings should not + * interact. * * The change in perf_event::ctx does not affect children (as claimed above) * because the sys_perf_event_open() case will install a new event and break @@ -3422,7 +3442,6 @@ static void free_event_rcu(struct rcu_head *head) if (event->ns) put_pid_ns(event->ns); perf_event_free_filter(event); - perf_event_free_bpf_prog(event); kfree(event); } @@ -3553,6 +3572,8 @@ static void __free_event(struct perf_event *event) put_callchain_buffers(); } + perf_event_free_bpf_prog(event); + if (event->destroy) event->destroy(event); @@ -3657,9 +3678,6 @@ static void perf_remove_from_owner(struct perf_event *event) } } -/* - * Called when the last reference to the file is gone. - */ static void put_event(struct perf_event *event) { struct perf_event_context *ctx; @@ -3697,6 +3715,9 @@ int perf_event_release_kernel(struct perf_event *event) } EXPORT_SYMBOL_GPL(perf_event_release_kernel); +/* + * Called when the last reference to the file is gone. + */ static int perf_release(struct inode *inode, struct file *file) { put_event(file->private_data); @@ -7364,7 +7385,12 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event) return -ENODEV; if (event->group_leader != event) { - ctx = perf_event_ctx_lock(event->group_leader); + /* + * This ctx->mutex can nest when we're called through + * inheritance. See the perf_event_ctx_lock_nested() comment. + */ + ctx = perf_event_ctx_lock_nested(event->group_leader, + SINGLE_DEPTH_NESTING); BUG_ON(!ctx); } diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 232f00f273cb..725c416085e3 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -493,6 +493,20 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, rb->aux_pages[rb->aux_nr_pages] = page_address(page++); } + /* + * In overwrite mode, PMUs that don't support SG may not handle more + * than one contiguous allocation, since they rely on PMI to do double + * buffering. In this case, the entire buffer has to be one contiguous + * chunk. + */ + if ((event->pmu->capabilities & PERF_PMU_CAP_AUX_NO_SG) && + overwrite) { + struct page *page = virt_to_page(rb->aux_pages[0]); + + if (page_private(page) != max_order) + goto out; + } + rb->aux_priv = event->pmu->setup_aux(event->cpu, rb->aux_pages, nr_pages, overwrite); if (!rb->aux_priv) diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c index 988dc58e8847..2feb6feca0cc 100644 --- a/kernel/irq/dummychip.c +++ b/kernel/irq/dummychip.c @@ -57,5 +57,6 @@ struct irq_chip dummy_irq_chip = { .irq_ack = noop, .irq_mask = noop, .irq_unmask = noop, + .flags = IRQCHIP_SKIP_SET_WAKE, }; EXPORT_SYMBOL_GPL(dummy_irq_chip); diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index b73279367087..b025295f4966 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -265,15 +265,17 @@ struct task_struct *rt_mutex_get_top_task(struct task_struct *task) } /* - * Called by sched_setscheduler() to check whether the priority change - * is overruled by a possible priority boosting. + * Called by sched_setscheduler() to get the priority which will be + * effective after the change. */ -int rt_mutex_check_prio(struct task_struct *task, int newprio) +int rt_mutex_get_effective_prio(struct task_struct *task, int newprio) { if (!task_has_pi_waiters(task)) - return 0; + return newprio; - return task_top_pi_waiter(task)->task->prio <= newprio; + if (task_top_pi_waiter(task)->task->prio <= newprio) + return task_top_pi_waiter(task)->task->prio; + return newprio; } /* diff --git a/kernel/module.c b/kernel/module.c index 42a1d2afb217..cfc9e843a924 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3370,6 +3370,9 @@ static int load_module(struct load_info *info, const char __user *uargs, module_bug_cleanup(mod); mutex_unlock(&module_mutex); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, mod); + /* we can't deallocate the module until we clear memory protection */ unset_module_init_ro_nx(mod); unset_module_core_ro_nx(mod); diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 233165da782f..8cf7304b2867 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -162,11 +162,14 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp); static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO; module_param(kthread_prio, int, 0644); -/* Delay in jiffies for grace-period initialization delays. */ -static int gp_init_delay = IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) - ? CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY - : 0; +/* Delay in jiffies for grace-period initialization delays, debug only. */ +#ifdef CONFIG_RCU_TORTURE_TEST_SLOW_INIT +static int gp_init_delay = CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY; module_param(gp_init_delay, int, 0644); +#else /* #ifdef CONFIG_RCU_TORTURE_TEST_SLOW_INIT */ +static const int gp_init_delay; +#endif /* #else #ifdef CONFIG_RCU_TORTURE_TEST_SLOW_INIT */ +#define PER_RCU_NODE_PERIOD 10 /* Number of grace periods between delays. */ /* * Track the rcutorture test sequence number and the update version @@ -1843,9 +1846,8 @@ static int rcu_gp_init(struct rcu_state *rsp) raw_spin_unlock_irq(&rnp->lock); cond_resched_rcu_qs(); ACCESS_ONCE(rsp->gp_activity) = jiffies; - if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) && - gp_init_delay > 0 && - !(rsp->gpnum % (rcu_num_nodes * 10))) + if (gp_init_delay > 0 && + !(rsp->gpnum % (rcu_num_nodes * PER_RCU_NODE_PERIOD))) schedule_timeout_uninterruptible(gp_init_delay); } diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fe22f7510bce..123673291ffb 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3300,15 +3300,18 @@ static void __setscheduler_params(struct task_struct *p, /* Actually do priority change: must hold pi & rq lock. */ static void __setscheduler(struct rq *rq, struct task_struct *p, - const struct sched_attr *attr) + const struct sched_attr *attr, bool keep_boost) { __setscheduler_params(p, attr); /* - * If we get here, there was no pi waiters boosting the - * task. It is safe to use the normal prio. + * Keep a potential priority boosting if called from + * sched_setscheduler(). */ - p->prio = normal_prio(p); + if (keep_boost) + p->prio = rt_mutex_get_effective_prio(p, normal_prio(p)); + else + p->prio = normal_prio(p); if (dl_prio(p->prio)) p->sched_class = &dl_sched_class; @@ -3408,7 +3411,7 @@ static int __sched_setscheduler(struct task_struct *p, int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : MAX_RT_PRIO - 1 - attr->sched_priority; int retval, oldprio, oldpolicy = -1, queued, running; - int policy = attr->sched_policy; + int new_effective_prio, policy = attr->sched_policy; unsigned long flags; const struct sched_class *prev_class; struct rq *rq; @@ -3590,15 +3593,14 @@ change: oldprio = p->prio; /* - * Special case for priority boosted tasks. - * - * If the new priority is lower or equal (user space view) - * than the current (boosted) priority, we just store the new + * Take priority boosted tasks into account. If the new + * effective priority is unchanged, we just store the new * normal parameters and do not touch the scheduler class and * the runqueue. This will be done when the task deboost * itself. */ - if (rt_mutex_check_prio(p, newprio)) { + new_effective_prio = rt_mutex_get_effective_prio(p, newprio); + if (new_effective_prio == oldprio) { __setscheduler_params(p, attr); task_rq_unlock(rq, p, &flags); return 0; @@ -3612,7 +3614,7 @@ change: put_prev_task(rq, p); prev_class = p->sched_class; - __setscheduler(rq, p, attr); + __setscheduler(rq, p, attr, true); if (running) p->sched_class->set_curr_task(rq); @@ -4387,10 +4389,7 @@ long __sched io_schedule_timeout(long timeout) long ret; current->in_iowait = 1; - if (old_iowait) - blk_schedule_flush_plug(current); - else - blk_flush_plug(current); + blk_schedule_flush_plug(current); delayacct_blkio_start(); rq = raw_rq(); @@ -6997,27 +6996,23 @@ static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action, unsigned long flags; long cpu = (long)hcpu; struct dl_bw *dl_b; + bool overflow; + int cpus; - switch (action & ~CPU_TASKS_FROZEN) { + switch (action) { case CPU_DOWN_PREPARE: - /* explicitly allow suspend */ - if (!(action & CPU_TASKS_FROZEN)) { - bool overflow; - int cpus; - - rcu_read_lock_sched(); - dl_b = dl_bw_of(cpu); + rcu_read_lock_sched(); + dl_b = dl_bw_of(cpu); - raw_spin_lock_irqsave(&dl_b->lock, flags); - cpus = dl_bw_cpus(cpu); - overflow = __dl_overflow(dl_b, cpus, 0, 0); - raw_spin_unlock_irqrestore(&dl_b->lock, flags); + raw_spin_lock_irqsave(&dl_b->lock, flags); + cpus = dl_bw_cpus(cpu); + overflow = __dl_overflow(dl_b, cpus, 0, 0); + raw_spin_unlock_irqrestore(&dl_b->lock, flags); - rcu_read_unlock_sched(); + rcu_read_unlock_sched(); - if (overflow) - return notifier_from_errno(-EBUSY); - } + if (overflow) + return notifier_from_errno(-EBUSY); cpuset_update_active_cpus(false); break; case CPU_DOWN_PREPARE_FROZEN: @@ -7346,7 +7341,7 @@ static void normalize_task(struct rq *rq, struct task_struct *p) queued = task_on_rq_queued(p); if (queued) dequeue_task(rq, p, 0); - __setscheduler(rq, p, &attr); + __setscheduler(rq, p, &attr, false); if (queued) { enqueue_task(rq, p, 0); resched_curr(rq); diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 11dc22a6983b..637a09461c1d 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -117,11 +117,7 @@ static int __clockevents_set_state(struct clock_event_device *dev, /* Transition with new state-specific callbacks */ switch (state) { case CLOCK_EVT_STATE_DETACHED: - /* - * This is an internal state, which is guaranteed to go from - * SHUTDOWN to DETACHED. No driver interaction required. - */ - return 0; + /* The clockevent device is getting replaced. Shut it down. */ case CLOCK_EVT_STATE_SHUTDOWN: return dev->set_state_shutdown(dev); diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 76d4bd962b19..93ef7190bdea 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -266,21 +266,23 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) /* * Divide a ktime value by a nanosecond value */ -u64 __ktime_divns(const ktime_t kt, s64 div) +s64 __ktime_divns(const ktime_t kt, s64 div) { - u64 dclc; int sft = 0; + s64 dclc; + u64 tmp; dclc = ktime_to_ns(kt); + tmp = dclc < 0 ? -dclc : dclc; + /* Make sure the divisor is less than 2^32: */ while (div >> 32) { sft++; div >>= 1; } - dclc >>= sft; - do_div(dclc, (unsigned long) div); - - return dclc; + tmp >>= sft; + do_div(tmp, (unsigned long) div); + return dclc < 0 ? -tmp : tmp; } EXPORT_SYMBOL_GPL(__ktime_divns); #endif /* BITS_PER_LONG >= 64 */ diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 692bf7184c8c..25a086bcb700 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -178,12 +178,13 @@ ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) EXPORT_SYMBOL(ftrace_print_hex_seq); const char * -ftrace_print_array_seq(struct trace_seq *p, const void *buf, int buf_len, +ftrace_print_array_seq(struct trace_seq *p, const void *buf, int count, size_t el_size) { const char *ret = trace_seq_buffer_ptr(p); const char *prefix = ""; void *ptr = (void *)buf; + size_t buf_len = count * el_size; trace_seq_putc(p, '{'); diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 2316f50b07a4..581a68a04c64 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -41,6 +41,8 @@ #define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) #define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +static DEFINE_MUTEX(watchdog_proc_mutex); + #ifdef CONFIG_HARDLOCKUP_DETECTOR static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED; #else @@ -608,26 +610,36 @@ void watchdog_nmi_enable_all(void) { int cpu; - if (!watchdog_user_enabled) - return; + mutex_lock(&watchdog_proc_mutex); + + if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) + goto unlock; get_online_cpus(); for_each_online_cpu(cpu) watchdog_nmi_enable(cpu); put_online_cpus(); + +unlock: + mutex_unlock(&watchdog_proc_mutex); } void watchdog_nmi_disable_all(void) { int cpu; + mutex_lock(&watchdog_proc_mutex); + if (!watchdog_running) - return; + goto unlock; get_online_cpus(); for_each_online_cpu(cpu) watchdog_nmi_disable(cpu); put_online_cpus(); + +unlock: + mutex_unlock(&watchdog_proc_mutex); } #else static int watchdog_nmi_enable(unsigned int cpu) { return 0; } @@ -744,8 +756,6 @@ static int proc_watchdog_update(void) } -static DEFINE_MUTEX(watchdog_proc_mutex); - /* * common function for watchdog, nmi_watchdog and soft_watchdog parameter * diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 17670573dda8..ba2b0c87e65b 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1281,6 +1281,7 @@ config RCU_TORTURE_TEST_SLOW_INIT_DELAY int "How much to slow down RCU grace-period initialization" range 0 5 default 3 + depends on RCU_TORTURE_TEST_SLOW_INIT help This option specifies the number of jiffies to wait between each rcu_node structure initialization. diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index 4fecaedc80a2..777eda7d1ab4 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -10,8 +10,11 @@ config KASAN help Enables kernel address sanitizer - runtime memory debugger, designed to find out-of-bounds accesses and use-after-free bugs. - This is strictly debugging feature. It consumes about 1/8 - of available memory and brings about ~x3 performance slowdown. + This is strictly a debugging feature and it requires a gcc version + of 4.9.2 or later. Detection of out of bounds accesses to stack or + global variables requires gcc 5.0 or later. + This feature consumes about 1/8 of available memory and brings about + ~x3 performance slowdown. For better error detection enable CONFIG_STACKTRACE, and add slub_debug=U to boot cmdline. @@ -40,6 +43,7 @@ config KASAN_INLINE memory accesses. This is faster than outline (in some workloads it gives about x2 boost over outline instrumentation), but make kernel's .text size much bigger. + This requires a gcc version of 5.0 or later. endchoice diff --git a/lib/cpumask.c b/lib/cpumask.c index 830dd5dec40f..5f627084f2e9 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -139,64 +139,42 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask) #endif /** - * cpumask_set_cpu_local_first - set i'th cpu with local numa cpu's first - * + * cpumask_local_spread - select the i'th cpu with local numa cpu's first * @i: index number - * @numa_node: local numa_node - * @dstp: cpumask with the relevant cpu bit set according to the policy + * @node: local numa_node * - * This function sets the cpumask according to a numa aware policy. - * cpumask could be used as an affinity hint for the IRQ related to a - * queue. When the policy is to spread queues across cores - local cores - * first. + * This function selects an online CPU according to a numa aware policy; + * local cpus are returned first, followed by non-local ones, then it + * wraps around. * - * Returns 0 on success, -ENOMEM for no memory, and -EAGAIN when failed to set - * the cpu bit and need to re-call the function. + * It's not very efficient, but useful for setup. */ -int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp) +unsigned int cpumask_local_spread(unsigned int i, int node) { - cpumask_var_t mask; int cpu; - int ret = 0; - - if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) - return -ENOMEM; + /* Wrap: we always want a cpu. */ i %= num_online_cpus(); - if (numa_node == -1 || !cpumask_of_node(numa_node)) { - /* Use all online cpu's for non numa aware system */ - cpumask_copy(mask, cpu_online_mask); + if (node == -1) { + for_each_cpu(cpu, cpu_online_mask) + if (i-- == 0) + return cpu; } else { - int n; - - cpumask_and(mask, - cpumask_of_node(numa_node), cpu_online_mask); - - n = cpumask_weight(mask); - if (i >= n) { - i -= n; - - /* If index > number of local cpu's, mask out local - * cpu's - */ - cpumask_andnot(mask, cpu_online_mask, mask); + /* NUMA first. */ + for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask) + if (i-- == 0) + return cpu; + + for_each_cpu(cpu, cpu_online_mask) { + /* Skip NUMA nodes, done above. */ + if (cpumask_test_cpu(cpu, cpumask_of_node(node))) + continue; + + if (i-- == 0) + return cpu; } } - - for_each_cpu(cpu, mask) { - if (--i < 0) - goto out; - } - - ret = -EAGAIN; - -out: - free_cpumask_var(mask); - - if (!ret) - cpumask_set_cpu(cpu, dstp); - - return ret; + BUG(); } -EXPORT_SYMBOL(cpumask_set_cpu_local_first); +EXPORT_SYMBOL(cpumask_local_spread); diff --git a/lib/find_last_bit.c b/lib/find_last_bit.c deleted file mode 100644 index 3e3be40c6a6e..000000000000 --- a/lib/find_last_bit.c +++ /dev/null @@ -1,41 +0,0 @@ -/* find_last_bit.c: fallback find next bit implementation - * - * Copyright (C) 2008 IBM Corporation - * Written by Rusty Russell <rusty@rustcorp.com.au> - * (Inspired by David Howell's find_next_bit implementation) - * - * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease - * size and improve performance, 2015. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <linux/bitops.h> -#include <linux/bitmap.h> -#include <linux/export.h> -#include <linux/kernel.h> - -#ifndef find_last_bit - -unsigned long find_last_bit(const unsigned long *addr, unsigned long size) -{ - if (size) { - unsigned long val = BITMAP_LAST_WORD_MASK(size); - unsigned long idx = (size-1) / BITS_PER_LONG; - - do { - val &= addr[idx]; - if (val) - return idx * BITS_PER_LONG + __fls(val); - - val = ~0ul; - } while (idx--); - } - return size; -} -EXPORT_SYMBOL(find_last_bit); - -#endif diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 48144cdae819..f051d69f0910 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -197,13 +197,13 @@ static int percpu_counter_hotcpu_callback(struct notifier_block *nb, * Compare counter against given value. * Return 1 if greater, 0 if equal and -1 if less */ -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) { s64 count; count = percpu_counter_read(fbc); /* Check to see if rough count will be sufficient for comparison */ - if (abs(count - rhs) > (percpu_counter_batch*num_online_cpus())) { + if (abs(count - rhs) > (batch * num_online_cpus())) { if (count > rhs) return 1; else @@ -218,7 +218,7 @@ int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) else return 0; } -EXPORT_SYMBOL(percpu_counter_compare); +EXPORT_SYMBOL(__percpu_counter_compare); static int __init percpu_counter_startup(void) { diff --git a/lib/rhashtable.c b/lib/rhashtable.c index b28df4019ade..4396434e4715 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -14,6 +14,7 @@ * published by the Free Software Foundation. */ +#include <linux/atomic.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/log2.h> @@ -446,6 +447,10 @@ int rhashtable_insert_slow(struct rhashtable *ht, const void *key, if (key && rhashtable_lookup_fast(ht, key, ht->p)) goto exit; + err = -E2BIG; + if (unlikely(rht_grow_above_max(ht, tbl))) + goto exit; + err = -EAGAIN; if (rhashtable_check_elasticity(ht, tbl, hash) || rht_grow_above_100(ht, tbl)) @@ -738,6 +743,12 @@ int rhashtable_init(struct rhashtable *ht, if (params->max_size) ht->p.max_size = rounddown_pow_of_two(params->max_size); + if (params->insecure_max_entries) + ht->p.insecure_max_entries = + rounddown_pow_of_two(params->insecure_max_entries); + else + ht->p.insecure_max_entries = ht->p.max_size * 2; + ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE); /* The maximum (not average) chain length grows with the diff --git a/lib/string.c b/lib/string.c index a5792019193c..bb3d4b6993c4 100644 --- a/lib/string.c +++ b/lib/string.c @@ -607,7 +607,7 @@ EXPORT_SYMBOL(memset); void memzero_explicit(void *s, size_t count) { memset(s, 0, count); - barrier(); + barrier_data(s); } EXPORT_SYMBOL(memzero_explicit); diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index a28df5206d95..fe9a32591c24 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c @@ -57,7 +57,8 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, return res + find_zero(data) + 1 - align; } res += sizeof(unsigned long); - if (unlikely(max < sizeof(unsigned long))) + /* We already handled 'unsigned long' bytes. Did we do it all ? */ + if (unlikely(max <= sizeof(unsigned long))) break; max -= sizeof(unsigned long); if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) @@ -89,8 +90,15 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, * Get the size of a NUL-terminated string in user space. * * Returns the size of the string INCLUDING the terminating NUL. - * If the string is too long, returns 'count+1'. + * If the string is too long, returns a number larger than @count. User + * has to check the return value against "> count". * On exception (or invalid count), returns 0. + * + * NOTE! You should basically never use this function. There is + * almost never any valid case for using the length of a user space + * string, since the string can be changed at any time by other + * threads. Use "strncpy_from_user()" instead to get a stable copy + * of the string. */ long strnlen_user(const char __user *str, long count) { diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 4abda074ea45..3c365ab6cf5f 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -537,8 +537,9 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); * Allocates bounce buffer and returns its kernel virtual address. */ -phys_addr_t map_single(struct device *hwdev, phys_addr_t phys, size_t size, - enum dma_data_direction dir) +static phys_addr_t +map_single(struct device *hwdev, phys_addr_t phys, size_t size, + enum dma_data_direction dir) { dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 6dc4580df2af..000e7b3b9896 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -359,23 +359,6 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) flush_delayed_work(&bdi->wb.dwork); } -/* - * Called when the device behind @bdi has been removed or ejected. - * - * We can't really do much here except for reducing the dirty ratio at - * the moment. In the future we should be able to set a flag so that - * the filesystem can handle errors at mark_inode_dirty time instead - * of only at writeback time. - */ -void bdi_unregister(struct backing_dev_info *bdi) -{ - if (WARN_ON_ONCE(!bdi->dev)) - return; - - bdi_set_min_ratio(bdi, 0); -} -EXPORT_SYMBOL(bdi_unregister); - static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) { memset(wb, 0, sizeof(*wb)); @@ -443,6 +426,7 @@ void bdi_destroy(struct backing_dev_info *bdi) int i; bdi_wb_shutdown(bdi); + bdi_set_min_ratio(bdi, 0); WARN_ON(!list_empty(&bdi->work_list)); WARN_ON(delayed_work_pending(&bdi->wb.dwork)); diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index 329caf56df22..4ca5fe0042e1 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -34,13 +34,13 @@ static int hwpoison_inject(void *data, u64 val) if (!hwpoison_filter_enable) goto inject; - if (!PageLRU(p) && !PageHuge(p)) - shake_page(p, 0); + if (!PageLRU(hpage) && !PageHuge(p)) + shake_page(hpage, 0); /* * This implies unable to support non-LRU pages. */ - if (!PageLRU(p) && !PageHuge(p)) - return 0; + if (!PageLRU(hpage) && !PageHuge(p)) + goto put_out; /* * do a racy check with elevated page count, to make sure PG_hwpoison @@ -52,11 +52,14 @@ static int hwpoison_inject(void *data, u64 val) err = hwpoison_filter(hpage); unlock_page(hpage); if (err) - return 0; + goto put_out; inject: pr_info("Injecting memory failure at pfn %#lx\n", pfn); return memory_failure(pfn, 18, MF_COUNT_INCREASED); +put_out: + put_page(hpage); + return 0; } static int hwpoison_unpoison(void *data, u64 val) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 5405aff5a590..f0fe4f2c1fa7 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -115,7 +115,8 @@ #define BYTES_PER_POINTER sizeof(void *) /* GFP bitmask for kmemleak internal allocations */ -#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ +#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \ + __GFP_NOACCOUNT)) | \ __GFP_NORETRY | __GFP_NOMEMALLOC | \ __GFP_NOWARN) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index d9359b770cd9..501820c815b3 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1187,10 +1187,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags) * The check (unnecessarily) ignores LRU pages being isolated and * walked by the page reclaim code, however that's not a big loss. */ - if (!PageHuge(p) && !PageTransTail(p)) { - if (!PageLRU(p)) - shake_page(p, 0); - if (!PageLRU(p)) { + if (!PageHuge(p)) { + if (!PageLRU(hpage)) + shake_page(hpage, 0); + if (!PageLRU(hpage)) { /* * shake_page could have turned it free. */ @@ -1777,12 +1777,12 @@ int soft_offline_page(struct page *page, int flags) } else if (ret == 0) { /* for free pages */ if (PageHuge(page)) { set_page_hwpoison_huge_page(hpage); - dequeue_hwpoisoned_huge_page(hpage); - atomic_long_add(1 << compound_order(hpage), + if (!dequeue_hwpoisoned_huge_page(hpage)) + atomic_long_add(1 << compound_order(hpage), &num_poisoned_pages); } else { - SetPageHWPoison(page); - atomic_long_inc(&num_poisoned_pages); + if (!TestSetPageHWPoison(page)) + atomic_long_inc(&num_poisoned_pages); } } unset_migratetype_isolate(page, MIGRATE_MOVABLE); diff --git a/mm/mempolicy.c b/mm/mempolicy.c index ede26291d4aa..747743237d9f 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2518,7 +2518,7 @@ static void __init check_numabalancing_enable(void) if (numabalancing_override) set_numabalancing_state(numabalancing_override == 1); - if (nr_node_ids > 1 && !numabalancing_override) { + if (num_online_nodes() > 1 && !numabalancing_override) { pr_info("%s automatic NUMA balancing. " "Configure with numa_balancing= or the " "kernel.numa_balancing sysctl", diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 5daf5568b9e1..eb59f7eea508 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -580,7 +580,7 @@ static long long pos_ratio_polynom(unsigned long setpoint, long x; x = div64_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT, - limit - setpoint + 1); + (limit - setpoint) | 1); pos_ratio = x; pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; @@ -807,7 +807,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, * scale global setpoint to bdi's: * bdi_setpoint = setpoint * bdi_thresh / thresh */ - x = div_u64((u64)bdi_thresh << 16, thresh + 1); + x = div_u64((u64)bdi_thresh << 16, thresh | 1); bdi_setpoint = setpoint * (u64)x >> 16; /* * Use span=(8*write_bw) in single bdi case as indicated by @@ -822,7 +822,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, if (bdi_dirty < x_intercept - span / 4) { pos_ratio = div64_u64(pos_ratio * (x_intercept - bdi_dirty), - x_intercept - bdi_setpoint + 1); + (x_intercept - bdi_setpoint) | 1); } else pos_ratio /= 4; diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 755a42c76eb4..303c908790ef 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -101,7 +101,8 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype) buddy_idx = __find_buddy_index(page_idx, order); buddy = page + (buddy_idx - page_idx); - if (!is_migrate_isolate_page(buddy)) { + if (pfn_valid_within(page_to_pfn(buddy)) && + !is_migrate_isolate_page(buddy)) { __isolate_free_page(page, order); kernel_map_pages(page, (1 << order), 1); set_page_refcounted(page); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 98a30a5b8664..59555f0f8fc8 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -443,7 +443,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UP: /* Put all VLANs for this dev in the up state too. */ vlan_group_for_each_dev(grp, i, vlandev) { - flgs = vlandev->flags; + flgs = dev_get_flags(vlandev); if (flgs & IFF_UP) continue; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 476709bd068a..c4802f3bd4c5 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1557,7 +1557,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) { BT_DBG("%s %p", hdev->name, hdev); - if (!hci_dev_test_flag(hdev, HCI_UNREGISTER)) { + if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && + test_bit(HCI_UP, &hdev->flags)) { /* Execute vendor specific shutdown routine */ if (hdev->shutdown) hdev->shutdown(hdev); @@ -2853,9 +2854,11 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status, * state. If we were running both LE and BR/EDR inquiry * simultaneously, and BR/EDR inquiry is already * finished, stop discovery, otherwise BR/EDR inquiry - * will stop discovery when finished. + * will stop discovery when finished. If we will resolve + * remote device name, do not change discovery state. */ - if (!test_bit(HCI_INQUIRY, &hdev->flags)) + if (!test_bit(HCI_INQUIRY, &hdev->flags) && + hdev->discovery.state != DISCOVERY_RESOLVING) hci_discovery_set_state(hdev, DISCOVERY_STOPPED); } else { diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 4b6722f8f179..22fd0419b314 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1072,7 +1072,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, vid); - if (!err) + if (err) break; } @@ -1822,7 +1822,7 @@ static void br_multicast_query_expired(struct net_bridge *br, if (query->startup_sent < br->multicast_startup_query_count) query->startup_sent++; - RCU_INIT_POINTER(querier, NULL); + RCU_INIT_POINTER(querier->port, NULL); br_multicast_send_query(br, NULL, query); spin_unlock(&br->multicast_lock); } diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index ab55e2472beb..60ddfbeb47f5 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -37,10 +37,6 @@ #include <net/route.h> #include <net/netfilter/br_netfilter.h> -#if IS_ENABLED(CONFIG_NF_CONNTRACK) -#include <net/netfilter/nf_conntrack.h> -#endif - #include <asm/uaccess.h> #include "br_private.h" #ifdef CONFIG_SYSCTL @@ -350,24 +346,15 @@ free_skb: return 0; } -static bool dnat_took_place(const struct sk_buff *skb) +static bool daddr_was_changed(const struct sk_buff *skb, + const struct nf_bridge_info *nf_bridge) { -#if IS_ENABLED(CONFIG_NF_CONNTRACK) - enum ip_conntrack_info ctinfo; - struct nf_conn *ct; - - ct = nf_ct_get(skb, &ctinfo); - if (!ct || nf_ct_is_untracked(ct)) - return false; - - return test_bit(IPS_DST_NAT_BIT, &ct->status); -#else - return false; -#endif + return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr; } /* This requires some explaining. If DNAT has taken place, * we will need to fix up the destination Ethernet address. + * This is also true when SNAT takes place (for the reply direction). * * There are two cases to consider: * 1. The packet was DNAT'ed to a device in the same bridge @@ -421,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb) nf_bridge->pkt_otherhost = false; } nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; - if (dnat_took_place(skb)) { + if (daddr_was_changed(skb, nf_bridge)) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { struct in_device *in_dev = __in_dev_get_rcu(dev); @@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct nf_hook_state *state) { + struct nf_bridge_info *nf_bridge; struct net_bridge_port *p; struct net_bridge *br; __u32 len = nf_bridge_encap_header_len(skb); @@ -669,6 +657,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, if (!setup_pre_routing(skb)) return NF_DROP; + nf_bridge = nf_bridge_info_get(skb); + nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr; + skb->protocol = htons(ETH_P_IP); NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c index 4fcaa67750fd..7caf7fae2d5b 100644 --- a/net/bridge/br_stp_timer.c +++ b/net/bridge/br_stp_timer.c @@ -97,7 +97,9 @@ static void br_forward_delay_timer_expired(unsigned long arg) netif_carrier_on(br->dev); } br_log_state(p); + rcu_read_lock(); br_ifinfo_notify(RTM_NEWLINK, p); + rcu_read_unlock(); spin_unlock(&br->lock); } diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 4ec0c803aef1..112ad784838a 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -330,6 +330,10 @@ static long caif_stream_data_wait(struct sock *sk, long timeo) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + + if (sock_flag(sk, SOCK_DEAD)) + break; + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); } @@ -373,6 +377,10 @@ static int caif_stream_recvmsg(struct socket *sock, struct msghdr *msg, struct sk_buff *skb; lock_sock(sk); + if (sock_flag(sk, SOCK_DEAD)) { + err = -ECONNRESET; + goto unlock; + } skb = skb_dequeue(&sk->sk_receive_queue); caif_check_flow_release(sk); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 41a4abc7e98e..c4ec9239249a 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1306,8 +1306,6 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc, if (list_empty(&req->r_osd_item)) req->r_osd = NULL; } - - list_del_init(&req->r_req_lru_item); /* can be on notarget */ ceph_osdc_put_request(req); } @@ -2017,20 +2015,29 @@ static void kick_requests(struct ceph_osd_client *osdc, bool force_resend, err = __map_request(osdc, req, force_resend || force_resend_writes); dout("__map_request returned %d\n", err); - if (err == 0) - continue; /* no change and no osd was specified */ if (err < 0) continue; /* hrm! */ - if (req->r_osd == NULL) { - dout("tid %llu maps to no valid osd\n", req->r_tid); - needmap++; /* request a newer map */ - continue; - } + if (req->r_osd == NULL || err > 0) { + if (req->r_osd == NULL) { + dout("lingering %p tid %llu maps to no osd\n", + req, req->r_tid); + /* + * A homeless lingering request makes + * no sense, as it's job is to keep + * a particular OSD connection open. + * Request a newer map and kick the + * request, knowing that it won't be + * resent until we actually get a map + * that can tell us where to send it. + */ + needmap++; + } - dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid, - req->r_osd ? req->r_osd->o_osd : -1); - __register_request(osdc, req); - __unregister_linger_request(osdc, req); + dout("kicking lingering %p tid %llu osd%d\n", req, + req->r_tid, req->r_osd ? req->r_osd->o_osd : -1); + __register_request(osdc, req); + __unregister_linger_request(osdc, req); + } } reset_changed_osds(osdc); mutex_unlock(&osdc->request_mutex); diff --git a/net/core/dev.c b/net/core/dev.c index c7ba0388f1be..2c1c67fad64d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5209,7 +5209,7 @@ static int __netdev_upper_dev_link(struct net_device *dev, if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper)) return -EBUSY; - if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper)) + if (__netdev_find_adj(dev, upper_dev, &dev->adj_list.upper)) return -EEXIST; if (master && netdev_master_upper_dev_get(dev)) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 78fc04ad36fc..572af0011997 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -601,7 +601,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh) } err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, - RTM_GETNSID, net, peer, -1); + RTM_NEWNSID, net, peer, -1); if (err < 0) goto err_out; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 666e0928ba40..8de36824018d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2416,6 +2416,9 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, { struct sk_buff *skb; + if (dev->reg_state != NETREG_REGISTERED) + return; + skb = rtmsg_ifinfo_build_skb(type, dev, change, flags); if (skb) rtmsg_ifinfo_send(skb, dev, flags); diff --git a/net/core/sock.c b/net/core/sock.c index e891bcf325ca..292f42228bfb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1474,8 +1474,8 @@ void sk_release_kernel(struct sock *sk) return; sock_hold(sk); - sock_net_set(sk, get_net(&init_net)); sock_release(sk->sk_socket); + sock_net_set(sk, get_net(&init_net)); sock_put(sk); } EXPORT_SYMBOL(sk_release_kernel); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index e6f6cc3a1bcf..392e29a0227d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -359,7 +359,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, */ ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); if (ds == NULL) - return NULL; + return ERR_PTR(-ENOMEM); ds->dst = dst; ds->index = index; @@ -370,7 +370,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ret = dsa_switch_setup_one(ds, parent); if (ret) - return NULL; + return ERR_PTR(ret); return ds; } diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index 05dab2957cd4..4adfd4d5471b 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -3,7 +3,9 @@ obj-$(CONFIG_IEEE802154_SOCKET) += ieee802154_socket.o obj-y += 6lowpan/ ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ - header_ops.o sysfs.o nl802154.o + header_ops.o sysfs.o nl802154.o trace.o ieee802154_socket-y := socket.o +CFLAGS_trace.o := -I$(src) + ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 1b9d25f6e898..346c6665d25e 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -175,6 +175,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) int rc = -ENOBUFS; struct net_device *dev; int type = __IEEE802154_DEV_INVALID; + unsigned char name_assign_type; pr_debug("%s\n", __func__); @@ -190,8 +191,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ + name_assign_type = NET_NAME_USER; } else { devname = "wpan%d"; + name_assign_type = NET_NAME_ENUM; } if (strlen(devname) >= IFNAMSIZ) @@ -221,7 +224,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) } dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname, - type); + name_assign_type, type); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index a4daf91b8d0a..f3c12f6a4a39 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -589,7 +589,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) return rdev_add_virtual_intf(rdev, nla_data(info->attrs[NL802154_ATTR_IFNAME]), - type, extended_addr); + NET_NAME_USER, type, extended_addr); } static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info) diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 7c46732fad2b..7b5a9dd94fe5 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -4,13 +4,16 @@ #include <net/cfg802154.h> #include "core.h" +#include "trace.h" static inline struct net_device * rdev_add_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, - const char *name, int type) + const char *name, + unsigned char name_assign_type, + int type) { return rdev->ops->add_virtual_intf_deprecated(&rdev->wpan_phy, name, - type); + name_assign_type, type); } static inline void @@ -22,75 +25,131 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, static inline int rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, + unsigned char name_assign_type, enum nl802154_iftype type, __le64 extended_addr) { - return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type, + int ret; + + trace_802154_rdev_add_virtual_intf(&rdev->wpan_phy, name, type, extended_addr); + ret = rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, + name_assign_type, type, + extended_addr); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_del_virtual_intf(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev) { - return rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev); + int ret; + + trace_802154_rdev_del_virtual_intf(&rdev->wpan_phy, wpan_dev); + ret = rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) { - return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); + int ret; + + trace_802154_rdev_set_channel(&rdev->wpan_phy, page, channel); + ret = rdev->ops->set_channel(&rdev->wpan_phy, page, channel); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_cca_mode(struct cfg802154_registered_device *rdev, const struct wpan_phy_cca *cca) { - return rdev->ops->set_cca_mode(&rdev->wpan_phy, cca); + int ret; + + trace_802154_rdev_set_cca_mode(&rdev->wpan_phy, cca); + ret = rdev->ops->set_cca_mode(&rdev->wpan_phy, cca); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_pan_id(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, __le16 pan_id) { - return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); + int ret; + + trace_802154_rdev_set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); + ret = rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_short_addr(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, __le16 short_addr) { - return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); + int ret; + + trace_802154_rdev_set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); + ret = rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, u8 min_be, u8 max_be) { - return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev, + int ret; + + trace_802154_rdev_set_backoff_exponent(&rdev->wpan_phy, wpan_dev, min_be, max_be); + ret = rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev, + min_be, max_be); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, u8 max_csma_backoffs) { - return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev, - max_csma_backoffs); + int ret; + + trace_802154_rdev_set_csma_backoffs(&rdev->wpan_phy, wpan_dev, + max_csma_backoffs); + ret = rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev, + max_csma_backoffs); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, s8 max_frame_retries) { - return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev, + int ret; + + trace_802154_rdev_set_max_frame_retries(&rdev->wpan_phy, wpan_dev, max_frame_retries); + ret = rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev, + max_frame_retries); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } static inline int rdev_set_lbt_mode(struct cfg802154_registered_device *rdev, struct wpan_dev *wpan_dev, bool mode) { - return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode); + int ret; + + trace_802154_rdev_set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode); + ret = rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; } #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/ieee802154/trace.c b/net/ieee802154/trace.c new file mode 100644 index 000000000000..95f997fad755 --- /dev/null +++ b/net/ieee802154/trace.c @@ -0,0 +1,7 @@ +#include <linux/module.h> + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "trace.h" + +#endif diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h new file mode 100644 index 000000000000..5ac25eb6ed17 --- /dev/null +++ b/net/ieee802154/trace.h @@ -0,0 +1,247 @@ +/* Based on net/wireless/tracing.h */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM cfg802154 + +#if !defined(__RDEV_CFG802154_OPS_TRACE) || defined(TRACE_HEADER_MULTI_READ) +#define __RDEV_CFG802154_OPS_TRACE + +#include <linux/tracepoint.h> + +#include <net/cfg802154.h> + +#define MAXNAME 32 +#define WPAN_PHY_ENTRY __array(char, wpan_phy_name, MAXNAME) +#define WPAN_PHY_ASSIGN strlcpy(__entry->wpan_phy_name, \ + wpan_phy_name(wpan_phy), \ + MAXNAME) +#define WPAN_PHY_PR_FMT "%s" +#define WPAN_PHY_PR_ARG __entry->wpan_phy_name + +#define WPAN_DEV_ENTRY __field(u32, identifier) +#define WPAN_DEV_ASSIGN (__entry->identifier) = (!IS_ERR_OR_NULL(wpan_dev) \ + ? wpan_dev->identifier : 0) +#define WPAN_DEV_PR_FMT "wpan_dev(%u)" +#define WPAN_DEV_PR_ARG (__entry->identifier) + +#define WPAN_CCA_ENTRY __field(enum nl802154_cca_modes, cca_mode) \ + __field(enum nl802154_cca_opts, cca_opt) +#define WPAN_CCA_ASSIGN \ + do { \ + (__entry->cca_mode) = cca->mode; \ + (__entry->cca_opt) = cca->opt; \ + } while (0) +#define WPAN_CCA_PR_FMT "cca_mode: %d, cca_opt: %d" +#define WPAN_CCA_PR_ARG __entry->cca_mode, __entry->cca_opt + +#define BOOL_TO_STR(bo) (bo) ? "true" : "false" + +/************************************************************* + * rdev->ops traces * + *************************************************************/ + +TRACE_EVENT(802154_rdev_add_virtual_intf, + TP_PROTO(struct wpan_phy *wpan_phy, char *name, + enum nl802154_iftype type, __le64 extended_addr), + TP_ARGS(wpan_phy, name, type, extended_addr), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + __string(vir_intf_name, name ? name : "<noname>") + __field(enum nl802154_iftype, type) + __field(__le64, extended_addr) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + __assign_str(vir_intf_name, name ? name : "<noname>"); + __entry->type = type; + __entry->extended_addr = extended_addr; + ), + TP_printk(WPAN_PHY_PR_FMT ", virtual intf name: %s, type: %d, ea %llx", + WPAN_PHY_PR_ARG, __get_str(vir_intf_name), __entry->type, + __le64_to_cpu(__entry->extended_addr)) +); + +TRACE_EVENT(802154_rdev_del_virtual_intf, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev), + TP_ARGS(wpan_phy, wpan_dev), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + ), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT, WPAN_PHY_PR_ARG, + WPAN_DEV_PR_ARG) +); + +TRACE_EVENT(802154_rdev_set_channel, + TP_PROTO(struct wpan_phy *wpan_phy, u8 page, u8 channel), + TP_ARGS(wpan_phy, page, channel), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + __field(u8, page) + __field(u8, channel) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + __entry->page = page; + __entry->channel = channel; + ), + TP_printk(WPAN_PHY_PR_FMT ", page: %d, channel: %d", WPAN_PHY_PR_ARG, + __entry->page, __entry->channel) +); + +TRACE_EVENT(802154_rdev_set_cca_mode, + TP_PROTO(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca), + TP_ARGS(wpan_phy, cca), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_CCA_ENTRY + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_CCA_ASSIGN; + ), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_CCA_PR_FMT, WPAN_PHY_PR_ARG, + WPAN_CCA_PR_ARG) +); + +DECLARE_EVENT_CLASS(802154_le16_template, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + __le16 le16arg), + TP_ARGS(wpan_phy, wpan_dev, le16arg), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + __field(__le16, le16arg) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + __entry->le16arg = le16arg; + ), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", pan id: 0x%04x", + WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG, + __le16_to_cpu(__entry->le16arg)) +); + +DEFINE_EVENT(802154_le16_template, 802154_rdev_set_pan_id, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + __le16 le16arg), + TP_ARGS(wpan_phy, wpan_dev, le16arg) +); + +DEFINE_EVENT_PRINT(802154_le16_template, 802154_rdev_set_short_addr, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + __le16 le16arg), + TP_ARGS(wpan_phy, wpan_dev, le16arg), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", sa: 0x%04x", + WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG, + __le16_to_cpu(__entry->le16arg)) +); + +TRACE_EVENT(802154_rdev_set_backoff_exponent, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + u8 min_be, u8 max_be), + TP_ARGS(wpan_phy, wpan_dev, min_be, max_be), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + __field(u8, min_be) + __field(u8, max_be) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + __entry->min_be = min_be; + __entry->max_be = max_be; + ), + + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT + ", min be: %d, max_be: %d", WPAN_PHY_PR_ARG, + WPAN_DEV_PR_ARG, __entry->min_be, __entry->max_be) +); + +TRACE_EVENT(802154_rdev_set_csma_backoffs, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + u8 max_csma_backoffs), + TP_ARGS(wpan_phy, wpan_dev, max_csma_backoffs), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + __field(u8, max_csma_backoffs) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + __entry->max_csma_backoffs = max_csma_backoffs; + ), + + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT + ", max csma backoffs: %d", WPAN_PHY_PR_ARG, + WPAN_DEV_PR_ARG, __entry->max_csma_backoffs) +); + +TRACE_EVENT(802154_rdev_set_max_frame_retries, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + s8 max_frame_retries), + TP_ARGS(wpan_phy, wpan_dev, max_frame_retries), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + __field(s8, max_frame_retries) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + __entry->max_frame_retries = max_frame_retries; + ), + + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT + ", max frame retries: %d", WPAN_PHY_PR_ARG, + WPAN_DEV_PR_ARG, __entry->max_frame_retries) +); + +TRACE_EVENT(802154_rdev_set_lbt_mode, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + bool mode), + TP_ARGS(wpan_phy, wpan_dev, mode), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + __field(bool, mode) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + __entry->mode = mode; + ), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT + ", lbt mode: %s", WPAN_PHY_PR_ARG, + WPAN_DEV_PR_ARG, BOOL_TO_STR(__entry->mode)) +); + +TRACE_EVENT(802154_rdev_return_int, + TP_PROTO(struct wpan_phy *wpan_phy, int ret), + TP_ARGS(wpan_phy, ret), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + __field(int, ret) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + __entry->ret = ret; + ), + TP_printk(WPAN_PHY_PR_FMT ", returned: %d", WPAN_PHY_PR_ARG, + __entry->ret) +); + +#endif /* !__RDEV_CFG802154_OPS_TRACE || TRACE_HEADER_MULTI_READ */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace +#include <trace/define_trace.h> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 421a80b09b62..30b544f025ac 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -256,7 +256,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) aead_givcrypt_set_crypt(req, sg, sg, clen, iv); aead_givcrypt_set_assoc(req, asg, assoclen); aead_givcrypt_set_giv(req, esph->enc_data, - XFRM_SKB_CB(skb)->seq.output.low); + XFRM_SKB_CB(skb)->seq.output.low + + ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32)); ESP_SKB_CB(skb)->tmp = tmp; err = crypto_aead_givencrypt(req); diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index e13fcc602da2..09b62e17dd8c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1164,6 +1164,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) state = fa->fa_state; new_fa->fa_state = state & ~FA_S_ACCESSED; new_fa->fa_slen = fa->fa_slen; + new_fa->tb_id = tb->tb_id; err = netdev_switch_fib_ipv4_add(key, plen, fi, new_fa->fa_tos, @@ -1764,7 +1765,7 @@ void fib_table_flush_external(struct fib_table *tb) /* record local slen */ slen = fa->fa_slen; - if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL)) + if (!fi || !(fi->fib_flags & RTNH_F_OFFLOAD)) continue; netdev_switch_fib_ipv4_del(n->key, diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index bb77ebdae3b3..4d32262c7502 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -224,14 +224,16 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, handler->idiag_get_info(sk, r, info); if (sk->sk_state < TCP_TIME_WAIT) { - int err = 0; + union tcp_cc_info info; + size_t sz = 0; + int attr; rcu_read_lock(); ca_ops = READ_ONCE(icsk->icsk_ca_ops); if (ca_ops && ca_ops->get_info) - err = ca_ops->get_info(sk, ext, skb); + sz = ca_ops->get_info(sk, ext, &attr, &info); rcu_read_unlock(); - if (err < 0) + if (sz && nla_put(skb, attr, sz, &info) < 0) goto errout; } diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 9f7269f3c54a..0c152087ca15 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -65,7 +65,6 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, goto drop; XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; - skb->mark = be32_to_cpu(tunnel->parms.i_key); return xfrm_input(skb, nexthdr, spi, encap_type); } @@ -91,6 +90,8 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) struct pcpu_sw_netstats *tstats; struct xfrm_state *x; struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; + u32 orig_mark = skb->mark; + int ret; if (!tunnel) return 1; @@ -107,7 +108,11 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) x = xfrm_input_state(skb); family = x->inner_mode->afinfo->family; - if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) + skb->mark = be32_to_cpu(tunnel->parms.i_key); + ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); + skb->mark = orig_mark; + + if (!ret) return -EPERM; skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev))); @@ -216,8 +221,6 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) memset(&fl, 0, sizeof(fl)); - skb->mark = be32_to_cpu(tunnel->parms.o_key); - switch (skb->protocol) { case htons(ETH_P_IP): xfrm_decode_session(skb, &fl, AF_INET); @@ -233,6 +236,9 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } + /* override mark with tunnel output key */ + fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key); + return vti_xmit(skb, dev, &fl); } diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 13bfe84bf3ca..a61200754f4b 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1075,6 +1075,9 @@ static int do_replace(struct net *net, const void __user *user, /* overflow check */ if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); @@ -1499,6 +1502,9 @@ static int compat_do_replace(struct net *net, void __user *user, return -ENOMEM; if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index c69db7fa25ee..2d0e265fef6e 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1262,6 +1262,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len) /* overflow check */ if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); @@ -1809,6 +1812,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) return -ENOMEM; if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bff62fc87b8e..f45f2a12f37b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -902,6 +902,10 @@ static int ip_error(struct sk_buff *skb) bool send; int code; + /* IP on this device is disabled. */ + if (!in_dev) + goto out; + net = dev_net(rt->dst.dev); if (!IN_DEV_FORWARD(in_dev)) { switch (rt->dst.error) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8c5cd9efebbc..f1377f2a0472 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -252,6 +252,7 @@ #include <linux/types.h> #include <linux/fcntl.h> #include <linux/poll.h> +#include <linux/inet_diag.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/skbuff.h> @@ -401,6 +402,7 @@ void tcp_init_sock(struct sock *sk) tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_cwnd_clamp = ~0; tp->mss_cache = TCP_MSS_DEFAULT; + u64_stats_init(&tp->syncp); tp->reordering = sysctl_tcp_reordering; tcp_enable_early_retrans(tp); @@ -2592,11 +2594,12 @@ EXPORT_SYMBOL(compat_tcp_setsockopt); #endif /* Return information about state of tcp endpoint in API format. */ -void tcp_get_info(const struct sock *sk, struct tcp_info *info) +void tcp_get_info(struct sock *sk, struct tcp_info *info) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); u32 now = tcp_time_stamp; + unsigned int start; u32 rate; memset(info, 0, sizeof(*info)); @@ -2663,6 +2666,12 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) rate = READ_ONCE(sk->sk_max_pacing_rate); info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL; + + do { + start = u64_stats_fetch_begin_irq(&tp->syncp); + info->tcpi_bytes_acked = tp->bytes_acked; + info->tcpi_bytes_received = tp->bytes_received; + } while (u64_stats_fetch_retry_irq(&tp->syncp, start)); } EXPORT_SYMBOL_GPL(tcp_get_info); @@ -2734,6 +2743,26 @@ static int do_tcp_getsockopt(struct sock *sk, int level, return -EFAULT; return 0; } + case TCP_CC_INFO: { + const struct tcp_congestion_ops *ca_ops; + union tcp_cc_info info; + size_t sz = 0; + int attr; + + if (get_user(len, optlen)) + return -EFAULT; + + ca_ops = icsk->icsk_ca_ops; + if (ca_ops && ca_ops->get_info) + sz = ca_ops->get_info(sk, ~0U, &attr, &info); + + len = min_t(unsigned int, len, sz); + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &info, len)) + return -EFAULT; + return 0; + } case TCP_QUICKACK: val = !icsk->icsk_ack.pingpong; break; diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 7a5ae50c80c8..84be008c945c 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -187,6 +187,7 @@ static void tcp_reinit_congestion_control(struct sock *sk, tcp_cleanup_congestion_control(sk); icsk->icsk_ca_ops = ca; + icsk->icsk_ca_setsockopt = 1; if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) icsk->icsk_ca_ops->init(sk); @@ -335,8 +336,10 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) rcu_read_lock(); ca = __tcp_ca_find_autoload(name); /* No change asking for existing value */ - if (ca == icsk->icsk_ca_ops) + if (ca == icsk->icsk_ca_ops) { + icsk->icsk_ca_setsockopt = 1; goto out; + } if (!ca) err = -ENOENT; else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c index 4376016f7fa5..4c41c1287197 100644 --- a/net/ipv4/tcp_dctcp.c +++ b/net/ipv4/tcp_dctcp.c @@ -277,7 +277,8 @@ static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev) } } -static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb) +static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info) { const struct dctcp *ca = inet_csk_ca(sk); @@ -286,18 +287,17 @@ static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb) */ if (ext & (1 << (INET_DIAG_DCTCPINFO - 1)) || ext & (1 << (INET_DIAG_VEGASINFO - 1))) { - struct tcp_dctcp_info info; - - memset(&info, 0, sizeof(info)); + memset(info, 0, sizeof(struct tcp_dctcp_info)); if (inet_csk(sk)->icsk_ca_ops != &dctcp_reno) { - info.dctcp_enabled = 1; - info.dctcp_ce_state = (u16) ca->ce_state; - info.dctcp_alpha = ca->dctcp_alpha; - info.dctcp_ab_ecn = ca->acked_bytes_ecn; - info.dctcp_ab_tot = ca->acked_bytes_total; + info->dctcp.dctcp_enabled = 1; + info->dctcp.dctcp_ce_state = (u16) ca->ce_state; + info->dctcp.dctcp_alpha = ca->dctcp_alpha; + info->dctcp.dctcp_ab_ecn = ca->acked_bytes_ecn; + info->dctcp.dctcp_ab_tot = ca->acked_bytes_total; } - return nla_put(skb, INET_DIAG_DCTCPINFO, sizeof(info), &info); + *attr = INET_DIAG_DCTCPINFO; + return sizeof(*info); } return 0; } diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index e3d87aca6be8..46b087a27503 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -206,6 +206,11 @@ static bool tcp_fastopen_create_child(struct sock *sk, skb_set_owner_r(skb2, child); __skb_queue_tail(&child->sk_receive_queue, skb2); tp->syn_data_acked = 1; + + /* u64_stats_update_begin(&tp->syncp) not needed here, + * as we certainly are not changing upper 32bit value (0) + */ + tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1; } else { end_seq = TCP_SKB_CB(skb)->seq + 1; } diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 67476f085e48..f71002e4db0b 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c @@ -300,24 +300,25 @@ static u32 tcp_illinois_ssthresh(struct sock *sk) } /* Extract info for Tcp socket info provided via netlink. */ -static int tcp_illinois_info(struct sock *sk, u32 ext, struct sk_buff *skb) +static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info) { const struct illinois *ca = inet_csk_ca(sk); if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) { - struct tcpvegas_info info = { - .tcpv_enabled = 1, - .tcpv_rttcnt = ca->cnt_rtt, - .tcpv_minrtt = ca->base_rtt, - }; + info->vegas.tcpv_enabled = 1; + info->vegas.tcpv_rttcnt = ca->cnt_rtt; + info->vegas.tcpv_minrtt = ca->base_rtt; + info->vegas.tcpv_rtt = 0; - if (info.tcpv_rttcnt > 0) { + if (info->vegas.tcpv_rttcnt > 0) { u64 t = ca->sum_rtt; - do_div(t, info.tcpv_rttcnt); - info.tcpv_rtt = t; + do_div(t, info->vegas.tcpv_rttcnt); + info->vegas.tcpv_rtt = t; } - return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); + *attr = INET_DIAG_VEGASINFO; + return sizeof(struct tcpvegas_info); } return 0; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3a4d9b34bed4..c9ab964189a0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1820,14 +1820,12 @@ advance_sp: for (j = 0; j < used_sacks; j++) tp->recv_sack_cache[i++] = sp[j]; - tcp_mark_lost_retrans(sk); - - tcp_verify_left_out(tp); - if ((state.reord < tp->fackets_out) && ((inet_csk(sk)->icsk_ca_state != TCP_CA_Loss) || tp->undo_marker)) tcp_update_reordering(sk, tp->fackets_out - state.reord, 0); + tcp_mark_lost_retrans(sk); + tcp_verify_left_out(tp); out: #if FASTRETRANS_DEBUG > 0 @@ -2700,16 +2698,21 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack) struct tcp_sock *tp = tcp_sk(sk); bool recovered = !before(tp->snd_una, tp->high_seq); + if ((flag & FLAG_SND_UNA_ADVANCED) && + tcp_try_undo_loss(sk, false)) + return; + if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ /* Step 3.b. A timeout is spurious if not all data are * lost, i.e., never-retransmitted data are (s)acked. */ - if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED)) + if ((flag & FLAG_ORIG_SACK_ACKED) && + tcp_try_undo_loss(sk, true)) return; - if (after(tp->snd_nxt, tp->high_seq) && - (flag & FLAG_DATA_SACKED || is_dupack)) { - tp->frto = 0; /* Loss was real: 2nd part of step 3.a */ + if (after(tp->snd_nxt, tp->high_seq)) { + if (flag & FLAG_DATA_SACKED || is_dupack) + tp->frto = 0; /* Step 3.a. loss was real */ } else if (flag & FLAG_SND_UNA_ADVANCED && !recovered) { tp->high_seq = tp->snd_nxt; __tcp_push_pending_frames(sk, tcp_current_mss(sk), @@ -2734,8 +2737,6 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack) else if (flag & FLAG_SND_UNA_ADVANCED) tcp_reset_reno_sack(tp); } - if (tcp_try_undo_loss(sk, false)) - return; tcp_xmit_retransmit_queue(sk); } @@ -3280,6 +3281,28 @@ static inline bool tcp_may_update_window(const struct tcp_sock *tp, (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd); } +/* If we update tp->snd_una, also update tp->bytes_acked */ +static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack) +{ + u32 delta = ack - tp->snd_una; + + u64_stats_update_begin(&tp->syncp); + tp->bytes_acked += delta; + u64_stats_update_end(&tp->syncp); + tp->snd_una = ack; +} + +/* If we update tp->rcv_nxt, also update tp->bytes_received */ +static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq) +{ + u32 delta = seq - tp->rcv_nxt; + + u64_stats_update_begin(&tp->syncp); + tp->bytes_received += delta; + u64_stats_update_end(&tp->syncp); + tp->rcv_nxt = seq; +} + /* Update our send window. * * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2 @@ -3315,7 +3338,7 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32 } } - tp->snd_una = ack; + tcp_snd_una_update(tp, ack); return flag; } @@ -3497,7 +3520,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) * Note, we use the fact that SND.UNA>=SND.WL2. */ tcp_update_wl(tp, ack_seq); - tp->snd_una = ack; + tcp_snd_una_update(tp, ack); flag |= FLAG_WIN_UPDATE; tcp_in_ack_event(sk, CA_ACK_WIN_UPDATE); @@ -4236,7 +4259,7 @@ static void tcp_ofo_queue(struct sock *sk) tail = skb_peek_tail(&sk->sk_receive_queue); eaten = tail && tcp_try_coalesce(sk, tail, skb, &fragstolen); - tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); if (!eaten) __skb_queue_tail(&sk->sk_receive_queue, skb); if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) @@ -4404,7 +4427,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int __skb_pull(skb, hdrlen); eaten = (tail && tcp_try_coalesce(sk, tail, skb, fragstolen)) ? 1 : 0; - tcp_sk(sk)->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq); if (!eaten) { __skb_queue_tail(&sk->sk_receive_queue, skb); skb_set_owner_r(skb, sk); @@ -4497,7 +4520,7 @@ queue_and_out: eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); } - tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); if (skb->len) tcp_event_data_recv(sk, skb); if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) @@ -5245,7 +5268,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, tcp_rcv_rtt_measure_ts(sk, skb); __skb_pull(skb, tcp_header_len); - tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITSTOUSER); eaten = 1; } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index e5d7649136fc..17e7339ee5ca 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -300,7 +300,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) tw->tw_v6_daddr = sk->sk_v6_daddr; tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr; tw->tw_tclass = np->tclass; - tw->tw_flowlabel = np->flow_label >> 12; + tw->tw_flowlabel = be32_to_cpu(np->flow_label & IPV6_FLOWLABEL_MASK); tw->tw_ipv6only = sk->sk_ipv6only; } #endif @@ -420,7 +420,10 @@ void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst) rcu_read_unlock(); } - if (!ca_got_dst && !try_module_get(icsk->icsk_ca_ops->owner)) + /* If no valid choice made yet, assign current system default ca. */ + if (!ca_got_dst && + (!icsk->icsk_ca_setsockopt || + !try_module_get(icsk->icsk_ca_ops->owner))) tcp_assign_congestion_control(sk); tcp_set_ca_state(sk, TCP_CA_Open); diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c index c71a1b8f7bde..a6cea1d5e20d 100644 --- a/net/ipv4/tcp_vegas.c +++ b/net/ipv4/tcp_vegas.c @@ -286,18 +286,19 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) } /* Extract info for Tcp socket info provided via netlink. */ -int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb) +size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info) { const struct vegas *ca = inet_csk_ca(sk); + if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) { - struct tcpvegas_info info = { - .tcpv_enabled = ca->doing_vegas_now, - .tcpv_rttcnt = ca->cntRTT, - .tcpv_rtt = ca->baseRTT, - .tcpv_minrtt = ca->minRTT, - }; - - return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); + info->vegas.tcpv_enabled = ca->doing_vegas_now, + info->vegas.tcpv_rttcnt = ca->cntRTT, + info->vegas.tcpv_rtt = ca->baseRTT, + info->vegas.tcpv_minrtt = ca->minRTT, + + *attr = INET_DIAG_VEGASINFO; + return sizeof(struct tcpvegas_info); } return 0; } diff --git a/net/ipv4/tcp_vegas.h b/net/ipv4/tcp_vegas.h index e8a6b33cc61d..ef9da5306c68 100644 --- a/net/ipv4/tcp_vegas.h +++ b/net/ipv4/tcp_vegas.h @@ -19,6 +19,7 @@ void tcp_vegas_init(struct sock *sk); void tcp_vegas_state(struct sock *sk, u8 ca_state); void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us); void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event); -int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb); +size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info); #endif /* __TCP_VEGAS_H */ diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c index b3c57cceb990..c10732e39837 100644 --- a/net/ipv4/tcp_westwood.c +++ b/net/ipv4/tcp_westwood.c @@ -256,18 +256,19 @@ static void tcp_westwood_event(struct sock *sk, enum tcp_ca_event event) } /* Extract info for Tcp socket info provided via netlink. */ -static int tcp_westwood_info(struct sock *sk, u32 ext, struct sk_buff *skb) +static size_t tcp_westwood_info(struct sock *sk, u32 ext, int *attr, + union tcp_cc_info *info) { const struct westwood *ca = inet_csk_ca(sk); if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) { - struct tcpvegas_info info = { - .tcpv_enabled = 1, - .tcpv_rtt = jiffies_to_usecs(ca->rtt), - .tcpv_minrtt = jiffies_to_usecs(ca->rtt_min), - }; + info->vegas.tcpv_enabled = 1; + info->vegas.tcpv_rttcnt = 0; + info->vegas.tcpv_rtt = jiffies_to_usecs(ca->rtt), + info->vegas.tcpv_minrtt = jiffies_to_usecs(ca->rtt_min), - return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); + *attr = INET_DIAG_VEGASINFO; + return sizeof(struct tcpvegas_info); } return 0; } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d10b7e0112eb..1c92ea67baef 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1345,10 +1345,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 31f1b5d5e2ef..7c07ce36aae2 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -248,7 +248,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) aead_givcrypt_set_crypt(req, sg, sg, clen, iv); aead_givcrypt_set_assoc(req, asg, assoclen); aead_givcrypt_set_giv(req, esph->enc_data, - XFRM_SKB_CB(skb)->seq.output.low); + XFRM_SKB_CB(skb)->seq.output.low + + ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32)); ESP_SKB_CB(skb)->tmp = tmp; err = crypto_aead_givencrypt(req); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 96dbffff5a24..bde57b113009 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -693,6 +693,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, { struct rt6_info *iter = NULL; struct rt6_info **ins; + struct rt6_info **fallback_ins = NULL; int replace = (info->nlh && (info->nlh->nlmsg_flags & NLM_F_REPLACE)); int add = (!info->nlh || @@ -716,8 +717,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, (info->nlh->nlmsg_flags & NLM_F_EXCL)) return -EEXIST; if (replace) { - found++; - break; + if (rt_can_ecmp == rt6_qualify_for_ecmp(iter)) { + found++; + break; + } + if (rt_can_ecmp) + fallback_ins = fallback_ins ?: ins; + goto next_iter; } if (iter->dst.dev == rt->dst.dev && @@ -753,9 +759,17 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (iter->rt6i_metric > rt->rt6i_metric) break; +next_iter: ins = &iter->dst.rt6_next; } + if (fallback_ins && !found) { + /* No ECMP-able route found, replace first non-ECMP one */ + ins = fallback_ins; + iter = *ins; + found++; + } + /* Reset round-robin state, if necessary */ if (ins == &fn->leaf) fn->rr_ptr = NULL; @@ -815,6 +829,8 @@ add: } } else { + int nsiblings; + if (!found) { if (add) goto add; @@ -835,8 +851,27 @@ add: info->nl_net->ipv6.rt6_stats->fib_route_nodes++; fn->fn_flags |= RTN_RTINFO; } + nsiblings = iter->rt6i_nsiblings; fib6_purge_rt(iter, fn, info->nl_net); rt6_release(iter); + + if (nsiblings) { + /* Replacing an ECMP route, remove all siblings */ + ins = &rt->dst.rt6_next; + iter = *ins; + while (iter) { + if (rt6_qualify_for_ecmp(iter)) { + *ins = iter->dst.rt6_next; + fib6_purge_rt(iter, fn, info->nl_net); + rt6_release(iter); + nsiblings--; + } else { + ins = &iter->dst.rt6_next; + } + iter = *ins; + } + WARN_ON(nsiblings != 0); + } } return 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7fde1f265c90..bc09cb97b840 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -886,22 +886,45 @@ static int ip6_dst_lookup_tail(struct sock *sk, #endif int err; - if (!*dst) - *dst = ip6_route_output(net, sk, fl6); - - err = (*dst)->error; - if (err) - goto out_err_release; + /* The correct way to handle this would be to do + * ip6_route_get_saddr, and then ip6_route_output; however, + * the route-specific preferred source forces the + * ip6_route_output call _before_ ip6_route_get_saddr. + * + * In source specific routing (no src=any default route), + * ip6_route_output will fail given src=any saddr, though, so + * that's why we try it again later. + */ + if (ipv6_addr_any(&fl6->saddr) && (!*dst || !(*dst)->error)) { + struct rt6_info *rt; + bool had_dst = *dst != NULL; - if (ipv6_addr_any(&fl6->saddr)) { - struct rt6_info *rt = (struct rt6_info *) *dst; + if (!had_dst) + *dst = ip6_route_output(net, sk, fl6); + rt = (*dst)->error ? NULL : (struct rt6_info *)*dst; err = ip6_route_get_saddr(net, rt, &fl6->daddr, sk ? inet6_sk(sk)->srcprefs : 0, &fl6->saddr); if (err) goto out_err_release; + + /* If we had an erroneous initial result, pretend it + * never existed and let the SA-enabled version take + * over. + */ + if (!had_dst && (*dst)->error) { + dst_release(*dst); + *dst = NULL; + } } + if (!*dst) + *dst = ip6_route_output(net, sk, fl6); + + err = (*dst)->error; + if (err) + goto out_err_release; + #ifdef CONFIG_IPV6_OPTIMISTIC_DAD /* * Here if the dst entry we've looked up @@ -1277,8 +1300,10 @@ emsgsize: /* If this is the first and only packet and device * supports checksum offloading, let's use it. + * Use transhdrlen, same as IPv4, because partial + * sums only work when transhdrlen is set. */ - if (!skb && sk->sk_protocol == IPPROTO_UDP && + if (transhdrlen && sk->sk_protocol == IPPROTO_UDP && length + fragheaderlen < mtu && rt->dst.dev->features & NETIF_F_V6_CSUM && !exthdrlen) diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index ed9d681207fa..0224c032dca5 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -322,7 +322,6 @@ static int vti6_rcv(struct sk_buff *skb) } XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; - skb->mark = be32_to_cpu(t->parms.i_key); rcu_read_unlock(); @@ -342,6 +341,8 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) struct pcpu_sw_netstats *tstats; struct xfrm_state *x; struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; + u32 orig_mark = skb->mark; + int ret; if (!t) return 1; @@ -358,7 +359,11 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) x = xfrm_input_state(skb); family = x->inner_mode->afinfo->family; - if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) + skb->mark = be32_to_cpu(t->parms.i_key); + ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); + skb->mark = orig_mark; + + if (!ret) return -EPERM; skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev))); @@ -430,6 +435,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) struct net_device *tdev; struct xfrm_state *x; int err = -1; + int mtu; if (!dst) goto tx_err_link_failure; @@ -463,6 +469,19 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) skb_dst_set(skb, dst); skb->dev = skb_dst(skb)->dev; + mtu = dst_mtu(dst); + if (!skb->ignore_df && skb->len > mtu) { + skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); + + if (skb->protocol == htons(ETH_P_IPV6)) + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + else + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); + + return -EMSGSIZE; + } + err = dst_output(skb); if (net_xmit_eval(err) == 0) { struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); @@ -495,7 +514,6 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) int ret; memset(&fl, 0, sizeof(fl)); - skb->mark = be32_to_cpu(t->parms.o_key); switch (skb->protocol) { case htons(ETH_P_IPV6): @@ -516,6 +534,9 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) goto tx_err; } + /* override mark with tunnel output key */ + fl.flowi_mark = be32_to_cpu(t->parms.o_key); + ret = vti6_xmit(skb, dev, &fl); if (ret < 0) goto tx_err; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 1a732a1d3c8e..62f5b0d0bc9b 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1275,6 +1275,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len) /* overflow check */ if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); @@ -1822,6 +1825,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) return -ENOMEM; if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) return -ENOMEM; + if (tmp.num_counters == 0) + return -EINVAL; + tmp.name[sizeof(tmp.name)-1] = 0; newinfo = xt_alloc_table_info(tmp.size); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5c48293ff062..c73ae5039e46 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2245,9 +2245,10 @@ int ip6_route_get_saddr(struct net *net, unsigned int prefs, struct in6_addr *saddr) { - struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt); + struct inet6_dev *idev = + rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL; int err = 0; - if (rt->rt6i_prefsrc.plen) + if (rt && rt->rt6i_prefsrc.plen) *saddr = rt->rt6i_prefsrc.addr; else err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, @@ -2503,9 +2504,9 @@ static int ip6_route_multipath(struct fib6_config *cfg, int add) int attrlen; int err = 0, last_err = 0; + remaining = cfg->fc_mp_len; beginning: rtnh = (struct rtnexthop *)cfg->fc_mp; - remaining = cfg->fc_mp_len; /* Parse a Multipath Entry */ while (rtnh_ok(rtnh, remaining)) { @@ -2535,15 +2536,19 @@ beginning: * next hops that have been already added. */ add = 0; + remaining = cfg->fc_mp_len - remaining; goto beginning; } } /* Because each route is added like a single route we remove - * this flag after the first nexthop (if there is a collision, - * we have already fail to add the first nexthop: - * fib6_add_rt2node() has reject it). + * these flags after the first nexthop: if there is a collision, + * we have already failed to add the first nexthop: + * fib6_add_rt2node() has rejected it; when replacing, old + * nexthops have been replaced by first new, the rest should + * be added to it. */ - cfg->fc_nlinfo.nlh->nlmsg_flags &= ~NLM_F_EXCL; + cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL | + NLM_F_REPLACE); rtnh = rtnh_next(rtnh, &remaining); } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b6575d665568..3adffb300238 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -914,7 +914,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, tcp_time_stamp + tcptw->tw_ts_offset, tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), - tw->tw_tclass, (tw->tw_flowlabel << 12)); + tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); inet_twsk_put(tw); } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3477c919fcc8..e51fc3eee6db 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -525,10 +525,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } @@ -731,7 +729,9 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk, (inet->inet_dport && inet->inet_dport != rmt_port) || (!ipv6_addr_any(&sk->sk_v6_daddr) && !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) || - (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) + (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) || + (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr))) return false; if (!inet6_mc_check(sk, loc_addr, rmt_addr)) return false; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 265e42721a66..ff347a0eebd4 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2495,51 +2495,22 @@ static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local, struct ieee80211_roc_work *new_roc, struct ieee80211_roc_work *cur_roc) { - unsigned long j = jiffies; - unsigned long cur_roc_end = cur_roc->hw_start_time + - msecs_to_jiffies(cur_roc->duration); - struct ieee80211_roc_work *next_roc; - int new_dur; + unsigned long now = jiffies; + unsigned long remaining = cur_roc->hw_start_time + + msecs_to_jiffies(cur_roc->duration) - + now; if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun)) return false; - if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end)) + /* if it doesn't fit entirely, schedule a new one */ + if (new_roc->duration > jiffies_to_msecs(remaining)) return false; ieee80211_handle_roc_started(new_roc); - new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j); - - /* cur_roc is long enough - add new_roc to the dependents list. */ - if (new_dur <= 0) { - list_add_tail(&new_roc->list, &cur_roc->dependents); - return true; - } - - new_roc->duration = new_dur; - - /* - * if cur_roc was already coalesced before, we might - * want to extend the next roc instead of adding - * a new one. - */ - next_roc = list_entry(cur_roc->list.next, - struct ieee80211_roc_work, list); - if (&next_roc->list != &local->roc_list && - next_roc->chan == new_roc->chan && - next_roc->sdata == new_roc->sdata && - !WARN_ON(next_roc->started)) { - list_add_tail(&new_roc->list, &next_roc->dependents); - next_roc->duration = max(next_roc->duration, - new_roc->duration); - next_roc->type = max(next_roc->type, new_roc->type); - return true; - } - - /* add right after cur_roc */ - list_add(&new_roc->list, &cur_roc->list); - + /* add to dependents so we send the expired event properly */ + list_add_tail(&new_roc->list, &cur_roc->dependents); return true; } @@ -2652,17 +2623,9 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, * In the offloaded ROC case, if it hasn't begun, add * this new one to the dependent list to be handled * when the master one begins. If it has begun, - * check that there's still a minimum time left and - * if so, start this one, transmitting the frame, but - * add it to the list directly after this one with - * a reduced time so we'll ask the driver to execute - * it right after finishing the previous one, in the - * hope that it'll also be executed right afterwards, - * effectively extending the old one. - * If there's no minimum time left, just add it to the - * normal list. - * TODO: the ROC type is ignored here, assuming that it - * is better to immediately use the current ROC. + * check if it fits entirely within the existing one, + * in which case it will just be dependent as well. + * Otherwise, schedule it by itself. */ if (!tmp->hw_begun) { list_add_tail(&roc->list, &tmp->dependents); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ab46ab4a7249..c0a9187bc3a9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -205,6 +205,8 @@ enum ieee80211_packet_rx_flags { * @IEEE80211_RX_CMNTR: received on cooked monitor already * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported * to cfg80211_report_obss_beacon(). + * @IEEE80211_RX_REORDER_TIMER: this frame is released by the + * reorder buffer timeout timer, not the normal RX path * * These flags are used across handling multiple interfaces * for a single frame. @@ -212,6 +214,7 @@ enum ieee80211_packet_rx_flags { enum ieee80211_rx_flags { IEEE80211_RX_CMNTR = BIT(0), IEEE80211_RX_BEACON_REPORTED = BIT(1), + IEEE80211_RX_REORDER_TIMER = BIT(2), }; struct ieee80211_rx_data { @@ -325,12 +328,6 @@ struct mesh_preq_queue { u8 flags; }; -#if HZ/100 == 0 -#define IEEE80211_ROC_MIN_LEFT 1 -#else -#define IEEE80211_ROC_MIN_LEFT (HZ/100) -#endif - struct ieee80211_roc_work { struct list_head list; struct list_head dependents; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b4ac596a7cb7..84cef600c573 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -522,6 +522,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) memcpy(sdata->vif.hw_queue, master->vif.hw_queue, sizeof(sdata->vif.hw_queue)); sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef; + + mutex_lock(&local->key_mtx); + sdata->crypto_tx_tailroom_needed_cnt += + master->crypto_tx_tailroom_needed_cnt; + mutex_unlock(&local->key_mtx); + break; } case NL80211_IFTYPE_AP: @@ -819,13 +825,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, * (because if we remove a STA after ops->remove_interface() * the driver will have removed the vif info already!) * - * This is relevant only in WDS mode, in all other modes we've - * already removed all stations when disconnecting or similar, - * so warn otherwise. + * In WDS mode a station must exist here and be flushed, for + * AP_VLANs stations may exist since there's nothing else that + * would have removed them, but in other modes there shouldn't + * be any stations. */ flushed = sta_info_flush(sdata); - WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || - (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); + WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || + (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1))); /* don't count this interface for promisc/allmulti while it is down */ if (sdata->flags & IEEE80211_SDATA_ALLMULTI) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 2291cd730091..a907f2d5c12d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -58,6 +58,22 @@ static void assert_key_lock(struct ieee80211_local *local) lockdep_assert_held(&local->key_mtx); } +static void +update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta) +{ + struct ieee80211_sub_if_data *vlan; + + if (sdata->vif.type != NL80211_IFTYPE_AP) + return; + + mutex_lock(&sdata->local->mtx); + + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) + vlan->crypto_tx_tailroom_needed_cnt += delta; + + mutex_unlock(&sdata->local->mtx); +} + static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) { /* @@ -79,6 +95,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net */ + update_vlan_tailroom_need_count(sdata, 1); + if (!sdata->crypto_tx_tailroom_needed_cnt++) { /* * Flush all XMIT packets currently using HW encryption or no @@ -88,6 +106,15 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) } } +static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata, + int delta) +{ + WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta); + + update_vlan_tailroom_need_count(sdata, -delta); + sdata->crypto_tx_tailroom_needed_cnt -= delta; +} + static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) { struct ieee80211_sub_if_data *sdata; @@ -144,7 +171,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) - sdata->crypto_tx_tailroom_needed_cnt--; + decrease_tailroom_need_count(sdata, 1); WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)); @@ -541,7 +568,7 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key, schedule_delayed_work(&sdata->dec_tailroom_needed_wk, HZ/2); } else { - sdata->crypto_tx_tailroom_needed_cnt--; + decrease_tailroom_need_count(sdata, 1); } } @@ -631,6 +658,7 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) { struct ieee80211_key *key; + struct ieee80211_sub_if_data *vlan; ASSERT_RTNL(); @@ -639,7 +667,14 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->local->key_mtx); - sdata->crypto_tx_tailroom_needed_cnt = 0; + WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || + sdata->crypto_tx_tailroom_pending_dec); + + if (sdata->vif.type == NL80211_IFTYPE_AP) { + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) + WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || + vlan->crypto_tx_tailroom_pending_dec); + } list_for_each_entry(key, &sdata->key_list, list) { increment_tailroom_need_count(sdata); @@ -649,6 +684,22 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) mutex_unlock(&sdata->local->key_mtx); } +void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_sub_if_data *vlan; + + mutex_lock(&sdata->local->key_mtx); + + sdata->crypto_tx_tailroom_needed_cnt = 0; + + if (sdata->vif.type == NL80211_IFTYPE_AP) { + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) + vlan->crypto_tx_tailroom_needed_cnt = 0; + } + + mutex_unlock(&sdata->local->key_mtx); +} + void ieee80211_iter_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void (*iter)(struct ieee80211_hw *hw, @@ -688,8 +739,8 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata, { struct ieee80211_key *key, *tmp; - sdata->crypto_tx_tailroom_needed_cnt -= - sdata->crypto_tx_tailroom_pending_dec; + decrease_tailroom_need_count(sdata, + sdata->crypto_tx_tailroom_pending_dec); sdata->crypto_tx_tailroom_pending_dec = 0; ieee80211_debugfs_key_remove_mgmt_default(sdata); @@ -709,6 +760,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_sub_if_data *vlan; + struct ieee80211_sub_if_data *master; struct ieee80211_key *key, *tmp; LIST_HEAD(keys); @@ -728,8 +780,20 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, list_for_each_entry_safe(key, tmp, &keys, list) __ieee80211_key_destroy(key, false); - WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || - sdata->crypto_tx_tailroom_pending_dec); + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + if (sdata->bss) { + master = container_of(sdata->bss, + struct ieee80211_sub_if_data, + u.ap); + + WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt != + master->crypto_tx_tailroom_needed_cnt); + } + } else { + WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || + sdata->crypto_tx_tailroom_pending_dec); + } + if (sdata->vif.type == NL80211_IFTYPE_AP) { list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || @@ -793,8 +857,8 @@ void ieee80211_delayed_tailroom_dec(struct work_struct *wk) */ mutex_lock(&sdata->local->key_mtx); - sdata->crypto_tx_tailroom_needed_cnt -= - sdata->crypto_tx_tailroom_pending_dec; + decrease_tailroom_need_count(sdata, + sdata->crypto_tx_tailroom_pending_dec); sdata->crypto_tx_tailroom_pending_dec = 0; mutex_unlock(&sdata->local->key_mtx); } diff --git a/net/mac80211/key.h b/net/mac80211/key.h index c5a31835be0e..96557dd1e77d 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -161,6 +161,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, void ieee80211_free_sta_keys(struct ieee80211_local *local, struct sta_info *sta); void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); +void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata); #define key_mtx_dereference(local, ref) \ rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 260eed45b6d2..5793f75c5ffd 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2121,7 +2121,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) /* deliver to local stack */ skb->protocol = eth_type_trans(skb, dev); memset(skb->cb, 0, sizeof(skb->cb)); - if (rx->local->napi) + if (!(rx->flags & IEEE80211_RX_REORDER_TIMER) && + rx->local->napi) napi_gro_receive(rx->local->napi, skb); else netif_receive_skb(skb); @@ -3231,7 +3232,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) /* This is OK -- must be QoS data frame */ .security_idx = tid, .seqno_idx = tid, - .flags = 0, + .flags = IEEE80211_RX_REORDER_TIMER, }; struct tid_ampdu_rx *tid_agg_rx; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 12971b71d0fa..2880f2ae99ab 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -66,6 +66,7 @@ static const struct rhashtable_params sta_rht_params = { .nelem_hint = 3, /* start small */ + .automatic_shrinking = true, .head_offset = offsetof(struct sta_info, hash_node), .key_offset = offsetof(struct sta_info, sta.addr), .key_len = ETH_ALEN, @@ -157,8 +158,24 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) { struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + struct rhash_head *tmp; + const struct bucket_table *tbl; + + rcu_read_lock(); + tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); - return rhashtable_lookup_fast(&local->sta_hash, addr, sta_rht_params); + for_each_sta_info(local, tbl, addr, sta, tmp) { + if (sta->sdata == sdata) { + rcu_read_unlock(); + /* this is safe as the caller must already hold + * another rcu read section or the mutex + */ + return sta; + } + } + rcu_read_unlock(); + return NULL; } /* diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 79412f16b61d..b864ebc6ab8f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2023,6 +2023,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* add back keys */ list_for_each_entry(sdata, &local->interfaces, list) + ieee80211_reset_crypto_tx_tailroom(sdata); + + list_for_each_entry(sdata, &local->interfaces, list) if (ieee80211_sdata_running(sdata)) ieee80211_enable_keys(sdata); diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index a4220e92f0cc..efa3f48f1ec5 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -98,8 +98,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); - if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN || - skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) + if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) return NULL; hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -167,6 +166,9 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, size_t len; u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; + if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) + return -1; + iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); if (!iv) return -1; diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 5d9f68c75e5f..70be9c799f8a 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -22,13 +22,14 @@ static struct net_device * ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, - const char *name, int type) + const char *name, + unsigned char name_assign_type, int type) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); struct net_device *dev; rtnl_lock(); - dev = ieee802154_if_add(local, name, type, + dev = ieee802154_if_add(local, name, name_assign_type, type, cpu_to_le64(0x0000000000000000ULL)); rtnl_unlock(); @@ -45,12 +46,14 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, static int ieee802154_add_iface(struct wpan_phy *phy, const char *name, + unsigned char name_assign_type, enum nl802154_iftype type, __le64 extended_addr) { struct ieee802154_local *local = wpan_phy_priv(phy); struct net_device *err; - err = ieee802154_if_add(local, name, type, extended_addr); + err = ieee802154_if_add(local, name, name_assign_type, type, + extended_addr); return PTR_ERR_OR_ZERO(err); } diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index bebd70ffc7a3..127ba18386fc 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -182,7 +182,8 @@ void ieee802154_iface_exit(void); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - enum nl802154_iftype type, __le64 extended_addr); + unsigned char name_assign_type, enum nl802154_iftype type, + __le64 extended_addr); void ieee802154_remove_interfaces(struct ieee802154_local *local); #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 38b56f9d9386..91b75abbd1a1 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -522,7 +522,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - enum nl802154_iftype type, __le64 extended_addr) + unsigned char name_assign_type, enum nl802154_iftype type, + __le64 extended_addr) { struct net_device *ndev = NULL; struct ieee802154_sub_if_data *sdata = NULL; @@ -531,7 +532,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, ASSERT_RTNL(); ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, name, - NET_NAME_UNKNOWN, ieee802154_if_setup); + name_assign_type, ieee802154_if_setup); if (!ndev) return ERR_PTR(-ENOMEM); diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index dcf73958133a..5b2be12832e6 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -134,7 +134,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template) for (i = 0; i < ARRAY_SIZE(key->tfm); i++) { key->tfm[i] = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); - if (!key->tfm[i]) + if (IS_ERR(key->tfm[i])) goto err_tfm; if (crypto_aead_setkey(key->tfm[i], template->key, IEEE802154_LLSEC_KEY_SIZE)) @@ -144,7 +144,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template) } key->tfm0 = crypto_alloc_blkcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC); - if (!key->tfm0) + if (IS_ERR(key->tfm0)) goto err_tfm; if (crypto_blkcipher_setkey(key->tfm0, template->key, diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 8500378c8318..08cb32dc8fd3 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -161,18 +161,21 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE, + dev = ieee802154_if_add(local, "wpan%d", NET_NAME_ENUM, + NL802154_IFTYPE_NODE, cpu_to_le64(0x0000000000000000ULL)); if (IS_ERR(dev)) { rtnl_unlock(); rc = PTR_ERR(dev); - goto out_wq; + goto out_phy; } rtnl_unlock(); return 0; +out_phy: + wpan_phy_unregister(local->phy); out_wq: destroy_workqueue(local->workqueue); out: diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 954810c76a86..7b3f732269e4 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -647,7 +647,7 @@ int nla_get_labels(const struct nlattr *nla, return -EINVAL; switch (dec.label) { - case LABEL_IMPLICIT_NULL: + case MPLS_LABEL_IMPLNULL: /* RFC3032: This is a label that an LSR may * assign and distribute, but which never * actually appears in the encapsulation. @@ -935,7 +935,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) } /* In case the predefined labels need to be populated */ - if (limit > LABEL_IPV4_EXPLICIT_NULL) { + if (limit > MPLS_LABEL_IPV4NULL) { struct net_device *lo = net->loopback_dev; rt0 = mpls_rt_alloc(lo->addr_len); if (!rt0) @@ -945,7 +945,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) rt0->rt_via_table = NEIGH_LINK_TABLE; memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len); } - if (limit > LABEL_IPV6_EXPLICIT_NULL) { + if (limit > MPLS_LABEL_IPV6NULL) { struct net_device *lo = net->loopback_dev; rt2 = mpls_rt_alloc(lo->addr_len); if (!rt2) @@ -973,15 +973,15 @@ static int resize_platform_label_table(struct net *net, size_t limit) memcpy(labels, old, cp_size); /* If needed set the predefined labels */ - if ((old_limit <= LABEL_IPV6_EXPLICIT_NULL) && - (limit > LABEL_IPV6_EXPLICIT_NULL)) { - RCU_INIT_POINTER(labels[LABEL_IPV6_EXPLICIT_NULL], rt2); + if ((old_limit <= MPLS_LABEL_IPV6NULL) && + (limit > MPLS_LABEL_IPV6NULL)) { + RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2); rt2 = NULL; } - if ((old_limit <= LABEL_IPV4_EXPLICIT_NULL) && - (limit > LABEL_IPV4_EXPLICIT_NULL)) { - RCU_INIT_POINTER(labels[LABEL_IPV4_EXPLICIT_NULL], rt0); + if ((old_limit <= MPLS_LABEL_IPV4NULL) && + (limit > MPLS_LABEL_IPV4NULL)) { + RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0); rt0 = NULL; } diff --git a/net/mpls/internal.h b/net/mpls/internal.h index 693877d69606..b064c345042c 100644 --- a/net/mpls/internal.h +++ b/net/mpls/internal.h @@ -1,16 +1,6 @@ #ifndef MPLS_INTERNAL_H #define MPLS_INTERNAL_H -#define LABEL_IPV4_EXPLICIT_NULL 0 /* RFC3032 */ -#define LABEL_ROUTER_ALERT_LABEL 1 /* RFC3032 */ -#define LABEL_IPV6_EXPLICIT_NULL 2 /* RFC3032 */ -#define LABEL_IMPLICIT_NULL 3 /* RFC3032 */ -#define LABEL_ENTROPY_INDICATOR 7 /* RFC6790 */ -#define LABEL_GAL 13 /* RFC5586 */ -#define LABEL_OAM_ALERT 14 /* RFC3429 */ -#define LABEL_EXTENSION 15 /* RFC7274 */ - - struct mpls_shim_hdr { __be32 label_stack_entry; }; diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index f70e34a68f70..a0f3e6a3c7d1 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -863,6 +863,7 @@ config NETFILTER_XT_TARGET_TPROXY depends on NETFILTER_XTABLES depends on NETFILTER_ADVANCED depends on (IPV6 || IPV6=n) + depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) depends on IP_NF_MANGLE select NF_DEFRAG_IPV4 select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES @@ -1356,6 +1357,7 @@ config NETFILTER_XT_MATCH_SOCKET depends on NETFILTER_ADVANCED depends on !NF_CONNTRACK || NF_CONNTRACK depends on (IPV6 || IPV6=n) + depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) select NF_DEFRAG_IPV4 select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES help diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 49532672f66d..285eae3a1454 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -3823,6 +3823,9 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) cancel_work_sync(&ipvs->defense_work.work); unregister_net_sysctl_table(ipvs->sysctl_hdr); ip_vs_stop_estimator(net, &ipvs->tot_stats); + + if (!net_eq(net, &init_net)) + kfree(ipvs->sysctl_tbl); } #else diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 5caa0c41bf26..70383de72054 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -202,7 +202,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { * sES -> sES :-) * sFW -> sCW Normal close request answered by ACK. * sCW -> sCW - * sLA -> sTW Last ACK detected. + * sLA -> sTW Last ACK detected (RFC5961 challenged) * sTW -> sTW Retransmitted last ACK. Remain in the same state. * sCL -> sCL */ @@ -261,7 +261,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { * sES -> sES :-) * sFW -> sCW Normal close request answered by ACK. * sCW -> sCW - * sLA -> sTW Last ACK detected. + * sLA -> sTW Last ACK detected (RFC5961 challenged) * sTW -> sTW Retransmitted last ACK. * sCL -> sCL */ @@ -906,6 +906,7 @@ static int tcp_packet(struct nf_conn *ct, 1 : ct->proto.tcp.last_win; ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale = ct->proto.tcp.last_wscale; + ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK; ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags = ct->proto.tcp.last_flags; memset(&ct->proto.tcp.seen[dir], 0, @@ -923,7 +924,9 @@ static int tcp_packet(struct nf_conn *ct, * may be in sync but we are not. In that case, we annotate * the TCP options and let the packet go through. If it is a * valid SYN packet, the server will reply with a SYN/ACK, and - * then we'll get in sync. Otherwise, the server ignores it. */ + * then we'll get in sync. Otherwise, the server potentially + * responds with a challenge ACK if implementing RFC5961. + */ if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) { struct ip_ct_tcp_state seen = {}; @@ -939,6 +942,13 @@ static int tcp_packet(struct nf_conn *ct, ct->proto.tcp.last_flags |= IP_CT_TCP_FLAG_SACK_PERM; } + /* Mark the potential for RFC5961 challenge ACK, + * this pose a special problem for LAST_ACK state + * as ACK is intrepretated as ACKing last FIN. + */ + if (old_state == TCP_CONNTRACK_LAST_ACK) + ct->proto.tcp.last_flags |= + IP_CT_EXP_CHALLENGE_ACK; } spin_unlock_bh(&ct->lock); if (LOG_INVALID(net, IPPROTO_TCP)) @@ -970,6 +980,25 @@ static int tcp_packet(struct nf_conn *ct, nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: invalid state "); return -NF_ACCEPT; + case TCP_CONNTRACK_TIME_WAIT: + /* RFC5961 compliance cause stack to send "challenge-ACK" + * e.g. in response to spurious SYNs. Conntrack MUST + * not believe this ACK is acking last FIN. + */ + if (old_state == TCP_CONNTRACK_LAST_ACK && + index == TCP_ACK_SET && + ct->proto.tcp.last_dir != dir && + ct->proto.tcp.last_index == TCP_SYN_SET && + (ct->proto.tcp.last_flags & IP_CT_EXP_CHALLENGE_ACK)) { + /* Detected RFC5961 challenge ACK */ + ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK; + spin_unlock_bh(&ct->lock); + if (LOG_INVALID(net, IPPROTO_TCP)) + nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, + "nf_ct_tcp: challenge-ACK ignored "); + return NF_ACCEPT; /* Don't change state */ + } + break; case TCP_CONNTRACK_CLOSE: if (index == TCP_RST_SET && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index ad9d11fb29fd..34ded09317e7 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4472,9 +4472,9 @@ EXPORT_SYMBOL_GPL(nft_data_init); */ void nft_data_uninit(const struct nft_data *data, enum nft_data_types type) { - switch (type) { - case NFT_DATA_VALUE: + if (type < NFT_DATA_VERDICT) return; + switch (type) { case NFT_DATA_VERDICT: return nft_verdict_uninit(data); default: diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 3ad91266c821..4ef1fae8445e 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -1073,7 +1073,13 @@ static struct pernet_operations nfnl_log_net_ops = { static int __init nfnetlink_log_init(void) { - int status = -ENOMEM; + int status; + + status = register_pernet_subsys(&nfnl_log_net_ops); + if (status < 0) { + pr_err("failed to register pernet ops\n"); + goto out; + } netlink_register_notifier(&nfulnl_rtnl_notifier); status = nfnetlink_subsys_register(&nfulnl_subsys); @@ -1088,28 +1094,23 @@ static int __init nfnetlink_log_init(void) goto cleanup_subsys; } - status = register_pernet_subsys(&nfnl_log_net_ops); - if (status < 0) { - pr_err("failed to register pernet ops\n"); - goto cleanup_logger; - } return status; -cleanup_logger: - nf_log_unregister(&nfulnl_logger); cleanup_subsys: nfnetlink_subsys_unregister(&nfulnl_subsys); cleanup_netlink_notifier: netlink_unregister_notifier(&nfulnl_rtnl_notifier); + unregister_pernet_subsys(&nfnl_log_net_ops); +out: return status; } static void __exit nfnetlink_log_fini(void) { - unregister_pernet_subsys(&nfnl_log_net_ops); nf_log_unregister(&nfulnl_logger); nfnetlink_subsys_unregister(&nfulnl_subsys); netlink_unregister_notifier(&nfulnl_rtnl_notifier); + unregister_pernet_subsys(&nfnl_log_net_ops); } MODULE_DESCRIPTION("netfilter userspace logging"); diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index 0b98c7420239..11c7682fa0ea 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -1317,7 +1317,13 @@ static struct pernet_operations nfnl_queue_net_ops = { static int __init nfnetlink_queue_init(void) { - int status = -ENOMEM; + int status; + + status = register_pernet_subsys(&nfnl_queue_net_ops); + if (status < 0) { + pr_err("nf_queue: failed to register pernet ops\n"); + goto out; + } netlink_register_notifier(&nfqnl_rtnl_notifier); status = nfnetlink_subsys_register(&nfqnl_subsys); @@ -1326,19 +1332,13 @@ static int __init nfnetlink_queue_init(void) goto cleanup_netlink_notifier; } - status = register_pernet_subsys(&nfnl_queue_net_ops); - if (status < 0) { - pr_err("nf_queue: failed to register pernet ops\n"); - goto cleanup_subsys; - } register_netdevice_notifier(&nfqnl_dev_notifier); nf_register_queue_handler(&nfqh); return status; -cleanup_subsys: - nfnetlink_subsys_unregister(&nfqnl_subsys); cleanup_netlink_notifier: netlink_unregister_notifier(&nfqnl_rtnl_notifier); +out: return status; } @@ -1346,9 +1346,9 @@ static void __exit nfnetlink_queue_fini(void) { nf_unregister_queue_handler(); unregister_netdevice_notifier(&nfqnl_dev_notifier); - unregister_pernet_subsys(&nfnl_queue_net_ops); nfnetlink_subsys_unregister(&nfqnl_subsys); netlink_unregister_notifier(&nfqnl_rtnl_notifier); + unregister_pernet_subsys(&nfnl_queue_net_ops); rcu_barrier(); /* Wait for completion of call_rcu()'s */ } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ec4adbdcb9b4..bf6e76643f78 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -89,7 +89,7 @@ static inline int netlink_is_kernel(struct sock *sk) return nlk_sk(sk)->flags & NETLINK_KERNEL_SOCKET; } -struct netlink_table *nl_table; +struct netlink_table *nl_table __read_mostly; EXPORT_SYMBOL_GPL(nl_table); static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait); @@ -1081,6 +1081,7 @@ static int netlink_insert(struct sock *sk, u32 portid) if (err) { if (err == -EEXIST) err = -EADDRINUSE; + nlk_sk(sk)->portid = 0; sock_put(sk); } @@ -3139,7 +3140,6 @@ static const struct rhashtable_params netlink_rhashtable_params = { .key_len = netlink_compare_arg_len, .obj_hashfn = netlink_hash, .obj_cmpfn = netlink_compare, - .max_size = 65536, .automatic_shrinking = true, }; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5102c3cc4eec..b5989c6ee551 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2311,11 +2311,14 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) tlen = dev->needed_tailroom; skb = sock_alloc_send_skb(&po->sk, hlen + tlen + sizeof(struct sockaddr_ll), - 0, &err); + !need_wait, &err); - if (unlikely(skb == NULL)) + if (unlikely(skb == NULL)) { + /* we assume the socket was initially writeable ... */ + if (likely(len_sum > 0)) + err = len_sum; goto out_status; - + } tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, addr, hlen); if (tp_len > dev->mtu + dev->hard_header_len) { diff --git a/net/rds/connection.c b/net/rds/connection.c index 14f041398ca1..da6da57e5f36 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -126,7 +126,10 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, struct rds_transport *loop_trans; unsigned long flags; int ret; + struct rds_transport *otrans = trans; + if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP) + goto new_conn; rcu_read_lock(); conn = rds_conn_lookup(head, laddr, faddr, trans); if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && @@ -142,6 +145,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, if (conn) goto out; +new_conn: conn = kmem_cache_zalloc(rds_conn_slab, gfp); if (!conn) { conn = ERR_PTR(-ENOMEM); @@ -230,13 +234,22 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, /* Creating normal conn */ struct rds_connection *found; - found = rds_conn_lookup(head, laddr, faddr, trans); + if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP) + found = NULL; + else + found = rds_conn_lookup(head, laddr, faddr, trans); if (found) { trans->conn_free(conn->c_transport_data); kmem_cache_free(rds_conn_slab, conn); conn = found; } else { - hlist_add_head_rcu(&conn->c_hash_node, head); + if ((is_outgoing && otrans->t_type == RDS_TRANS_TCP) || + (otrans->t_type != RDS_TRANS_TCP)) { + /* Only the active side should be added to + * reconnect list for TCP. + */ + hlist_add_head_rcu(&conn->c_hash_node, head); + } rds_cong_add_conn(conn); rds_conn_count++; } diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 31b74f5e61ad..8a09ee7db3c1 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -183,8 +183,17 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even /* If the peer gave us the last packet it saw, process this as if * we had received a regular ACK. */ - if (dp && dp->dp_ack_seq) - rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL); + if (dp) { + /* dp structure start is not guaranteed to be 8 bytes aligned. + * Since dp_ack_seq is 64-bit extended load operations can be + * used so go through get_unaligned to avoid unaligned errors. + */ + __be64 dp_ack_seq = get_unaligned(&dp->dp_ack_seq); + + if (dp_ack_seq) + rds_send_drop_acked(conn, be64_to_cpu(dp_ack_seq), + NULL); + } rds_connect_complete(conn); } diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index f9f564a6c960..973109c7b8e8 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c @@ -62,6 +62,7 @@ void rds_tcp_state_change(struct sock *sk) case TCP_ESTABLISHED: rds_connect_complete(conn); break; + case TCP_CLOSE_WAIT: case TCP_CLOSE: rds_conn_drop(conn); default: diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 23ab4dcd1d9f..0da49e34495f 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -45,12 +45,45 @@ static void rds_tcp_accept_worker(struct work_struct *work); static DECLARE_WORK(rds_tcp_listen_work, rds_tcp_accept_worker); static struct socket *rds_tcp_listen_sock; +static int rds_tcp_keepalive(struct socket *sock) +{ + /* values below based on xs_udp_default_timeout */ + int keepidle = 5; /* send a probe 'keepidle' secs after last data */ + int keepcnt = 5; /* number of unack'ed probes before declaring dead */ + int keepalive = 1; + int ret = 0; + + ret = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, + (char *)&keepalive, sizeof(keepalive)); + if (ret < 0) + goto bail; + + ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, + (char *)&keepcnt, sizeof(keepcnt)); + if (ret < 0) + goto bail; + + ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, + (char *)&keepidle, sizeof(keepidle)); + if (ret < 0) + goto bail; + + /* KEEPINTVL is the interval between successive probes. We follow + * the model in xs_tcp_finish_connecting() and re-use keepidle. + */ + ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, + (char *)&keepidle, sizeof(keepidle)); +bail: + return ret; +} + static int rds_tcp_accept_one(struct socket *sock) { struct socket *new_sock = NULL; struct rds_connection *conn; int ret; struct inet_sock *inet; + struct rds_tcp_connection *rs_tcp; ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, sock->sk->sk_protocol, &new_sock); @@ -63,6 +96,10 @@ static int rds_tcp_accept_one(struct socket *sock) if (ret < 0) goto out; + ret = rds_tcp_keepalive(new_sock); + if (ret < 0) + goto out; + rds_tcp_tune(new_sock); inet = inet_sk(new_sock->sk); @@ -77,6 +114,15 @@ static int rds_tcp_accept_one(struct socket *sock) ret = PTR_ERR(conn); goto out; } + /* An incoming SYN request came in, and TCP just accepted it. + * We always create a new conn for listen side of TCP, and do not + * add it to the c_hash_list. + * + * If the client reboots, this conn will need to be cleaned up. + * rds_tcp_state_change() will do that cleanup + */ + rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; + WARN_ON(!rs_tcp || rs_tcp->t_sock); /* * see the comment above rds_queue_delayed_reconnect() diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 8b0470e418dc..a75864d93142 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -81,6 +81,11 @@ int unregister_tcf_proto_ops(struct tcf_proto_ops *ops) struct tcf_proto_ops *t; int rc = -ENOENT; + /* Wait for outstanding call_rcu()s, if any, from a + * tcf_proto_ops's destroy() handler. + */ + rcu_barrier(); + write_lock(&cls_mod_lock); list_for_each_entry(t, &tcf_proto_base, head) { if (t == ops) { @@ -308,12 +313,11 @@ replay: case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); if (err == 0) { - tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); - if (tcf_destroy(tp, false)) { - struct tcf_proto *next = rtnl_dereference(tp->next); + struct tcf_proto *next = rtnl_dereference(tp->next); + tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); + if (tcf_destroy(tp, false)) RCU_INIT_POINTER(*back, next); - } } goto errout; case RTM_GETTFILTER: diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index ad9eed70bc8f..1e1c89e51a11 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -815,10 +815,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, if (dev->flags & IFF_UP) dev_deactivate(dev); - if (new && new->ops->attach) { - new->ops->attach(new); - num_q = 0; - } + if (new && new->ops->attach) + goto skip; for (i = 0; i < num_q; i++) { struct netdev_queue *dev_queue = dev_ingress_queue(dev); @@ -834,12 +832,16 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, qdisc_destroy(old); } +skip: if (!ingress) { notify_and_destroy(net, skb, n, classid, dev->qdisc, new); if (new && !new->ops->attach) atomic_inc(&new->refcnt); dev->qdisc = new ? : &noop_qdisc; + + if (new && new->ops->attach) + new->ops->attach(new); } else { notify_and_destroy(net, skb, n, classid, old, new); } diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c index de28f8e968e8..7a0bdb16ac92 100644 --- a/net/sched/sch_codel.c +++ b/net/sched/sch_codel.c @@ -164,7 +164,7 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt) sch->limit = DEFAULT_CODEL_LIMIT; - codel_params_init(&q->params); + codel_params_init(&q->params, sch); codel_vars_init(&q->vars); codel_stats_init(&q->stats); diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 1e52decb7b59..c244c45b78d7 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -391,7 +391,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) q->perturbation = prandom_u32(); INIT_LIST_HEAD(&q->new_flows); INIT_LIST_HEAD(&q->old_flows); - codel_params_init(&q->cparams); + codel_params_init(&q->cparams, sch); codel_stats_init(&q->cstats); q->cparams.ecn = true; diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index a4ca4517cdc8..634529e0ce6b 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -229,7 +229,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch) break; } - if (q->backlog + qdisc_pkt_len(skb) <= q->limit) { + if (gred_backlog(t, q, sch) + qdisc_pkt_len(skb) <= q->limit) { q->backlog += qdisc_pkt_len(skb); return qdisc_enqueue_tail(skb, sch); } @@ -553,7 +553,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) opt.limit = q->limit; opt.DP = q->DP; - opt.backlog = q->backlog; + opt.backlog = gred_backlog(table, q, sch); opt.prio = q->prio; opt.qth_min = q->parms.qth_min >> q->parms.Wlog; opt.qth_max = q->parms.qth_max >> q->parms.Wlog; diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index 1ec19f6f0c2b..eeeba5adee6d 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -793,20 +793,26 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, { u32 value_follows; int err; + struct page *scratch; + + scratch = alloc_page(GFP_KERNEL); + if (!scratch) + return -ENOMEM; + xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE); /* res->status */ err = gssx_dec_status(xdr, &res->status); if (err) - return err; + goto out_free; /* res->context_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { err = gssx_dec_ctx(xdr, res->context_handle); if (err) - return err; + goto out_free; } else { res->context_handle = NULL; } @@ -814,11 +820,11 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, /* res->output_token */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { err = gssx_dec_buffer(xdr, res->output_token); if (err) - return err; + goto out_free; } else { res->output_token = NULL; } @@ -826,14 +832,17 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, /* res->delegated_cred_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { /* we do not support upcall servers sending this data. */ - return -EINVAL; + err = -EINVAL; + goto out_free; } /* res->options */ err = gssx_dec_option_array(xdr, &res->options); +out_free: + __free_page(scratch); return err; } diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 46568b85c333..055453d48668 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -338,7 +338,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, fi, tos, type, nlflags, tb_id); if (!err) - fi->fib_flags |= RTNH_F_EXTERNAL; + fi->fib_flags |= RTNH_F_OFFLOAD; } return err; @@ -364,7 +364,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, const struct swdev_ops *ops; int err = 0; - if (!(fi->fib_flags & RTNH_F_EXTERNAL)) + if (!(fi->fib_flags & RTNH_F_OFFLOAD)) return 0; dev = netdev_switch_get_dev_by_nhs(fi); @@ -376,7 +376,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, err = ops->swdev_fib_ipv4_del(dev, htonl(dst), dst_len, fi, tos, type, tb_id); if (!err) - fi->fib_flags &= ~RTNH_F_EXTERNAL; + fi->fib_flags &= ~RTNH_F_OFFLOAD; } return err; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5266ea7b922b..06430598cf51 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1880,6 +1880,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, unix_state_unlock(sk); timeo = freezable_schedule_timeout(timeo); unix_state_lock(sk); + + if (sock_flag(sk, SOCK_DEAD)) + break; + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); } @@ -1939,6 +1943,10 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, struct sk_buff *skb, *last; unix_state_lock(sk); + if (sock_flag(sk, SOCK_DEAD)) { + err = -ECONNRESET; + goto unlock; + } last = skb = skb_peek(&sk->sk_receive_queue); again: if (skb == NULL) { diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 526c4feb3b50..b58286ecd156 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -13,6 +13,8 @@ #include <net/dst.h> #include <net/ip.h> #include <net/xfrm.h> +#include <net/ip_tunnels.h> +#include <net/ip6_tunnel.h> static struct kmem_cache *secpath_cachep __read_mostly; @@ -186,6 +188,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) struct xfrm_state *x = NULL; xfrm_address_t *daddr; struct xfrm_mode *inner_mode; + u32 mark = skb->mark; unsigned int family; int decaps = 0; int async = 0; @@ -203,6 +206,18 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_SPI_SKB_CB(skb)->daddroff); family = XFRM_SPI_SKB_CB(skb)->family; + /* if tunnel is present override skb->mark value with tunnel i_key */ + if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { + switch (family) { + case AF_INET: + mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); + break; + case AF_INET6: + mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); + break; + } + } + /* Allocate new secpath or COW existing one. */ if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { struct sec_path *sp; @@ -229,7 +244,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } - x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family); + x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family); if (x == NULL) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); xfrm_audit_state_notfound(skb, family, spi, seq); diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index dab57daae408..4fd725a0c500 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -99,6 +99,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb) if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq; + XFRM_SKB_CB(skb)->seq.output.hi = 0; if (unlikely(x->replay.oseq == 0)) { x->replay.oseq--; xfrm_audit_state_replay_overflow(x, skb); @@ -177,6 +178,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb) if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; + XFRM_SKB_CB(skb)->seq.output.hi = 0; if (unlikely(replay_esn->oseq == 0)) { replay_esn->oseq--; xfrm_audit_state_replay_overflow(x, skb); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f5e39e35d73a..96688cd0f6f1 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -927,8 +927,8 @@ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi, x->id.spi != spi) continue; - spin_unlock_bh(&net->xfrm.xfrm_state_lock); xfrm_state_hold(x); + spin_unlock_bh(&net->xfrm.xfrm_state_lock); return x; } spin_unlock_bh(&net->xfrm.xfrm_state_lock); diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index a1504c4f1900..25db8cff44a2 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -73,18 +73,11 @@ class LxLsmod(gdb.Command): " " if utils.get_long_type().sizeof == 8 else "")) for module in module_list(): - ref = 0 - module_refptr = module['refptr'] - for cpu in cpus.cpu_list("cpu_possible_mask"): - refptr = cpus.per_cpu(module_refptr, cpu) - ref += refptr['incs'] - ref -= refptr['decs'] - gdb.write("{address} {name:<19} {size:>8} {ref}".format( address=str(module['module_core']).split()[0], name=module['name'].string(), size=str(module['core_size']), - ref=str(ref))) + ref=str(module['refcnt']['counter']))) source_list = module['source_list'] t = self._module_use_type.get_type().pointer() diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index cf4cedf2b420..6dad042630d8 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -916,7 +916,6 @@ static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) { struct ac97c_platform_data *pdata; struct device_node *node = dev->of_node; - const struct of_device_id *match; if (!node) { dev_err(dev, "Device does not have associated DT data\n"); diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ac6b33f3779c..7d45645f10ba 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -339,7 +339,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (delta > new_hw_ptr) { /* check for double acknowledged interrupts */ hdelta = curr_jiffies - runtime->hw_ptr_jiffies; - if (hdelta > runtime->hw_ptr_buffer_jiffies/2) { + if (hdelta > runtime->hw_ptr_buffer_jiffies/2 + 1) { hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) { hw_base = 0; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 788f969b1a68..ac0db1679f09 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -844,8 +844,16 @@ static hda_nid_t path_power_update(struct hda_codec *codec, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, state); changed = nid; + /* all known codecs seem to be capable to handl + * widgets state even in D3, so far. + * if any new codecs need to restore the widget + * states after D0 transition, call the function + * below. + */ +#if 0 /* disabled */ if (state == AC_PWRST_D0) snd_hdac_regmap_sync_node(&codec->core, nid); +#endif } } return changed; @@ -4918,9 +4926,12 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, dig_only: parse_digital(codec); - if (spec->power_down_unused || codec->power_save_node) + if (spec->power_down_unused || codec->power_save_node) { if (!codec->power_filter) codec->power_filter = snd_hda_gen_path_power_filter; + if (!codec->patch_ops.stream_pm) + codec->patch_ops.stream_pm = snd_hda_gen_stream_pm; + } if (!spec->no_analog && spec->beep_nid) { err = snd_hda_attach_beep_device(codec, spec->beep_nid); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 34040d26c94f..fea198c58196 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2089,6 +2089,8 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, { PCI_DEVICE(0x1002, 0xaab0), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, + { PCI_DEVICE(0x1002, 0xaac8), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, /* VIA VT8251/VT8237A */ { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f8f0dfbef149..78b719b5b34d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -968,6 +968,14 @@ static const struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_conexant_auto }, { .id = 0x14f150b9, .name = "CX20665", .patch = patch_conexant_auto }, + { .id = 0x14f150f1, .name = "CX20721", + .patch = patch_conexant_auto }, + { .id = 0x14f150f2, .name = "CX20722", + .patch = patch_conexant_auto }, + { .id = 0x14f150f3, .name = "CX20723", + .patch = patch_conexant_auto }, + { .id = 0x14f150f4, .name = "CX20724", + .patch = patch_conexant_auto }, { .id = 0x14f1510f, .name = "CX20751/2", .patch = patch_conexant_auto }, { .id = 0x14f15110, .name = "CX20751/2", @@ -1002,6 +1010,10 @@ MODULE_ALIAS("snd-hda-codec-id:14f150ab"); MODULE_ALIAS("snd-hda-codec-id:14f150ac"); MODULE_ALIAS("snd-hda-codec-id:14f150b8"); MODULE_ALIAS("snd-hda-codec-id:14f150b9"); +MODULE_ALIAS("snd-hda-codec-id:14f150f1"); +MODULE_ALIAS("snd-hda-codec-id:14f150f2"); +MODULE_ALIAS("snd-hda-codec-id:14f150f3"); +MODULE_ALIAS("snd-hda-codec-id:14f150f4"); MODULE_ALIAS("snd-hda-codec-id:14f1510f"); MODULE_ALIAS("snd-hda-codec-id:14f15110"); MODULE_ALIAS("snd-hda-codec-id:14f15111"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e2afd53cc14c..0320cb523d9e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -883,6 +883,8 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = { { 0x10ec0668, 0x1028, 0, "ALC3661" }, { 0x10ec0275, 0x1028, 0, "ALC3260" }, { 0x10ec0899, 0x1028, 0, "ALC3861" }, + { 0x10ec0298, 0x1028, 0, "ALC3266" }, + { 0x10ec0256, 0x1028, 0, "ALC3246" }, { 0x10ec0670, 0x1025, 0, "ALC669X" }, { 0x10ec0676, 0x1025, 0, "ALC679X" }, { 0x10ec0282, 0x1043, 0, "ALC3229" }, @@ -2166,6 +2168,7 @@ static const struct hda_fixup alc882_fixups[] = { static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), @@ -3673,6 +3676,10 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, alc_process_coef_fw(codec, coef0293); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; + case 0x10ec0662: + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); @@ -3738,7 +3745,6 @@ static void alc_headset_mode_default(struct hda_codec *codec) case 0x10ec0288: alc_process_coef_fw(codec, coef0288); break; - break; case 0x10ec0292: alc_process_coef_fw(codec, coef0292); break; @@ -4012,7 +4018,7 @@ static void alc_update_headset_mode(struct hda_codec *codec) if (new_headset_mode != ALC_HEADSET_MODE_MIC) { snd_hda_set_pin_ctl_cache(codec, hp_pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); - if (spec->headphone_mic_pin) + if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin) snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, PIN_VREFHIZ); } @@ -4215,6 +4221,23 @@ static void alc_fixup_dell_xps13(struct hda_codec *codec, } } +static void alc_fixup_headset_mode_alc662(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; + spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */ + + /* Disable boost for mic-in permanently. (This code is only called + from quirks that guarantee that the headphone is at NID 0x1b.) */ + snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000); + snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP); + } else + alc_fixup_headset_mode(codec, fix, action); +} + static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -5119,6 +5142,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), + SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC), @@ -5148,6 +5172,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK), + SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), @@ -5345,6 +5370,20 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x17, 0x40000000}, {0x1d, 0x40700001}, {0x21, 0x02211050}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC255_STANDARD_PINS, + {0x12, 0x90a60180}, + {0x14, 0x90170130}, + {0x17, 0x40000000}, + {0x1d, 0x40700001}, + {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC255_STANDARD_PINS, + {0x12, 0x90a60160}, + {0x14, 0x90170120}, + {0x17, 0x40000000}, + {0x1d, 0x40700001}, + {0x21, 0x02211030}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC256_STANDARD_PINS, {0x13, 0x40000000}), @@ -5598,7 +5637,8 @@ static int patch_alc269(struct hda_codec *codec) spec = codec->spec; spec->gen.shared_mic_vref_pin = 0x18; - codec->power_save_node = 1; + if (codec->core.vendor_id != 0x10ec0292) + codec->power_save_node = 1; snd_hda_pick_fixup(codec, alc269_fixup_models, alc269_fixup_tbl, alc269_fixups); @@ -6079,7 +6119,9 @@ enum { ALC662_FIXUP_NO_JACK_DETECT, ALC662_FIXUP_ZOTAC_Z68, ALC662_FIXUP_INV_DMIC, + ALC662_FIXUP_DELL_MIC_NO_PRESENCE, ALC668_FIXUP_DELL_MIC_NO_PRESENCE, + ALC662_FIXUP_HEADSET_MODE, ALC668_FIXUP_HEADSET_MODE, ALC662_FIXUP_BASS_MODE4_CHMAP, ALC662_FIXUP_BASS_16, @@ -6272,6 +6314,20 @@ static const struct hda_fixup alc662_fixups[] = { .chained = true, .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE }, + [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */ + /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */ + { } + }, + .chained = true, + .chain_id = ALC662_FIXUP_HEADSET_MODE + }, + [ALC662_FIXUP_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_alc662, + }, [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -6423,6 +6479,18 @@ static const struct hda_model_fixup alc662_fixup_models[] = { }; static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE, + {0x12, 0x4004c000}, + {0x14, 0x01014010}, + {0x15, 0x411111f0}, + {0x16, 0x411111f0}, + {0x18, 0x01a19020}, + {0x19, 0x411111f0}, + {0x1a, 0x0181302f}, + {0x1b, 0x0221401f}, + {0x1c, 0x411111f0}, + {0x1d, 0x4054c601}, + {0x1e, 0x411111f0}), SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, {0x12, 0x99a30130}, {0x14, 0x90170110}, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 43c99ce4a520..6833c74ed6ff 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4403,7 +4403,6 @@ static const struct hda_codec_ops stac_patch_ops = { #ifdef CONFIG_PM .suspend = stac_suspend, #endif - .stream_pm = snd_hda_gen_stream_pm, .reboot_notify = stac_shutup, }; @@ -4697,7 +4696,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) return err; spec = codec->spec; - codec->power_save_node = 1; + /* disabled power_save_node since it causes noises on a Dell machine */ + /* codec->power_save_node = 1; */ spec->linear_tone_beep = 0; spec->gen.own_eapd_ctl = 1; spec->gen.power_down_unused = 1; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 31a95cca015d..bab6c04932aa 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -449,6 +449,15 @@ static int via_suspend(struct hda_codec *codec) return 0; } + +static int via_resume(struct hda_codec *codec) +{ + /* some delay here to make jack detection working (bko#98921) */ + msleep(10); + codec->patch_ops.init(codec); + regcache_sync(codec->core.regmap); + return 0; +} #endif #ifdef CONFIG_PM @@ -475,6 +484,7 @@ static const struct hda_codec_ops via_patch_ops = { .stream_pm = snd_hda_gen_stream_pm, #ifdef CONFIG_PM .suspend = via_suspend, + .resume = via_resume, .check_power_status = via_check_power_status, #endif }; diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index d51703e30523..0a4ad5feb82e 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -72,7 +72,6 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { old_vmaster_hook = spec->vmaster_mute.hook; spec->vmaster_mute.hook = update_tpacpi_mute_led; - spec->vmaster_mute_enum = 1; removefunc = false; } if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2ffb9a0570dc..3d44fc50e4d0 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -623,14 +623,14 @@ static int mc13783_probe(struct snd_soc_codec *codec) AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, - 0, AUDIO_SSI_SEL); + AUDIO_SSI_SEL, AUDIO_SSI_SEL); if (priv->dac_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, - 0, AUDIO_SSI_SEL); + AUDIO_SSI_SEL, AUDIO_SSI_SEL); return 0; } diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index dc7778b6dd7f..c3c33bd0df1c 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -437,7 +437,7 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai, if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) return -EINVAL; - uda1380_write(codec, UDA1380_IFACE, iface); + uda1380_write_reg_cache(codec, UDA1380_IFACE, iface); return 0; } diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 3035d9856415..e97a7615df85 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -395,7 +395,7 @@ static const struct snd_soc_dapm_route audio_paths[] = { { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", }, { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */ { "Right Input Mixer", NULL, "RINPUT2" }, - { "Right Input Mixer", NULL, "LINPUT3" }, + { "Right Input Mixer", NULL, "RINPUT3" }, { "Left ADC", NULL, "Left Input Mixer" }, { "Right ADC", NULL, "Right Input Mixer" }, diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 4fbc7689339a..a1c04dab6684 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2754,7 +2754,7 @@ static struct { }; static int fs_ratios[] = { - 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536 + 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536 }; static int bclk_divs[] = { diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index bb4b78eada58..23c91fa65ab8 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1247,7 +1247,7 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) u32 reg; int i; - context->pm_state = pm_runtime_enabled(mcasp->dev); + context->pm_state = pm_runtime_active(mcasp->dev); if (!context->pm_state) pm_runtime_get_sync(mcasp->dev); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index defe0f0082b5..158204d08924 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3100,11 +3100,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } prefix = soc_dapm_prefix(dapm); - if (prefix) + if (prefix) { w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name); - else + if (widget->sname) + w->sname = kasprintf(GFP_KERNEL, "%s %s", prefix, + widget->sname); + } else { w->name = kasprintf(GFP_KERNEL, "%s", widget->name); - + if (widget->sname) + w->sname = kasprintf(GFP_KERNEL, "%s", widget->sname); + } if (w->name == NULL) { kfree(w); return NULL; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 3e2ef61c627b..8b7e391dd0b8 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -918,6 +918,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */ + case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */ case USB_ID(0x046d, 0x0991): /* Most audio usb devices lie about volume resolution. * Most Logitech webcams have res = 384. @@ -1582,12 +1583,6 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unitid); return -EINVAL; } - /* no bmControls field (e.g. Maya44) -> ignore */ - if (desc->bLength <= 10 + input_pins) { - usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", - unitid); - return 0; - } num_ins = 0; ich = 0; @@ -1595,6 +1590,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, err = parse_audio_unit(state, desc->baSourceID[pin]); if (err < 0) continue; + /* no bmControls field (e.g. Maya44) -> ignore */ + if (desc->bLength <= 10 + input_pins) + continue; err = check_input_term(state, desc->baSourceID[pin], &iterm); if (err < 0) return err; diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index b703cb3cda19..e5000da9e9d7 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -437,6 +437,11 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .map = ebox44_map, }, { + /* MAYA44 USB+ */ + .id = USB_ID(0x2573, 0x0008), + .map = maya44_map, + }, + { /* KEF X300A */ .id = USB_ID(0x27ac, 0x1000), .map = scms_usb3318_map, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 7c5a70139278..b8c97d092a47 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1117,7 +1117,10 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) switch (chip->usb_id) { case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */ case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */ + case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ + case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ + case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ return true; } return false; diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index d8fe29fc19a4..8bd960658463 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -16,7 +16,7 @@ MAKEFLAGS += --no-print-directory LIBFILE = $(OUTPUT)libapi.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 RM = rm -f diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 0c356fb65022..18ffccf00426 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -14,9 +14,10 @@ define allow-override $(eval $(1) = $(2))) endef -# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. +# Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix. $(call allow-override,CC,$(CROSS_COMPILE)gcc) $(call allow-override,AR,$(CROSS_COMPILE)ar) +$(call allow-override,LD,$(CROSS_COMPILE)ld) INSTALL = install diff --git a/tools/lib/lockdep/uinclude/linux/kernel.h b/tools/lib/lockdep/uinclude/linux/kernel.h index a11e3c357be7..cd2cc59a5da7 100644 --- a/tools/lib/lockdep/uinclude/linux/kernel.h +++ b/tools/lib/lockdep/uinclude/linux/kernel.h @@ -28,6 +28,9 @@ #define __init #define noinline #define list_add_tail_rcu list_add_tail +#define list_for_each_entry_rcu list_for_each_entry +#define barrier() +#define synchronize_sched() #ifndef CALLER_ADDR0 #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index e0917c0f5d9f..29f94f6f0d9e 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3865,7 +3865,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, } else if (el_size == 4) { trace_seq_printf(s, "%u", *(uint32_t *)num); } else if (el_size == 8) { - trace_seq_printf(s, "%lu", *(uint64_t *)num); + trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num); } else { trace_seq_printf(s, "BAD SIZE:%d 0x%x", el_size, *(uint8_t *)num); diff --git a/tools/net/bpf_jit_disasm.c b/tools/net/bpf_jit_disasm.c index c5baf9c591b7..618c2bcd4eab 100644 --- a/tools/net/bpf_jit_disasm.c +++ b/tools/net/bpf_jit_disasm.c @@ -123,6 +123,8 @@ static int get_last_jit_image(char *haystack, size_t hlen, assert(ret == 0); ptr = haystack; + memset(pmatch, 0, sizeof(pmatch)); + while (1) { ret = regexec(®ex, ptr, 1, pmatch, 0); if (ret == 0) { diff --git a/tools/perf/Makefile b/tools/perf/Makefile index c699dc35eef9..d31a7bbd7cee 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -24,7 +24,7 @@ unexport MAKEFLAGS # (To override it, run 'make JOBS=1' and similar.) # ifeq ($(JOBS),) - JOBS := $(shell egrep -c '^processor|^CPU' /proc/cpuinfo 2>/dev/null) + JOBS := $(shell (getconf _NPROCESSORS_ONLN || egrep -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null) ifeq ($(JOBS),0) JOBS := 1 endif diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index bedff6b5b3cf..ad0d9b5342fb 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -132,6 +132,9 @@ int bench_futex_requeue(int argc, const char **argv, if (!fshared) futex_flag = FUTEX_PRIVATE_FLAG; + if (nrequeue > nthreads) + nrequeue = nthreads; + printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " "%d at a time.\n\n", getpid(), nthreads, fshared ? "shared":"private", &futex1, &futex2, nrequeue); @@ -161,20 +164,18 @@ int bench_futex_requeue(int argc, const char **argv, /* Ok, all threads are patiently blocked, start requeueing */ gettimeofday(&start, NULL); - for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) { + while (nrequeued < nthreads) { /* * Do not wakeup any tasks blocked on futex1, allowing * us to really measure futex_wait functionality. */ - futex_cmp_requeue(&futex1, 0, &futex2, 0, - nrequeue, futex_flag); + nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0, + nrequeue, futex_flag); } + gettimeofday(&end, NULL); timersub(&end, &start, &runtime); - if (nrequeued > nthreads) - nrequeued = nthreads; - update_stats(&requeued_stats, nrequeued); update_stats(&requeuetime_stats, runtime.tv_usec); @@ -184,7 +185,7 @@ int bench_futex_requeue(int argc, const char **argv, } /* everybody should be blocked on futex2, wake'em up */ - nrequeued = futex_wake(&futex2, nthreads, futex_flag); + nrequeued = futex_wake(&futex2, nrequeued, futex_flag); if (nthreads != nrequeued) warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index ebfa163b80b5..ba5efa4710b5 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -180,7 +180,7 @@ static const struct option options[] = { OPT_INTEGER('H', "thp" , &p0.thp, "MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"), OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details"), OPT_BOOLEAN('m', "measure_convergence", &p0.measure_convergence, "measure convergence latency"), - OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "bzero the initial allocations"), + OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "quiet mode"), OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"), /* Special option string parsing callbacks: */ @@ -828,6 +828,9 @@ static int count_process_nodes(int process_nr) td = g->threads + task_nr; node = numa_node_of_cpu(td->curr_cpu); + if (node < 0) /* curr_cpu was likely still -1 */ + return 0; + node_present[node] = 1; } @@ -882,6 +885,11 @@ static void calc_convergence_compression(int *strong) for (p = 0; p < g->p.nr_proc; p++) { unsigned int nodes = count_process_nodes(p); + if (!nodes) { + *strong = 0; + return; + } + nodes_min = min(nodes, nodes_min); nodes_max = max(nodes, nodes_max); } @@ -1395,7 +1403,7 @@ static void print_res(const char *name, double val, if (!name) name = "main,"; - if (g->p.show_quiet) + if (!g->p.show_quiet) printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short); else printf(" %14.3f %s\n", val, txt_long); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 63ea01349b6e..1634186d537c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -319,7 +319,7 @@ static int page_stat_cmp(struct page_stat *a, struct page_stat *b) return 0; } -static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool create) +static struct page_stat *search_page_alloc_stat(struct page_stat *pstat, bool create) { struct rb_node **node = &page_alloc_tree.rb_node; struct rb_node *parent = NULL; @@ -331,7 +331,7 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre parent = *node; data = rb_entry(*node, struct page_stat, node); - cmp = page_stat_cmp(data, stat); + cmp = page_stat_cmp(data, pstat); if (cmp < 0) node = &parent->rb_left; else if (cmp > 0) @@ -345,10 +345,10 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre data = zalloc(sizeof(*data)); if (data != NULL) { - data->page = stat->page; - data->order = stat->order; - data->gfp_flags = stat->gfp_flags; - data->migrate_type = stat->migrate_type; + data->page = pstat->page; + data->order = pstat->order; + data->gfp_flags = pstat->gfp_flags; + data->migrate_type = pstat->migrate_type; rb_link_node(&data->node, parent, node); rb_insert_color(&data->node, &page_alloc_tree); @@ -375,7 +375,7 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, unsigned int migrate_type = perf_evsel__intval(evsel, sample, "migratetype"); u64 bytes = kmem_page_size << order; - struct page_stat *stat; + struct page_stat *pstat; struct page_stat this = { .order = order, .gfp_flags = gfp_flags, @@ -401,21 +401,21 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, * This is to find the current page (with correct gfp flags and * migrate type) at free event. */ - stat = search_page(page, true); - if (stat == NULL) + pstat = search_page(page, true); + if (pstat == NULL) return -ENOMEM; - stat->order = order; - stat->gfp_flags = gfp_flags; - stat->migrate_type = migrate_type; + pstat->order = order; + pstat->gfp_flags = gfp_flags; + pstat->migrate_type = migrate_type; this.page = page; - stat = search_page_alloc_stat(&this, true); - if (stat == NULL) + pstat = search_page_alloc_stat(&this, true); + if (pstat == NULL) return -ENOMEM; - stat->nr_alloc++; - stat->alloc_bytes += bytes; + pstat->nr_alloc++; + pstat->alloc_bytes += bytes; order_stats[order][migrate_type]++; @@ -428,7 +428,7 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, u64 page; unsigned int order = perf_evsel__intval(evsel, sample, "order"); u64 bytes = kmem_page_size << order; - struct page_stat *stat; + struct page_stat *pstat; struct page_stat this = { .order = order, }; @@ -441,8 +441,8 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, nr_page_frees++; total_page_free_bytes += bytes; - stat = search_page(page, false); - if (stat == NULL) { + pstat = search_page(page, false); + if (pstat == NULL) { pr_debug2("missing free at page %"PRIx64" (order: %d)\n", page, order); @@ -453,18 +453,18 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, } this.page = page; - this.gfp_flags = stat->gfp_flags; - this.migrate_type = stat->migrate_type; + this.gfp_flags = pstat->gfp_flags; + this.migrate_type = pstat->migrate_type; - rb_erase(&stat->node, &page_tree); - free(stat); + rb_erase(&pstat->node, &page_tree); + free(pstat); - stat = search_page_alloc_stat(&this, false); - if (stat == NULL) + pstat = search_page_alloc_stat(&this, false); + if (pstat == NULL) return -ENOENT; - stat->nr_free++; - stat->free_bytes += bytes; + pstat->nr_free++; + pstat->free_bytes += bytes; return 0; } @@ -640,9 +640,9 @@ static void print_page_summary(void) nr_page_frees, total_page_free_bytes / 1024); printf("\n"); - printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests", + printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests", nr_alloc_freed, (total_alloc_freed_bytes) / 1024); - printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc-only requests", + printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc-only requests", nr_page_allocs - nr_alloc_freed, (total_page_alloc_bytes - total_alloc_freed_bytes) / 1024); printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total free-only requests", diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 476cdf7afcca..b63aeda719be 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -329,7 +329,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, fprintf(stdout, "\n\n"); } - if (sort_order == default_sort_order && + if (sort_order == NULL && parent_pattern == default_parent_pattern) { fprintf(stdout, "#\n# (%s)\n#\n", help); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1cb3436276d1..6a4d5d41c671 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -733,7 +733,7 @@ static void perf_event__process_sample(struct perf_tool *tool, "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" "Check /proc/sys/kernel/kptr_restrict.\n\n" "Kernel%s samples will not be resolved.\n", - !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? + al.map && !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? " modules" : ""); if (use_browser <= 0) sleep(5); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index e124741be187..e122970361f2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2241,10 +2241,11 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_mmap; + if (!target__none(&trace->opts.target)) + perf_evlist__enable(evlist); + if (forks) perf_evlist__start_workload(evlist); - else - perf_evlist__enable(evlist); trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1 || @@ -2272,6 +2273,11 @@ next_event: if (interrupted) goto out_disable; + + if (done && !draining) { + perf_evlist__disable(evlist); + draining = true; + } } } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index d8bb616ff57c..d05b77cf35f7 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1084,6 +1084,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) * * TODO:Group name support */ + if (!arg) + return -EINVAL; ptr = strpbrk(arg, ";=@+%"); if (ptr && *ptr == '=') { /* Event name */ diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index b5bf9d5efeaf..2a76e14db732 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) /* Search child die for local variables and parameters. */ if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { /* Search again in global variables */ - if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) + if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, + 0, &vr_die)) { pr_warning("Failed to find '%s' in this function.\n", pf->pvar->var); ret = -ENOENT; + } } if (ret >= 0) ret = convert_variable(&vr_die, pf); diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index bac98ca3d4ca..323b65edfc97 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -52,6 +52,7 @@ unsigned int skip_c0; unsigned int skip_c1; unsigned int do_nhm_cstates; unsigned int do_snb_cstates; +unsigned int do_knl_cstates; unsigned int do_pc2; unsigned int do_pc3; unsigned int do_pc6; @@ -91,6 +92,7 @@ unsigned int do_gfx_perf_limit_reasons; unsigned int do_ring_perf_limit_reasons; unsigned int crystal_hz; unsigned long long tsc_hz; +int base_cpu; #define RAPL_PKG (1 << 0) /* 0x610 MSR_PKG_POWER_LIMIT */ @@ -316,7 +318,7 @@ void print_header(void) if (do_nhm_cstates) outp += sprintf(outp, " CPU%%c1"); - if (do_nhm_cstates && !do_slm_cstates) + if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) outp += sprintf(outp, " CPU%%c3"); if (do_nhm_cstates) outp += sprintf(outp, " CPU%%c6"); @@ -546,7 +548,7 @@ int format_counters(struct thread_data *t, struct core_data *c, if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) goto done; - if (do_nhm_cstates && !do_slm_cstates) + if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) outp += sprintf(outp, "%8.2f", 100.0 * c->c3/t->tsc); if (do_nhm_cstates) outp += sprintf(outp, "%8.2f", 100.0 * c->c6/t->tsc); @@ -1018,14 +1020,17 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; - if (do_nhm_cstates && !do_slm_cstates) { + if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) { if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) return -6; } - if (do_nhm_cstates) { + if (do_nhm_cstates && !do_knl_cstates) { if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) return -7; + } else if (do_knl_cstates) { + if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) + return -7; } if (do_snb_cstates) @@ -1150,7 +1155,7 @@ dump_nhm_platform_info(void) unsigned long long msr; unsigned int ratio; - get_msr(0, MSR_NHM_PLATFORM_INFO, &msr); + get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr); fprintf(stderr, "cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx\n", msr); @@ -1162,7 +1167,7 @@ dump_nhm_platform_info(void) fprintf(stderr, "%d * %.0f = %.0f MHz base frequency\n", ratio, bclk, ratio * bclk); - get_msr(0, MSR_IA32_POWER_CTL, &msr); + get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr); fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", msr, msr & 0x2 ? "EN" : "DIS"); @@ -1175,7 +1180,7 @@ dump_hsw_turbo_ratio_limits(void) unsigned long long msr; unsigned int ratio; - get_msr(0, MSR_TURBO_RATIO_LIMIT2, &msr); + get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr); fprintf(stderr, "cpu0: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", msr); @@ -1197,7 +1202,7 @@ dump_ivt_turbo_ratio_limits(void) unsigned long long msr; unsigned int ratio; - get_msr(0, MSR_TURBO_RATIO_LIMIT1, &msr); + get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr); fprintf(stderr, "cpu0: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", msr); @@ -1249,7 +1254,7 @@ dump_nhm_turbo_ratio_limits(void) unsigned long long msr; unsigned int ratio; - get_msr(0, MSR_TURBO_RATIO_LIMIT, &msr); + get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); fprintf(stderr, "cpu0: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", msr); @@ -1296,11 +1301,72 @@ dump_nhm_turbo_ratio_limits(void) } static void +dump_knl_turbo_ratio_limits(void) +{ + int cores; + unsigned int ratio; + unsigned long long msr; + int delta_cores; + int delta_ratio; + int i; + + get_msr(base_cpu, MSR_NHM_TURBO_RATIO_LIMIT, &msr); + + fprintf(stderr, "cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx\n", + msr); + + /** + * Turbo encoding in KNL is as follows: + * [7:0] -- Base value of number of active cores of bucket 1. + * [15:8] -- Base value of freq ratio of bucket 1. + * [20:16] -- +ve delta of number of active cores of bucket 2. + * i.e. active cores of bucket 2 = + * active cores of bucket 1 + delta + * [23:21] -- Negative delta of freq ratio of bucket 2. + * i.e. freq ratio of bucket 2 = + * freq ratio of bucket 1 - delta + * [28:24]-- +ve delta of number of active cores of bucket 3. + * [31:29]-- -ve delta of freq ratio of bucket 3. + * [36:32]-- +ve delta of number of active cores of bucket 4. + * [39:37]-- -ve delta of freq ratio of bucket 4. + * [44:40]-- +ve delta of number of active cores of bucket 5. + * [47:45]-- -ve delta of freq ratio of bucket 5. + * [52:48]-- +ve delta of number of active cores of bucket 6. + * [55:53]-- -ve delta of freq ratio of bucket 6. + * [60:56]-- +ve delta of number of active cores of bucket 7. + * [63:61]-- -ve delta of freq ratio of bucket 7. + */ + cores = msr & 0xFF; + ratio = (msr >> 8) && 0xFF; + if (ratio > 0) + fprintf(stderr, + "%d * %.0f = %.0f MHz max turbo %d active cores\n", + ratio, bclk, ratio * bclk, cores); + + for (i = 16; i < 64; i = i + 8) { + delta_cores = (msr >> i) & 0x1F; + delta_ratio = (msr >> (i + 5)) && 0x7; + if (!delta_cores || !delta_ratio) + return; + cores = cores + delta_cores; + ratio = ratio - delta_ratio; + + /** -ve ratios will make successive ratio calculations + * negative. Hence return instead of carrying on. + */ + if (ratio > 0) + fprintf(stderr, + "%d * %.0f = %.0f MHz max turbo %d active cores\n", + ratio, bclk, ratio * bclk, cores); + } +} + +static void dump_nhm_cst_cfg(void) { unsigned long long msr; - get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); + get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); #define SNB_C1_AUTO_UNDEMOTE (1UL << 27) #define SNB_C3_AUTO_UNDEMOTE (1UL << 28) @@ -1381,12 +1447,41 @@ int parse_int_file(const char *fmt, ...) } /* - * cpu_is_first_sibling_in_core(cpu) - * return 1 if given CPU is 1st HT sibling in the core + * get_cpu_position_in_core(cpu) + * return the position of the CPU among its HT siblings in the core + * return -1 if the sibling is not in list */ -int cpu_is_first_sibling_in_core(int cpu) +int get_cpu_position_in_core(int cpu) { - return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); + char path[64]; + FILE *filep; + int this_cpu; + char character; + int i; + + sprintf(path, + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", + cpu); + filep = fopen(path, "r"); + if (filep == NULL) { + perror(path); + exit(1); + } + + for (i = 0; i < topo.num_threads_per_core; i++) { + fscanf(filep, "%d", &this_cpu); + if (this_cpu == cpu) { + fclose(filep); + return i; + } + + /* Account for no separator after last thread*/ + if (i != (topo.num_threads_per_core - 1)) + fscanf(filep, "%c", &character); + } + + fclose(filep); + return -1; } /* @@ -1412,25 +1507,31 @@ int get_num_ht_siblings(int cpu) { char path[80]; FILE *filep; - int sib1, sib2; - int matches; + int sib1; + int matches = 0; char character; + char str[100]; + char *ch; sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); filep = fopen_or_die(path, "r"); + /* * file format: - * if a pair of number with a character between: 2 siblings (eg. 1-2, or 1,4) - * otherwinse 1 sibling (self). + * A ',' separated or '-' separated set of numbers + * (eg 1-2 or 1,3,4,5) */ - matches = fscanf(filep, "%d%c%d\n", &sib1, &character, &sib2); + fscanf(filep, "%d%c\n", &sib1, &character); + fseek(filep, 0, SEEK_SET); + fgets(str, 100, filep); + ch = strchr(str, character); + while (ch != NULL) { + matches++; + ch = strchr(ch+1, character); + } fclose(filep); - - if (matches == 3) - return 2; - else - return 1; + return matches+1; } /* @@ -1594,8 +1695,10 @@ restart: void check_dev_msr() { struct stat sb; + char pathname[32]; - if (stat("/dev/cpu/0/msr", &sb)) + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); + if (stat(pathname, &sb)) if (system("/sbin/modprobe msr > /dev/null 2>&1")) err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); } @@ -1608,6 +1711,7 @@ void check_permissions() cap_user_data_t cap_data = &cap_data_data; extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); int do_exit = 0; + char pathname[32]; /* check for CAP_SYS_RAWIO */ cap_header->pid = getpid(); @@ -1622,7 +1726,8 @@ void check_permissions() } /* test file permissions */ - if (euidaccess("/dev/cpu/0/msr", R_OK)) { + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); + if (euidaccess(pathname, R_OK)) { do_exit++; warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr"); } @@ -1704,7 +1809,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) default: return 0; } - get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); + get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; @@ -1753,6 +1858,21 @@ int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model) } } +int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) +{ + if (!genuine_intel) + return 0; + + if (family != 6) + return 0; + + switch (model) { + case 0x57: /* Knights Landing */ + return 1; + default: + return 0; + } +} static void dump_cstate_pstate_config_info(family, model) { @@ -1770,6 +1890,9 @@ dump_cstate_pstate_config_info(family, model) if (has_nhm_turbo_ratio_limit(family, model)) dump_nhm_turbo_ratio_limits(); + if (has_knl_turbo_ratio_limit(family, model)) + dump_knl_turbo_ratio_limits(); + dump_nhm_cst_cfg(); } @@ -1801,7 +1924,7 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr)) return 0; - switch (msr & 0x7) { + switch (msr & 0xF) { case ENERGY_PERF_BIAS_PERFORMANCE: epb_string = "performance"; break; @@ -1925,7 +2048,7 @@ double get_tdp(model) unsigned long long msr; if (do_rapl & RAPL_PKG_POWER_INFO) - if (!get_msr(0, MSR_PKG_POWER_INFO, &msr)) + if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr)) return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; switch (model) { @@ -1950,6 +2073,7 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) case 0x3F: /* HSX */ case 0x4F: /* BDX */ case 0x56: /* BDX-DE */ + case 0x57: /* KNL */ return (rapl_dram_energy_units = 15.3 / 1000000); default: return (rapl_energy_units); @@ -1991,6 +2115,7 @@ void rapl_probe(unsigned int family, unsigned int model) case 0x3F: /* HSX */ case 0x4F: /* BDX */ case 0x56: /* BDX-DE */ + case 0x57: /* KNL */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; break; case 0x2D: @@ -2006,7 +2131,7 @@ void rapl_probe(unsigned int family, unsigned int model) } /* units on package 0, verify later other packages match */ - if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr)) + if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr)) return; rapl_power_units = 1.0 / (1 << (msr & 0xF)); @@ -2331,6 +2456,17 @@ int is_slm(unsigned int family, unsigned int model) return 0; } +int is_knl(unsigned int family, unsigned int model) +{ + if (!genuine_intel) + return 0; + switch (model) { + case 0x57: /* KNL */ + return 1; + } + return 0; +} + #define SLM_BCLK_FREQS 5 double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0}; @@ -2340,7 +2476,7 @@ double slm_bclk(void) unsigned int i; double freq; - if (get_msr(0, MSR_FSB_FREQ, &msr)) + if (get_msr(base_cpu, MSR_FSB_FREQ, &msr)) fprintf(stderr, "SLM BCLK: unknown\n"); i = msr & 0xf; @@ -2408,7 +2544,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk if (!do_nhm_platform_info) goto guess; - if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr)) + if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr)) goto guess; target_c_local = (msr >> 16) & 0xFF; @@ -2541,6 +2677,7 @@ void process_cpuid() do_c8_c9_c10 = has_hsw_msrs(family, model); do_skl_residency = has_skl_msrs(family, model); do_slm_cstates = is_slm(family, model); + do_knl_cstates = is_knl(family, model); bclk = discover_bclk(family, model); rapl_probe(family, model); @@ -2755,13 +2892,9 @@ int initialize_counters(int cpu_id) my_package_id = get_physical_package_id(cpu_id); my_core_id = get_core_id(cpu_id); - - if (cpu_is_first_sibling_in_core(cpu_id)) { - my_thread_id = 0; + my_thread_id = get_cpu_position_in_core(cpu_id); + if (!my_thread_id) topo.num_cores++; - } else { - my_thread_id = 1; - } init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id); init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id); @@ -2785,13 +2918,24 @@ void setup_all_buffers(void) for_all_proc_cpus(initialize_counters); } +void set_base_cpu(void) +{ + base_cpu = sched_getcpu(); + if (base_cpu < 0) + err(-ENODEV, "No valid cpus found"); + + if (debug > 1) + fprintf(stderr, "base_cpu = %d\n", base_cpu); +} + void turbostat_init() { + setup_all_buffers(); + set_base_cpu(); check_dev_msr(); check_permissions(); process_cpuid(); - setup_all_buffers(); if (debug) for_all_cpus(print_epb, ODD_COUNTERS); @@ -2870,7 +3014,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(stderr, "turbostat version 4.5 2 Apr, 2015" + fprintf(stderr, "turbostat version 4.7 27-May, 2015" " - Len Brown <lenb@kernel.org>\n"); } diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index ddf63569df5a..9b0d8baf2934 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -1,48 +1,59 @@ -.PHONY: all all_32 all_64 check_build32 clean run_tests +all: + +include ../lib.mk + +.PHONY: all all_32 all_64 warn_32bit_failure clean TARGETS_C_BOTHBITS := sigreturn single_step_syscall +TARGETS_C_32BIT_ONLY := entry_from_vm86 -BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32) +TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) +BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64) CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -UNAME_P := $(shell uname -p) +UNAME_M := $(shell uname -m) +CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) +CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) -# Always build 32-bit tests +ifeq ($(CAN_BUILD_I386),1) all: all_32 +TEST_PROGS += $(BINARIES_32) +endif -# If we're on a 64-bit host, build 64-bit tests as well -ifeq ($(shell uname -p),x86_64) +ifeq ($(CAN_BUILD_X86_64),1) all: all_64 +TEST_PROGS += $(BINARIES_64) endif -all_32: check_build32 $(BINARIES_32) +all_32: $(BINARIES_32) all_64: $(BINARIES_64) clean: $(RM) $(BINARIES_32) $(BINARIES_64) -run_tests: - ./run_x86_tests.sh - -$(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c +$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -check_build32: - @if ! $(CC) -m32 -o /dev/null trivial_32bit_program.c; then \ - echo "Warning: you seem to have a broken 32-bit build" 2>&1; \ - echo "environment. If you are using a Debian-like"; \ - echo " distribution, try:"; \ - echo ""; \ - echo " apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \ - echo ""; \ - echo "If you are using a Fedora-like distribution, try:"; \ - echo ""; \ - echo " yum install glibc-devel.*i686"; \ - exit 1; \ - fi +# x86_64 users should be encouraged to install 32-bit libraries +ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01) +all: warn_32bit_failure + +warn_32bit_failure: + @echo "Warning: you seem to have a broken 32-bit build" 2>&1; \ + echo "environment. This will reduce test coverage of 64-bit" 2>&1; \ + echo "kernels. If you are using a Debian-like distribution," 2>&1; \ + echo "try:"; 2>&1; \ + echo ""; \ + echo " apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \ + echo ""; \ + echo "If you are using a Fedora-like distribution, try:"; \ + echo ""; \ + echo " yum install glibc-devel.*i686"; \ + exit 0; +endif diff --git a/tools/testing/selftests/x86/check_cc.sh b/tools/testing/selftests/x86/check_cc.sh new file mode 100755 index 000000000000..172d3293fb7b --- /dev/null +++ b/tools/testing/selftests/x86/check_cc.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# check_cc.sh - Helper to test userspace compilation support +# Copyright (c) 2015 Andrew Lutomirski +# GPL v2 + +CC="$1" +TESTPROG="$2" +shift 2 + +if "$CC" -o /dev/null "$TESTPROG" -O0 "$@" 2>/dev/null; then + echo 1 +else + echo 0 +fi + +exit 0 diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c new file mode 100644 index 000000000000..5c38a187677b --- /dev/null +++ b/tools/testing/selftests/x86/entry_from_vm86.c @@ -0,0 +1,114 @@ +/* + * entry_from_vm86.c - tests kernel entries from vm86 mode + * Copyright (c) 2014-2015 Andrew Lutomirski + * + * This exercises a few paths that need to special-case vm86 mode. + * + * GPL v2. + */ + +#define _GNU_SOURCE + +#include <assert.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <sys/signal.h> +#include <sys/ucontext.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <sys/mman.h> +#include <err.h> +#include <stddef.h> +#include <stdbool.h> +#include <errno.h> +#include <sys/vm86.h> + +static unsigned long load_addr = 0x10000; +static int nerrs = 0; + +asm ( + ".pushsection .rodata\n\t" + ".type vmcode_bound, @object\n\t" + "vmcode:\n\t" + "vmcode_bound:\n\t" + ".code16\n\t" + "bound %ax, (2048)\n\t" + "int3\n\t" + "vmcode_sysenter:\n\t" + "sysenter\n\t" + ".size vmcode, . - vmcode\n\t" + "end_vmcode:\n\t" + ".code32\n\t" + ".popsection" + ); + +extern unsigned char vmcode[], end_vmcode[]; +extern unsigned char vmcode_bound[], vmcode_sysenter[]; + +static void do_test(struct vm86plus_struct *v86, unsigned long eip, + const char *text) +{ + long ret; + + printf("[RUN]\t%s from vm86 mode\n", text); + v86->regs.eip = eip; + ret = vm86(VM86_ENTER, v86); + + if (ret == -1 && errno == ENOSYS) { + printf("[SKIP]\tvm86 not supported\n"); + return; + } + + if (VM86_TYPE(ret) == VM86_INTx) { + char trapname[32]; + int trapno = VM86_ARG(ret); + if (trapno == 13) + strcpy(trapname, "GP"); + else if (trapno == 5) + strcpy(trapname, "BR"); + else if (trapno == 14) + strcpy(trapname, "PF"); + else + sprintf(trapname, "%d", trapno); + + printf("[OK]\tExited vm86 mode due to #%s\n", trapname); + } else if (VM86_TYPE(ret) == VM86_UNKNOWN) { + printf("[OK]\tExited vm86 mode due to unhandled GP fault\n"); + } else { + printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n", + VM86_TYPE(ret), VM86_ARG(ret)); + } +} + +int main(void) +{ + struct vm86plus_struct v86; + unsigned char *addr = mmap((void *)load_addr, 4096, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANONYMOUS | MAP_PRIVATE, -1,0); + if (addr != (unsigned char *)load_addr) + err(1, "mmap"); + + memcpy(addr, vmcode, end_vmcode - vmcode); + addr[2048] = 2; + addr[2050] = 3; + + memset(&v86, 0, sizeof(v86)); + + v86.regs.cs = load_addr / 16; + v86.regs.ss = load_addr / 16; + v86.regs.ds = load_addr / 16; + v86.regs.es = load_addr / 16; + + assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */ + + /* #BR -- should deliver SIG??? */ + do_test(&v86, vmcode_bound - vmcode, "#BR"); + + /* SYSENTER -- should cause #GP or #UD depending on CPU */ + do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER"); + + return (nerrs == 0 ? 0 : 1); +} diff --git a/tools/testing/selftests/x86/run_x86_tests.sh b/tools/testing/selftests/x86/run_x86_tests.sh deleted file mode 100644 index 3fc19b376812..000000000000 --- a/tools/testing/selftests/x86/run_x86_tests.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# This is deliberately minimal. IMO kselftests should provide a standard -# script here. -./sigreturn_32 || exit 1 -./single_step_syscall_32 || exit 1 - -if [[ "$uname -p" -eq "x86_64" ]]; then - ./sigreturn_64 || exit 1 - ./single_step_syscall_64 || exit 1 -fi - -exit 0 diff --git a/tools/testing/selftests/x86/trivial_32bit_program.c b/tools/testing/selftests/x86/trivial_32bit_program.c index 2e231beb0a39..fabdf0f51621 100644 --- a/tools/testing/selftests/x86/trivial_32bit_program.c +++ b/tools/testing/selftests/x86/trivial_32bit_program.c @@ -4,6 +4,10 @@ * GPL v2 */ +#ifndef __i386__ +# error wrong architecture +#endif + #include <stdio.h> int main() diff --git a/tools/testing/selftests/x86/trivial_64bit_program.c b/tools/testing/selftests/x86/trivial_64bit_program.c new file mode 100644 index 000000000000..b994946c40fb --- /dev/null +++ b/tools/testing/selftests/x86/trivial_64bit_program.c @@ -0,0 +1,18 @@ +/* + * Trivial program to check that we have a valid 32-bit build environment. + * Copyright (c) 2015 Andy Lutomirski + * GPL v2 + */ + +#ifndef __x86_64__ +# error wrong architecture +#endif + +#include <stdio.h> + +int main() +{ + printf("\n"); + + return 0; +} diff --git a/tools/thermal/tmon/Makefile b/tools/thermal/tmon/Makefile index 0788621c8d76..2e83dd3655a2 100644 --- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile @@ -12,10 +12,6 @@ TARGET=tmon INSTALL_PROGRAM=install -m 755 -p DEL_FILE=rm -f -INSTALL_CONFIGFILE=install -m 644 -p -CONFIG_FILE= -CONFIG_PATH= - # Static builds might require -ltinfo, for instance ifneq ($(findstring -static, $(LDFLAGS)),) STATIC := --static @@ -38,13 +34,9 @@ valgrind: tmon install: - mkdir -p $(INSTALL_ROOT)/$(BINDIR) - $(INSTALL_PROGRAM) "$(TARGET)" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)" - - mkdir -p $(INSTALL_ROOT)/$(CONFIG_PATH) - - $(INSTALL_CONFIGFILE) "$(CONFIG_FILE)" "$(INSTALL_ROOT)/$(CONFIG_PATH)" uninstall: $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)" - $(CONFIG_FILE) "$(CONFIG_PATH)" - clean: find . -name "*.o" | xargs $(DEL_FILE) diff --git a/tools/vm/Makefile b/tools/vm/Makefile index ac884b65a072..93aadaf7ff63 100644 --- a/tools/vm/Makefile +++ b/tools/vm/Makefile @@ -3,7 +3,7 @@ TARGETS=page-types slabinfo page_owner_sort LIB_DIR = ../lib/api -LIBS = $(LIB_DIR)/libapikfs.a +LIBS = $(LIB_DIR)/libapi.a CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall -Wextra -I../lib/ |