diff options
669 files changed, 25666 insertions, 20818 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index b8f220f978dd..530809ccfacf 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -170,6 +170,16 @@ Description: Has all of the equivalent parameters as per voltageY. Units after application of scale and offset are m/s^2. +What: /sys/bus/iio/devices/iio:deviceX/in_gravity_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_gravity_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_gravity_z_raw +KernelVersion: 4.11 +Contact: linux-iio@vger.kernel.org +Description: + Gravity in direction x, y or z (may be arbitrarily assigned + but should match other such assignments on device). + Units after application of scale and offset are m/s^2. + What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw @@ -805,7 +815,7 @@ Description: attribute. E.g. if in_voltage0_raw_thresh_rising_value is set to 1200 and in_voltage0_raw_thresh_rising_hysteresis is set to 50. The event will get activated once in_voltage0_raw goes above 1200 and will become - deactived again once the value falls below 1150. + deactivated again once the value falls below 1150. What: /sys/.../events/in_accel_x_raw_roc_rising_value What: /sys/.../events/in_accel_x_raw_roc_falling_value @@ -1245,7 +1255,8 @@ Description: reflectivity of infrared or ultrasound emitted. Often these sensors are unit less and as such conversion to SI units is not possible. Higher proximity measurements - indicate closer objects, and vice versa. + indicate closer objects, and vice versa. Units after + application of scale and offset are meters. What: /sys/.../iio:deviceX/in_illuminance_input What: /sys/.../iio:deviceX/in_illuminance_raw diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-adc-stm32 new file mode 100644 index 000000000000..efe4c85e3c8b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-stm32 @@ -0,0 +1,18 @@ +What: /sys/bus/iio/devices/triggerX/trigger_polarity +KernelVersion: 4.11 +Contact: fabrice.gasnier@st.com +Description: + The STM32 ADC can be configured to use external trigger sources + (e.g. timers, pwm or exti gpio). Then, it can be tuned to start + conversions on external trigger by either: + - "rising-edge" + - "falling-edge" + - "both-edges". + Reading returns current trigger polarity. + Writing value before enabling conversions sets trigger polarity. + +What: /sys/bus/iio/devices/triggerX/trigger_polarity_available +KernelVersion: 4.11 +Contact: fabrice.gasnier@st.com +Description: + List all available trigger_polarity settings. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 new file mode 100644 index 000000000000..0a1ca1487fa9 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 @@ -0,0 +1,22 @@ +What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity +Date: January 2017 +KernelVersion: 4.11 +Contact: linux-iio@vger.kernel.org +Description: + Show or set the gain boost of the amp, from 0-31 range. + default 31 + +What /sys/bus/iio/devices/iio:deviceX/sensor_max_range +Date: January 2017 +KernelVersion: 4.11 +Contact: linux-iio@vger.kernel.org +Description: + Show or set the maximum range between the sensor and the + first object echoed in meters. Default value is 6.020. + This setting limits the time the driver is waiting for a + echo. + Showing the range of available values is represented as the + minimum value, the step and the maximum value, all enclosed + in square brackets. + Example: + [0.043 0.043 11.008] diff --git a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 new file mode 100644 index 000000000000..6534a60037ff --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 @@ -0,0 +1,29 @@ +What: /sys/bus/iio/devices/triggerX/master_mode_available +KernelVersion: 4.11 +Contact: benjamin.gaignard@st.com +Description: + Reading returns the list possible master modes which are: + - "reset" : The UG bit from the TIMx_EGR register is used as trigger output (TRGO). + - "enable" : The Counter Enable signal CNT_EN is used as trigger output. + - "update" : The update event is selected as trigger output. + For instance a master timer can then be used as a prescaler for a slave timer. + - "compare_pulse" : The trigger output send a positive pulse when the CC1IF flag is to be set. + - "OC1REF" : OC1REF signal is used as trigger output. + - "OC2REF" : OC2REF signal is used as trigger output. + - "OC3REF" : OC3REF signal is used as trigger output. + - "OC4REF" : OC4REF signal is used as trigger output. + +What: /sys/bus/iio/devices/triggerX/master_mode +KernelVersion: 4.11 +Contact: benjamin.gaignard@st.com +Description: + Reading returns the current master modes. + Writing set the master mode + +What: /sys/bus/iio/devices/triggerX/sampling_frequency +KernelVersion: 4.11 +Contact: benjamin.gaignard@st.com +Description: + Reading returns the current sampling frequency. + Writing an value different of 0 set and start sampling. + Writing 0 stop sampling. diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index cdd7b48826c3..ad10fbe61562 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -36,6 +36,7 @@ dallas,ds1775 Tiny Digital Thermometer and Thermostat dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O dallas,ds75 Digital Thermometer and Thermostat +devantech,srf08 Devantech SRF08 ultrasonic ranger dlg,da9053 DA9053: flexible system level PMIC with multicore support dlg,da9063 DA9063: system PMIC for quad-core application processors domintech,dmard09 DMARD09: 3-axis Accelerometer diff --git a/Documentation/devicetree/bindings/iio/accel/lis302.txt b/Documentation/devicetree/bindings/iio/accel/lis302.txt index 2a19bff9693f..dfdce67826ba 100644 --- a/Documentation/devicetree/bindings/iio/accel/lis302.txt +++ b/Documentation/devicetree/bindings/iio/accel/lis302.txt @@ -5,7 +5,7 @@ that apply in on the generic device (independent from the bus). Required properties for the SPI bindings: - - compatible: should be set to "st,lis3lv02d_spi" + - compatible: should be set to "st,lis3lv02d-spi" - reg: the chipselect index - spi-max-frequency: maximal bus speed, should be set to 1000000 unless constrained by external circuitry diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt new file mode 100644 index 000000000000..f9e3ff2c656e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt @@ -0,0 +1,32 @@ +* Amlogic Meson SAR (Successive Approximation Register) A/D converter + +Required properties: +- compatible: depending on the SoC this should be one of: + - "amlogic,meson-gxbb-saradc" for GXBB + - "amlogic,meson-gxl-saradc" for GXL + - "amlogic,meson-gxm-saradc" for GXM + along with the generic "amlogic,meson-saradc" +- reg: the physical base address and length of the registers +- clocks: phandle and clock identifier (see clock-names) +- clock-names: mandatory clocks: + - "clkin" for the reference clock (typically XTAL) + - "core" for the SAR ADC core clock + optional clocks: + - "sana" for the analog clock + - "adc_clk" for the ADC (sampling) clock + - "adc_sel" for the ADC (sampling) clock mux +- vref-supply: the regulator supply for the ADC reference voltage +- #io-channel-cells: must be 1, see ../iio-bindings.txt + +Example: + saradc: adc@8680 { + compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; + #io-channel-cells = <1>; + reg = <0x0 0x8680 0x0 0x34>; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; + clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt new file mode 100644 index 000000000000..b3629405f568 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt @@ -0,0 +1,18 @@ +* AVIA HX711 ADC chip for weight cells + Bit-banging driver + +Required properties: + - compatible: Should be "avia,hx711" + - sck-gpios: Definition of the GPIO for the clock + - dout-gpios: Definition of the GPIO for data-out + See Documentation/devicetree/bindings/gpio/gpio.txt + - avdd-supply: Definition of the regulator used as analog supply + +Example: +weight@0 { + compatible = "avia,hx711"; + sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>; + dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; + avdd-suppy = <&avdd>; +}; + diff --git a/Documentation/devicetree/bindings/iio/adc/max11100.txt b/Documentation/devicetree/bindings/iio/adc/max11100.txt new file mode 100644 index 000000000000..b7f7177b8aca --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/max11100.txt @@ -0,0 +1,18 @@ +* Maxim max11100 Analog to Digital Converter (ADC) + +Required properties: + - compatible: Should be "maxim,max11100" + - reg: the adc unit address + - vref-supply: phandle to the regulator that provides reference voltage + +Optional properties: + - spi-max-frequency: SPI maximum frequency + +Example: + +max11100: adc@0 { + compatible = "maxim,max11100"; + reg = <0>; + vref-supply = <&adc0_vref>; + spi-max-frequency = <240000>; +}; diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,pm8xxx-xoadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,pm8xxx-xoadc.txt new file mode 100644 index 000000000000..53cd146d8096 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/qcom,pm8xxx-xoadc.txt @@ -0,0 +1,149 @@ +Qualcomm's PM8xxx voltage XOADC + +The Qualcomm PM8xxx PMICs contain a HK/XO ADC (Housekeeping/Crystal +oscillator ADC) encompassing PM8018, PM8038, PM8058 and PM8921. + +Required properties: + +- compatible: should be one of: + "qcom,pm8018-adc" + "qcom,pm8038-adc" + "qcom,pm8058-adc" + "qcom,pm8921-adc" + +- reg: should contain the ADC base address in the PMIC, typically + 0x197. + +- xoadc-ref-supply: should reference a regulator that can supply + a reference voltage on demand. The reference voltage may vary + with PMIC variant but is typically something like 2.2 or 1.8V. + +The following required properties are standard for IO channels, see +iio-bindings.txt for more details: + +- #address-cells: should be set to <1> + +- #size-cells: should be set to <0> + +- #io-channel-cells: should be set to <1> + +- interrupts: should refer to the parent PMIC interrupt controller + and reference the proper ADC interrupt. + +Required subnodes: + +The ADC channels are configured as subnodes of the ADC. Since some of +them are used for calibrating the ADC, these nodes are compulsory: + +adc-channel@c { + reg = <0x0c>; +}; + +adc-channel@d { + reg = <0x0d>; +}; + +adc-channel@f { + reg = <0x0f>; +}; + +These three nodes are used for absolute and ratiometric calibration +and only need to have these reg values: they are by hardware definition +1:1 ratio converters that sample 625, 1250 and 0 milliV and create +an interpolation calibration for all other ADCs. + +Optional subnodes: any channels other than channel 0x0c, 0x0d and +0x0f are optional. + +Required channel node properties: + +- reg: should contain the hardware channel number in the range + 0 .. 0x0f (4 bits). The hardware only supports 16 channels. + +Optional channel node properties: + +- qcom,decimation: + Value type: <u32> + Definition: This parameter is used to decrease the ADC sampling rate. + Quicker measurements can be made by reducing the decimation ratio. + Valid values are 512, 1024, 2048, 4096. + If the property is not found, a default value of 512 will be used. + +- qcom,ratiometric: + Value type: <u32> + Definition: Channel calibration type. If this property is specified + VADC will use a special voltage references for channel + calibration. The available references are specified in the + as a u32 value setting (see below) and it is compulsory + to also specify this reference if ratiometric calibration + is selected. + + If the property is not found, the channel will be + calibrated with the 0.625V and 1.25V reference channels, also + known as an absolute calibration. + The reference voltage pairs when using ratiometric calibration: + 0 = XO_IN/XOADC_GND + 1 = PMIC_IN/XOADC_GND + 2 = PMIC_IN/BMS_CSP + 3 (invalid) + 4 = XOADC_GND/XOADC_GND + 5 = XOADC_VREF/XOADC_GND + +Example: + +xoadc: xoadc@197 { + compatible = "qcom,pm8058-adc"; + reg = <0x197>; + interrupt-parent = <&pm8058>; + interrupts = <76 1>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + vcoin: adc-channel@0 { + reg = <0x00>; + }; + vbat: adc-channel@1 { + reg = <0x01>; + }; + dcin: adc-channel@2 { + reg = <0x02>; + }; + ichg: adc-channel@3 { + reg = <0x03>; + }; + vph_pwr: adc-channel@4 { + reg = <0x04>; + }; + usb_vbus: adc-channel@a { + reg = <0x0a>; + }; + die_temp: adc-channel@b { + reg = <0x0b>; + }; + ref_625mv: adc-channel@c { + reg = <0x0c>; + }; + ref_1250mv: adc-channel@d { + reg = <0x0d>; + }; + ref_325mv: adc-channel@e { + reg = <0x0e>; + }; + ref_muxoff: adc-channel@f { + reg = <0x0f>; + }; +}; + + +/* IIO client node */ +iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&xoadc 0x01>, /* Battery */ + <&xoadc 0x02>, /* DC in (charger) */ + <&xoadc 0x04>, /* VPH the main system voltage */ + <&xoadc 0x0b>, /* Die temperature */ + <&xoadc 0x0c>, /* Reference voltage 1.25V */ + <&xoadc 0x0d>, /* Reference voltage 0.625V */ + <&xoadc 0x0e>; /* Reference voltage 0.325V */ +}; diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt new file mode 100644 index 000000000000..f5b0adae6010 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt @@ -0,0 +1,99 @@ +* Renesas RCar GyroADC device driver + +The GyroADC block is a reduced SPI block with up to 8 chipselect lines, +which supports the SPI protocol of a selected few SPI ADCs. The SPI ADCs +are sampled by the GyroADC block in a round-robin fashion and the result +presented in the GyroADC registers. + +Required properties: +- compatible: Should be "<soc-specific>", "renesas,rcar-gyroadc". + The <soc-specific> should be one of: + renesas,r8a7791-gyroadc - for the GyroADC block present + in r8a7791 SoC + renesas,r8a7792-gyroadc - for the GyroADC with interrupt + block present in r8a7792 SoC +- reg: Address and length of the register set for the device +- clocks: References to all the clocks specified in the clock-names + property as specified in + Documentation/devicetree/bindings/clock/clock-bindings.txt. +- clock-names: Shall contain "fck" and "if". The "fck" is the GyroADC block + clock, the "if" is the interface clock. +- power-domains: Must contain a reference to the PM domain, if available. +- #address-cells: Should be <1> (setting for the subnodes) for all ADCs + except for "fujitsu,mb88101a". Should be <0> (setting for + only subnode) for "fujitsu,mb88101a". +- #size-cells: Should be <0> (setting for the subnodes) + +Sub-nodes: +You must define subnode(s) which select the connected ADC type and reference +voltage for the GyroADC channels. + +Required properties for subnodes: +- compatible: Should be either of: + "fujitsu,mb88101a" + - Fujitsu MB88101A compatible mode, + 12bit sampling, up to 4 channels can be sampled in + round-robin fashion. One Fujitsu chip supplies four + GyroADC channels with data as it contains four ADCs + on the chip and thus for 4-channel operation, single + MB88101A is required. The Cx chipselect lines of the + MB88101A connect directly to two CHS lines of the + GyroADC, no demuxer is required. The data out line + of each MB88101A connects to a shared input pin of + the GyroADC. + "ti,adcs7476" or "ti,adc121" or "adi,ad7476" + - TI ADCS7476 / TI ADC121 / ADI AD7476 compatible mode, + 15bit sampling, up to 8 channels can be sampled in + round-robin fashion. One TI/ADI chip supplies single + ADC channel with data, thus for 8-channel operation, + 8 chips are required. A 3:8 chipselect demuxer is + required to connect the nCS line of the TI/ADI chips + to the GyroADC, while MISO line of each TI/ADI ADC + connects to a shared input pin of the GyroADC. + "maxim,max1162" or "maxim,max11100" + - Maxim MAX1162 / Maxim MAX11100 compatible mode, + 16bit sampling, up to 8 channels can be sampled in + round-robin fashion. One Maxim chip supplies single + ADC channel with data, thus for 8-channel operation, + 8 chips are required. A 3:8 chipselect demuxer is + required to connect the nCS line of the MAX chips + to the GyroADC, while MISO line of each Maxim ADC + connects to a shared input pin of the GyroADC. +- reg: Should be the number of the analog input. Should be present + for all ADCs except "fujitsu,mb88101a". +- vref-supply: Reference to the channel reference voltage regulator. + +Example: + vref_max1162: regulator-vref-max1162 { + compatible = "regulator-fixed"; + + regulator-name = "MAX1162 Vref"; + regulator-min-microvolt = <4096000>; + regulator-max-microvolt = <4096000>; + }; + + adc@e6e54000 { + compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc"; + reg = <0 0xe6e54000 0 64>; + clocks = <&mstp9_clks R8A7791_CLK_GYROADC>, <&clk_65m>; + clock-names = "fck", "if"; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + + pinctrl-0 = <&adc_pins>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + reg = <0>; + compatible = "maxim,max1162"; + vref-supply = <&vref_max1162>; + }; + + adc@1 { + reg = <1>; + compatible = "maxim,max1162"; + vref-supply = <&vref_max1162>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt index 49ed82e89870..5dfc88ec24a4 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt @@ -53,6 +53,11 @@ Required properties: - #io-channel-cells = <1>: See the IIO bindings section "IIO consumers" in Documentation/devicetree/bindings/iio/iio-bindings.txt +Optional properties: +- dmas: Phandle to dma channel for this ADC instance. + See ../../dma/dma.txt for details. +- dma-names: Must be "rx" when dmas property is being used. + Example: adc: adc@40012000 { compatible = "st,stm32f4-adc-core"; @@ -77,6 +82,8 @@ Example: interrupt-parent = <&adc>; interrupts = <0>; st,adc-channels = <8>; + dmas = <&dma2 0 0 0x400 0x0>; + dma-names = "rx"; }; ... other adc child nodes follow... diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt new file mode 100644 index 000000000000..e77a6f7e1001 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt @@ -0,0 +1,23 @@ +* Texas Instruments ADS7950 family of A/DC chips + +Required properties: + - compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952", + "ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957", + "ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961" + - reg: SPI chip select number for the device + - #io-channel-cells: Must be 1 as per ../iio-bindings.txt + - vref-supply: phandle to a regulator node that supplies the 2.5V or 5V + reference voltage + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Example: +adc@0 { + compatible = "ti,ads7957"; + reg = <0>; + #io-channel-cells = <1>; + vref-supply = <&refin_supply>; + spi-max-frequency = <10000000>; +}; diff --git a/Documentation/devicetree/bindings/iio/imu/bmi160.txt b/Documentation/devicetree/bindings/iio/imu/bmi160.txt new file mode 100644 index 000000000000..ae0112c7debc --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/bmi160.txt @@ -0,0 +1,36 @@ +Bosch BMI160 - Inertial Measurement Unit with Accelerometer, Gyroscope +and externally connectable Magnetometer + +https://www.bosch-sensortec.com/bst/products/all_products/bmi160 + +Required properties: + - compatible : should be "bosch,bmi160" + - reg : the I2C address or SPI chip select number of the sensor + - spi-max-frequency : set maximum clock frequency (only for SPI) + +Optional properties: + - interrupt-parent : should be the phandle of the interrupt controller + - interrupts : interrupt mapping for IRQ, must be IRQ_TYPE_LEVEL_LOW + - interrupt-names : set to "INT1" if INT1 pin should be used as interrupt + input, set to "INT2" if INT2 pin should be used instead + +Examples: + +bmi160@68 { + compatible = "bosch,bmi160"; + reg = <0x68>; + + interrupt-parent = <&gpio4>; + interrupts = <12 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "INT1"; +}; + +bmi160@0 { + compatible = "bosch,bmi160"; + reg = <0>; + spi-max-frequency = <10000000>; + + interrupt-parent = <&gpio2>; + interrupts = <12 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "INT2"; +}; diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt new file mode 100644 index 000000000000..cf81afdf7803 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt @@ -0,0 +1,26 @@ +* ST_LSM6DSx driver for STM 6-axis (acc + gyro) imu Mems sensors + +Required properties: +- compatible: must be one of: + "st,lsm6ds3" + "st,lsm6dsm" +- reg: i2c address of the sensor / spi cs line + +Optional properties: +- st,drdy-int-pin: the pin on the package that will be used to signal + "data ready" (valid values: 1 or 2). +- interrupt-parent: should be the phandle for the interrupt controller +- interrupts: interrupt mapping for IRQ. It should be configured with + flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING. + + Refer to interrupt-controller/interrupts.txt for generic interrupt + client node bindings. + +Example: + +lsm6dsm@6b { + compatible = "st,lsm6dsm"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; +}; diff --git a/Documentation/devicetree/bindings/iio/light/cm3605.txt b/Documentation/devicetree/bindings/iio/light/cm3605.txt new file mode 100644 index 000000000000..56331a79f9ab --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/cm3605.txt @@ -0,0 +1,41 @@ +Capella Microsystems CM3605 +Ambient Light and Short Distance Proximity Sensor + +The CM3605 is an entirely analog part which however require quite a bit of +software logic to interface a host operating system. + +This ALS and proximity sensor was one of the very first deployed in mobile +handsets, notably it is used in the very first Nexus One Android phone from +2010. + +Required properties: +- compatible: must be: "capella,cm3605" +- aset-gpios: GPIO line controlling the ASET line (drive low + to activate the ALS, should be flagged GPIO_ACTIVE_LOW) +- interrupts: the IRQ line (such as a GPIO) that is connected to + the POUT (proximity sensor out) line. The edge detection must + be set to IRQ_TYPE_EDGE_BOTH so as to detect movements toward + and away from the proximity sensor. +- io-channels: the ADC channel used for converting the voltage from + AOUT to a digital representation. +- io-channel-names: must be "aout" + +Optional properties: +- vdd-supply: regulator supplying VDD power to the component. +- capella,aset-resistance-ohms: the sensitivity calibration resistance, + in Ohms. Valid values are: 50000, 100000, 300000 and 600000, + as these are the resistance values that we are supplied with + calibration curves for. If not supplied, 100 kOhm will be assumed + but it is strongly recommended to supply this. + +Example: + +cm3605 { + compatible = "capella,cm3605"; + vdd-supply = <&foo_reg>; + aset-gpios = <&foo_gpio 1 GPIO_ACTIVE_LOW>; + capella,aset-resistance-ohms = <100000>; + interrupts = <1 IRQ_TYPE_EDGE_BOTH>; + io-channels = <&adc 0x01>; + io-channel-names = "aout"; +}; diff --git a/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt new file mode 100644 index 000000000000..6a91b106e076 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt @@ -0,0 +1,23 @@ +* Maxim Linear-Taper Digital Potentiometer MAX5481-MAX5484 + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in + + Documentation/devicetree/bindings/spi/spi-bus.txt + +must be specified. + +Required properties: + - compatible: Must be one of the following, depending on the + model: + "maxim,max5481" + "maxim,max5482" + "maxim,max5483" + "maxim,max5484" + +Example: +max548x: max548x@0 { + compatible = "maxim,max5482"; + spi-max-frequency = <7000000>; + reg = <0>; /* chip-select */ +}; diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index c040c9ad1889..eaa8fbba34e2 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -27,6 +27,8 @@ standard bindings from pinctrl/pinctrl-bindings.txt. Valid compatible strings: Accelerometers: +- st,lis3lv02d (deprecated, use st,lis3lv02dl-accel) +- st,lis302dl-spi (deprecated, use st,lis3lv02dl-accel) - st,lis3lv02dl-accel - st,lsm303dlh-accel - st,lsm303dlhc-accel diff --git a/Documentation/devicetree/bindings/iio/temperature/tmp007.txt b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt new file mode 100644 index 000000000000..b63aba91ef03 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt @@ -0,0 +1,35 @@ +* TI TMP007 - IR thermopile sensor with integrated math engine + +Link to datasheet: http://www.ti.com/lit/ds/symlink/tmp007.pdf + +Required properties: + + - compatible: should be "ti,tmp007" + - reg: the I2C address of the sensor (changeable via ADR pins) + ------------------------------ + |ADR1 | ADR0 | Device Address| + ------------------------------ + 0 0 0x40 + 0 1 0x41 + 0 SDA 0x42 + 0 SCL 0x43 + 1 0 0x44 + 1 1 0x45 + 1 SDA 0x46 + 1 SCL 0x47 + +Optional properties: + + - interrupt-parent: should be the phandle for the interrupt controller + + - interrupts: interrupt mapping for GPIO IRQ (level active low) + +Example: + +tmp007@40 { + compatible = "ti,tmp007"; + reg = <0x40>; + interrupt-parent = <&gpio0>; + interrupts = <5 0x08>; +}; + diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt new file mode 100644 index 000000000000..55a653d15303 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt @@ -0,0 +1,23 @@ +STMicroelectronics STM32 Timers IIO timer bindings + +Must be a sub-node of an STM32 Timers device tree node. +See ../mfd/stm32-timers.txt for details about the parent node. + +Required parameters: +- compatible: Must be "st,stm32-timer-trigger". +- reg: Identify trigger hardware block. + +Example: + timers@40010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x40010000 0x400>; + clocks = <&rcc 0 160>; + clock-names = "clk_int"; + + timer@0 { + compatible = "st,stm32-timer-trigger"; + reg = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt new file mode 100644 index 000000000000..bbd083f5600a --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt @@ -0,0 +1,46 @@ +STM32 Timers driver bindings + +This IP provides 3 types of timer along with PWM functionality: +- advanced-control timers consist of a 16-bit auto-reload counter driven by a programmable + prescaler, break input feature, PWM outputs and complementary PWM ouputs channels. +- general-purpose timers consist of a 16-bit or 32-bit auto-reload counter driven by a + programmable prescaler and PWM outputs. +- basic timers consist of a 16-bit auto-reload counter driven by a programmable prescaler. + +Required parameters: +- compatible: must be "st,stm32-timers" + +- reg: Physical base address and length of the controller's + registers. +- clock-names: Set to "int". +- clocks: Phandle to the clock used by the timer module. + For Clk properties, please refer to ../clock/clock-bindings.txt + +Optional parameters: +- resets: Phandle to the parent reset controller. + See ../reset/st,stm32-rcc.txt + +Optional subnodes: +- pwm: See ../pwm/pwm-stm32.txt +- timer: See ../iio/timer/stm32-timer-trigger.txt + +Example: + timers@40010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x40010000 0x400>; + clocks = <&rcc 0 160>; + clock-names = "clk_int"; + + pwm { + compatible = "st,stm32-pwm"; + pinctrl-0 = <&pwm1_pins>; + pinctrl-names = "default"; + }; + + timer@0 { + compatible = "st,stm32-timer-trigger"; + reg = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt new file mode 100644 index 000000000000..6dd040363e5e --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt @@ -0,0 +1,35 @@ +STMicroelectronics STM32 Timers PWM bindings + +Must be a sub-node of an STM32 Timers device tree node. +See ../mfd/stm32-timers.txt for details about the parent node. + +Required parameters: +- compatible: Must be "st,stm32-pwm". +- pinctrl-names: Set to "default". +- pinctrl-0: List of phandles pointing to pin configuration nodes for PWM module. + For Pinctrl properties see ../pinctrl/pinctrl-bindings.txt + +Optional parameters: +- st,breakinput: One or two <index level filter> to describe break input configurations. + "index" indicates on which break input (0 or 1) the configuration + should be applied. + "level" gives the active level (0=low or 1=high) of the input signal + for this configuration. + "filter" gives the filtering value to be applied. + +Example: + timers@40010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x40010000 0x400>; + clocks = <&rcc 0 160>; + clock-names = "clk_int"; + + pwm { + compatible = "st,stm32-pwm"; + pinctrl-0 = <&pwm1_pins>; + pinctrl-names = "default"; + st,breakinput = <0 1 5>; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 16d3b5e7f5d1..cf1c36616507 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -40,6 +40,7 @@ atmel Atmel Corporation auo AU Optronics Corporation auvidea Auvidea GmbH avago Avago Technologies +avia avia semiconductor avic Shanghai AVIC Optoelectronics Co., Ltd. axentia Axentia Technologies AB axis Axis Communications AB @@ -75,6 +76,7 @@ dallas Maxim Integrated Products (formerly Dallas Semiconductor) davicom DAVICOM Semiconductor, Inc. delta Delta Electronics, Inc. denx Denx Software Engineering +devantech Devantech, Ltd. digi Digi International Inc. digilent Diglent, Inc. dlg Dialog Semiconductor @@ -118,6 +120,7 @@ gmt Global Mixed-mode Technology, Inc. goodix Shenzhen Huiding Technology Co., Ltd. google Google, Inc. grinn Grinn +grmn Garmin Limited gumstix Gumstix, Inc. gw Gateworks Corporation hannstar HannStar Display Corporation diff --git a/MAINTAINERS b/MAINTAINERS index 427c97e429bf..7021feed5aa6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10251,7 +10251,8 @@ F: include/uapi/linux/qnx4_fs.h F: include/uapi/linux/qnxtypes.h QORIQ DPAA2 FSL-MC BUS DRIVER -M: Stuart Yoder <stuart.yoder@nxp.com> +M: Stuart Yoder <stuyoder@gmail.com> +M: Laurentiu Tudor <laurentiu.tudor@nxp.com> L: linux-kernel@vger.kernel.org S: Maintained F: drivers/staging/fsl-mc/ @@ -10528,6 +10529,12 @@ L: linux-renesas-soc@vger.kernel.org F: drivers/net/ethernet/renesas/ F: include/linux/sh_eth.h +RENESAS R-CAR GYROADC DRIVER +M: Marek Vasut <marek.vasut@gmail.com> +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/adc/rcar_gyro_adc.c + RENESAS USB2 PHY DRIVER M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> L: linux-renesas-soc@vger.kernel.org diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index c68bdb649005..ef8401ac1141 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -120,6 +120,8 @@ config HID_SENSOR_ACCEL_3D config IIO_ST_ACCEL_3AXIS tristate "STMicroelectronics accelerometers 3-Axis Driver" depends on (I2C || SPI_MASTER) && SYSFS + depends on !SENSORS_LIS3_I2C + depends on !SENSORS_LIS3_SPI select IIO_ST_SENSORS_CORE select IIO_ST_ACCEL_I2C_3AXIS if (I2C) select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 59b380dbf27f..6b5d3be283c4 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1638,7 +1638,8 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, if (block_supported) { indio_dev->modes |= INDIO_BUFFER_SOFTWARE; indio_dev->info = &bmc150_accel_info_fifo; - indio_dev->buffer->attrs = bmc150_accel_fifo_attributes; + iio_buffer_set_attrs(indio_dev->buffer, + bmc150_accel_fifo_attributes); } } diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index ab1e238d5c75..ca5759c0c318 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -42,11 +42,13 @@ struct accel_3d_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; - u32 accel_val[ACCEL_3D_CHANNEL_MAX]; + /* Reserve for 3 channels + padding + timestamp */ + u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3]; int scale_pre_decml; int scale_post_decml; int scale_precision; int value_offset; + int64_t timestamp; }; static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = { @@ -87,6 +89,42 @@ static const struct iio_chan_spec accel_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, + }, + IIO_CHAN_SOFT_TIMESTAMP(3) +}; + +/* Channel definitions */ +static const struct iio_chan_spec gravity_channels[] = { + { + .type = IIO_GRAVITY, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_X, + }, { + .type = IIO_GRAVITY, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_Y, + }, { + .type = IIO_GRAVITY, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_Z, } }; @@ -111,6 +149,8 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev, int report_id = -1; u32 address; int ret_type; + struct hid_sensor_hub_device *hsdev = + accel_state->common_attributes.hsdev; *val = 0; *val2 = 0; @@ -122,8 +162,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev, if (report_id >= 0) *val = sensor_hub_input_attr_get_raw_value( accel_state->common_attributes.hsdev, - HID_USAGE_SENSOR_ACCEL_3D, address, - report_id, + hsdev->usage, address, report_id, SENSOR_HUB_SYNC); else { *val = 0; @@ -192,11 +231,11 @@ static const struct iio_info accel_3d_info = { }; /* Function to push data to buffer */ -static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data, - int len) +static void hid_sensor_push_data(struct iio_dev *indio_dev, void *data, + int len, int64_t timestamp) { dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - iio_push_to_buffers(indio_dev, data); + iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); } /* Callback handler to send event after all samples are received and captured */ @@ -208,10 +247,17 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev, struct accel_3d_state *accel_state = iio_priv(indio_dev); dev_dbg(&indio_dev->dev, "accel_3d_proc_event\n"); - if (atomic_read(&accel_state->common_attributes.data_ready)) + if (atomic_read(&accel_state->common_attributes.data_ready)) { + if (!accel_state->timestamp) + accel_state->timestamp = iio_get_time_ns(indio_dev); + hid_sensor_push_data(indio_dev, - accel_state->accel_val, - sizeof(accel_state->accel_val)); + accel_state->accel_val, + sizeof(accel_state->accel_val), + accel_state->timestamp); + + accel_state->timestamp = 0; + } return 0; } @@ -236,6 +282,12 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, *(u32 *)raw_data; ret = 0; break; + case HID_USAGE_SENSOR_TIME_TIMESTAMP: + accel_state->timestamp = + hid_sensor_convert_timestamp( + &accel_state->common_attributes, + *(int64_t *)raw_data); + break; default: break; } @@ -272,7 +324,7 @@ static int accel_3d_parse_report(struct platform_device *pdev, st->accel[2].index, st->accel[2].report_id); st->scale_precision = hid_sensor_format_scale( - HID_USAGE_SENSOR_ACCEL_3D, + hsdev->usage, &st->accel[CHANNEL_SCAN_INDEX_X], &st->scale_pre_decml, &st->scale_post_decml); @@ -295,9 +347,12 @@ static int accel_3d_parse_report(struct platform_device *pdev, static int hid_accel_3d_probe(struct platform_device *pdev) { int ret = 0; - static const char *name = "accel_3d"; + static const char *name; struct iio_dev *indio_dev; struct accel_3d_state *accel_state; + const struct iio_chan_spec *channel_spec; + int channel_size; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, @@ -311,24 +366,30 @@ static int hid_accel_3d_probe(struct platform_device *pdev) accel_state->common_attributes.hsdev = hsdev; accel_state->common_attributes.pdev = pdev; - ret = hid_sensor_parse_common_attributes(hsdev, - HID_USAGE_SENSOR_ACCEL_3D, + if (hsdev->usage == HID_USAGE_SENSOR_ACCEL_3D) { + name = "accel_3d"; + channel_spec = accel_3d_channels; + channel_size = sizeof(accel_3d_channels); + } else { + name = "gravity"; + channel_spec = gravity_channels; + channel_size = sizeof(gravity_channels); + } + ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage, &accel_state->common_attributes); if (ret) { dev_err(&pdev->dev, "failed to setup common attributes\n"); return ret; } + indio_dev->channels = kmemdup(channel_spec, channel_size, GFP_KERNEL); - indio_dev->channels = kmemdup(accel_3d_channels, - sizeof(accel_3d_channels), GFP_KERNEL); if (!indio_dev->channels) { dev_err(&pdev->dev, "failed to duplicate channels\n"); return -ENOMEM; } - ret = accel_3d_parse_report(pdev, hsdev, - (struct iio_chan_spec *)indio_dev->channels, - HID_USAGE_SENSOR_ACCEL_3D, accel_state); + (struct iio_chan_spec *)indio_dev->channels, + hsdev->usage, accel_state); if (ret) { dev_err(&pdev->dev, "failed to setup attributes\n"); goto error_free_dev_mem; @@ -363,7 +424,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev) accel_state->callbacks.send_event = accel_3d_proc_event; accel_state->callbacks.capture_sample = accel_3d_capture_sample; accel_state->callbacks.pdev = pdev; - ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D, + ret = sensor_hub_register_callback(hsdev, hsdev->usage, &accel_state->callbacks); if (ret < 0) { dev_err(&pdev->dev, "callback reg failed\n"); @@ -390,7 +451,7 @@ static int hid_accel_3d_remove(struct platform_device *pdev) struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct accel_3d_state *accel_state = iio_priv(indio_dev); - sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D); + sensor_hub_remove_callback(hsdev, hsdev->usage); iio_device_unregister(indio_dev); hid_sensor_remove_trigger(&accel_state->common_attributes); iio_triggered_buffer_cleanup(indio_dev); @@ -404,6 +465,9 @@ static const struct platform_device_id hid_accel_3d_ids[] = { /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ .name = "HID-SENSOR-200073", }, + { /* gravity sensor */ + .name = "HID-SENSOR-20007b", + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids); diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index f418c588af6a..eb6e3dc789b2 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -248,7 +248,7 @@ static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n, return -EINVAL; } -static int mma8452_get_odr_index(struct mma8452_data *data) +static unsigned int mma8452_get_odr_index(struct mma8452_data *data) { return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >> MMA8452_CTRL_DR_SHIFT; @@ -260,7 +260,7 @@ static const int mma8452_samp_freq[8][2] = { }; /* Datasheet table: step time "Relationship with the ODR" (sample frequency) */ -static const int mma8452_transient_time_step_us[4][8] = { +static const unsigned int mma8452_transient_time_step_us[4][8] = { { 1250, 2500, 5000, 10000, 20000, 20000, 20000, 20000 }, /* normal */ { 1250, 2500, 5000, 10000, 20000, 80000, 80000, 80000 }, /* l p l n */ { 1250, 2500, 2500, 2500, 2500, 2500, 2500, 2500 }, /* high res*/ diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c index 31db00970fa0..dd6ece8f9239 100644 --- a/drivers/iio/accel/ssp_accel_sensor.c +++ b/drivers/iio/accel/ssp_accel_sensor.c @@ -15,6 +15,7 @@ #include <linux/iio/common/ssp_sensors.h> #include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -135,7 +136,7 @@ static int ssp_accel_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret < 0) return ret; @@ -145,21 +146,11 @@ static int ssp_accel_probe(struct platform_device *pdev) return 0; } -static int ssp_accel_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - - iio_device_unregister(indio_dev); - - return 0; -} - static struct platform_driver ssp_accel_driver = { .driver = { .name = SSP_ACCEL_NAME, }, .probe = ssp_accel_probe, - .remove = ssp_accel_remove, }; module_platform_driver(ssp_accel_driver); diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 7c231687109a..3ad44ce7ae82 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -14,6 +14,24 @@ #include <linux/types.h> #include <linux/iio/common/st_sensors.h> +enum st_accel_type { + LSM303DLH, + LSM303DLHC, + LIS3DH, + LSM330D, + LSM330DL, + LSM330DLC, + LIS331DLH, + LSM303DL, + LSM303DLM, + LSM330, + LSM303AGR, + LIS2DH12, + LIS3L02DQ, + LNG2DM, + ST_ACCEL_MAX, +}; + #define H3LIS331DL_DRIVER_NAME "h3lis331dl_accel" #define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel" #define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel" diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index c0f8867aa1ea..543f0ad7fd7e 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/acpi.h> #include <linux/i2c.h> #include <linux/iio/iio.h> @@ -21,6 +22,11 @@ #ifdef CONFIG_OF static const struct of_device_id st_accel_of_match[] = { { + /* An older compatible */ + .compatible = "st,lis3lv02d", + .data = LIS3LV02DL_ACCEL_DEV_NAME, + }, + { .compatible = "st,lis3lv02dl-accel", .data = LIS3LV02DL_ACCEL_DEV_NAME, }, @@ -95,25 +101,67 @@ MODULE_DEVICE_TABLE(of, st_accel_of_match); #define st_accel_of_match NULL #endif +#ifdef CONFIG_ACPI +static const struct acpi_device_id st_accel_acpi_match[] = { + {"SMO8A90", LNG2DM}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match); +#else +#define st_accel_acpi_match NULL +#endif + +static const struct i2c_device_id st_accel_id_table[] = { + { LSM303DLH_ACCEL_DEV_NAME, LSM303DLH }, + { LSM303DLHC_ACCEL_DEV_NAME, LSM303DLHC }, + { LIS3DH_ACCEL_DEV_NAME, LIS3DH }, + { LSM330D_ACCEL_DEV_NAME, LSM330D }, + { LSM330DL_ACCEL_DEV_NAME, LSM330DL }, + { LSM330DLC_ACCEL_DEV_NAME, LSM330DLC }, + { LIS331DLH_ACCEL_DEV_NAME, LIS331DLH }, + { LSM303DL_ACCEL_DEV_NAME, LSM303DL }, + { LSM303DLM_ACCEL_DEV_NAME, LSM303DLM }, + { LSM330_ACCEL_DEV_NAME, LSM330 }, + { LSM303AGR_ACCEL_DEV_NAME, LSM303AGR }, + { LIS2DH12_ACCEL_DEV_NAME, LIS2DH12 }, + { LIS3L02DQ_ACCEL_DEV_NAME, LIS3L02DQ }, + { LNG2DM_ACCEL_DEV_NAME, LNG2DM }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, st_accel_id_table); + static int st_accel_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct iio_dev *indio_dev; struct st_sensor_data *adata; - int err; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata)); if (!indio_dev) return -ENOMEM; adata = iio_priv(indio_dev); - st_sensors_of_i2c_probe(client, st_accel_of_match); + + if (client->dev.of_node) { + st_sensors_of_i2c_probe(client, st_accel_of_match); + } else if (ACPI_HANDLE(&client->dev)) { + ret = st_sensors_match_acpi_device(&client->dev); + if ((ret < 0) || (ret >= ST_ACCEL_MAX)) + return -ENODEV; + + strncpy(client->name, st_accel_id_table[ret].name, + sizeof(client->name)); + client->name[sizeof(client->name) - 1] = '\0'; + } else if (!id) + return -ENODEV; + st_sensors_i2c_configure(indio_dev, client, adata); - err = st_accel_common_probe(indio_dev); - if (err < 0) - return err; + ret = st_accel_common_probe(indio_dev); + if (ret < 0) + return ret; return 0; } @@ -125,29 +173,11 @@ static int st_accel_i2c_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id st_accel_id_table[] = { - { LSM303DLH_ACCEL_DEV_NAME }, - { LSM303DLHC_ACCEL_DEV_NAME }, - { LIS3DH_ACCEL_DEV_NAME }, - { LSM330D_ACCEL_DEV_NAME }, - { LSM330DL_ACCEL_DEV_NAME }, - { LSM330DLC_ACCEL_DEV_NAME }, - { LIS331DLH_ACCEL_DEV_NAME }, - { LSM303DL_ACCEL_DEV_NAME }, - { LSM303DLM_ACCEL_DEV_NAME }, - { LSM330_ACCEL_DEV_NAME }, - { LSM303AGR_ACCEL_DEV_NAME }, - { LIS2DH12_ACCEL_DEV_NAME }, - { LIS3L02DQ_ACCEL_DEV_NAME }, - { LNG2DM_ACCEL_DEV_NAME }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, st_accel_id_table); - static struct i2c_driver st_accel_driver = { .driver = { .name = "st-accel-i2c", .of_match_table = of_match_ptr(st_accel_of_match), + .acpi_match_table = ACPI_PTR(st_accel_acpi_match), }, .probe = st_accel_i2c_probe, .remove = st_accel_i2c_remove, diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index c25ac50d4600..29a15f27a51b 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -65,9 +65,18 @@ static const struct spi_device_id st_accel_id_table[] = { }; MODULE_DEVICE_TABLE(spi, st_accel_id_table); +#ifdef CONFIG_OF +static const struct of_device_id lis302dl_spi_dt_ids[] = { + { .compatible = "st,lis302dl-spi" }, + {} +}; +MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids); +#endif + static struct spi_driver st_accel_driver = { .driver = { .name = "st-accel-spi", + .of_match_table = of_match_ptr(lis302dl_spi_dt_ids), }, .probe = st_accel_spi_probe, .remove = st_accel_spi_remove, diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 9c8b558ba19e..dedae7adbce9 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -247,6 +247,25 @@ config HI8435 This driver can also be built as a module. If so, the module will be called hi8435. +config HX711 + tristate "AVIA HX711 ADC for weight cells" + depends on GPIOLIB + help + If you say yes here you get support for AVIA HX711 ADC which is used + for weigh cells + + This driver uses two GPIOs, one acts as the clock and controls the + channel selection and gain, the other one is used for the measurement + data + + Currently the raw value is read from the chip and delivered. + To get an actual weight one needs to subtract the + zero offset and multiply by a scale factor. + This should be done in userspace. + + This driver can also be built as a module. If so, the module will be + called hx711. + config INA2XX_ADC tristate "Texas Instruments INA2xx Power Monitors IIO driver" depends on I2C && !SENSORS_INA2XX @@ -307,6 +326,15 @@ config MAX1027 To compile this driver as a module, choose M here: the module will be called max1027. +config MAX11100 + tristate "Maxim max11100 ADC driver" + depends on SPI_MASTER + help + Say yes here to build support for Maxim max11100 SPI ADC + + To compile this driver as a module, choose M here: the module will be + called max11100. + config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2C @@ -371,6 +399,18 @@ config MEN_Z188_ADC This driver can also be built as a module. If so, the module will be called men_z188_adc. +config MESON_SARADC + tristate "Amlogic Meson SAR ADC driver" + default ARCH_MESON + depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST) + select REGMAP_MMIO + help + Say yes here to build support for the SAR ADC found in Amlogic Meson + SoCs. + + To compile this driver as a module, choose M here: the + module will be called meson_saradc. + config MXS_LRADC tristate "Freescale i.MX23/i.MX28 LRADC" depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM @@ -430,6 +470,19 @@ config QCOM_SPMI_VADC To compile this driver as a module, choose M here: the module will be called qcom-spmi-vadc. +config RCAR_GYRO_ADC + tristate "Renesas R-Car GyroADC driver" + depends on ARCH_RCAR_GEN2 || (ARM && COMPILE_TEST) + help + Say yes here to build support for the GyroADC found in Renesas + R-Car Gen2 SoCs. This block is a simple SPI offload engine for + reading data out of attached compatible ADCs in a round-robin + fashion. Up to 4 or 8 ADC channels are supported by this block, + depending on which ADCs are attached. + + To compile this driver as a module, choose M here: the + module will be called rcar-gyroadc. + config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) @@ -444,8 +497,13 @@ config ROCKCHIP_SARADC config STM32_ADC_CORE tristate "STMicroelectronics STM32 adc core" depends on ARCH_STM32 || COMPILE_TEST + depends on HAS_DMA depends on OF depends on REGULATOR + select IIO_BUFFER + select MFD_STM32_TIMERS + select IIO_STM32_TIMER_TRIGGER + select IIO_TRIGGERED_BUFFER help Select this option to enable the core driver for STMicroelectronics STM32 analog-to-digital converter (ADC). @@ -549,6 +607,19 @@ config TI_ADS1015 This driver can also be built as a module. If so, the module will be called ti-ads1015. +config TI_ADS7950 + tristate "Texas Instruments ADS7950 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Texas Instruments ADS7950, ADS7951, + ADS7952, ADS7953, ADS7954, ADS7955, ADS7956, ADS7957, ADS7958, ADS7959. + ADS7960, ADS7961. + + To compile this driver as a module, choose M here: the + module will be called ti-ads7950. + config TI_ADS8688 tristate "Texas Instruments ADS8688" depends on SPI && OF @@ -571,6 +642,18 @@ config TI_AM335X_ADC To compile this driver as a module, choose M here: the module will be called ti_am335x_adc. +config TI_TLC4541 + tristate "Texas Instruments TLC4541 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Texas Instruments TLC4541 / TLC3541 + ADC chips. + + This driver can also be built as a module. If so, the module will be + called ti-tlc4541. + config TWL4030_MADC tristate "TWL4030 MADC (Monitoring A/D Converter)" depends on TWL4030_CORE diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index d36c4be8d1fc..d0012620cd1c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -25,22 +25,26 @@ obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o obj-$(CONFIG_HI8435) += hi8435.o +obj-$(CONFIG_HX711) += hx711.o obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o obj-$(CONFIG_LTC2485) += ltc2485.o obj-$(CONFIG_MAX1027) += max1027.o +obj-$(CONFIG_MAX11100) += max11100.o obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o +obj-$(CONFIG_MESON_SARADC) += meson_saradc.o obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o +obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_STX104) += stx104.o obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o @@ -51,8 +55,10 @@ obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o +obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o +obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o obj-$(CONFIG_VF610_ADC) += vf610_adc.o diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 7fd24949c0c1..64799ad7ebad 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -28,8 +28,6 @@ #include <linux/iio/driver.h> #define AXP288_ADC_EN_MASK 0xF1 -#define AXP288_ADC_TS_PIN_GPADC 0xF2 -#define AXP288_ADC_TS_PIN_ON 0xF3 enum axp288_adc_id { AXP288_ADC_TS, @@ -123,16 +121,6 @@ static int axp288_adc_read_channel(int *val, unsigned long address, return IIO_VAL_INT; } -static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode, - unsigned long address) -{ - /* channels other than GPADC do not need to switch TS pin */ - if (address != AXP288_GP_ADC_H) - return 0; - - return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode); -} - static int axp288_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -143,16 +131,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { case IIO_CHAN_INFO_RAW: - if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC, - chan->address)) { - dev_err(&indio_dev->dev, "GPADC mode\n"); - ret = -EINVAL; - break; - } ret = axp288_adc_read_channel(val, chan->address, info->regmap); - if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON, - chan->address)) - dev_err(&indio_dev->dev, "TS pin restore\n"); break; default: ret = -EINVAL; @@ -162,15 +141,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, return ret; } -static int axp288_adc_set_state(struct regmap *regmap) -{ - /* ADC should be always enabled for internal FG to function */ - if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON)) - return -EIO; - - return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); -} - static const struct iio_info axp288_adc_iio_info = { .read_raw = &axp288_adc_read_raw, .driver_module = THIS_MODULE, @@ -199,7 +169,7 @@ static int axp288_adc_probe(struct platform_device *pdev) * Set ADC to enabled state at all time, including system suspend. * otherwise internal fuel gauge functionality may be affected. */ - ret = axp288_adc_set_state(axp20x->regmap); + ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); if (ret) { dev_err(&pdev->dev, "unable to enable ADC device\n"); return ret; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index c15756d7bf7f..ad1775b5f83c 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -632,7 +632,7 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id) input_report_key(info->input, BTN_TOUCH, 1); input_sync(info->input); - msleep(1); + usleep_range(1000, 1100); }; writel(0, ADC_V1_CLRINTPNDNUP(info->regs)); diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c index 72b32c1ab257..ea264fa9e567 100644 --- a/drivers/iio/adc/fsl-imx25-gcq.c +++ b/drivers/iio/adc/fsl-imx25-gcq.c @@ -401,6 +401,7 @@ static const struct of_device_id mx25_gcq_ids[] = { { .compatible = "fsl,imx25-gcq", }, { /* Sentinel */ } }; +MODULE_DEVICE_TABLE(of, mx25_gcq_ids); static struct platform_driver mx25_gcq_driver = { .driver = { diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c new file mode 100644 index 000000000000..139639f73769 --- /dev/null +++ b/drivers/iio/adc/hx711.c @@ -0,0 +1,532 @@ +/* + * HX711: analog to digital converter for weight sensor module + * + * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de> + * + * 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/err.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/gpio/consumer.h> +#include <linux/regulator/consumer.h> + +/* gain to pulse and scale conversion */ +#define HX711_GAIN_MAX 3 + +struct hx711_gain_to_scale { + int gain; + int gain_pulse; + int scale; + int channel; +}; + +/* + * .scale depends on AVDD which in turn is known as soon as the regulator + * is available + * therefore we set .scale in hx711_probe() + * + * channel A in documentation is channel 0 in source code + * channel B in documentation is channel 1 in source code + */ +static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = { + { 128, 1, 0, 0 }, + { 32, 2, 0, 1 }, + { 64, 3, 0, 0 } +}; + +static int hx711_get_gain_to_pulse(int gain) +{ + int i; + + for (i = 0; i < HX711_GAIN_MAX; i++) + if (hx711_gain_to_scale[i].gain == gain) + return hx711_gain_to_scale[i].gain_pulse; + return 1; +} + +static int hx711_get_gain_to_scale(int gain) +{ + int i; + + for (i = 0; i < HX711_GAIN_MAX; i++) + if (hx711_gain_to_scale[i].gain == gain) + return hx711_gain_to_scale[i].scale; + return 0; +} + +static int hx711_get_scale_to_gain(int scale) +{ + int i; + + for (i = 0; i < HX711_GAIN_MAX; i++) + if (hx711_gain_to_scale[i].scale == scale) + return hx711_gain_to_scale[i].gain; + return -EINVAL; +} + +struct hx711_data { + struct device *dev; + struct gpio_desc *gpiod_pd_sck; + struct gpio_desc *gpiod_dout; + struct regulator *reg_avdd; + int gain_set; /* gain set on device */ + int gain_chan_a; /* gain for channel A */ + struct mutex lock; +}; + +static int hx711_cycle(struct hx711_data *hx711_data) +{ + int val; + + /* + * if preempted for more then 60us while PD_SCK is high: + * hx711 is going in reset + * ==> measuring is false + */ + preempt_disable(); + gpiod_set_value(hx711_data->gpiod_pd_sck, 1); + val = gpiod_get_value(hx711_data->gpiod_dout); + /* + * here we are not waiting for 0.2 us as suggested by the datasheet, + * because the oscilloscope showed in a test scenario + * at least 1.15 us for PD_SCK high (T3 in datasheet) + * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz + */ + gpiod_set_value(hx711_data->gpiod_pd_sck, 0); + preempt_enable(); + + return val; +} + +static int hx711_read(struct hx711_data *hx711_data) +{ + int i, ret; + int value = 0; + int val = gpiod_get_value(hx711_data->gpiod_dout); + + /* we double check if it's really down */ + if (val) + return -EIO; + + for (i = 0; i < 24; i++) { + value <<= 1; + ret = hx711_cycle(hx711_data); + if (ret) + value++; + } + + value ^= 0x800000; + + for (i = 0; i < hx711_get_gain_to_pulse(hx711_data->gain_set); i++) + hx711_cycle(hx711_data); + + return value; +} + +static int hx711_wait_for_ready(struct hx711_data *hx711_data) +{ + int i, val; + + /* + * a maximum reset cycle time of 56 ms was measured. + * we round it up to 100 ms + */ + for (i = 0; i < 100; i++) { + val = gpiod_get_value(hx711_data->gpiod_dout); + if (!val) + break; + /* sleep at least 1 ms */ + msleep(1); + } + if (val) + return -EIO; + + return 0; +} + +static int hx711_reset(struct hx711_data *hx711_data) +{ + int ret; + int val = gpiod_get_value(hx711_data->gpiod_dout); + + if (val) { + /* + * an examination with the oszilloscope indicated + * that the first value read after the reset is not stable + * if we reset too short; + * the shorter the reset cycle + * the less reliable the first value after reset is; + * there were no problems encountered with a value + * of 10 ms or higher + */ + gpiod_set_value(hx711_data->gpiod_pd_sck, 1); + msleep(10); + gpiod_set_value(hx711_data->gpiod_pd_sck, 0); + + ret = hx711_wait_for_ready(hx711_data); + if (ret) + return ret; + /* + * after a reset the gain is 128 so we do a dummy read + * to set the gain for the next read + */ + ret = hx711_read(hx711_data); + if (ret < 0) + return ret; + + /* + * after a dummy read we need to wait vor readiness + * for not mixing gain pulses with the clock + */ + ret = hx711_wait_for_ready(hx711_data); + if (ret) + return ret; + } + + return val; +} + +static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan) +{ + int ret; + + if (chan == 0) { + if (hx711_data->gain_set == 32) { + hx711_data->gain_set = hx711_data->gain_chan_a; + + ret = hx711_read(hx711_data); + if (ret < 0) + return ret; + + ret = hx711_wait_for_ready(hx711_data); + if (ret) + return ret; + } + } else { + if (hx711_data->gain_set != 32) { + hx711_data->gain_set = 32; + + ret = hx711_read(hx711_data); + if (ret < 0) + return ret; + + ret = hx711_wait_for_ready(hx711_data); + if (ret) + return ret; + } + } + + return 0; +} + +static int hx711_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct hx711_data *hx711_data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&hx711_data->lock); + + /* + * hx711_reset() must be called from here + * because it could be calling hx711_read() by itself + */ + if (hx711_reset(hx711_data)) { + mutex_unlock(&hx711_data->lock); + dev_err(hx711_data->dev, "reset failed!"); + return -EIO; + } + + ret = hx711_set_gain_for_channel(hx711_data, chan->channel); + if (ret < 0) { + mutex_unlock(&hx711_data->lock); + return ret; + } + + *val = hx711_read(hx711_data); + + mutex_unlock(&hx711_data->lock); + + if (*val < 0) + return *val; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + mutex_lock(&hx711_data->lock); + + *val2 = hx711_get_gain_to_scale(hx711_data->gain_set); + + mutex_unlock(&hx711_data->lock); + + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int hx711_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct hx711_data *hx711_data = iio_priv(indio_dev); + int ret; + int gain; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + /* + * a scale greater than 1 mV per LSB is not possible + * with the HX711, therefore val must be 0 + */ + if (val != 0) + return -EINVAL; + + mutex_lock(&hx711_data->lock); + + gain = hx711_get_scale_to_gain(val2); + if (gain < 0) { + mutex_unlock(&hx711_data->lock); + return gain; + } + + if (gain != hx711_data->gain_set) { + hx711_data->gain_set = gain; + if (gain != 32) + hx711_data->gain_chan_a = gain; + + ret = hx711_read(hx711_data); + if (ret < 0) { + mutex_unlock(&hx711_data->lock); + return ret; + } + } + + mutex_unlock(&hx711_data->lock); + return 0; + default: + return -EINVAL; + } + + return 0; +} + +static int hx711_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_NANO; +} + +static ssize_t hx711_scale_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr); + int channel = iio_attr->address; + int i, len = 0; + + for (i = 0; i < HX711_GAIN_MAX; i++) + if (hx711_gain_to_scale[i].channel == channel) + len += sprintf(buf + len, "0.%09d ", + hx711_gain_to_scale[i].scale); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR(in_voltage0_scale_available, S_IRUGO, + hx711_scale_available_show, NULL, 0); + +static IIO_DEVICE_ATTR(in_voltage1_scale_available, S_IRUGO, + hx711_scale_available_show, NULL, 1); + +static struct attribute *hx711_attributes[] = { + &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr, + NULL, +}; + +static struct attribute_group hx711_attribute_group = { + .attrs = hx711_attributes, +}; + +static const struct iio_info hx711_iio_info = { + .driver_module = THIS_MODULE, + .read_raw = hx711_read_raw, + .write_raw = hx711_write_raw, + .write_raw_get_fmt = hx711_write_raw_get_fmt, + .attrs = &hx711_attribute_group, +}; + +static const struct iio_chan_spec hx711_chan_spec[] = { + { + .type = IIO_VOLTAGE, + .channel = 0, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_VOLTAGE, + .channel = 1, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static int hx711_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hx711_data *hx711_data; + struct iio_dev *indio_dev; + int ret; + int i; + + indio_dev = devm_iio_device_alloc(dev, sizeof(struct hx711_data)); + if (!indio_dev) { + dev_err(dev, "failed to allocate IIO device\n"); + return -ENOMEM; + } + + hx711_data = iio_priv(indio_dev); + hx711_data->dev = dev; + + mutex_init(&hx711_data->lock); + + /* + * PD_SCK stands for power down and serial clock input of HX711 + * in the driver it is an output + */ + hx711_data->gpiod_pd_sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); + if (IS_ERR(hx711_data->gpiod_pd_sck)) { + dev_err(dev, "failed to get sck-gpiod: err=%ld\n", + PTR_ERR(hx711_data->gpiod_pd_sck)); + return PTR_ERR(hx711_data->gpiod_pd_sck); + } + + /* + * DOUT stands for serial data output of HX711 + * for the driver it is an input + */ + hx711_data->gpiod_dout = devm_gpiod_get(dev, "dout", GPIOD_IN); + if (IS_ERR(hx711_data->gpiod_dout)) { + dev_err(dev, "failed to get dout-gpiod: err=%ld\n", + PTR_ERR(hx711_data->gpiod_dout)); + return PTR_ERR(hx711_data->gpiod_dout); + } + + hx711_data->reg_avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(hx711_data->reg_avdd)) + return PTR_ERR(hx711_data->reg_avdd); + + ret = regulator_enable(hx711_data->reg_avdd); + if (ret < 0) + return ret; + + /* + * with + * full scale differential input range: AVDD / GAIN + * full scale output data: 2^24 + * we can say: + * AVDD / GAIN = 2^24 + * therefore: + * 1 LSB = AVDD / GAIN / 2^24 + * AVDD is in uV, but we need 10^-9 mV + * approximately to fit into a 32 bit number: + * 1 LSB = (AVDD * 100) / GAIN / 1678 [10^-9 mV] + */ + ret = regulator_get_voltage(hx711_data->reg_avdd); + if (ret < 0) { + regulator_disable(hx711_data->reg_avdd); + return ret; + } + /* we need 10^-9 mV */ + ret *= 100; + + for (i = 0; i < HX711_GAIN_MAX; i++) + hx711_gain_to_scale[i].scale = + ret / hx711_gain_to_scale[i].gain / 1678; + + hx711_data->gain_set = 128; + hx711_data->gain_chan_a = 128; + + platform_set_drvdata(pdev, indio_dev); + + indio_dev->name = "hx711"; + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &hx711_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = hx711_chan_spec; + indio_dev->num_channels = ARRAY_SIZE(hx711_chan_spec); + + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "Couldn't register the device\n"); + regulator_disable(hx711_data->reg_avdd); + } + + return ret; +} + +static int hx711_remove(struct platform_device *pdev) +{ + struct hx711_data *hx711_data; + struct iio_dev *indio_dev; + + indio_dev = platform_get_drvdata(pdev); + hx711_data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + regulator_disable(hx711_data->reg_avdd); + + return 0; +} + +static const struct of_device_id of_hx711_match[] = { + { .compatible = "avia,hx711", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, of_hx711_match); + +static struct platform_driver hx711_driver = { + .probe = hx711_probe, + .remove = hx711_remove, + .driver = { + .name = "hx711-gpio", + .of_match_table = of_hx711_match, + }, +}; + +module_platform_driver(hx711_driver); + +MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); +MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:hx711-gpio"); + diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 59b7d76e1ad2..3263231276ca 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -22,6 +22,8 @@ #include <linux/delay.h> #include <linux/i2c.h> +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include <linux/iio/sysfs.h> #include <linux/kthread.h> diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c new file mode 100644 index 000000000000..a088cf99bfe1 --- /dev/null +++ b/drivers/iio/adc/max11100.c @@ -0,0 +1,181 @@ +/* + * iio/adc/max11100.c + * Maxim max11100 ADC Driver with IIO interface + * + * Copyright (C) 2016-17 Renesas Electronics Corporation + * Copyright (C) 2016-17 Jacopo Mondi + * + * 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/delay.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/spi/spi.h> + +#include <linux/iio/iio.h> +#include <linux/iio/driver.h> + +/* + * LSB is the ADC single digital step + * 1 LSB = (vref_mv / 2 ^ 16) + * + * LSB is used to calculate analog voltage value + * from the number of ADC steps count + * + * Ain = (count * LSB) + */ +#define MAX11100_LSB_DIV (1 << 16) + +struct max11100_state { + struct regulator *vref_reg; + struct spi_device *spi; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 buffer[3] ____cacheline_aligned; +}; + +static struct iio_chan_spec max11100_channels[] = { + { /* [0] */ + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static int max11100_read_single(struct iio_dev *indio_dev, int *val) +{ + int ret; + struct max11100_state *state = iio_priv(indio_dev); + + ret = spi_read(state->spi, state->buffer, sizeof(state->buffer)); + if (ret) { + dev_err(&indio_dev->dev, "SPI transfer failed\n"); + return ret; + } + + /* the first 8 bits sent out from ADC must be 0s */ + if (state->buffer[0]) { + dev_err(&indio_dev->dev, "Invalid value: buffer[0] != 0\n"); + return -EINVAL; + } + + *val = (state->buffer[1] << 8) | state->buffer[2]; + + return 0; +} + +static int max11100_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + int ret, vref_uv; + struct max11100_state *state = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + ret = max11100_read_single(indio_dev, val); + if (ret) + return ret; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + vref_uv = regulator_get_voltage(state->vref_reg); + if (vref_uv < 0) + /* dummy regulator "get_voltage" returns -EINVAL */ + return -EINVAL; + + *val = vref_uv / 1000; + *val2 = MAX11100_LSB_DIV; + return IIO_VAL_FRACTIONAL; + } + + return -EINVAL; +} + +static const struct iio_info max11100_info = { + .driver_module = THIS_MODULE, + .read_raw = max11100_read_raw, +}; + +static int max11100_probe(struct spi_device *spi) +{ + int ret; + struct iio_dev *indio_dev; + struct max11100_state *state; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + spi_set_drvdata(spi, indio_dev); + + state = iio_priv(indio_dev); + state->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->dev.of_node = spi->dev.of_node; + indio_dev->name = "max11100"; + indio_dev->info = &max11100_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = max11100_channels, + indio_dev->num_channels = ARRAY_SIZE(max11100_channels), + + state->vref_reg = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(state->vref_reg)) + return PTR_ERR(state->vref_reg); + + ret = regulator_enable(state->vref_reg); + if (ret) + return ret; + + ret = iio_device_register(indio_dev); + if (ret) + goto disable_regulator; + + return 0; + +disable_regulator: + regulator_disable(state->vref_reg); + + return ret; +} + +static int max11100_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct max11100_state *state = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + regulator_disable(state->vref_reg); + + return 0; +} + +static const struct of_device_id max11100_ids[] = { + {.compatible = "maxim,max11100"}, + { }, +}; +MODULE_DEVICE_TABLE(of, max11100_ids); + +static struct spi_driver max11100_driver = { + .driver = { + .name = "max11100", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(max11100_ids), + }, + .probe = max11100_probe, + .remove = max11100_remove, +}; + +module_spi_driver(max11100_driver); + +MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>"); +MODULE_DESCRIPTION("Maxim max11100 ADC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 841a13c9b6ea..c6c12feb4a08 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1567,6 +1567,7 @@ static const struct of_device_id max1363_of_match[] = { MAX1363_COMPATIBLE("maxim,max11647", max11647), { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, max1363_of_match); #endif static int max1363_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c new file mode 100644 index 000000000000..89def6034f40 --- /dev/null +++ b/drivers/iio/adc/meson_saradc.c @@ -0,0 +1,922 @@ +/* + * Amlogic Meson Successive Approximation Register (SAR) A/D Converter + * + * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.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. + * + * 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/bitfield.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/iio/iio.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> + +#define MESON_SAR_ADC_REG0 0x00 + #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31) + #define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28) + #define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30) + #define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29) + #define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28) + #define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27) + #define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26) + #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21) + #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19) + #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16) + #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15) + #define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14) + #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12) + #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10) + #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9) + #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4) + #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3) + #define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2) + #define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1) + #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0) + +#define MESON_SAR_ADC_CHAN_LIST 0x04 + #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24) + #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \ + (GENMASK(2, 0) << ((_chan) * 3)) + +#define MESON_SAR_ADC_AVG_CNTL 0x08 + #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \ + (16 + ((_chan) * 2)) + #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \ + (GENMASK(17, 16) << ((_chan) * 2)) + #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \ + (0 + ((_chan) * 2)) + #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \ + (GENMASK(1, 0) << ((_chan) * 2)) + +#define MESON_SAR_ADC_REG3 0x0c + #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31) + #define MESON_SAR_ADC_REG3_CLK_EN BIT(30) + #define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28) + #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27) + #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26) + #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23) + #define MESON_SAR_ADC_REG3_DETECT_EN BIT(22) + #define MESON_SAR_ADC_REG3_ADC_EN BIT(21) + #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) + #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) + #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 + #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 + #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) + #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0) + +#define MESON_SAR_ADC_DELAY 0x10 + #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24) + #define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15) + #define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14) + #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16) + #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8) + #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0) + +#define MESON_SAR_ADC_LAST_RD 0x14 + #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16) + #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0) + +#define MESON_SAR_ADC_FIFO_RD 0x18 + #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12) + #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0) + +#define MESON_SAR_ADC_AUX_SW 0x1c + #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \ + (GENMASK(10, 8) << (((_chan) - 2) * 2)) + #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6) + #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5) + #define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4) + #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3) + #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2) + #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1) + #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0) + +#define MESON_SAR_ADC_CHAN_10_SW 0x20 + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1) + #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0) + +#define MESON_SAR_ADC_DETECT_IDLE_SW 0x24 + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17) + #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1) + #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0) + +#define MESON_SAR_ADC_DELTA_10 0x28 + #define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27) + #define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26) + #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16) + #define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15) + #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11 + #define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11) + #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10) + #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0) + +/* + * NOTE: registers from here are undocumented (the vendor Linux kernel driver + * and u-boot source served as reference). These only seem to be relevant on + * GXBB and newer. + */ +#define MESON_SAR_ADC_REG11 0x2c + #define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13) + +#define MESON_SAR_ADC_REG13 0x34 + #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8) + +#define MESON_SAR_ADC_MAX_FIFO_SIZE 32 + +#define MESON_SAR_ADC_CHAN(_chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .datasheet_name = "SAR_ADC_CH"#_chan, \ +} + +/* + * TODO: the hardware supports IIO_TEMP for channel 6 as well which is + * currently not supported by this driver. + */ +static const struct iio_chan_spec meson_sar_adc_iio_channels[] = { + MESON_SAR_ADC_CHAN(0), + MESON_SAR_ADC_CHAN(1), + MESON_SAR_ADC_CHAN(2), + MESON_SAR_ADC_CHAN(3), + MESON_SAR_ADC_CHAN(4), + MESON_SAR_ADC_CHAN(5), + MESON_SAR_ADC_CHAN(6), + MESON_SAR_ADC_CHAN(7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +enum meson_sar_adc_avg_mode { + NO_AVERAGING = 0x0, + MEAN_AVERAGING = 0x1, + MEDIAN_AVERAGING = 0x2, +}; + +enum meson_sar_adc_num_samples { + ONE_SAMPLE = 0x0, + TWO_SAMPLES = 0x1, + FOUR_SAMPLES = 0x2, + EIGHT_SAMPLES = 0x3, +}; + +enum meson_sar_adc_chan7_mux_sel { + CHAN7_MUX_VSS = 0x0, + CHAN7_MUX_VDD_DIV4 = 0x1, + CHAN7_MUX_VDD_DIV2 = 0x2, + CHAN7_MUX_VDD_MUL3_DIV4 = 0x3, + CHAN7_MUX_VDD = 0x4, + CHAN7_MUX_CH7_INPUT = 0x7, +}; + +struct meson_sar_adc_data { + unsigned int resolution; + const char *name; +}; + +struct meson_sar_adc_priv { + struct regmap *regmap; + struct regulator *vref; + const struct meson_sar_adc_data *data; + struct clk *clkin; + struct clk *core_clk; + struct clk *sana_clk; + struct clk *adc_sel_clk; + struct clk *adc_clk; + struct clk_gate clk_gate; + struct clk *adc_div_clk; + struct clk_divider clk_div; +}; + +static const struct regmap_config meson_sar_adc_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + .reg_stride = 4, + .max_register = MESON_SAR_ADC_REG13, +}; + +static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + u32 regval; + + regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); + + return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval); +} + +static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int regval, timeout = 10000; + + /* + * NOTE: we need a small delay before reading the status, otherwise + * the sample engine may not have started internally (which would + * seem to us that sampling is already finished). + */ + do { + udelay(1); + regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val); + } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--); + + if (timeout < 0) + return -ETIMEDOUT; + + return 0; +} + +static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0; + + ret = meson_sar_adc_wait_busy_clear(indio_dev); + if (ret) + return ret; + + while (meson_sar_adc_get_fifo_count(indio_dev) > 0 && + count < MESON_SAR_ADC_MAX_FIFO_SIZE) { + regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, ®val); + + fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, + regval); + if (fifo_chan != chan->channel) + continue; + + fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, + regval); + fifo_val &= (BIT(priv->data->resolution) - 1); + + sum += fifo_val; + count++; + } + + if (!count) + return -ENOENT; + + *val = sum / count; + + return 0; +} + +static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum meson_sar_adc_avg_mode mode, + enum meson_sar_adc_num_samples samples) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int val, channel = chan->channel; + + val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, + MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel), + val); + + val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, + MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val); +} + +static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + u32 regval; + + /* + * the SAR ADC engine allows sampling multiple channels at the same + * time. to keep it simple we're only working with one *internal* + * channel, which starts counting at index 0 (which means: count = 1). + */ + regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, + MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval); + + /* map channel index 0 to the channel which we want to read */ + regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), + chan->channel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, + MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval); + + regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, + chan->channel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, + MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK, + regval); + + regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, + chan->channel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, + MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, + regval); + + if (chan->channel == 6) + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, + MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0); +} + +static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev, + enum meson_sar_adc_chan7_mux_sel sel) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + u32 regval; + + regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval); + + usleep_range(10, 20); +} + +static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, + MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, + MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, + MESON_SAR_ADC_REG0_SAMPLING_START, + MESON_SAR_ADC_REG0_SAMPLING_START); +} + +static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, + MESON_SAR_ADC_REG0_SAMPLING_STOP, + MESON_SAR_ADC_REG0_SAMPLING_STOP); + + /* wait until all modules are stopped */ + meson_sar_adc_wait_busy_clear(indio_dev); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, + MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0); +} + +static int meson_sar_adc_lock(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int val, timeout = 10000; + + mutex_lock(&indio_dev->mlock); + + /* prevent BL30 from using the SAR ADC while we are using it */ + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_KERNEL_BUSY, + MESON_SAR_ADC_DELAY_KERNEL_BUSY); + + /* wait until BL30 releases it's lock (so we can use the SAR ADC) */ + do { + udelay(1); + regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); + } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--); + + if (timeout < 0) + return -ETIMEDOUT; + + return 0; +} + +static void meson_sar_adc_unlock(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + + /* allow BL30 to use the SAR ADC again */ + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); + + mutex_unlock(&indio_dev->mlock); +} + +static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int count; + + for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) { + if (!meson_sar_adc_get_fifo_count(indio_dev)) + break; + + regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0); + } +} + +static int meson_sar_adc_get_sample(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum meson_sar_adc_avg_mode avg_mode, + enum meson_sar_adc_num_samples avg_samples, + int *val) +{ + int ret; + + ret = meson_sar_adc_lock(indio_dev); + if (ret) + return ret; + + /* clear the FIFO to make sure we're not reading old values */ + meson_sar_adc_clear_fifo(indio_dev); + + meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples); + + meson_sar_adc_enable_channel(indio_dev, chan); + + meson_sar_adc_start_sample_engine(indio_dev); + ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val); + meson_sar_adc_stop_sample_engine(indio_dev); + + meson_sar_adc_unlock(indio_dev); + + if (ret) { + dev_warn(indio_dev->dev.parent, + "failed to read sample for channel %d: %d\n", + chan->channel, ret); + return ret; + } + + return IIO_VAL_INT; +} + +static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING, + ONE_SAMPLE, val); + break; + + case IIO_CHAN_INFO_AVERAGE_RAW: + return meson_sar_adc_get_sample(indio_dev, chan, + MEAN_AVERAGING, EIGHT_SAMPLES, + val); + break; + + case IIO_CHAN_INFO_SCALE: + ret = regulator_get_voltage(priv->vref); + if (ret < 0) { + dev_err(indio_dev->dev.parent, + "failed to get vref voltage: %d\n", ret); + return ret; + } + + *val = ret / 1000; + *val2 = priv->data->resolution; + return IIO_VAL_FRACTIONAL_LOG2; + + default: + return -EINVAL; + } +} + +static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, + void __iomem *base) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + struct clk_init_data init; + const char *clk_parents[1]; + + init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div", + of_node_full_name(indio_dev->dev.of_node)); + init.flags = 0; + init.ops = &clk_divider_ops; + clk_parents[0] = __clk_get_name(priv->clkin); + init.parent_names = clk_parents; + init.num_parents = 1; + + priv->clk_div.reg = base + MESON_SAR_ADC_REG3; + priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT; + priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH; + priv->clk_div.hw.init = &init; + priv->clk_div.flags = 0; + + priv->adc_div_clk = devm_clk_register(&indio_dev->dev, + &priv->clk_div.hw); + if (WARN_ON(IS_ERR(priv->adc_div_clk))) + return PTR_ERR(priv->adc_div_clk); + + init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en", + of_node_full_name(indio_dev->dev.of_node)); + init.flags = CLK_SET_RATE_PARENT; + init.ops = &clk_gate_ops; + clk_parents[0] = __clk_get_name(priv->adc_div_clk); + init.parent_names = clk_parents; + init.num_parents = 1; + + priv->clk_gate.reg = base + MESON_SAR_ADC_REG3; + priv->clk_gate.bit_idx = fls(MESON_SAR_ADC_REG3_CLK_EN); + priv->clk_gate.hw.init = &init; + + priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw); + if (WARN_ON(IS_ERR(priv->adc_clk))) + return PTR_ERR(priv->adc_clk); + + return 0; +} + +static int meson_sar_adc_init(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int regval, ret; + + /* + * make sure we start at CH7 input since the other muxes are only used + * for internal calibration. + */ + meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); + + /* + * leave sampling delay and the input clocks as configured by BL30 to + * make sure BL30 gets the values it expects when reading the + * temperature sensor. + */ + regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); + if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) + return 0; + + meson_sar_adc_stop_sample_engine(indio_dev); + + /* update the channel 6 MUX to select the temperature sensor */ + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, + MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, + MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL); + + /* disable all channels by default */ + regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY, + MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY); + + /* delay between two samples = (10+1) * 1uS */ + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, + FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK, + 10)); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, + FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK, + 0)); + + /* delay between two samples = (10+1) * 1uS */ + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, + FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK, + 10)); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, + MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, + FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK, + 1)); + + ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); + if (ret) { + dev_err(indio_dev->dev.parent, + "failed to set adc parent to clkin\n"); + return ret; + } + + ret = clk_set_rate(priv->adc_clk, 1200000); + if (ret) { + dev_err(indio_dev->dev.parent, + "failed to set adc clock rate\n"); + return ret; + } + + return 0; +} + +static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int ret; + + ret = meson_sar_adc_lock(indio_dev); + if (ret) + goto err_lock; + + ret = regulator_enable(priv->vref); + if (ret < 0) { + dev_err(indio_dev->dev.parent, + "failed to enable vref regulator\n"); + goto err_vref; + } + + ret = clk_prepare_enable(priv->core_clk); + if (ret) { + dev_err(indio_dev->dev.parent, "failed to enable core clk\n"); + goto err_core_clk; + } + + ret = clk_prepare_enable(priv->sana_clk); + if (ret) { + dev_err(indio_dev->dev.parent, "failed to enable sana clk\n"); + goto err_sana_clk; + } + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, + MESON_SAR_ADC_REG11_BANDGAP_EN, + MESON_SAR_ADC_REG11_BANDGAP_EN); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_ADC_EN, + MESON_SAR_ADC_REG3_ADC_EN); + + udelay(5); + + ret = clk_prepare_enable(priv->adc_clk); + if (ret) { + dev_err(indio_dev->dev.parent, "failed to enable adc clk\n"); + goto err_adc_clk; + } + + meson_sar_adc_unlock(indio_dev); + + return 0; + +err_adc_clk: + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_ADC_EN, 0); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, + MESON_SAR_ADC_REG11_BANDGAP_EN, 0); + clk_disable_unprepare(priv->sana_clk); +err_sana_clk: + clk_disable_unprepare(priv->core_clk); +err_core_clk: + regulator_disable(priv->vref); +err_vref: + meson_sar_adc_unlock(indio_dev); +err_lock: + return ret; +} + +static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev) +{ + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); + int ret; + + ret = meson_sar_adc_lock(indio_dev); + if (ret) + return ret; + + clk_disable_unprepare(priv->adc_clk); + + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, + MESON_SAR_ADC_REG3_ADC_EN, 0); + regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, + MESON_SAR_ADC_REG11_BANDGAP_EN, 0); + + clk_disable_unprepare(priv->sana_clk); + clk_disable_unprepare(priv->core_clk); + + regulator_disable(priv->vref); + + meson_sar_adc_unlock(indio_dev); + + return 0; +} + +static const struct iio_info meson_sar_adc_iio_info = { + .read_raw = meson_sar_adc_iio_info_read_raw, + .driver_module = THIS_MODULE, +}; + +struct meson_sar_adc_data meson_sar_adc_gxbb_data = { + .resolution = 10, + .name = "meson-gxbb-saradc", +}; + +struct meson_sar_adc_data meson_sar_adc_gxl_data = { + .resolution = 12, + .name = "meson-gxl-saradc", +}; + +struct meson_sar_adc_data meson_sar_adc_gxm_data = { + .resolution = 12, + .name = "meson-gxm-saradc", +}; + +static const struct of_device_id meson_sar_adc_of_match[] = { + { + .compatible = "amlogic,meson-gxbb-saradc", + .data = &meson_sar_adc_gxbb_data, + }, { + .compatible = "amlogic,meson-gxl-saradc", + .data = &meson_sar_adc_gxl_data, + }, { + .compatible = "amlogic,meson-gxm-saradc", + .data = &meson_sar_adc_gxm_data, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); + +static int meson_sar_adc_probe(struct platform_device *pdev) +{ + struct meson_sar_adc_priv *priv; + struct iio_dev *indio_dev; + struct resource *res; + void __iomem *base; + const struct of_device_id *match; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); + if (!indio_dev) { + dev_err(&pdev->dev, "failed allocating iio device\n"); + return -ENOMEM; + } + + priv = iio_priv(indio_dev); + + match = of_match_device(meson_sar_adc_of_match, &pdev->dev); + priv->data = match->data; + + indio_dev->name = priv->data->name; + indio_dev->dev.parent = &pdev->dev; + indio_dev->dev.of_node = pdev->dev.of_node; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &meson_sar_adc_iio_info; + + indio_dev->channels = meson_sar_adc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &meson_sar_adc_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + priv->clkin = devm_clk_get(&pdev->dev, "clkin"); + if (IS_ERR(priv->clkin)) { + dev_err(&pdev->dev, "failed to get clkin\n"); + return PTR_ERR(priv->clkin); + } + + priv->core_clk = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(priv->core_clk)) { + dev_err(&pdev->dev, "failed to get core clk\n"); + return PTR_ERR(priv->core_clk); + } + + priv->sana_clk = devm_clk_get(&pdev->dev, "sana"); + if (IS_ERR(priv->sana_clk)) { + if (PTR_ERR(priv->sana_clk) == -ENOENT) { + priv->sana_clk = NULL; + } else { + dev_err(&pdev->dev, "failed to get sana clk\n"); + return PTR_ERR(priv->sana_clk); + } + } + + priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk"); + if (IS_ERR(priv->adc_clk)) { + if (PTR_ERR(priv->adc_clk) == -ENOENT) { + priv->adc_clk = NULL; + } else { + dev_err(&pdev->dev, "failed to get adc clk\n"); + return PTR_ERR(priv->adc_clk); + } + } + + priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel"); + if (IS_ERR(priv->adc_sel_clk)) { + if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) { + priv->adc_sel_clk = NULL; + } else { + dev_err(&pdev->dev, "failed to get adc_sel clk\n"); + return PTR_ERR(priv->adc_sel_clk); + } + } + + /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */ + if (!priv->adc_clk) { + ret = meson_sar_adc_clk_init(indio_dev, base); + if (ret) + return ret; + } + + priv->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(priv->vref)) { + dev_err(&pdev->dev, "failed to get vref regulator\n"); + return PTR_ERR(priv->vref); + } + + ret = meson_sar_adc_init(indio_dev); + if (ret) + goto err; + + ret = meson_sar_adc_hw_enable(indio_dev); + if (ret) + goto err; + + platform_set_drvdata(pdev, indio_dev); + + ret = iio_device_register(indio_dev); + if (ret) + goto err_hw; + + return 0; + +err_hw: + meson_sar_adc_hw_disable(indio_dev); +err: + return ret; +} + +static int meson_sar_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + iio_device_unregister(indio_dev); + + return meson_sar_adc_hw_disable(indio_dev); +} + +static int __maybe_unused meson_sar_adc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + return meson_sar_adc_hw_disable(indio_dev); +} + +static int __maybe_unused meson_sar_adc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + return meson_sar_adc_hw_enable(indio_dev); +} + +static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops, + meson_sar_adc_suspend, meson_sar_adc_resume); + +static struct platform_driver meson_sar_adc_driver = { + .probe = meson_sar_adc_probe, + .remove = meson_sar_adc_remove, + .driver = { + .name = "meson-saradc", + .of_match_table = meson_sar_adc_of_match, + .pm = &meson_sar_adc_pm_ops, + }, +}; + +module_platform_driver(meson_sar_adc_driver); + +MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); +MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index c2babe50a0d8..0a19761d656c 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. 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 version 2 and @@ -84,7 +84,7 @@ #define VADC_MAX_ADC_CODE 0xa800 #define VADC_ABSOLUTE_RANGE_UV 625000 -#define VADC_RATIOMETRIC_RANGE_UV 1800000 +#define VADC_RATIOMETRIC_RANGE 1800 #define VADC_DEF_PRESCALING 0 /* 1:1 */ #define VADC_DEF_DECIMATION 0 /* 512 */ @@ -100,9 +100,23 @@ #define KELVINMIL_CELSIUSMIL 273150 +#define PMI_CHG_SCALE_1 -138890 +#define PMI_CHG_SCALE_2 391750000000LL + #define VADC_CHAN_MIN VADC_USBIN #define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM +/** + * struct vadc_map_pt - Map the graph representation for ADC channel + * @x: Represent the ADC digitized code. + * @y: Represent the physical data which can be temperature, voltage, + * resistance. + */ +struct vadc_map_pt { + s32 x; + s32 y; +}; + /* * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels. * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for @@ -148,6 +162,9 @@ struct vadc_prescale_ratio { * start of conversion. * @avg_samples: ability to provide single result from the ADC * that is an average of multiple measurements. + * @scale_fn: Represents the scaling function to convert voltage + * physical units desired by the client for the channel. + * Referenced from enum vadc_scale_fn_type. */ struct vadc_channel_prop { unsigned int channel; @@ -156,6 +173,7 @@ struct vadc_channel_prop { unsigned int prescale; unsigned int hw_settle_time; unsigned int avg_samples; + unsigned int scale_fn; }; /** @@ -186,6 +204,35 @@ struct vadc_priv { struct mutex lock; }; +/** + * struct vadc_scale_fn - Scaling function prototype + * @scale: Function pointer to one of the scaling functions + * which takes the adc properties, channel properties, + * and returns the physical result. + */ +struct vadc_scale_fn { + int (*scale)(struct vadc_priv *, const struct vadc_channel_prop *, + u16, int *); +}; + +/** + * enum vadc_scale_fn_type - Scaling function to convert ADC code to + * physical scaled units for the channel. + * SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV). + * SCALE_THERM_100K_PULLUP: Returns temperature in millidegC. + * Uses a mapping table with 100K pullup. + * SCALE_PMIC_THERM: Returns result in milli degree's Centigrade. + * SCALE_XOTHERM: Returns XO thermistor voltage in millidegC. + * SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp + */ +enum vadc_scale_fn_type { + SCALE_DEFAULT = 0, + SCALE_THERM_100K_PULLUP, + SCALE_PMIC_THERM, + SCALE_XOTHERM, + SCALE_PMI_CHG_TEMP, +}; + static const struct vadc_prescale_ratio vadc_prescale_ratios[] = { {.num = 1, .den = 1}, {.num = 1, .den = 3}, @@ -197,6 +244,44 @@ static const struct vadc_prescale_ratio vadc_prescale_ratios[] = { {.num = 1, .den = 10} }; +/* Voltage to temperature */ +static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = { + {1758, -40}, + {1742, -35}, + {1719, -30}, + {1691, -25}, + {1654, -20}, + {1608, -15}, + {1551, -10}, + {1483, -5}, + {1404, 0}, + {1315, 5}, + {1218, 10}, + {1114, 15}, + {1007, 20}, + {900, 25}, + {795, 30}, + {696, 35}, + {605, 40}, + {522, 45}, + {448, 50}, + {383, 55}, + {327, 60}, + {278, 65}, + {237, 70}, + {202, 75}, + {172, 80}, + {146, 85}, + {125, 90}, + {107, 95}, + {92, 100}, + {79, 105}, + {68, 110}, + {59, 115}, + {51, 120}, + {44, 125} +}; + static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data) { return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1); @@ -418,7 +503,7 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc) u16 read_1, read_2; int ret; - vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE_UV; + vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; prop = vadc_get_channel(vadc, VADC_REF_1250MV); @@ -468,27 +553,148 @@ err: return ret; } -static s32 vadc_calibrate(struct vadc_priv *vadc, - const struct vadc_channel_prop *prop, u16 adc_code) +static int vadc_map_voltage_temp(const struct vadc_map_pt *pts, + u32 tablesize, s32 input, s64 *output) +{ + bool descending = 1; + u32 i = 0; + + if (!pts) + return -EINVAL; + + /* Check if table is descending or ascending */ + if (tablesize > 1) { + if (pts[0].x < pts[1].x) + descending = 0; + } + + while (i < tablesize) { + if ((descending) && (pts[i].x < input)) { + /* table entry is less than measured*/ + /* value and table is descending, stop */ + break; + } else if ((!descending) && + (pts[i].x > input)) { + /* table entry is greater than measured*/ + /*value and table is ascending, stop */ + break; + } + i++; + } + + if (i == 0) { + *output = pts[0].y; + } else if (i == tablesize) { + *output = pts[tablesize - 1].y; + } else { + /* result is between search_index and search_index-1 */ + /* interpolate linearly */ + *output = (((s32)((pts[i].y - pts[i - 1].y) * + (input - pts[i - 1].x)) / + (pts[i].x - pts[i - 1].x)) + + pts[i - 1].y); + } + + return 0; +} + +static void vadc_scale_calib(struct vadc_priv *vadc, u16 adc_code, + const struct vadc_channel_prop *prop, + s64 *scale_voltage) +{ + *scale_voltage = (adc_code - + vadc->graph[prop->calibration].gnd); + *scale_voltage *= vadc->graph[prop->calibration].dx; + *scale_voltage = div64_s64(*scale_voltage, + vadc->graph[prop->calibration].dy); + if (prop->calibration == VADC_CALIB_ABSOLUTE) + *scale_voltage += + vadc->graph[prop->calibration].dx; + + if (*scale_voltage < 0) + *scale_voltage = 0; +} + +static int vadc_scale_volt(struct vadc_priv *vadc, + const struct vadc_channel_prop *prop, u16 adc_code, + int *result_uv) { const struct vadc_prescale_ratio *prescale; - s64 voltage; + s64 voltage = 0, result = 0; - voltage = adc_code - vadc->graph[prop->calibration].gnd; - voltage *= vadc->graph[prop->calibration].dx; - voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); + vadc_scale_calib(vadc, adc_code, prop, &voltage); + + prescale = &vadc_prescale_ratios[prop->prescale]; + voltage = voltage * prescale->den; + result = div64_s64(voltage, prescale->num); + *result_uv = result; + + return 0; +} + +static int vadc_scale_therm(struct vadc_priv *vadc, + const struct vadc_channel_prop *prop, u16 adc_code, + int *result_mdec) +{ + s64 voltage = 0, result = 0; + + vadc_scale_calib(vadc, adc_code, prop, &voltage); if (prop->calibration == VADC_CALIB_ABSOLUTE) - voltage += vadc->graph[prop->calibration].dx; + voltage = div64_s64(voltage, 1000); + + vadc_map_voltage_temp(adcmap_100k_104ef_104fb, + ARRAY_SIZE(adcmap_100k_104ef_104fb), + voltage, &result); + result *= 1000; + *result_mdec = result; - if (voltage < 0) + return 0; +} + +static int vadc_scale_die_temp(struct vadc_priv *vadc, + const struct vadc_channel_prop *prop, + u16 adc_code, int *result_mdec) +{ + const struct vadc_prescale_ratio *prescale; + s64 voltage = 0; + u64 temp; /* Temporary variable for do_div */ + + vadc_scale_calib(vadc, adc_code, prop, &voltage); + + if (voltage > 0) { + prescale = &vadc_prescale_ratios[prop->prescale]; + temp = voltage * prescale->den; + do_div(temp, prescale->num * 2); + voltage = temp; + } else { voltage = 0; + } - prescale = &vadc_prescale_ratios[prop->prescale]; + voltage -= KELVINMIL_CELSIUSMIL; + *result_mdec = voltage; + + return 0; +} + +static int vadc_scale_chg_temp(struct vadc_priv *vadc, + const struct vadc_channel_prop *prop, + u16 adc_code, int *result_mdec) +{ + const struct vadc_prescale_ratio *prescale; + s64 voltage = 0, result = 0; + vadc_scale_calib(vadc, adc_code, prop, &voltage); + + prescale = &vadc_prescale_ratios[prop->prescale]; voltage = voltage * prescale->den; + voltage = div64_s64(voltage, prescale->num); + voltage = ((PMI_CHG_SCALE_1) * (voltage * 2)); + voltage = (voltage + PMI_CHG_SCALE_2); + result = div64_s64(voltage, 1000000); + *result_mdec = result; - return div64_s64(voltage, prescale->num); + return 0; } static int vadc_decimation_from_dt(u32 value) @@ -536,6 +742,14 @@ static int vadc_avg_samples_from_dt(u32 value) return __ffs64(value); } +static struct vadc_scale_fn scale_fn[] = { + [SCALE_DEFAULT] = {vadc_scale_volt}, + [SCALE_THERM_100K_PULLUP] = {vadc_scale_therm}, + [SCALE_PMIC_THERM] = {vadc_scale_die_temp}, + [SCALE_XOTHERM] = {vadc_scale_therm}, + [SCALE_PMI_CHG_TEMP] = {vadc_scale_chg_temp}, +}; + static int vadc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -552,11 +766,8 @@ static int vadc_read_raw(struct iio_dev *indio_dev, if (ret) break; - *val = vadc_calibrate(vadc, prop, adc_code); + scale_fn[prop->scale_fn].scale(vadc, prop, adc_code, val); - /* 2mV/K, return milli Celsius */ - *val /= 2; - *val -= KELVINMIL_CELSIUSMIL; return IIO_VAL_INT; case IIO_CHAN_INFO_RAW: prop = &vadc->chan_props[chan->address]; @@ -564,12 +775,8 @@ static int vadc_read_raw(struct iio_dev *indio_dev, if (ret) break; - *val = vadc_calibrate(vadc, prop, adc_code); + *val = (int)adc_code; return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - *val = 0; - *val2 = 1000; - return IIO_VAL_INT_PLUS_MICRO; default: ret = -EINVAL; break; @@ -602,22 +809,39 @@ struct vadc_channels { unsigned int prescale_index; enum iio_chan_type type; long info_mask; + unsigned int scale_fn; }; -#define VADC_CHAN(_dname, _type, _mask, _pre) \ +#define VADC_CHAN(_dname, _type, _mask, _pre, _scale) \ [VADC_##_dname] = { \ .datasheet_name = __stringify(_dname), \ .prescale_index = _pre, \ .type = _type, \ - .info_mask = _mask \ + .info_mask = _mask, \ + .scale_fn = _scale \ }, \ -#define VADC_CHAN_TEMP(_dname, _pre) \ - VADC_CHAN(_dname, IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre) \ +#define VADC_NO_CHAN(_dname, _type, _mask, _pre) \ + [VADC_##_dname] = { \ + .datasheet_name = __stringify(_dname), \ + .prescale_index = _pre, \ + .type = _type, \ + .info_mask = _mask \ + }, -#define VADC_CHAN_VOLT(_dname, _pre) \ +#define VADC_CHAN_TEMP(_dname, _pre, _scale) \ + VADC_CHAN(_dname, IIO_TEMP, \ + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED), \ + _pre, _scale) \ + +#define VADC_CHAN_VOLT(_dname, _pre, _scale) \ VADC_CHAN(_dname, IIO_VOLTAGE, \ - BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED),\ + _pre, _scale) \ + +#define VADC_CHAN_NO_SCALE(_dname, _pre) \ + VADC_NO_CHAN(_dname, IIO_VOLTAGE, \ + BIT(IIO_CHAN_INFO_RAW), \ _pre) \ /* @@ -626,106 +850,106 @@ struct vadc_channels { * gaps in the array should be treated as reserved channels. */ static const struct vadc_channels vadc_chans[] = { - VADC_CHAN_VOLT(USBIN, 4) - VADC_CHAN_VOLT(DCIN, 4) - VADC_CHAN_VOLT(VCHG_SNS, 3) - VADC_CHAN_VOLT(SPARE1_03, 1) - VADC_CHAN_VOLT(USB_ID_MV, 1) - VADC_CHAN_VOLT(VCOIN, 1) - VADC_CHAN_VOLT(VBAT_SNS, 1) - VADC_CHAN_VOLT(VSYS, 1) - VADC_CHAN_TEMP(DIE_TEMP, 0) - VADC_CHAN_VOLT(REF_625MV, 0) - VADC_CHAN_VOLT(REF_1250MV, 0) - VADC_CHAN_VOLT(CHG_TEMP, 0) - VADC_CHAN_VOLT(SPARE1, 0) - VADC_CHAN_VOLT(SPARE2, 0) - VADC_CHAN_VOLT(GND_REF, 0) - VADC_CHAN_VOLT(VDD_VADC, 0) - - VADC_CHAN_VOLT(P_MUX1_1_1, 0) - VADC_CHAN_VOLT(P_MUX2_1_1, 0) - VADC_CHAN_VOLT(P_MUX3_1_1, 0) - VADC_CHAN_VOLT(P_MUX4_1_1, 0) - VADC_CHAN_VOLT(P_MUX5_1_1, 0) - VADC_CHAN_VOLT(P_MUX6_1_1, 0) - VADC_CHAN_VOLT(P_MUX7_1_1, 0) - VADC_CHAN_VOLT(P_MUX8_1_1, 0) - VADC_CHAN_VOLT(P_MUX9_1_1, 0) - VADC_CHAN_VOLT(P_MUX10_1_1, 0) - VADC_CHAN_VOLT(P_MUX11_1_1, 0) - VADC_CHAN_VOLT(P_MUX12_1_1, 0) - VADC_CHAN_VOLT(P_MUX13_1_1, 0) - VADC_CHAN_VOLT(P_MUX14_1_1, 0) - VADC_CHAN_VOLT(P_MUX15_1_1, 0) - VADC_CHAN_VOLT(P_MUX16_1_1, 0) - - VADC_CHAN_VOLT(P_MUX1_1_3, 1) - VADC_CHAN_VOLT(P_MUX2_1_3, 1) - VADC_CHAN_VOLT(P_MUX3_1_3, 1) - VADC_CHAN_VOLT(P_MUX4_1_3, 1) - VADC_CHAN_VOLT(P_MUX5_1_3, 1) - VADC_CHAN_VOLT(P_MUX6_1_3, 1) - VADC_CHAN_VOLT(P_MUX7_1_3, 1) - VADC_CHAN_VOLT(P_MUX8_1_3, 1) - VADC_CHAN_VOLT(P_MUX9_1_3, 1) - VADC_CHAN_VOLT(P_MUX10_1_3, 1) - VADC_CHAN_VOLT(P_MUX11_1_3, 1) - VADC_CHAN_VOLT(P_MUX12_1_3, 1) - VADC_CHAN_VOLT(P_MUX13_1_3, 1) - VADC_CHAN_VOLT(P_MUX14_1_3, 1) - VADC_CHAN_VOLT(P_MUX15_1_3, 1) - VADC_CHAN_VOLT(P_MUX16_1_3, 1) - - VADC_CHAN_VOLT(LR_MUX1_BAT_THERM, 0) - VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_XO_THERM, 0) - VADC_CHAN_VOLT(LR_MUX4_AMUX_THM1, 0) - VADC_CHAN_VOLT(LR_MUX5_AMUX_THM2, 0) - VADC_CHAN_VOLT(LR_MUX6_AMUX_THM3, 0) - VADC_CHAN_VOLT(LR_MUX7_HW_ID, 0) - VADC_CHAN_VOLT(LR_MUX8_AMUX_THM4, 0) - VADC_CHAN_VOLT(LR_MUX9_AMUX_THM5, 0) - VADC_CHAN_VOLT(LR_MUX10_USB_ID, 0) - VADC_CHAN_VOLT(AMUX_PU1, 0) - VADC_CHAN_VOLT(AMUX_PU2, 0) - VADC_CHAN_VOLT(LR_MUX3_BUF_XO_THERM, 0) - - VADC_CHAN_VOLT(LR_MUX1_PU1_BAT_THERM, 0) - VADC_CHAN_VOLT(LR_MUX2_PU1_BAT_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_PU1_XO_THERM, 0) - VADC_CHAN_VOLT(LR_MUX4_PU1_AMUX_THM1, 0) - VADC_CHAN_VOLT(LR_MUX5_PU1_AMUX_THM2, 0) - VADC_CHAN_VOLT(LR_MUX6_PU1_AMUX_THM3, 0) - VADC_CHAN_VOLT(LR_MUX7_PU1_AMUX_HW_ID, 0) - VADC_CHAN_VOLT(LR_MUX8_PU1_AMUX_THM4, 0) - VADC_CHAN_VOLT(LR_MUX9_PU1_AMUX_THM5, 0) - VADC_CHAN_VOLT(LR_MUX10_PU1_AMUX_USB_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_XO_THERM, 0) - - VADC_CHAN_VOLT(LR_MUX1_PU2_BAT_THERM, 0) - VADC_CHAN_VOLT(LR_MUX2_PU2_BAT_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_PU2_XO_THERM, 0) - VADC_CHAN_VOLT(LR_MUX4_PU2_AMUX_THM1, 0) - VADC_CHAN_VOLT(LR_MUX5_PU2_AMUX_THM2, 0) - VADC_CHAN_VOLT(LR_MUX6_PU2_AMUX_THM3, 0) - VADC_CHAN_VOLT(LR_MUX7_PU2_AMUX_HW_ID, 0) - VADC_CHAN_VOLT(LR_MUX8_PU2_AMUX_THM4, 0) - VADC_CHAN_VOLT(LR_MUX9_PU2_AMUX_THM5, 0) - VADC_CHAN_VOLT(LR_MUX10_PU2_AMUX_USB_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_BUF_PU2_XO_THERM, 0) - - VADC_CHAN_VOLT(LR_MUX1_PU1_PU2_BAT_THERM, 0) - VADC_CHAN_VOLT(LR_MUX2_PU1_PU2_BAT_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_PU1_PU2_XO_THERM, 0) - VADC_CHAN_VOLT(LR_MUX4_PU1_PU2_AMUX_THM1, 0) - VADC_CHAN_VOLT(LR_MUX5_PU1_PU2_AMUX_THM2, 0) - VADC_CHAN_VOLT(LR_MUX6_PU1_PU2_AMUX_THM3, 0) - VADC_CHAN_VOLT(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0) - VADC_CHAN_VOLT(LR_MUX8_PU1_PU2_AMUX_THM4, 0) - VADC_CHAN_VOLT(LR_MUX9_PU1_PU2_AMUX_THM5, 0) - VADC_CHAN_VOLT(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0) - VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0) + VADC_CHAN_VOLT(USBIN, 4, SCALE_DEFAULT) + VADC_CHAN_VOLT(DCIN, 4, SCALE_DEFAULT) + VADC_CHAN_NO_SCALE(VCHG_SNS, 3) + VADC_CHAN_NO_SCALE(SPARE1_03, 1) + VADC_CHAN_NO_SCALE(USB_ID_MV, 1) + VADC_CHAN_VOLT(VCOIN, 1, SCALE_DEFAULT) + VADC_CHAN_NO_SCALE(VBAT_SNS, 1) + VADC_CHAN_VOLT(VSYS, 1, SCALE_DEFAULT) + VADC_CHAN_TEMP(DIE_TEMP, 0, SCALE_PMIC_THERM) + VADC_CHAN_VOLT(REF_625MV, 0, SCALE_DEFAULT) + VADC_CHAN_VOLT(REF_1250MV, 0, SCALE_DEFAULT) + VADC_CHAN_NO_SCALE(CHG_TEMP, 0) + VADC_CHAN_NO_SCALE(SPARE1, 0) + VADC_CHAN_TEMP(SPARE2, 0, SCALE_PMI_CHG_TEMP) + VADC_CHAN_VOLT(GND_REF, 0, SCALE_DEFAULT) + VADC_CHAN_VOLT(VDD_VADC, 0, SCALE_DEFAULT) + + VADC_CHAN_NO_SCALE(P_MUX1_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX2_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX3_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX4_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX5_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX6_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX7_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX8_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX9_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX10_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX11_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX12_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX13_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX14_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX15_1_1, 0) + VADC_CHAN_NO_SCALE(P_MUX16_1_1, 0) + + VADC_CHAN_NO_SCALE(P_MUX1_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX2_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX3_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX4_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX5_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX6_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX7_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX8_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX9_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX10_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX11_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX12_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX13_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX14_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX15_1_3, 1) + VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) + + VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) + VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) + VADC_CHAN_NO_SCALE(LR_MUX6_AMUX_THM3, 0) + VADC_CHAN_NO_SCALE(LR_MUX7_HW_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX8_AMUX_THM4, 0) + VADC_CHAN_NO_SCALE(LR_MUX9_AMUX_THM5, 0) + VADC_CHAN_NO_SCALE(LR_MUX10_USB_ID, 0) + VADC_CHAN_NO_SCALE(AMUX_PU1, 0) + VADC_CHAN_NO_SCALE(AMUX_PU2, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_BUF_XO_THERM, 0) + + VADC_CHAN_NO_SCALE(LR_MUX1_PU1_BAT_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX2_PU1_BAT_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_PU1_XO_THERM, 0) + VADC_CHAN_TEMP(LR_MUX4_PU1_AMUX_THM1, 0, SCALE_THERM_100K_PULLUP) + VADC_CHAN_TEMP(LR_MUX5_PU1_AMUX_THM2, 0, SCALE_THERM_100K_PULLUP) + VADC_CHAN_TEMP(LR_MUX6_PU1_AMUX_THM3, 0, SCALE_THERM_100K_PULLUP) + VADC_CHAN_NO_SCALE(LR_MUX7_PU1_AMUX_HW_ID, 0) + VADC_CHAN_TEMP(LR_MUX8_PU1_AMUX_THM4, 0, SCALE_THERM_100K_PULLUP) + VADC_CHAN_TEMP(LR_MUX9_PU1_AMUX_THM5, 0, SCALE_THERM_100K_PULLUP) + VADC_CHAN_NO_SCALE(LR_MUX10_PU1_AMUX_USB_ID, 0) + VADC_CHAN_TEMP(LR_MUX3_BUF_PU1_XO_THERM, 0, SCALE_XOTHERM) + + VADC_CHAN_NO_SCALE(LR_MUX1_PU2_BAT_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX2_PU2_BAT_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_PU2_XO_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX4_PU2_AMUX_THM1, 0) + VADC_CHAN_NO_SCALE(LR_MUX5_PU2_AMUX_THM2, 0) + VADC_CHAN_NO_SCALE(LR_MUX6_PU2_AMUX_THM3, 0) + VADC_CHAN_NO_SCALE(LR_MUX7_PU2_AMUX_HW_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX8_PU2_AMUX_THM4, 0) + VADC_CHAN_NO_SCALE(LR_MUX9_PU2_AMUX_THM5, 0) + VADC_CHAN_NO_SCALE(LR_MUX10_PU2_AMUX_USB_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU2_XO_THERM, 0) + + VADC_CHAN_NO_SCALE(LR_MUX1_PU1_PU2_BAT_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX2_PU1_PU2_BAT_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_PU1_PU2_XO_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX4_PU1_PU2_AMUX_THM1, 0) + VADC_CHAN_NO_SCALE(LR_MUX5_PU1_PU2_AMUX_THM2, 0) + VADC_CHAN_NO_SCALE(LR_MUX6_PU1_PU2_AMUX_THM3, 0) + VADC_CHAN_NO_SCALE(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX8_PU1_PU2_AMUX_THM4, 0) + VADC_CHAN_NO_SCALE(LR_MUX9_PU1_PU2_AMUX_THM5, 0) + VADC_CHAN_NO_SCALE(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0) + VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0) }; static int vadc_get_dt_channel_data(struct device *dev, @@ -844,6 +1068,7 @@ static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node) return ret; } + prop.scale_fn = vadc_chans[prop.channel].scale_fn; vadc->chan_props[index] = prop; vadc_chan = &vadc_chans[prop.channel]; diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c new file mode 100644 index 000000000000..0c44f72c32a8 --- /dev/null +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -0,0 +1,631 @@ +/* + * Renesas R-Car GyroADC driver + * + * Copyright 2016 Marek Vasut <marek.vasut@gmail.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. + * + * 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/platform_device.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/regulator/consumer.h> +#include <linux/of_platform.h> +#include <linux/err.h> +#include <linux/pm_runtime.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> + +#define DRIVER_NAME "rcar-gyroadc" + +/* GyroADC registers. */ +#define RCAR_GYROADC_MODE_SELECT 0x00 +#define RCAR_GYROADC_MODE_SELECT_1_MB88101A 0x0 +#define RCAR_GYROADC_MODE_SELECT_2_ADCS7476 0x1 +#define RCAR_GYROADC_MODE_SELECT_3_MAX1162 0x3 + +#define RCAR_GYROADC_START_STOP 0x04 +#define RCAR_GYROADC_START_STOP_START BIT(0) + +#define RCAR_GYROADC_CLOCK_LENGTH 0x08 +#define RCAR_GYROADC_1_25MS_LENGTH 0x0c + +#define RCAR_GYROADC_REALTIME_DATA(ch) (0x10 + ((ch) * 4)) +#define RCAR_GYROADC_100MS_ADDED_DATA(ch) (0x30 + ((ch) * 4)) +#define RCAR_GYROADC_10MS_AVG_DATA(ch) (0x50 + ((ch) * 4)) + +#define RCAR_GYROADC_FIFO_STATUS 0x70 +#define RCAR_GYROADC_FIFO_STATUS_EMPTY(ch) BIT(0 + (4 * (ch))) +#define RCAR_GYROADC_FIFO_STATUS_FULL(ch) BIT(1 + (4 * (ch))) +#define RCAR_GYROADC_FIFO_STATUS_ERROR(ch) BIT(2 + (4 * (ch))) + +#define RCAR_GYROADC_INTR 0x74 +#define RCAR_GYROADC_INTR_INT BIT(0) + +#define RCAR_GYROADC_INTENR 0x78 +#define RCAR_GYROADC_INTENR_INTEN BIT(0) + +#define RCAR_GYROADC_SAMPLE_RATE 800 /* Hz */ + +#define RCAR_GYROADC_RUNTIME_PM_DELAY_MS 2000 + +enum rcar_gyroadc_model { + RCAR_GYROADC_MODEL_DEFAULT, + RCAR_GYROADC_MODEL_R8A7792, +}; + +struct rcar_gyroadc { + struct device *dev; + void __iomem *regs; + struct clk *iclk; + struct regulator *vref[8]; + unsigned int num_channels; + enum rcar_gyroadc_model model; + unsigned int mode; + unsigned int sample_width; +}; + +static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv) +{ + const unsigned long clk_mhz = clk_get_rate(priv->iclk) / 1000000; + const unsigned long clk_mul = + (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5; + unsigned long clk_len = clk_mhz * clk_mul; + + /* + * According to the R-Car Gen2 datasheet Rev. 1.01, Sept 08 2014, + * page 77-7, clock length must be even number. If it's odd number, + * add one. + */ + if (clk_len & 1) + clk_len++; + + /* Stop the GyroADC. */ + writel(0, priv->regs + RCAR_GYROADC_START_STOP); + + /* Disable IRQ on V2H. */ + if (priv->model == RCAR_GYROADC_MODEL_R8A7792) + writel(0, priv->regs + RCAR_GYROADC_INTENR); + + /* Set mode and timing. */ + writel(priv->mode, priv->regs + RCAR_GYROADC_MODE_SELECT); + writel(clk_len, priv->regs + RCAR_GYROADC_CLOCK_LENGTH); + writel(clk_mhz * 1250, priv->regs + RCAR_GYROADC_1_25MS_LENGTH); +} + +static void rcar_gyroadc_hw_start(struct rcar_gyroadc *priv) +{ + /* Start sampling. */ + writel(RCAR_GYROADC_START_STOP_START, + priv->regs + RCAR_GYROADC_START_STOP); + + /* + * Wait for the first conversion to complete. This is longer than + * the 1.25 mS in the datasheet because 1.25 mS is not enough for + * the hardware to deliver the first sample and the hardware does + * then return zeroes instead of valid data. + */ + mdelay(3); +} + +static void rcar_gyroadc_hw_stop(struct rcar_gyroadc *priv) +{ + /* Stop the GyroADC. */ + writel(0, priv->regs + RCAR_GYROADC_START_STOP); +} + +#define RCAR_GYROADC_CHAN(_idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ +} + +static const struct iio_chan_spec rcar_gyroadc_iio_channels_1[] = { + RCAR_GYROADC_CHAN(0), + RCAR_GYROADC_CHAN(1), + RCAR_GYROADC_CHAN(2), + RCAR_GYROADC_CHAN(3), +}; + +static const struct iio_chan_spec rcar_gyroadc_iio_channels_2[] = { + RCAR_GYROADC_CHAN(0), + RCAR_GYROADC_CHAN(1), + RCAR_GYROADC_CHAN(2), + RCAR_GYROADC_CHAN(3), + RCAR_GYROADC_CHAN(4), + RCAR_GYROADC_CHAN(5), + RCAR_GYROADC_CHAN(6), + RCAR_GYROADC_CHAN(7), +}; + +static const struct iio_chan_spec rcar_gyroadc_iio_channels_3[] = { + RCAR_GYROADC_CHAN(0), + RCAR_GYROADC_CHAN(1), + RCAR_GYROADC_CHAN(2), + RCAR_GYROADC_CHAN(3), + RCAR_GYROADC_CHAN(4), + RCAR_GYROADC_CHAN(5), + RCAR_GYROADC_CHAN(6), + RCAR_GYROADC_CHAN(7), +}; + +static int rcar_gyroadc_set_power(struct rcar_gyroadc *priv, bool on) +{ + struct device *dev = priv->dev; + int ret; + + if (on) { + ret = pm_runtime_get_sync(dev); + if (ret < 0) + pm_runtime_put_noidle(dev); + } else { + pm_runtime_mark_last_busy(dev); + ret = pm_runtime_put_autosuspend(dev); + } + + return ret; +} + +static int rcar_gyroadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct rcar_gyroadc *priv = iio_priv(indio_dev); + struct regulator *consumer; + unsigned int datareg = RCAR_GYROADC_REALTIME_DATA(chan->channel); + unsigned int vref; + int ret; + + /* + * MB88101 is special in that it has only single regulator for + * all four channels. + */ + if (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) + consumer = priv->vref[0]; + else + consumer = priv->vref[chan->channel]; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (chan->type != IIO_VOLTAGE) + return -EINVAL; + + /* Channel not connected. */ + if (!consumer) + return -EINVAL; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + ret = rcar_gyroadc_set_power(priv, true); + if (ret < 0) { + iio_device_release_direct_mode(indio_dev); + return ret; + } + + *val = readl(priv->regs + datareg); + *val &= BIT(priv->sample_width) - 1; + + ret = rcar_gyroadc_set_power(priv, false); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* Channel not connected. */ + if (!consumer) + return -EINVAL; + + vref = regulator_get_voltage(consumer); + *val = vref / 1000; + *val2 = 1 << priv->sample_width; + + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = RCAR_GYROADC_SAMPLE_RATE; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int rcar_gyroadc_reg_access(struct iio_dev *indio_dev, + unsigned int reg, unsigned int writeval, + unsigned int *readval) +{ + struct rcar_gyroadc *priv = iio_priv(indio_dev); + unsigned int maxreg = RCAR_GYROADC_FIFO_STATUS; + + if (readval == NULL) + return -EINVAL; + + if (reg % 4) + return -EINVAL; + + /* Handle the V2H case with extra interrupt block. */ + if (priv->model == RCAR_GYROADC_MODEL_R8A7792) + maxreg = RCAR_GYROADC_INTENR; + + if (reg > maxreg) + return -EINVAL; + + *readval = readl(priv->regs + reg); + + return 0; +} + +static const struct iio_info rcar_gyroadc_iio_info = { + .driver_module = THIS_MODULE, + .read_raw = rcar_gyroadc_read_raw, + .debugfs_reg_access = rcar_gyroadc_reg_access, +}; + +static const struct of_device_id rcar_gyroadc_match[] = { + { + /* R-Car compatible GyroADC */ + .compatible = "renesas,rcar-gyroadc", + .data = (void *)RCAR_GYROADC_MODEL_DEFAULT, + }, { + /* R-Car V2H specialty with interrupt registers. */ + .compatible = "renesas,r8a7792-gyroadc", + .data = (void *)RCAR_GYROADC_MODEL_R8A7792, + }, { + /* sentinel */ + } +}; + +MODULE_DEVICE_TABLE(of, rcar_gyroadc_match); + +static const struct of_device_id rcar_gyroadc_child_match[] = { + /* Mode 1 ADCs */ + { + .compatible = "fujitsu,mb88101a", + .data = (void *)RCAR_GYROADC_MODE_SELECT_1_MB88101A, + }, + /* Mode 2 ADCs */ + { + .compatible = "ti,adcs7476", + .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476, + }, { + .compatible = "ti,adc121", + .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476, + }, { + .compatible = "adi,ad7476", + .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476, + }, + /* Mode 3 ADCs */ + { + .compatible = "maxim,max1162", + .data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162, + }, { + .compatible = "maxim,max11100", + .data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162, + }, + { /* sentinel */ } +}; + +static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) +{ + const struct of_device_id *of_id; + const struct iio_chan_spec *channels; + struct rcar_gyroadc *priv = iio_priv(indio_dev); + struct device *dev = priv->dev; + struct device_node *np = dev->of_node; + struct device_node *child; + struct regulator *vref; + unsigned int reg; + unsigned int adcmode, childmode; + unsigned int sample_width; + unsigned int num_channels; + int ret, first = 1; + + for_each_child_of_node(np, child) { + of_id = of_match_node(rcar_gyroadc_child_match, child); + if (!of_id) { + dev_err(dev, "Ignoring unsupported ADC \"%s\".", + child->name); + continue; + } + + childmode = (unsigned int)of_id->data; + switch (childmode) { + case RCAR_GYROADC_MODE_SELECT_1_MB88101A: + sample_width = 12; + channels = rcar_gyroadc_iio_channels_1; + num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_1); + break; + case RCAR_GYROADC_MODE_SELECT_2_ADCS7476: + sample_width = 15; + channels = rcar_gyroadc_iio_channels_2; + num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_2); + break; + case RCAR_GYROADC_MODE_SELECT_3_MAX1162: + sample_width = 16; + channels = rcar_gyroadc_iio_channels_3; + num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3); + break; + } + + /* + * MB88101 is special in that it's only a single chip taking + * up all the CHS lines. Thus, the DT binding is also special + * and has no reg property. If we run into such ADC, handle + * it here. + */ + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) { + reg = 0; + } else { + ret = of_property_read_u32(child, "reg", ®); + if (ret) { + dev_err(dev, + "Failed to get child reg property of ADC \"%s\".\n", + child->name); + return ret; + } + + /* Channel number is too high. */ + if (reg >= num_channels) { + dev_err(dev, + "Only %i channels supported with %s, but reg = <%i>.\n", + num_channels, child->name, reg); + return ret; + } + } + + /* Child node selected different mode than the rest. */ + if (!first && (adcmode != childmode)) { + dev_err(dev, + "Channel %i uses different ADC mode than the rest.\n", + reg); + return ret; + } + + /* Channel is valid, grab the regulator. */ + dev->of_node = child; + vref = devm_regulator_get(dev, "vref"); + dev->of_node = np; + if (IS_ERR(vref)) { + dev_dbg(dev, "Channel %i 'vref' supply not connected.\n", + reg); + return PTR_ERR(vref); + } + + priv->vref[reg] = vref; + + if (!first) + continue; + + /* First child node which passed sanity tests. */ + adcmode = childmode; + first = 0; + + priv->num_channels = num_channels; + priv->mode = childmode; + priv->sample_width = sample_width; + + indio_dev->channels = channels; + indio_dev->num_channels = num_channels; + + /* + * MB88101 is special and we only have one such device + * attached to the GyroADC at a time, so if we found it, + * we can stop parsing here. + */ + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) + break; + } + + if (first) { + dev_err(dev, "No valid ADC channels found, aborting.\n"); + return -EINVAL; + } + + return 0; +} + +static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev) +{ + struct rcar_gyroadc *priv = iio_priv(indio_dev); + unsigned int i; + + for (i = 0; i < priv->num_channels; i++) { + if (!priv->vref[i]) + continue; + + regulator_disable(priv->vref[i]); + } +} + +static int rcar_gyroadc_init_supplies(struct iio_dev *indio_dev) +{ + struct rcar_gyroadc *priv = iio_priv(indio_dev); + struct device *dev = priv->dev; + unsigned int i; + int ret; + + for (i = 0; i < priv->num_channels; i++) { + if (!priv->vref[i]) + continue; + + ret = regulator_enable(priv->vref[i]); + if (ret) { + dev_err(dev, "Failed to enable regulator %i (ret=%i)\n", + i, ret); + goto err; + } + } + + return 0; + +err: + rcar_gyroadc_deinit_supplies(indio_dev); + return ret; +} + +static int rcar_gyroadc_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(rcar_gyroadc_match, &pdev->dev); + struct device *dev = &pdev->dev; + struct rcar_gyroadc *priv; + struct iio_dev *indio_dev; + struct resource *mem; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) { + dev_err(dev, "Failed to allocate IIO device.\n"); + return -ENOMEM; + } + + priv = iio_priv(indio_dev); + priv->dev = dev; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(dev, mem); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + priv->iclk = devm_clk_get(dev, "if"); + if (IS_ERR(priv->iclk)) { + ret = PTR_ERR(priv->iclk); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret); + return ret; + } + + ret = rcar_gyroadc_parse_subdevs(indio_dev); + if (ret) + return ret; + + ret = rcar_gyroadc_init_supplies(indio_dev); + if (ret) + return ret; + + priv->model = (enum rcar_gyroadc_model)of_id->data; + + platform_set_drvdata(pdev, indio_dev); + + indio_dev->name = DRIVER_NAME; + indio_dev->dev.parent = dev; + indio_dev->dev.of_node = pdev->dev.of_node; + indio_dev->info = &rcar_gyroadc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = clk_prepare_enable(priv->iclk); + if (ret) { + dev_err(dev, "Could not prepare or enable the IF clock.\n"); + goto err_clk_if_enable; + } + + pm_runtime_set_autosuspend_delay(dev, RCAR_GYROADC_RUNTIME_PM_DELAY_MS); + pm_runtime_use_autosuspend(dev); + pm_runtime_enable(dev); + + pm_runtime_get_sync(dev); + rcar_gyroadc_hw_init(priv); + rcar_gyroadc_hw_start(priv); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(dev, "Couldn't register IIO device.\n"); + goto err_iio_device_register; + } + + pm_runtime_put_sync(dev); + + return 0; + +err_iio_device_register: + rcar_gyroadc_hw_stop(priv); + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + clk_disable_unprepare(priv->iclk); +err_clk_if_enable: + rcar_gyroadc_deinit_supplies(indio_dev); + + return ret; +} + +static int rcar_gyroadc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct rcar_gyroadc *priv = iio_priv(indio_dev); + struct device *dev = priv->dev; + + iio_device_unregister(indio_dev); + pm_runtime_get_sync(dev); + rcar_gyroadc_hw_stop(priv); + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + clk_disable_unprepare(priv->iclk); + rcar_gyroadc_deinit_supplies(indio_dev); + + return 0; +} + +#if defined(CONFIG_PM) +static int rcar_gyroadc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct rcar_gyroadc *priv = iio_priv(indio_dev); + + rcar_gyroadc_hw_stop(priv); + + return 0; +} + +static int rcar_gyroadc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct rcar_gyroadc *priv = iio_priv(indio_dev); + + rcar_gyroadc_hw_start(priv); + + return 0; +} +#endif + +static const struct dev_pm_ops rcar_gyroadc_pm_ops = { + SET_RUNTIME_PM_OPS(rcar_gyroadc_suspend, rcar_gyroadc_resume, NULL) +}; + +static struct platform_driver rcar_gyroadc_driver = { + .probe = rcar_gyroadc_probe, + .remove = rcar_gyroadc_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = rcar_gyroadc_match, + .pm = &rcar_gyroadc_pm_ops, + }, +}; + +module_platform_driver(rcar_gyroadc_driver); + +MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); +MODULE_DESCRIPTION("Renesas R-Car GyroADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 4214b0cd6b1b..22b7c9321e78 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -201,6 +201,7 @@ static int stm32_adc_probe(struct platform_device *pdev) priv->common.base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->common.base)) return PTR_ERR(priv->common.base); + priv->common.phys_base = res->start; priv->vref = devm_regulator_get(&pdev->dev, "vref"); if (IS_ERR(priv->vref)) { diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h index 081fa5f55015..2ec7abbfbcaa 100644 --- a/drivers/iio/adc/stm32-adc-core.h +++ b/drivers/iio/adc/stm32-adc-core.h @@ -42,10 +42,12 @@ /** * struct stm32_adc_common - stm32 ADC driver common data (for all instances) * @base: control registers base cpu addr + * @phys_base: control registers base physical addr * @vref_mv: vref voltage (mv) */ struct stm32_adc_common { void __iomem *base; + phys_addr_t phys_base; int vref_mv; }; diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 5715e79f4935..9b49a6addc2a 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -21,7 +21,14 @@ #include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/timer/stm32-timer-trigger.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> @@ -58,21 +65,71 @@ /* STM32F4_ADC_CR2 - bit fields */ #define STM32F4_SWSTART BIT(30) +#define STM32F4_EXTEN_SHIFT 28 #define STM32F4_EXTEN_MASK GENMASK(29, 28) +#define STM32F4_EXTSEL_SHIFT 24 +#define STM32F4_EXTSEL_MASK GENMASK(27, 24) #define STM32F4_EOCS BIT(10) +#define STM32F4_DDS BIT(9) +#define STM32F4_DMA BIT(8) #define STM32F4_ADON BIT(0) -/* STM32F4_ADC_SQR1 - bit fields */ -#define STM32F4_L_SHIFT 20 -#define STM32F4_L_MASK GENMASK(23, 20) - -/* STM32F4_ADC_SQR3 - bit fields */ -#define STM32F4_SQ1_SHIFT 0 -#define STM32F4_SQ1_MASK GENMASK(4, 0) - +#define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */ #define STM32_ADC_TIMEOUT_US 100000 #define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000)) +#define STM32_DMA_BUFFER_SIZE PAGE_SIZE + +/* External trigger enable */ +enum stm32_adc_exten { + STM32_EXTEN_SWTRIG, + STM32_EXTEN_HWTRIG_RISING_EDGE, + STM32_EXTEN_HWTRIG_FALLING_EDGE, + STM32_EXTEN_HWTRIG_BOTH_EDGES, +}; + +/* extsel - trigger mux selection value */ +enum stm32_adc_extsel { + STM32_EXT0, + STM32_EXT1, + STM32_EXT2, + STM32_EXT3, + STM32_EXT4, + STM32_EXT5, + STM32_EXT6, + STM32_EXT7, + STM32_EXT8, + STM32_EXT9, + STM32_EXT10, + STM32_EXT11, + STM32_EXT12, + STM32_EXT13, + STM32_EXT14, + STM32_EXT15, +}; + +/** + * struct stm32_adc_trig_info - ADC trigger info + * @name: name of the trigger, corresponding to its source + * @extsel: trigger selection + */ +struct stm32_adc_trig_info { + const char *name; + enum stm32_adc_extsel extsel; +}; + +/** + * stm32_adc_regs - stm32 ADC misc registers & bitfield desc + * @reg: register offset + * @mask: bitfield mask + * @shift: left shift + */ +struct stm32_adc_regs { + int reg; + int mask; + int shift; +}; + /** * struct stm32_adc - private data of each ADC IIO instance * @common: reference to ADC block common data @@ -82,15 +139,29 @@ * @clk: clock for this adc instance * @irq: interrupt for this adc instance * @lock: spinlock + * @bufi: data buffer index + * @num_conv: expected number of scan conversions + * @trigger_polarity: external trigger polarity (e.g. exten) + * @dma_chan: dma channel + * @rx_buf: dma rx buffer cpu address + * @rx_dma_buf: dma rx buffer bus address + * @rx_buf_sz: dma rx buffer size */ struct stm32_adc { struct stm32_adc_common *common; u32 offset; struct completion completion; - u16 *buffer; + u16 buffer[STM32_ADC_MAX_SQ]; struct clk *clk; int irq; spinlock_t lock; /* interrupt lock */ + unsigned int bufi; + unsigned int num_conv; + u32 trigger_polarity; + struct dma_chan *dma_chan; + u8 *rx_buf; + dma_addr_t rx_dma_buf; + unsigned int rx_buf_sz; }; /** @@ -126,6 +197,53 @@ static const struct stm32_adc_chan_spec stm32f4_adc123_channels[] = { }; /** + * stm32f4_sq - describe regular sequence registers + * - L: sequence len (register & bit field) + * - SQ1..SQ16: sequence entries (register & bit field) + */ +static const struct stm32_adc_regs stm32f4_sq[STM32_ADC_MAX_SQ + 1] = { + /* L: len bit field description to be kept as first element */ + { STM32F4_ADC_SQR1, GENMASK(23, 20), 20 }, + /* SQ1..SQ16 registers & bit fields (reg, mask, shift) */ + { STM32F4_ADC_SQR3, GENMASK(4, 0), 0 }, + { STM32F4_ADC_SQR3, GENMASK(9, 5), 5 }, + { STM32F4_ADC_SQR3, GENMASK(14, 10), 10 }, + { STM32F4_ADC_SQR3, GENMASK(19, 15), 15 }, + { STM32F4_ADC_SQR3, GENMASK(24, 20), 20 }, + { STM32F4_ADC_SQR3, GENMASK(29, 25), 25 }, + { STM32F4_ADC_SQR2, GENMASK(4, 0), 0 }, + { STM32F4_ADC_SQR2, GENMASK(9, 5), 5 }, + { STM32F4_ADC_SQR2, GENMASK(14, 10), 10 }, + { STM32F4_ADC_SQR2, GENMASK(19, 15), 15 }, + { STM32F4_ADC_SQR2, GENMASK(24, 20), 20 }, + { STM32F4_ADC_SQR2, GENMASK(29, 25), 25 }, + { STM32F4_ADC_SQR1, GENMASK(4, 0), 0 }, + { STM32F4_ADC_SQR1, GENMASK(9, 5), 5 }, + { STM32F4_ADC_SQR1, GENMASK(14, 10), 10 }, + { STM32F4_ADC_SQR1, GENMASK(19, 15), 15 }, +}; + +/* STM32F4 external trigger sources for all instances */ +static struct stm32_adc_trig_info stm32f4_adc_trigs[] = { + { TIM1_CH1, STM32_EXT0 }, + { TIM1_CH2, STM32_EXT1 }, + { TIM1_CH3, STM32_EXT2 }, + { TIM2_CH2, STM32_EXT3 }, + { TIM2_CH3, STM32_EXT4 }, + { TIM2_CH4, STM32_EXT5 }, + { TIM2_TRGO, STM32_EXT6 }, + { TIM3_CH1, STM32_EXT7 }, + { TIM3_TRGO, STM32_EXT8 }, + { TIM4_CH4, STM32_EXT9 }, + { TIM5_CH1, STM32_EXT10 }, + { TIM5_CH2, STM32_EXT11 }, + { TIM5_CH3, STM32_EXT12 }, + { TIM8_CH1, STM32_EXT13 }, + { TIM8_TRGO, STM32_EXT14 }, + {}, /* sentinel */ +}; + +/** * STM32 ADC registers access routines * @adc: stm32 adc instance * @reg: reg offset in adc instance @@ -187,10 +305,21 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc) /** * stm32_adc_start_conv() - Start conversions for regular channels. * @adc: stm32 adc instance + * @dma: use dma to transfer conversion result + * + * Start conversions for regular channels. + * Also take care of normal or DMA mode. Circular DMA may be used for regular + * conversions, in IIO buffer modes. Otherwise, use ADC interrupt with direct + * DR read instead (e.g. read_raw, or triggered buffer mode without DMA). */ -static void stm32_adc_start_conv(struct stm32_adc *adc) +static void stm32_adc_start_conv(struct stm32_adc *adc, bool dma) { stm32_adc_set_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN); + + if (dma) + stm32_adc_set_bits(adc, STM32F4_ADC_CR2, + STM32F4_DMA | STM32F4_DDS); + stm32_adc_set_bits(adc, STM32F4_ADC_CR2, STM32F4_EOCS | STM32F4_ADON); /* Wait for Power-up time (tSTAB from datasheet) */ @@ -207,10 +336,153 @@ static void stm32_adc_stop_conv(struct stm32_adc *adc) stm32_adc_clr_bits(adc, STM32F4_ADC_SR, STM32F4_STRT); stm32_adc_clr_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN); - stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, STM32F4_ADON); + stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, + STM32F4_ADON | STM32F4_DMA | STM32F4_DDS); +} + +/** + * stm32_adc_conf_scan_seq() - Build regular channels scan sequence + * @indio_dev: IIO device + * @scan_mask: channels to be converted + * + * Conversion sequence : + * Configure ADC scan sequence based on selected channels in scan_mask. + * Add channels to SQR registers, from scan_mask LSB to MSB, then + * program sequence len. + */ +static int stm32_adc_conf_scan_seq(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + const struct iio_chan_spec *chan; + u32 val, bit; + int i = 0; + + for_each_set_bit(bit, scan_mask, indio_dev->masklength) { + chan = indio_dev->channels + bit; + /* + * Assign one channel per SQ entry in regular + * sequence, starting with SQ1. + */ + i++; + if (i > STM32_ADC_MAX_SQ) + return -EINVAL; + + dev_dbg(&indio_dev->dev, "%s chan %d to SQ%d\n", + __func__, chan->channel, i); + + val = stm32_adc_readl(adc, stm32f4_sq[i].reg); + val &= ~stm32f4_sq[i].mask; + val |= chan->channel << stm32f4_sq[i].shift; + stm32_adc_writel(adc, stm32f4_sq[i].reg, val); + } + + if (!i) + return -EINVAL; + + /* Sequence len */ + val = stm32_adc_readl(adc, stm32f4_sq[0].reg); + val &= ~stm32f4_sq[0].mask; + val |= ((i - 1) << stm32f4_sq[0].shift); + stm32_adc_writel(adc, stm32f4_sq[0].reg, val); + + return 0; +} + +/** + * stm32_adc_get_trig_extsel() - Get external trigger selection + * @trig: trigger + * + * Returns trigger extsel value, if trig matches, -EINVAL otherwise. + */ +static int stm32_adc_get_trig_extsel(struct iio_trigger *trig) +{ + int i; + + /* lookup triggers registered by stm32 timer trigger driver */ + for (i = 0; stm32f4_adc_trigs[i].name; i++) { + /** + * Checking both stm32 timer trigger type and trig name + * should be safe against arbitrary trigger names. + */ + if (is_stm32_timer_trigger(trig) && + !strcmp(stm32f4_adc_trigs[i].name, trig->name)) { + return stm32f4_adc_trigs[i].extsel; + } + } + + return -EINVAL; } /** + * stm32_adc_set_trig() - Set a regular trigger + * @indio_dev: IIO device + * @trig: IIO trigger + * + * Set trigger source/polarity (e.g. SW, or HW with polarity) : + * - if HW trigger disabled (e.g. trig == NULL, conversion launched by sw) + * - if HW trigger enabled, set source & polarity + */ +static int stm32_adc_set_trig(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + u32 val, extsel = 0, exten = STM32_EXTEN_SWTRIG; + unsigned long flags; + int ret; + + if (trig) { + ret = stm32_adc_get_trig_extsel(trig); + if (ret < 0) + return ret; + + /* set trigger source and polarity (default to rising edge) */ + extsel = ret; + exten = adc->trigger_polarity + STM32_EXTEN_HWTRIG_RISING_EDGE; + } + + spin_lock_irqsave(&adc->lock, flags); + val = stm32_adc_readl(adc, STM32F4_ADC_CR2); + val &= ~(STM32F4_EXTEN_MASK | STM32F4_EXTSEL_MASK); + val |= exten << STM32F4_EXTEN_SHIFT; + val |= extsel << STM32F4_EXTSEL_SHIFT; + stm32_adc_writel(adc, STM32F4_ADC_CR2, val); + spin_unlock_irqrestore(&adc->lock, flags); + + return 0; +} + +static int stm32_adc_set_trig_pol(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int type) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + + adc->trigger_polarity = type; + + return 0; +} + +static int stm32_adc_get_trig_pol(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + + return adc->trigger_polarity; +} + +static const char * const stm32_trig_pol_items[] = { + "rising-edge", "falling-edge", "both-edges", +}; + +static const struct iio_enum stm32_adc_trig_pol = { + .items = stm32_trig_pol_items, + .num_items = ARRAY_SIZE(stm32_trig_pol_items), + .get = stm32_adc_get_trig_pol, + .set = stm32_adc_set_trig_pol, +}; + +/** * stm32_adc_single_conv() - Performs a single conversion * @indio_dev: IIO device * @chan: IIO channel @@ -228,28 +500,27 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev, struct stm32_adc *adc = iio_priv(indio_dev); long timeout; u32 val; - u16 result; int ret; reinit_completion(&adc->completion); - adc->buffer = &result; + adc->bufi = 0; - /* Program chan number in regular sequence */ - val = stm32_adc_readl(adc, STM32F4_ADC_SQR3); - val &= ~STM32F4_SQ1_MASK; - val |= chan->channel << STM32F4_SQ1_SHIFT; - stm32_adc_writel(adc, STM32F4_ADC_SQR3, val); + /* Program chan number in regular sequence (SQ1) */ + val = stm32_adc_readl(adc, stm32f4_sq[1].reg); + val &= ~stm32f4_sq[1].mask; + val |= chan->channel << stm32f4_sq[1].shift; + stm32_adc_writel(adc, stm32f4_sq[1].reg, val); /* Set regular sequence len (0 for 1 conversion) */ - stm32_adc_clr_bits(adc, STM32F4_ADC_SQR1, STM32F4_L_MASK); + stm32_adc_clr_bits(adc, stm32f4_sq[0].reg, stm32f4_sq[0].mask); /* Trigger detection disabled (conversion can be launched in SW) */ stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, STM32F4_EXTEN_MASK); stm32_adc_conv_irq_enable(adc); - stm32_adc_start_conv(adc); + stm32_adc_start_conv(adc, false); timeout = wait_for_completion_interruptible_timeout( &adc->completion, STM32_ADC_TIMEOUT); @@ -258,7 +529,7 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev, } else if (timeout < 0) { ret = timeout; } else { - *res = result; + *res = adc->buffer[0]; ret = IIO_VAL_INT; } @@ -301,17 +572,73 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev, static irqreturn_t stm32_adc_isr(int irq, void *data) { struct stm32_adc *adc = data; + struct iio_dev *indio_dev = iio_priv_to_dev(adc); u32 status = stm32_adc_readl(adc, STM32F4_ADC_SR); if (status & STM32F4_EOC) { - *adc->buffer = stm32_adc_readw(adc, STM32F4_ADC_DR); - complete(&adc->completion); + /* Reading DR also clears EOC status flag */ + adc->buffer[adc->bufi] = stm32_adc_readw(adc, STM32F4_ADC_DR); + if (iio_buffer_enabled(indio_dev)) { + adc->bufi++; + if (adc->bufi >= adc->num_conv) { + stm32_adc_conv_irq_disable(adc); + iio_trigger_poll(indio_dev->trig); + } + } else { + complete(&adc->completion); + } return IRQ_HANDLED; } return IRQ_NONE; } +/** + * stm32_adc_validate_trigger() - validate trigger for stm32 adc + * @indio_dev: IIO device + * @trig: new trigger + * + * Returns: 0 if trig matches one of the triggers registered by stm32 adc + * driver, -EINVAL otherwise. + */ +static int stm32_adc_validate_trigger(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + return stm32_adc_get_trig_extsel(trig) < 0 ? -EINVAL : 0; +} + +static int stm32_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + unsigned int watermark = STM32_DMA_BUFFER_SIZE / 2; + + /* + * dma cyclic transfers are used, buffer is split into two periods. + * There should be : + * - always one buffer (period) dma is working on + * - one buffer (period) driver can push with iio_trigger_poll(). + */ + watermark = min(watermark, val * (unsigned)(sizeof(u16))); + adc->rx_buf_sz = watermark * 2; + + return 0; +} + +static int stm32_adc_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + int ret; + + adc->num_conv = bitmap_weight(scan_mask, indio_dev->masklength); + + ret = stm32_adc_conf_scan_seq(indio_dev, scan_mask); + if (ret) + return ret; + + return 0; +} + static int stm32_adc_of_xlate(struct iio_dev *indio_dev, const struct of_phandle_args *iiospec) { @@ -350,11 +677,199 @@ static int stm32_adc_debugfs_reg_access(struct iio_dev *indio_dev, static const struct iio_info stm32_adc_iio_info = { .read_raw = stm32_adc_read_raw, + .validate_trigger = stm32_adc_validate_trigger, + .hwfifo_set_watermark = stm32_adc_set_watermark, + .update_scan_mode = stm32_adc_update_scan_mode, .debugfs_reg_access = stm32_adc_debugfs_reg_access, .of_xlate = stm32_adc_of_xlate, .driver_module = THIS_MODULE, }; +static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc) +{ + struct dma_tx_state state; + enum dma_status status; + + status = dmaengine_tx_status(adc->dma_chan, + adc->dma_chan->cookie, + &state); + if (status == DMA_IN_PROGRESS) { + /* Residue is size in bytes from end of buffer */ + unsigned int i = adc->rx_buf_sz - state.residue; + unsigned int size; + + /* Return available bytes */ + if (i >= adc->bufi) + size = i - adc->bufi; + else + size = adc->rx_buf_sz + i - adc->bufi; + + return size; + } + + return 0; +} + +static void stm32_adc_dma_buffer_done(void *data) +{ + struct iio_dev *indio_dev = data; + + iio_trigger_poll_chained(indio_dev->trig); +} + +static int stm32_adc_dma_start(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + struct dma_async_tx_descriptor *desc; + dma_cookie_t cookie; + int ret; + + if (!adc->dma_chan) + return 0; + + dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__, + adc->rx_buf_sz, adc->rx_buf_sz / 2); + + /* Prepare a DMA cyclic transaction */ + desc = dmaengine_prep_dma_cyclic(adc->dma_chan, + adc->rx_dma_buf, + adc->rx_buf_sz, adc->rx_buf_sz / 2, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + if (!desc) + return -EBUSY; + + desc->callback = stm32_adc_dma_buffer_done; + desc->callback_param = indio_dev; + + cookie = dmaengine_submit(desc); + ret = dma_submit_error(cookie); + if (ret) { + dmaengine_terminate_all(adc->dma_chan); + return ret; + } + + /* Issue pending DMA requests */ + dma_async_issue_pending(adc->dma_chan); + + return 0; +} + +static int stm32_adc_buffer_postenable(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + int ret; + + ret = stm32_adc_set_trig(indio_dev, indio_dev->trig); + if (ret) { + dev_err(&indio_dev->dev, "Can't set trigger\n"); + return ret; + } + + ret = stm32_adc_dma_start(indio_dev); + if (ret) { + dev_err(&indio_dev->dev, "Can't start dma\n"); + goto err_clr_trig; + } + + ret = iio_triggered_buffer_postenable(indio_dev); + if (ret < 0) + goto err_stop_dma; + + /* Reset adc buffer index */ + adc->bufi = 0; + + if (!adc->dma_chan) + stm32_adc_conv_irq_enable(adc); + + stm32_adc_start_conv(adc, !!adc->dma_chan); + + return 0; + +err_stop_dma: + if (adc->dma_chan) + dmaengine_terminate_all(adc->dma_chan); +err_clr_trig: + stm32_adc_set_trig(indio_dev, NULL); + + return ret; +} + +static int stm32_adc_buffer_predisable(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + int ret; + + stm32_adc_stop_conv(adc); + if (!adc->dma_chan) + stm32_adc_conv_irq_disable(adc); + + ret = iio_triggered_buffer_predisable(indio_dev); + if (ret < 0) + dev_err(&indio_dev->dev, "predisable failed\n"); + + if (adc->dma_chan) + dmaengine_terminate_all(adc->dma_chan); + + if (stm32_adc_set_trig(indio_dev, NULL)) + dev_err(&indio_dev->dev, "Can't clear trigger\n"); + + return ret; +} + +static const struct iio_buffer_setup_ops stm32_adc_buffer_setup_ops = { + .postenable = &stm32_adc_buffer_postenable, + .predisable = &stm32_adc_buffer_predisable, +}; + +static irqreturn_t stm32_adc_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct stm32_adc *adc = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi); + + if (!adc->dma_chan) { + /* reset buffer index */ + adc->bufi = 0; + iio_push_to_buffers_with_timestamp(indio_dev, adc->buffer, + pf->timestamp); + } else { + int residue = stm32_adc_dma_residue(adc); + + while (residue >= indio_dev->scan_bytes) { + u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi]; + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, + pf->timestamp); + residue -= indio_dev->scan_bytes; + adc->bufi += indio_dev->scan_bytes; + if (adc->bufi >= adc->rx_buf_sz) + adc->bufi = 0; + } + } + + iio_trigger_notify_done(indio_dev->trig); + + /* re-enable eoc irq */ + if (!adc->dma_chan) + stm32_adc_conv_irq_enable(adc); + + return IRQ_HANDLED; +} + +static const struct iio_chan_spec_ext_info stm32_adc_ext_info[] = { + IIO_ENUM("trigger_polarity", IIO_SHARED_BY_ALL, &stm32_adc_trig_pol), + { + .name = "trigger_polarity_available", + .shared = IIO_SHARED_BY_ALL, + .read = iio_enum_available_read, + .private = (uintptr_t)&stm32_adc_trig_pol, + }, + {}, +}; + static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, struct iio_chan_spec *chan, const struct stm32_adc_chan_spec *channel, @@ -370,6 +885,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, chan->scan_type.sign = 'u'; chan->scan_type.realbits = 12; chan->scan_type.storagebits = 16; + chan->ext_info = stm32_adc_ext_info; } static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) @@ -410,6 +926,45 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) return 0; } +static int stm32_adc_dma_request(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + struct dma_slave_config config; + int ret; + + adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx"); + if (!adc->dma_chan) + return 0; + + adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, + STM32_DMA_BUFFER_SIZE, + &adc->rx_dma_buf, GFP_KERNEL); + if (!adc->rx_buf) { + ret = -ENOMEM; + goto err_release; + } + + /* Configure DMA channel to read data register */ + memset(&config, 0, sizeof(config)); + config.src_addr = (dma_addr_t)adc->common->phys_base; + config.src_addr += adc->offset + STM32F4_ADC_DR; + config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + + ret = dmaengine_slave_config(adc->dma_chan, &config); + if (ret) + goto err_free; + + return 0; + +err_free: + dma_free_coherent(adc->dma_chan->device->dev, STM32_DMA_BUFFER_SIZE, + adc->rx_buf, adc->rx_dma_buf); +err_release: + dma_release_channel(adc->dma_chan); + + return ret; +} + static int stm32_adc_probe(struct platform_device *pdev) { struct iio_dev *indio_dev; @@ -471,14 +1026,37 @@ static int stm32_adc_probe(struct platform_device *pdev) if (ret < 0) goto err_clk_disable; + ret = stm32_adc_dma_request(indio_dev); + if (ret < 0) + goto err_clk_disable; + + ret = iio_triggered_buffer_setup(indio_dev, + &iio_pollfunc_store_time, + &stm32_adc_trigger_handler, + &stm32_adc_buffer_setup_ops); + if (ret) { + dev_err(&pdev->dev, "buffer setup failed\n"); + goto err_dma_disable; + } + ret = iio_device_register(indio_dev); if (ret) { dev_err(&pdev->dev, "iio dev register failed\n"); - goto err_clk_disable; + goto err_buffer_cleanup; } return 0; +err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + +err_dma_disable: + if (adc->dma_chan) { + dma_free_coherent(adc->dma_chan->device->dev, + STM32_DMA_BUFFER_SIZE, + adc->rx_buf, adc->rx_dma_buf); + dma_release_channel(adc->dma_chan); + } err_clk_disable: clk_disable_unprepare(adc->clk); @@ -491,6 +1069,13 @@ static int stm32_adc_remove(struct platform_device *pdev) struct iio_dev *indio_dev = iio_priv_to_dev(adc); iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (adc->dma_chan) { + dma_free_coherent(adc->dma_chan->device->dev, + STM32_DMA_BUFFER_SIZE, + adc->rx_buf, adc->rx_dma_buf); + dma_release_channel(adc->dma_chan); + } clk_disable_unprepare(adc->clk); return 0; diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c index 7e3645749eaf..be2de48844bc 100644 --- a/drivers/iio/adc/stx104.c +++ b/drivers/iio/adc/stx104.c @@ -76,16 +76,6 @@ struct stx104_gpio { unsigned int out_state; }; -/** - * struct stx104_dev - STX104 device private data structure - * @indio_dev: IIO device - * @chip: instance of the gpio_chip - */ -struct stx104_dev { - struct iio_dev *indio_dev; - struct gpio_chip *chip; -}; - static int stx104_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { @@ -266,12 +256,38 @@ static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset, spin_unlock_irqrestore(&stx104gpio->lock, flags); } +#define STX104_NGPIO 8 +static const char *stx104_names[STX104_NGPIO] = { + "DIN0", "DIN1", "DIN2", "DIN3", "DOUT0", "DOUT1", "DOUT2", "DOUT3" +}; + +static void stx104_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + unsigned long flags; + + /* verify masked GPIO are output */ + if (!(*mask & 0xF0)) + return; + + *mask >>= 4; + *bits >>= 4; + + spin_lock_irqsave(&stx104gpio->lock, flags); + + stx104gpio->out_state &= ~*mask; + stx104gpio->out_state |= *mask & *bits; + outb(stx104gpio->out_state, stx104gpio->base); + + spin_unlock_irqrestore(&stx104gpio->lock, flags); +} + static int stx104_probe(struct device *dev, unsigned int id) { struct iio_dev *indio_dev; struct stx104_iio *priv; struct stx104_gpio *stx104gpio; - struct stx104_dev *stx104dev; int err; indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); @@ -282,10 +298,6 @@ static int stx104_probe(struct device *dev, unsigned int id) if (!stx104gpio) return -ENOMEM; - stx104dev = devm_kzalloc(dev, sizeof(*stx104dev), GFP_KERNEL); - if (!stx104dev) - return -ENOMEM; - if (!devm_request_region(dev, base[id], STX104_EXTENT, dev_name(dev))) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", @@ -324,45 +336,26 @@ static int stx104_probe(struct device *dev, unsigned int id) stx104gpio->chip.parent = dev; stx104gpio->chip.owner = THIS_MODULE; stx104gpio->chip.base = -1; - stx104gpio->chip.ngpio = 8; + stx104gpio->chip.ngpio = STX104_NGPIO; + stx104gpio->chip.names = stx104_names; stx104gpio->chip.get_direction = stx104_gpio_get_direction; stx104gpio->chip.direction_input = stx104_gpio_direction_input; stx104gpio->chip.direction_output = stx104_gpio_direction_output; stx104gpio->chip.get = stx104_gpio_get; stx104gpio->chip.set = stx104_gpio_set; + stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; stx104gpio->base = base[id] + 3; stx104gpio->out_state = 0x0; spin_lock_init(&stx104gpio->lock); - stx104dev->indio_dev = indio_dev; - stx104dev->chip = &stx104gpio->chip; - dev_set_drvdata(dev, stx104dev); - - err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); + err = devm_gpiochip_add_data(dev, &stx104gpio->chip, stx104gpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); return err; } - err = iio_device_register(indio_dev); - if (err) { - dev_err(dev, "IIO device registering failed (%d)\n", err); - gpiochip_remove(&stx104gpio->chip); - return err; - } - - return 0; -} - -static int stx104_remove(struct device *dev, unsigned int id) -{ - struct stx104_dev *const stx104dev = dev_get_drvdata(dev); - - iio_device_unregister(stx104dev->indio_dev); - gpiochip_remove(stx104dev->chip); - - return 0; + return devm_iio_device_register(dev, indio_dev); } static struct isa_driver stx104_driver = { @@ -370,7 +363,6 @@ static struct isa_driver stx104_driver = { .driver = { .name = "stx104" }, - .remove = stx104_remove }; module_isa_driver(stx104_driver, num_stx104); diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index cde6f130a99a..422b314f5a3f 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -472,14 +472,14 @@ static const struct attribute_group ads1115_attribute_group = { .attrs = ads1115_attributes, }; -static struct iio_info ads1015_info = { +static const struct iio_info ads1015_info = { .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .attrs = &ads1015_attribute_group, }; -static struct iio_info ads1115_info = { +static const struct iio_info ads1115_info = { .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c new file mode 100644 index 000000000000..16a06633332c --- /dev/null +++ b/drivers/iio/adc/ti-ads7950.c @@ -0,0 +1,490 @@ +/* + * Texas Instruments ADS7950 SPI ADC driver + * + * Copyright 2016 David Lechner <david@lechnology.com> + * + * Based on iio/ad7923.c: + * Copyright 2011 Analog Devices Inc + * Copyright 2012 CS Systemes d'Information + * + * And also on hwmon/ads79xx.c + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/spi/spi.h> + +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> + +#define TI_ADS7950_CR_MANUAL BIT(12) +#define TI_ADS7950_CR_WRITE BIT(11) +#define TI_ADS7950_CR_CHAN(ch) ((ch) << 7) +#define TI_ADS7950_CR_RANGE_5V BIT(6) + +#define TI_ADS7950_MAX_CHAN 16 + +#define TI_ADS7950_TIMESTAMP_SIZE (sizeof(int64_t) / sizeof(__be16)) + +/* val = value, dec = left shift, bits = number of bits of the mask */ +#define TI_ADS7950_EXTRACT(val, dec, bits) \ + (((val) >> (dec)) & ((1 << (bits)) - 1)) + +struct ti_ads7950_state { + struct spi_device *spi; + struct spi_transfer ring_xfer[TI_ADS7950_MAX_CHAN + 2]; + struct spi_transfer scan_single_xfer[3]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; + + struct regulator *reg; + + unsigned int settings; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be16 rx_buf[TI_ADS7950_MAX_CHAN + TI_ADS7950_TIMESTAMP_SIZE] + ____cacheline_aligned; + __be16 tx_buf[TI_ADS7950_MAX_CHAN]; +}; + +struct ti_ads7950_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +enum ti_ads7950_id { + TI_ADS7950, + TI_ADS7951, + TI_ADS7952, + TI_ADS7953, + TI_ADS7954, + TI_ADS7955, + TI_ADS7956, + TI_ADS7957, + TI_ADS7958, + TI_ADS7959, + TI_ADS7960, + TI_ADS7961, +}; + +#define TI_ADS7950_V_CHAN(index, bits) \ +{ \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = index, \ + .datasheet_name = "CH##index", \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = 16, \ + .shift = 12 - (bits), \ + .endianness = IIO_BE, \ + }, \ +} + +#define DECLARE_TI_ADS7950_4_CHANNELS(name, bits) \ +const struct iio_chan_spec name ## _channels[] = { \ + TI_ADS7950_V_CHAN(0, bits), \ + TI_ADS7950_V_CHAN(1, bits), \ + TI_ADS7950_V_CHAN(2, bits), \ + TI_ADS7950_V_CHAN(3, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + +#define DECLARE_TI_ADS7950_8_CHANNELS(name, bits) \ +const struct iio_chan_spec name ## _channels[] = { \ + TI_ADS7950_V_CHAN(0, bits), \ + TI_ADS7950_V_CHAN(1, bits), \ + TI_ADS7950_V_CHAN(2, bits), \ + TI_ADS7950_V_CHAN(3, bits), \ + TI_ADS7950_V_CHAN(4, bits), \ + TI_ADS7950_V_CHAN(5, bits), \ + TI_ADS7950_V_CHAN(6, bits), \ + TI_ADS7950_V_CHAN(7, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(8), \ +} + +#define DECLARE_TI_ADS7950_12_CHANNELS(name, bits) \ +const struct iio_chan_spec name ## _channels[] = { \ + TI_ADS7950_V_CHAN(0, bits), \ + TI_ADS7950_V_CHAN(1, bits), \ + TI_ADS7950_V_CHAN(2, bits), \ + TI_ADS7950_V_CHAN(3, bits), \ + TI_ADS7950_V_CHAN(4, bits), \ + TI_ADS7950_V_CHAN(5, bits), \ + TI_ADS7950_V_CHAN(6, bits), \ + TI_ADS7950_V_CHAN(7, bits), \ + TI_ADS7950_V_CHAN(8, bits), \ + TI_ADS7950_V_CHAN(9, bits), \ + TI_ADS7950_V_CHAN(10, bits), \ + TI_ADS7950_V_CHAN(11, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(12), \ +} + +#define DECLARE_TI_ADS7950_16_CHANNELS(name, bits) \ +const struct iio_chan_spec name ## _channels[] = { \ + TI_ADS7950_V_CHAN(0, bits), \ + TI_ADS7950_V_CHAN(1, bits), \ + TI_ADS7950_V_CHAN(2, bits), \ + TI_ADS7950_V_CHAN(3, bits), \ + TI_ADS7950_V_CHAN(4, bits), \ + TI_ADS7950_V_CHAN(5, bits), \ + TI_ADS7950_V_CHAN(6, bits), \ + TI_ADS7950_V_CHAN(7, bits), \ + TI_ADS7950_V_CHAN(8, bits), \ + TI_ADS7950_V_CHAN(9, bits), \ + TI_ADS7950_V_CHAN(10, bits), \ + TI_ADS7950_V_CHAN(11, bits), \ + TI_ADS7950_V_CHAN(12, bits), \ + TI_ADS7950_V_CHAN(13, bits), \ + TI_ADS7950_V_CHAN(14, bits), \ + TI_ADS7950_V_CHAN(15, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(16), \ +} + +static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7950, 12); +static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7951, 12); +static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7952, 12); +static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7953, 12); +static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7954, 10); +static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7955, 10); +static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7956, 10); +static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7957, 10); +static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7958, 8); +static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7959, 8); +static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7960, 8); +static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7961, 8); + +static const struct ti_ads7950_chip_info ti_ads7950_chip_info[] = { + [TI_ADS7950] = { + .channels = ti_ads7950_channels, + .num_channels = ARRAY_SIZE(ti_ads7950_channels), + }, + [TI_ADS7951] = { + .channels = ti_ads7951_channels, + .num_channels = ARRAY_SIZE(ti_ads7951_channels), + }, + [TI_ADS7952] = { + .channels = ti_ads7952_channels, + .num_channels = ARRAY_SIZE(ti_ads7952_channels), + }, + [TI_ADS7953] = { + .channels = ti_ads7953_channels, + .num_channels = ARRAY_SIZE(ti_ads7953_channels), + }, + [TI_ADS7954] = { + .channels = ti_ads7954_channels, + .num_channels = ARRAY_SIZE(ti_ads7954_channels), + }, + [TI_ADS7955] = { + .channels = ti_ads7955_channels, + .num_channels = ARRAY_SIZE(ti_ads7955_channels), + }, + [TI_ADS7956] = { + .channels = ti_ads7956_channels, + .num_channels = ARRAY_SIZE(ti_ads7956_channels), + }, + [TI_ADS7957] = { + .channels = ti_ads7957_channels, + .num_channels = ARRAY_SIZE(ti_ads7957_channels), + }, + [TI_ADS7958] = { + .channels = ti_ads7958_channels, + .num_channels = ARRAY_SIZE(ti_ads7958_channels), + }, + [TI_ADS7959] = { + .channels = ti_ads7959_channels, + .num_channels = ARRAY_SIZE(ti_ads7959_channels), + }, + [TI_ADS7960] = { + .channels = ti_ads7960_channels, + .num_channels = ARRAY_SIZE(ti_ads7960_channels), + }, + [TI_ADS7961] = { + .channels = ti_ads7961_channels, + .num_channels = ARRAY_SIZE(ti_ads7961_channels), + }, +}; + +/* + * ti_ads7950_update_scan_mode() setup the spi transfer buffer for the new + * scan mask + */ +static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ti_ads7950_state *st = iio_priv(indio_dev); + int i, cmd, len; + + len = 0; + for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) { + cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(i) | st->settings; + st->tx_buf[len++] = cpu_to_be16(cmd); + } + + /* Data for the 1st channel is not returned until the 3rd transfer */ + len += 2; + for (i = 0; i < len; i++) { + if ((i + 2) < len) + st->ring_xfer[i].tx_buf = &st->tx_buf[i]; + if (i >= 2) + st->ring_xfer[i].rx_buf = &st->rx_buf[i - 2]; + st->ring_xfer[i].len = 2; + st->ring_xfer[i].cs_change = 1; + } + /* make sure last transfer's cs_change is not set */ + st->ring_xfer[len - 1].cs_change = 0; + + spi_message_init_with_transfers(&st->ring_msg, st->ring_xfer, len); + + return 0; +} + +static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ti_ads7950_state *st = iio_priv(indio_dev); + int ret; + + ret = spi_sync(st->spi, &st->ring_msg); + if (ret < 0) + goto out; + + iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, + iio_get_time_ns(indio_dev)); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ti_ads7950_scan_direct(struct ti_ads7950_state *st, unsigned int ch) +{ + int ret, cmd; + + cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings; + st->tx_buf[0] = cpu_to_be16(cmd); + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret) + return ret; + + return be16_to_cpu(st->rx_buf[0]); +} + +static int ti_ads7950_get_range(struct ti_ads7950_state *st) +{ + int vref; + + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + + vref /= 1000; + + if (st->settings & TI_ADS7950_CR_RANGE_5V) + vref *= 2; + + return vref; +} + +static int ti_ads7950_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long m) +{ + struct ti_ads7950_state *st = iio_priv(indio_dev); + int ret; + + switch (m) { + case IIO_CHAN_INFO_RAW: + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + return ret; + + ret = ti_ads7950_scan_direct(st, chan->address); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + + if (chan->address != TI_ADS7950_EXTRACT(ret, 12, 4)) + return -EIO; + + *val = TI_ADS7950_EXTRACT(ret, chan->scan_type.shift, + chan->scan_type.realbits); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + ret = ti_ads7950_get_range(st); + if (ret < 0) + return ret; + + *val = ret; + *val2 = (1 << chan->scan_type.realbits) - 1; + + return IIO_VAL_FRACTIONAL; + } + + return -EINVAL; +} + +static const struct iio_info ti_ads7950_info = { + .read_raw = &ti_ads7950_read_raw, + .update_scan_mode = ti_ads7950_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static int ti_ads7950_probe(struct spi_device *spi) +{ + struct ti_ads7950_state *st; + struct iio_dev *indio_dev; + const struct ti_ads7950_chip_info *info; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + st->settings = TI_ADS7950_CR_MANUAL | TI_ADS7950_CR_RANGE_5V; + + info = &ti_ads7950_chip_info[spi_get_device_id(spi)->driver_data]; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = info->channels; + indio_dev->num_channels = info->num_channels; + indio_dev->info = &ti_ads7950_info; + + /* + * Setup default message. The sample is read at the end of the first + * transfer, then it takes one full cycle to convert the sample and one + * more cycle to send the value. The conversion process is driven by + * the SPI clock, which is why we have 3 transfers. The middle one is + * just dummy data sent while the chip is converting the sample that + * was read at the end of the first transfer. + */ + + st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[0].len = 2; + st->scan_single_xfer[0].cs_change = 1; + st->scan_single_xfer[1].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[1].len = 2; + st->scan_single_xfer[1].cs_change = 1; + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[2].len = 2; + + spi_message_init_with_transfers(&st->scan_single_msg, + st->scan_single_xfer, 3); + + st->reg = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + dev_err(&spi->dev, "Failed get get regulator \"vref\"\n"); + return PTR_ERR(st->reg); + } + + ret = regulator_enable(st->reg); + if (ret) { + dev_err(&spi->dev, "Failed to enable regulator \"vref\"\n"); + return ret; + } + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ti_ads7950_trigger_handler, NULL); + if (ret) { + dev_err(&spi->dev, "Failed to setup triggered buffer\n"); + goto error_disable_reg; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&spi->dev, "Failed to register iio device\n"); + goto error_cleanup_ring; + } + + return 0; + +error_cleanup_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + regulator_disable(st->reg); + + return ret; +} + +static int ti_ads7950_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ti_ads7950_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + regulator_disable(st->reg); + + return 0; +} + +static const struct spi_device_id ti_ads7950_id[] = { + { "ads7950", TI_ADS7950 }, + { "ads7951", TI_ADS7951 }, + { "ads7952", TI_ADS7952 }, + { "ads7953", TI_ADS7953 }, + { "ads7954", TI_ADS7954 }, + { "ads7955", TI_ADS7955 }, + { "ads7956", TI_ADS7956 }, + { "ads7957", TI_ADS7957 }, + { "ads7958", TI_ADS7958 }, + { "ads7959", TI_ADS7959 }, + { "ads7960", TI_ADS7960 }, + { "ads7961", TI_ADS7961 }, + { } +}; +MODULE_DEVICE_TABLE(spi, ti_ads7950_id); + +static struct spi_driver ti_ads7950_driver = { + .driver = { + .name = "ads7950", + }, + .probe = ti_ads7950_probe, + .remove = ti_ads7950_remove, + .id_table = ti_ads7950_id, +}; +module_spi_driver(ti_ads7950_driver); + +MODULE_AUTHOR("David Lechner <david@lechnology.com>"); +MODULE_DESCRIPTION("TI TI_ADS7950 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c new file mode 100644 index 000000000000..78d91a069ea4 --- /dev/null +++ b/drivers/iio/adc/ti-tlc4541.c @@ -0,0 +1,271 @@ +/* + * TI tlc4541 ADC Driver + * + * Copyright (C) 2017 Phil Reid + * + * Datasheets can be found here: + * http://www.ti.com/lit/gpn/tlc3541 + * http://www.ti.com/lit/gpn/tlc4541 + * + * 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. + * + * The tlc4541 requires 24 clock cycles to start a transfer. + * Conversion then takes 2.94us to complete before data is ready + * Data is returned MSB first. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/spi/spi.h> +#include <linux/sysfs.h> + +struct tlc4541_state { + struct spi_device *spi; + struct regulator *reg; + struct spi_transfer scan_single_xfer[3]; + struct spi_message scan_single_msg; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * 2 bytes data + 6 bytes padding + 8 bytes timestamp when + * call iio_push_to_buffers_with_timestamp. + */ + __be16 rx_buf[8] ____cacheline_aligned; +}; + +struct tlc4541_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +enum tlc4541_id { + TLC3541, + TLC4541, +}; + +#define TLC4541_V_CHAN(bits, bitshift) { \ + .type = IIO_VOLTAGE, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = (bitshift), \ + .endianness = IIO_BE, \ + }, \ + } + +#define DECLARE_TLC4541_CHANNELS(name, bits, bitshift) \ +const struct iio_chan_spec name ## _channels[] = { \ + TLC4541_V_CHAN(bits, bitshift), \ + IIO_CHAN_SOFT_TIMESTAMP(1), \ +} + +static DECLARE_TLC4541_CHANNELS(tlc3541, 14, 2); +static DECLARE_TLC4541_CHANNELS(tlc4541, 16, 0); + +static const struct tlc4541_chip_info tlc4541_chip_info[] = { + [TLC3541] = { + .channels = tlc3541_channels, + .num_channels = ARRAY_SIZE(tlc3541_channels), + }, + [TLC4541] = { + .channels = tlc4541_channels, + .num_channels = ARRAY_SIZE(tlc4541_channels), + }, +}; + +static irqreturn_t tlc4541_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct tlc4541_state *st = iio_priv(indio_dev); + int ret; + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret < 0) + goto done; + + iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, + iio_get_time_ns(indio_dev)); + +done: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int tlc4541_get_range(struct tlc4541_state *st) +{ + int vref; + + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + + vref /= 1000; + + return vref; +} + +static int tlc4541_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret = 0; + struct tlc4541_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = spi_sync(st->spi, &st->scan_single_msg); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + *val = be16_to_cpu(st->rx_buf[0]); + *val = *val >> chan->scan_type.shift; + *val &= GENMASK(chan->scan_type.realbits - 1, 0); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + ret = tlc4541_get_range(st); + if (ret < 0) + return ret; + *val = ret; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + } + return -EINVAL; +} + +static const struct iio_info tlc4541_info = { + .read_raw = &tlc4541_read_raw, + .driver_module = THIS_MODULE, +}; + +static int tlc4541_probe(struct spi_device *spi) +{ + struct tlc4541_state *st; + struct iio_dev *indio_dev; + const struct tlc4541_chip_info *info; + int ret; + int8_t device_init = 0; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + info = &tlc4541_chip_info[spi_get_device_id(spi)->driver_data]; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = info->channels; + indio_dev->num_channels = info->num_channels; + indio_dev->info = &tlc4541_info; + + /* perform reset */ + spi_write(spi, &device_init, 1); + + /* Setup default message */ + st->scan_single_xfer[0].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[0].len = 3; + st->scan_single_xfer[1].delay_usecs = 3; + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[2].len = 2; + + spi_message_init_with_transfers(&st->scan_single_msg, + st->scan_single_xfer, 3); + + st->reg = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) + return PTR_ERR(st->reg); + + ret = regulator_enable(st->reg); + if (ret) + return ret; + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &tlc4541_trigger_handler, NULL); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_cleanup_buffer; + + return 0; + +error_cleanup_buffer: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + regulator_disable(st->reg); + + return ret; +} + +static int tlc4541_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct tlc4541_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + regulator_disable(st->reg); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id tlc4541_dt_ids[] = { + { .compatible = "ti,tlc3541", }, + { .compatible = "ti,tlc4541", }, + {} +}; +MODULE_DEVICE_TABLE(of, tlc4541_dt_ids); +#endif + +static const struct spi_device_id tlc4541_id[] = { + {"tlc3541", TLC3541}, + {"tlc4541", TLC4541}, + {} +}; +MODULE_DEVICE_TABLE(spi, tlc4541_id); + +static struct spi_driver tlc4541_driver = { + .driver = { + .name = "tlc4541", + .of_match_table = of_match_ptr(tlc4541_dt_ids), + }, + .probe = tlc4541_probe, + .remove = tlc4541_remove, + .id_table = tlc4541_id, +}; +module_spi_driver(tlc4541_driver); + +MODULE_AUTHOR("Phil Reid <preid@electromag.com.au>"); +MODULE_DESCRIPTION("Texas Instruments TLC4541 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c index b8f550e47d3d..4847534700e7 100644 --- a/drivers/iio/buffer/industrialio-buffer-cb.c +++ b/drivers/iio/buffer/industrialio-buffer-cb.c @@ -10,7 +10,8 @@ #include <linux/slab.h> #include <linux/err.h> #include <linux/export.h> -#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/buffer_impl.h> #include <linux/iio/consumer.h> struct iio_cb_buffer { diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c index c5b999f0c519..047fe757ab97 100644 --- a/drivers/iio/buffer/kfifo_buf.c +++ b/drivers/iio/buffer/kfifo_buf.c @@ -5,7 +5,10 @@ #include <linux/workqueue.h> #include <linux/kfifo.h> #include <linux/mutex.h> +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> +#include <linux/iio/buffer_impl.h> #include <linux/sched.h> #include <linux/poll.h> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index 7ef94a90ecf7..7afdac42ed42 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c @@ -58,6 +58,10 @@ static struct { {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000}, + + {HID_USAGE_SENSOR_TIME_TIMESTAMP, 0, 1000000000, 0}, + {HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND, + 1000000, 0}, }; static int pow_10(unsigned power) @@ -346,6 +350,13 @@ int hid_sensor_format_scale(u32 usage_id, } EXPORT_SYMBOL(hid_sensor_format_scale); +int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st, + int64_t raw_value) +{ + return st->timestamp_ns_scale * raw_value; +} +EXPORT_SYMBOL(hid_sensor_convert_timestamp); + static int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev, u32 usage_id, @@ -367,6 +378,7 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, struct hid_sensor_common *st) { + struct hid_sensor_hub_attribute_info timestamp; hid_sensor_get_reporting_interval(hsdev, usage_id, st); @@ -385,11 +397,25 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, &st->sensitivity); - hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x\n", - st->poll.index, st->poll.report_id, - st->report_state.index, st->report_state.report_id, - st->power_state.index, st->power_state.report_id, - st->sensitivity.index, st->sensitivity.report_id); + sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, usage_id, + HID_USAGE_SENSOR_TIME_TIMESTAMP, + ×tamp); + if (timestamp.index >= 0 && timestamp.report_id) { + int val0, val1; + + hid_sensor_format_scale(HID_USAGE_SENSOR_TIME_TIMESTAMP, + ×tamp, &val0, &val1); + st->timestamp_ns_scale = val0; + } else + st->timestamp_ns_scale = 1000000000; + + hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n", + st->poll.index, st->poll.report_id, + st->report_state.index, st->report_state.report_id, + st->power_state.index, st->power_state.report_id, + st->sensitivity.index, st->sensitivity.report_id, + timestamp.index, timestamp.report_id); return 0; } diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c index a3ae165f8d9f..645f2e3975db 100644 --- a/drivers/iio/common/ssp_sensors/ssp_iio.c +++ b/drivers/iio/common/ssp_sensors/ssp_iio.c @@ -14,6 +14,7 @@ */ #include <linux/iio/common/ssp_sensors.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include <linux/module.h> #include <linux/slab.h> diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c index b43aa36031f8..c83df4dbfcd7 100644 --- a/drivers/iio/common/st_sensors/st_sensors_i2c.c +++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c @@ -13,6 +13,7 @@ #include <linux/slab.h> #include <linux/iio/iio.h> #include <linux/of_device.h> +#include <linux/acpi.h> #include <linux/iio/common/st_sensors_i2c.h> @@ -107,6 +108,25 @@ void st_sensors_of_i2c_probe(struct i2c_client *client, EXPORT_SYMBOL(st_sensors_of_i2c_probe); #endif +#ifdef CONFIG_ACPI +int st_sensors_match_acpi_device(struct device *dev) +{ + const struct acpi_device_id *acpi_id; + kernel_ulong_t driver_data = 0; + + if (ACPI_HANDLE(dev)) { + acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!acpi_id) { + dev_err(dev, "No driver data\n"); + return -EINVAL; + } + driver_data = acpi_id->driver_data; + } + return driver_data; +} +EXPORT_SYMBOL(st_sensors_match_acpi_device); +#endif + MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/ad5592r.c b/drivers/iio/dac/ad5592r.c index 6eed5b7729be..6a12a3c9d94f 100644 --- a/drivers/iio/dac/ad5592r.c +++ b/drivers/iio/dac/ad5592r.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/spi/spi.h> +#include <linux/acpi.h> #define AD5592R_GPIO_READBACK_EN BIT(10) #define AD5592R_LDAC_READBACK_EN BIT(6) @@ -148,10 +149,17 @@ static const struct of_device_id ad5592r_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad5592r_of_match); +static const struct acpi_device_id ad5592r_acpi_match[] = { + {"ADS5592", }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match); + static struct spi_driver ad5592r_spi_driver = { .driver = { .name = "ad5592r", .of_match_table = of_match_ptr(ad5592r_of_match), + .acpi_match_table = ACPI_PTR(ad5592r_acpi_match), }, .probe = ad5592r_spi_probe, .remove = ad5592r_spi_remove, diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index dca158a88f47..fc11ea098f98 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -13,6 +13,7 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/acpi.h> #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) @@ -115,10 +116,17 @@ static const struct of_device_id ad5593r_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad5593r_of_match); +static const struct acpi_device_id ad5593r_acpi_match[] = { + {"ADS5593", }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match); + static struct i2c_driver ad5593r_driver = { .driver = { .name = "ad5593r", .of_match_table = of_match_ptr(ad5593r_of_match), + .acpi_match_table = ACPI_PTR(ad5593r_acpi_match), }, .probe = ad5593r_i2c_probe, .remove = ad5593r_i2c_remove, diff --git a/drivers/iio/dummy/iio_simple_dummy.h b/drivers/iio/dummy/iio_simple_dummy.h index b9069a180672..f7005c3f5df3 100644 --- a/drivers/iio/dummy/iio_simple_dummy.h +++ b/drivers/iio/dummy/iio_simple_dummy.h @@ -88,11 +88,11 @@ static inline int iio_simple_dummy_events_register(struct iio_dev *indio_dev) { return 0; -}; +} static inline void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev) -{ }; +{} #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS*/ @@ -119,11 +119,11 @@ void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev); static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) { return 0; -}; +} static inline void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) -{}; +{} #endif /* CONFIG_IIO_SIMPLE_DUMMY_BUFFER */ #endif /* _IIO_SIMPLE_DUMMY_H_ */ diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c index b383892a5193..744ca92c3c99 100644 --- a/drivers/iio/dummy/iio_simple_dummy_buffer.c +++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c @@ -20,6 +20,7 @@ #include <linux/iio/iio.h> #include <linux/iio/trigger_consumer.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include "iio_simple_dummy.h" @@ -131,9 +132,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) iio_device_attach_buffer(indio_dev, buffer); - /* Enable timestamps by default */ - buffer->scan_timestamp = true; - /* * Tell the core what device type specific functions should * be run on either side of buffer capture enable / disable. diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c index 1f25f406c545..2dacd8e01045 100644 --- a/drivers/iio/gyro/ssp_gyro_sensor.c +++ b/drivers/iio/gyro/ssp_gyro_sensor.c @@ -15,6 +15,7 @@ #include <linux/iio/common/ssp_sensors.h> #include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -134,7 +135,7 @@ static int ssp_gyro_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret < 0) return ret; @@ -144,21 +145,11 @@ static int ssp_gyro_probe(struct platform_device *pdev) return 0; } -static int ssp_gyro_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - - iio_device_unregister(indio_dev); - - return 0; -} - static struct platform_driver ssp_gyro_driver = { .driver = { .name = SSP_GYROSCOPE_NAME, }, .probe = ssp_gyro_probe, - .remove = ssp_gyro_remove, }; module_platform_driver(ssp_gyro_driver); diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 183c14329d6e..f6e283c4d686 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -378,7 +378,7 @@ static int max30100_get_temp(struct max30100_data *data, int *val) if (ret) return ret; - usleep_range(35000, 50000); + msleep(35); return max30100_read_temp(data, val); } diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c index 367ecd509f31..8333c0296c0e 100644 --- a/drivers/iio/humidity/hts221_i2c.c +++ b/drivers/iio/humidity/hts221_i2c.c @@ -10,6 +10,7 @@ #include <linux/kernel.h> #include <linux/module.h> +#include <linux/acpi.h> #include <linux/i2c.h> #include <linux/slab.h> #include "hts221.h" @@ -83,6 +84,12 @@ static int hts221_i2c_probe(struct i2c_client *client, return hts221_probe(iio_dev); } +static const struct acpi_device_id hts221_acpi_match[] = { + {"SMO9100", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hts221_acpi_match); + static const struct of_device_id hts221_i2c_of_match[] = { { .compatible = "st,hts221", }, {}, @@ -99,6 +106,7 @@ static struct i2c_driver hts221_driver = { .driver = { .name = "hts221_i2c", .of_match_table = of_match_ptr(hts221_i2c_of_match), + .acpi_match_table = ACPI_PTR(hts221_acpi_match), }, .probe = hts221_i2c_probe, .id_table = hts221_i2c_id_table, diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index 1f1ad41ef881..156630a21696 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -39,6 +39,7 @@ config KMX61 be called kmx61. source "drivers/iio/imu/inv_mpu6050/Kconfig" +source "drivers/iio/imu/st_lsm6dsx/Kconfig" endmenu diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index c71bcd30dc38..8b563c3323b5 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -17,3 +17,5 @@ obj-y += bmi160/ obj-y += inv_mpu6050/ obj-$(CONFIG_KMX61) += kmx61.o + +obj-y += st_lsm6dsx/ diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index c9e319bff58b..cfd225ed1c8d 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -325,9 +325,9 @@ static int bmi160_get_data(struct bmi160_data *data, int chan_type, __le16 sample; enum bmi160_sensor_type t = bmi160_to_sensor(chan_type); - reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(__le16); + reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(sample); - ret = regmap_bulk_read(data->regmap, reg, &sample, sizeof(__le16)); + ret = regmap_bulk_read(data->regmap, reg, &sample, sizeof(sample)); if (ret < 0) return ret; @@ -392,8 +392,8 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p) for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) { - ret = regmap_bulk_read(data->regmap, base + i * sizeof(__le16), - &sample, sizeof(__le16)); + ret = regmap_bulk_read(data->regmap, base + i * sizeof(sample), + &sample, sizeof(sample)); if (ret < 0) goto done; buf[j++] = sample; diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index 07a179d8fb48..155a31f72445 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -11,10 +11,11 @@ * - 0x68 if SDO is pulled to GND * - 0x69 if SDO is pulled to VDDIO */ -#include <linux/module.h> +#include <linux/acpi.h> #include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> #include <linux/regmap.h> -#include <linux/acpi.h> #include "bmi160.h" @@ -56,10 +57,19 @@ static const struct acpi_device_id bmi160_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); +#ifdef CONFIG_OF +static const struct of_device_id bmi160_of_match[] = { + { .compatible = "bosch,bmi160" }, + { }, +}; +MODULE_DEVICE_TABLE(of, bmi160_of_match); +#endif + static struct i2c_driver bmi160_i2c_driver = { .driver = { .name = "bmi160_i2c", .acpi_match_table = ACPI_PTR(bmi160_acpi_match), + .of_match_table = of_match_ptr(bmi160_of_match), }, .probe = bmi160_i2c_probe, .remove = bmi160_i2c_remove, diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c index 1ec8b12bd984..d34dfdfd1a7d 100644 --- a/drivers/iio/imu/bmi160/bmi160_spi.c +++ b/drivers/iio/imu/bmi160/bmi160_spi.c @@ -7,10 +7,11 @@ * the GNU General Public License. See the file COPYING in the main * directory of this archive for more details. */ +#include <linux/acpi.h> #include <linux/module.h> -#include <linux/spi/spi.h> +#include <linux/of.h> #include <linux/regmap.h> -#include <linux/acpi.h> +#include <linux/spi/spi.h> #include "bmi160.h" @@ -47,13 +48,22 @@ static const struct acpi_device_id bmi160_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); +#ifdef CONFIG_OF +static const struct of_device_id bmi160_of_match[] = { + { .compatible = "bosch,bmi160" }, + { }, +}; +MODULE_DEVICE_TABLE(of, bmi160_of_match); +#endif + static struct spi_driver bmi160_spi_driver = { .probe = bmi160_spi_probe, .remove = bmi160_spi_remove, .id_table = bmi160_spi_id, .driver = { - .acpi_match_table = ACPI_PTR(bmi160_acpi_match), - .name = "bmi160_spi", + .acpi_match_table = ACPI_PTR(bmi160_acpi_match), + .of_match_table = of_match_ptr(bmi160_of_match), + .name = "bmi160_spi", }, }; module_spi_driver(bmi160_spi_driver); diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig new file mode 100644 index 000000000000..935d4cd071a3 --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -0,0 +1,22 @@ + +config IIO_ST_LSM6DSX + tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors" + depends on (I2C || SPI) + select IIO_BUFFER + select IIO_KFIFO_BUF + select IIO_ST_LSM6DSX_I2C if (I2C) + select IIO_ST_LSM6DSX_SPI if (SPI_MASTER) + help + Say yes here to build support for STMicroelectronics LSM6DSx imu + sensor. Supported devices: lsm6ds3, lsm6dsm + + To compile this driver as a module, choose M here: the module + will be called st_lsm6dsx. + +config IIO_ST_LSM6DSX_I2C + tristate + depends on IIO_ST_LSM6DSX + +config IIO_ST_LSM6DSX_SPI + tristate + depends on IIO_ST_LSM6DSX diff --git a/drivers/iio/imu/st_lsm6dsx/Makefile b/drivers/iio/imu/st_lsm6dsx/Makefile new file mode 100644 index 000000000000..35919febea2a --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/Makefile @@ -0,0 +1,5 @@ +st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o + +obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o +obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o +obj-$(CONFIG_IIO_ST_LSM6DSX_SPI) += st_lsm6dsx_spi.o diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h new file mode 100644 index 000000000000..69deafe1c10d --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -0,0 +1,141 @@ +/* + * STMicroelectronics st_lsm6dsx sensor driver + * + * Copyright 2016 STMicroelectronics Inc. + * + * Lorenzo Bianconi <lorenzo.bianconi@st.com> + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#ifndef ST_LSM6DSX_H +#define ST_LSM6DSX_H + +#include <linux/device.h> + +#define ST_LSM6DS3_DEV_NAME "lsm6ds3" +#define ST_LSM6DSM_DEV_NAME "lsm6dsm" + +enum st_lsm6dsx_hw_id { + ST_LSM6DS3_ID, + ST_LSM6DSM_ID, +}; + +#define ST_LSM6DSX_CHAN_SIZE 2 +#define ST_LSM6DSX_SAMPLE_SIZE 6 +#define ST_LSM6DSX_SAMPLE_DEPTH (ST_LSM6DSX_SAMPLE_SIZE / \ + ST_LSM6DSX_CHAN_SIZE) + +#if defined(CONFIG_SPI_MASTER) +#define ST_LSM6DSX_RX_MAX_LENGTH 256 +#define ST_LSM6DSX_TX_MAX_LENGTH 8 + +struct st_lsm6dsx_transfer_buffer { + u8 rx_buf[ST_LSM6DSX_RX_MAX_LENGTH]; + u8 tx_buf[ST_LSM6DSX_TX_MAX_LENGTH] ____cacheline_aligned; +}; +#endif /* CONFIG_SPI_MASTER */ + +struct st_lsm6dsx_transfer_function { + int (*read)(struct device *dev, u8 addr, int len, u8 *data); + int (*write)(struct device *dev, u8 addr, int len, u8 *data); +}; + +struct st_lsm6dsx_reg { + u8 addr; + u8 mask; +}; + +struct st_lsm6dsx_settings { + u8 wai; + u16 max_fifo_size; + enum st_lsm6dsx_hw_id id; +}; + +enum st_lsm6dsx_sensor_id { + ST_LSM6DSX_ID_ACC, + ST_LSM6DSX_ID_GYRO, + ST_LSM6DSX_ID_MAX, +}; + +enum st_lsm6dsx_fifo_mode { + ST_LSM6DSX_FIFO_BYPASS = 0x0, + ST_LSM6DSX_FIFO_CONT = 0x6, +}; + +/** + * struct st_lsm6dsx_sensor - ST IMU sensor instance + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. + * @odr: Output data rate of the sensor [Hz]. + * @watermark: Sensor watermark level. + * @sip: Number of samples in a given pattern. + * @decimator: FIFO decimation factor. + * @decimator_mask: Sensor mask for decimation register. + * @delta_ts: Delta time between two consecutive interrupts. + * @ts: Latest timestamp from the interrupt handler. + */ +struct st_lsm6dsx_sensor { + enum st_lsm6dsx_sensor_id id; + struct st_lsm6dsx_hw *hw; + + u32 gain; + u16 odr; + + u16 watermark; + u8 sip; + u8 decimator; + u8 decimator_mask; + + s64 delta_ts; + s64 ts; +}; + +/** + * struct st_lsm6dsx_hw - ST IMU MEMS hw instance + * @dev: Pointer to instance of struct device (I2C or SPI). + * @irq: Device interrupt line (I2C or SPI). + * @lock: Mutex to protect read and write operations. + * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. + * @fifo_mode: FIFO operating mode supported by the device. + * @enable_mask: Enabled sensor bitmask. + * @sip: Total number of samples (acc/gyro) in a given pattern. + * @iio_devs: Pointers to acc/gyro iio_dev instances. + * @settings: Pointer to the specific sensor settings in use. + * @tf: Transfer function structure used by I/O operations. + * @tb: Transfer buffers used by SPI I/O operations. + */ +struct st_lsm6dsx_hw { + struct device *dev; + int irq; + + struct mutex lock; + struct mutex fifo_lock; + + enum st_lsm6dsx_fifo_mode fifo_mode; + u8 enable_mask; + u8 sip; + + struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX]; + + const struct st_lsm6dsx_settings *settings; + + const struct st_lsm6dsx_transfer_function *tf; +#if defined(CONFIG_SPI_MASTER) + struct st_lsm6dsx_transfer_buffer tb; +#endif /* CONFIG_SPI_MASTER */ +}; + +int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, + const struct st_lsm6dsx_transfer_function *tf_ops); +int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor); +int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor); +int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw); +int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask, + u8 val); +int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, + u16 watermark); + +#endif /* ST_LSM6DSX_H */ diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c new file mode 100644 index 000000000000..78532ce07449 --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -0,0 +1,454 @@ +/* + * STMicroelectronics st_lsm6dsx FIFO buffer library driver + * + * LSM6DS3/LSM6DSM: The FIFO buffer can be configured to store data + * from gyroscope and accelerometer. Samples are queued without any tag + * according to a specific pattern based on 'FIFO data sets' (6 bytes each): + * - 1st data set is reserved for gyroscope data + * - 2nd data set is reserved for accelerometer data + * The FIFO pattern changes depending on the ODRs and decimation factors + * assigned to the FIFO data sets. The first sequence of data stored in FIFO + * buffer contains the data of all the enabled FIFO data sets + * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the + * value of the decimation factor and ODR set for each FIFO data set. + * FIFO supported modes: + * - BYPASS: FIFO disabled + * - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index + * restarts from the beginning and the oldest sample is overwritten + * + * Copyright 2016 STMicroelectronics Inc. + * + * Lorenzo Bianconi <lorenzo.bianconi@st.com> + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> + +#include "st_lsm6dsx.h" + +#define ST_LSM6DSX_REG_FIFO_THL_ADDR 0x06 +#define ST_LSM6DSX_REG_FIFO_THH_ADDR 0x07 +#define ST_LSM6DSX_FIFO_TH_MASK GENMASK(11, 0) +#define ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR 0x08 +#define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a +#define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0) +#define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3) +#define ST_LSM6DSX_REG_FIFO_DIFFL_ADDR 0x3a +#define ST_LSM6DSX_FIFO_DIFF_MASK GENMASK(11, 0) +#define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12) +#define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e + +#define ST_LSM6DSX_MAX_FIFO_ODR_VAL 0x08 + +struct st_lsm6dsx_decimator_entry { + u8 decimator; + u8 val; +}; + +static const +struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = { + { 0, 0x0 }, + { 1, 0x1 }, + { 2, 0x2 }, + { 3, 0x3 }, + { 4, 0x4 }, + { 8, 0x5 }, + { 16, 0x6 }, + { 32, 0x7 }, +}; + +static int st_lsm6dsx_get_decimator_val(u8 val) +{ + const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table); + int i; + + for (i = 0; i < max_size; i++) + if (st_lsm6dsx_decimator_table[i].decimator == val) + break; + + return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val; +} + +static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, + u16 *max_odr, u16 *min_odr) +{ + struct st_lsm6dsx_sensor *sensor; + int i; + + *max_odr = 0, *min_odr = ~0; + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + sensor = iio_priv(hw->iio_devs[i]); + + if (!(hw->enable_mask & BIT(sensor->id))) + continue; + + *max_odr = max_t(u16, *max_odr, sensor->odr); + *min_odr = min_t(u16, *min_odr, sensor->odr); + } +} + +static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) +{ + struct st_lsm6dsx_sensor *sensor; + u16 max_odr, min_odr, sip = 0; + int err, i; + u8 data; + + st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr); + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + sensor = iio_priv(hw->iio_devs[i]); + + /* update fifo decimators and sample in pattern */ + if (hw->enable_mask & BIT(sensor->id)) { + sensor->sip = sensor->odr / min_odr; + sensor->decimator = max_odr / sensor->odr; + data = st_lsm6dsx_get_decimator_val(sensor->decimator); + } else { + sensor->sip = 0; + sensor->decimator = 0; + data = 0; + } + + err = st_lsm6dsx_write_with_mask(hw, + ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR, + sensor->decimator_mask, data); + if (err < 0) + return err; + + sip += sensor->sip; + } + hw->sip = sip; + + return 0; +} + +static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, + enum st_lsm6dsx_fifo_mode fifo_mode) +{ + u8 data; + int err; + + switch (fifo_mode) { + case ST_LSM6DSX_FIFO_BYPASS: + data = fifo_mode; + break; + case ST_LSM6DSX_FIFO_CONT: + data = (ST_LSM6DSX_MAX_FIFO_ODR_VAL << + __ffs(ST_LSM6DSX_FIFO_ODR_MASK)) | fifo_mode; + break; + default: + return -EINVAL; + } + + err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_MODE_ADDR, + sizeof(data), &data); + if (err < 0) + return err; + + hw->fifo_mode = fifo_mode; + + return 0; +} + +int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) +{ + u16 fifo_watermark = ~0, cur_watermark, sip = 0; + struct st_lsm6dsx_hw *hw = sensor->hw; + struct st_lsm6dsx_sensor *cur_sensor; + __le16 wdata; + int i, err; + u8 data; + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + cur_sensor = iio_priv(hw->iio_devs[i]); + + if (!(hw->enable_mask & BIT(cur_sensor->id))) + continue; + + cur_watermark = (cur_sensor == sensor) ? watermark + : cur_sensor->watermark; + + fifo_watermark = min_t(u16, fifo_watermark, cur_watermark); + sip += cur_sensor->sip; + } + + if (!sip) + return 0; + + fifo_watermark = max_t(u16, fifo_watermark, sip); + fifo_watermark = (fifo_watermark / sip) * sip; + fifo_watermark = fifo_watermark * ST_LSM6DSX_SAMPLE_DEPTH; + + mutex_lock(&hw->lock); + + err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_THH_ADDR, + sizeof(data), &data); + if (err < 0) + goto out; + + fifo_watermark = ((data & ~ST_LSM6DSX_FIFO_TH_MASK) << 8) | + (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK); + + wdata = cpu_to_le16(fifo_watermark); + err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_THL_ADDR, + sizeof(wdata), (u8 *)&wdata); +out: + mutex_unlock(&hw->lock); + + return err < 0 ? err : 0; +} + +/** + * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DSM read FIFO routine + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * + * Read samples from the hw FIFO and push them to IIO buffers. + * + * Return: Number of bytes read from the FIFO + */ +static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) +{ + u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; + int err, acc_sip, gyro_sip, read_len, samples, offset; + struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor; + s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts; + u8 iio_buff[ALIGN(ST_LSM6DSX_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)]; + u8 buff[pattern_len]; + __le16 fifo_status; + + err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_DIFFL_ADDR, + sizeof(fifo_status), (u8 *)&fifo_status); + if (err < 0) + return err; + + if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK)) + return 0; + + fifo_len = (le16_to_cpu(fifo_status) & ST_LSM6DSX_FIFO_DIFF_MASK) * + ST_LSM6DSX_CHAN_SIZE; + samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE; + fifo_len = (fifo_len / pattern_len) * pattern_len; + + /* + * compute delta timestamp between two consecutive samples + * in order to estimate queueing time of data generated + * by the sensor + */ + acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); + acc_ts = acc_sensor->ts - acc_sensor->delta_ts; + acc_delta_ts = div_s64(acc_sensor->delta_ts * acc_sensor->decimator, + samples); + + gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]); + gyro_ts = gyro_sensor->ts - gyro_sensor->delta_ts; + gyro_delta_ts = div_s64(gyro_sensor->delta_ts * gyro_sensor->decimator, + samples); + + for (read_len = 0; read_len < fifo_len; read_len += pattern_len) { + err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_OUTL_ADDR, + sizeof(buff), buff); + if (err < 0) + return err; + + /* + * Data are written to the FIFO with a specific pattern + * depending on the configured ODRs. The first sequence of data + * stored in FIFO contains the data of all enabled sensors + * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated + * depending on the value of the decimation factor set for each + * sensor. + * + * Supposing the FIFO is storing data from gyroscope and + * accelerometer at different ODRs: + * - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz + * Since the gyroscope ODR is twice the accelerometer one, the + * following pattern is repeated every 9 samples: + * - Gx, Gy, Gz, Ax, Ay, Az, Gx, Gy, Gz + */ + gyro_sip = gyro_sensor->sip; + acc_sip = acc_sensor->sip; + offset = 0; + + while (acc_sip > 0 || gyro_sip > 0) { + if (gyro_sip-- > 0) { + memcpy(iio_buff, &buff[offset], + ST_LSM6DSX_SAMPLE_SIZE); + iio_push_to_buffers_with_timestamp( + hw->iio_devs[ST_LSM6DSX_ID_GYRO], + iio_buff, gyro_ts); + offset += ST_LSM6DSX_SAMPLE_SIZE; + gyro_ts += gyro_delta_ts; + } + + if (acc_sip-- > 0) { + memcpy(iio_buff, &buff[offset], + ST_LSM6DSX_SAMPLE_SIZE); + iio_push_to_buffers_with_timestamp( + hw->iio_devs[ST_LSM6DSX_ID_ACC], + iio_buff, acc_ts); + offset += ST_LSM6DSX_SAMPLE_SIZE; + acc_ts += acc_delta_ts; + } + } + } + + return read_len; +} + +static int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) +{ + int err; + + mutex_lock(&hw->fifo_lock); + + st_lsm6dsx_read_fifo(hw); + err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS); + + mutex_unlock(&hw->fifo_lock); + + return err; +} + +static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + struct st_lsm6dsx_hw *hw = sensor->hw; + int err; + + if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) { + err = st_lsm6dsx_flush_fifo(hw); + if (err < 0) + return err; + } + + if (enable) { + err = st_lsm6dsx_sensor_enable(sensor); + if (err < 0) + return err; + } else { + err = st_lsm6dsx_sensor_disable(sensor); + if (err < 0) + return err; + } + + err = st_lsm6dsx_update_decimators(hw); + if (err < 0) + return err; + + err = st_lsm6dsx_update_watermark(sensor, sensor->watermark); + if (err < 0) + return err; + + if (hw->enable_mask) { + err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); + if (err < 0) + return err; + + /* + * store enable buffer timestamp as reference to compute + * first delta timestamp + */ + sensor->ts = iio_get_time_ns(iio_dev); + } + + return 0; +} + +static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private) +{ + struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private; + struct st_lsm6dsx_sensor *sensor; + int i; + + if (!hw->sip) + return IRQ_NONE; + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + sensor = iio_priv(hw->iio_devs[i]); + + if (sensor->sip > 0) { + s64 timestamp; + + timestamp = iio_get_time_ns(hw->iio_devs[i]); + sensor->delta_ts = timestamp - sensor->ts; + sensor->ts = timestamp; + } + } + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) +{ + struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private; + int count; + + mutex_lock(&hw->fifo_lock); + count = st_lsm6dsx_read_fifo(hw); + mutex_unlock(&hw->fifo_lock); + + return !count ? IRQ_NONE : IRQ_HANDLED; +} + +static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev) +{ + return st_lsm6dsx_update_fifo(iio_dev, true); +} + +static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev) +{ + return st_lsm6dsx_update_fifo(iio_dev, false); +} + +static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = { + .preenable = st_lsm6dsx_buffer_preenable, + .postdisable = st_lsm6dsx_buffer_postdisable, +}; + +int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) +{ + struct iio_buffer *buffer; + unsigned long irq_type; + int i, err; + + irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); + + switch (irq_type) { + case IRQF_TRIGGER_HIGH: + case IRQF_TRIGGER_RISING: + break; + default: + dev_info(hw->dev, "mode %lx unsupported\n", irq_type); + return -EINVAL; + } + + err = devm_request_threaded_irq(hw->dev, hw->irq, + st_lsm6dsx_handler_irq, + st_lsm6dsx_handler_thread, + irq_type | IRQF_ONESHOT, + "lsm6dsx", hw); + if (err) { + dev_err(hw->dev, "failed to request trigger irq %d\n", + hw->irq); + return err; + } + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + buffer = devm_iio_kfifo_allocate(hw->dev); + if (!buffer) + return -ENOMEM; + + iio_device_attach_buffer(hw->iio_devs[i], buffer); + hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE; + hw->iio_devs[i]->setup_ops = &st_lsm6dsx_buffer_ops; + } + + return 0; +} diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c new file mode 100644 index 000000000000..c92ddcc190e2 --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -0,0 +1,720 @@ +/* + * STMicroelectronics st_lsm6dsx sensor driver + * + * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer + * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial + * interface standard output. + * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale + * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of + * +-125/+-245/+-500/+-1000/+-2000 dps + * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer + * allowing dynamic batching of sensor data. + * + * Supported sensors: + * - LSM6DS3: + * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 + * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 + * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 + * - FIFO size: 8KB + * + * - LSM6DSM: + * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 + * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 + * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 + * - FIFO size: 4KB + * + * Copyright 2016 STMicroelectronics Inc. + * + * Lorenzo Bianconi <lorenzo.bianconi@st.com> + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#include <linux/platform_data/st_sensors_pdata.h> + +#include "st_lsm6dsx.h" + +#define ST_LSM6DSX_REG_ACC_DEC_MASK GENMASK(2, 0) +#define ST_LSM6DSX_REG_GYRO_DEC_MASK GENMASK(5, 3) +#define ST_LSM6DSX_REG_INT1_ADDR 0x0d +#define ST_LSM6DSX_REG_INT2_ADDR 0x0e +#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3) +#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f +#define ST_LSM6DSX_REG_RESET_ADDR 0x12 +#define ST_LSM6DSX_REG_RESET_MASK BIT(0) +#define ST_LSM6DSX_REG_BDU_ADDR 0x12 +#define ST_LSM6DSX_REG_BDU_MASK BIT(6) +#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13 +#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5) +#define ST_LSM6DSX_REG_ROUNDING_ADDR 0x16 +#define ST_LSM6DSX_REG_ROUNDING_MASK BIT(2) +#define ST_LSM6DSX_REG_LIR_ADDR 0x58 +#define ST_LSM6DSX_REG_LIR_MASK BIT(0) + +#define ST_LSM6DSX_REG_ACC_ODR_ADDR 0x10 +#define ST_LSM6DSX_REG_ACC_ODR_MASK GENMASK(7, 4) +#define ST_LSM6DSX_REG_ACC_FS_ADDR 0x10 +#define ST_LSM6DSX_REG_ACC_FS_MASK GENMASK(3, 2) +#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR 0x28 +#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR 0x2a +#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR 0x2c + +#define ST_LSM6DSX_REG_GYRO_ODR_ADDR 0x11 +#define ST_LSM6DSX_REG_GYRO_ODR_MASK GENMASK(7, 4) +#define ST_LSM6DSX_REG_GYRO_FS_ADDR 0x11 +#define ST_LSM6DSX_REG_GYRO_FS_MASK GENMASK(3, 2) +#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR 0x22 +#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24 +#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26 + +#define ST_LSM6DS3_WHOAMI 0x69 +#define ST_LSM6DSM_WHOAMI 0x6a + +#define ST_LSM6DS3_MAX_FIFO_SIZE 8192 +#define ST_LSM6DSM_MAX_FIFO_SIZE 4096 + +#define ST_LSM6DSX_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61) +#define ST_LSM6DSX_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122) +#define ST_LSM6DSX_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244) +#define ST_LSM6DSX_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488) + +#define ST_LSM6DSX_GYRO_FS_245_GAIN IIO_DEGREE_TO_RAD(8750) +#define ST_LSM6DSX_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500) +#define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000) +#define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000) + +struct st_lsm6dsx_odr { + u16 hz; + u8 val; +}; + +#define ST_LSM6DSX_ODR_LIST_SIZE 6 +struct st_lsm6dsx_odr_table_entry { + struct st_lsm6dsx_reg reg; + struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE]; +}; + +static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = ST_LSM6DSX_REG_ACC_ODR_ADDR, + .mask = ST_LSM6DSX_REG_ACC_ODR_MASK, + }, + .odr_avl[0] = { 13, 0x01 }, + .odr_avl[1] = { 26, 0x02 }, + .odr_avl[2] = { 52, 0x03 }, + .odr_avl[3] = { 104, 0x04 }, + .odr_avl[4] = { 208, 0x05 }, + .odr_avl[5] = { 416, 0x06 }, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = ST_LSM6DSX_REG_GYRO_ODR_ADDR, + .mask = ST_LSM6DSX_REG_GYRO_ODR_MASK, + }, + .odr_avl[0] = { 13, 0x01 }, + .odr_avl[1] = { 26, 0x02 }, + .odr_avl[2] = { 52, 0x03 }, + .odr_avl[3] = { 104, 0x04 }, + .odr_avl[4] = { 208, 0x05 }, + .odr_avl[5] = { 416, 0x06 }, + } +}; + +struct st_lsm6dsx_fs { + u32 gain; + u8 val; +}; + +#define ST_LSM6DSX_FS_LIST_SIZE 4 +struct st_lsm6dsx_fs_table_entry { + struct st_lsm6dsx_reg reg; + struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE]; +}; + +static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = ST_LSM6DSX_REG_ACC_FS_ADDR, + .mask = ST_LSM6DSX_REG_ACC_FS_MASK, + }, + .fs_avl[0] = { ST_LSM6DSX_ACC_FS_2G_GAIN, 0x0 }, + .fs_avl[1] = { ST_LSM6DSX_ACC_FS_4G_GAIN, 0x2 }, + .fs_avl[2] = { ST_LSM6DSX_ACC_FS_8G_GAIN, 0x3 }, + .fs_avl[3] = { ST_LSM6DSX_ACC_FS_16G_GAIN, 0x1 }, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = ST_LSM6DSX_REG_GYRO_FS_ADDR, + .mask = ST_LSM6DSX_REG_GYRO_FS_MASK, + }, + .fs_avl[0] = { ST_LSM6DSX_GYRO_FS_245_GAIN, 0x0 }, + .fs_avl[1] = { ST_LSM6DSX_GYRO_FS_500_GAIN, 0x1 }, + .fs_avl[2] = { ST_LSM6DSX_GYRO_FS_1000_GAIN, 0x2 }, + .fs_avl[3] = { ST_LSM6DSX_GYRO_FS_2000_GAIN, 0x3 }, + } +}; + +static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { + { + .wai = ST_LSM6DS3_WHOAMI, + .max_fifo_size = ST_LSM6DS3_MAX_FIFO_SIZE, + .id = ST_LSM6DS3_ID, + }, + { + .wai = ST_LSM6DSM_WHOAMI, + .max_fifo_size = ST_LSM6DSM_MAX_FIFO_SIZE, + .id = ST_LSM6DSM_ID, + }, +}; + +#define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \ +{ \ + .type = chan_type, \ + .address = addr, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = scan_idx, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { + ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR, + IIO_MOD_X, 0), + ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR, + IIO_MOD_Y, 1), + ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR, + IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR, + IIO_MOD_X, 0), + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR, + IIO_MOD_Y, 1), + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR, + IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask, + u8 val) +{ + u8 data; + int err; + + mutex_lock(&hw->lock); + + err = hw->tf->read(hw->dev, addr, sizeof(data), &data); + if (err < 0) { + dev_err(hw->dev, "failed to read %02x register\n", addr); + goto out; + } + + data = (data & ~mask) | ((val << __ffs(mask)) & mask); + + err = hw->tf->write(hw->dev, addr, sizeof(data), &data); + if (err < 0) + dev_err(hw->dev, "failed to write %02x register\n", addr); + +out: + mutex_unlock(&hw->lock); + + return err; +} + +static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) +{ + int err, i; + u8 data; + + for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { + if (id == st_lsm6dsx_sensor_settings[i].id) + break; + } + + if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { + dev_err(hw->dev, "unsupported hw id [%02x]\n", id); + return -ENODEV; + } + + err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_WHOAMI_ADDR, sizeof(data), + &data); + if (err < 0) { + dev_err(hw->dev, "failed to read whoami register\n"); + return err; + } + + if (data != st_lsm6dsx_sensor_settings[i].wai) { + dev_err(hw->dev, "unsupported whoami [%02x]\n", data); + return -ENODEV; + } + + hw->settings = &st_lsm6dsx_sensor_settings[i]; + + return 0; +} + +static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, + u32 gain) +{ + enum st_lsm6dsx_sensor_id id = sensor->id; + int i, err; + u8 val; + + for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) + if (st_lsm6dsx_fs_table[id].fs_avl[i].gain == gain) + break; + + if (i == ST_LSM6DSX_FS_LIST_SIZE) + return -EINVAL; + + val = st_lsm6dsx_fs_table[id].fs_avl[i].val; + err = st_lsm6dsx_write_with_mask(sensor->hw, + st_lsm6dsx_fs_table[id].reg.addr, + st_lsm6dsx_fs_table[id].reg.mask, + val); + if (err < 0) + return err; + + sensor->gain = gain; + + return 0; +} + +static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) +{ + enum st_lsm6dsx_sensor_id id = sensor->id; + int i, err; + u8 val; + + for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) + if (st_lsm6dsx_odr_table[id].odr_avl[i].hz == odr) + break; + + if (i == ST_LSM6DSX_ODR_LIST_SIZE) + return -EINVAL; + + val = st_lsm6dsx_odr_table[id].odr_avl[i].val; + err = st_lsm6dsx_write_with_mask(sensor->hw, + st_lsm6dsx_odr_table[id].reg.addr, + st_lsm6dsx_odr_table[id].reg.mask, + val); + if (err < 0) + return err; + + sensor->odr = odr; + + return 0; +} + +int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor) +{ + int err; + + err = st_lsm6dsx_set_odr(sensor, sensor->odr); + if (err < 0) + return err; + + sensor->hw->enable_mask |= BIT(sensor->id); + + return 0; +} + +int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor) +{ + enum st_lsm6dsx_sensor_id id = sensor->id; + int err; + + err = st_lsm6dsx_write_with_mask(sensor->hw, + st_lsm6dsx_odr_table[id].reg.addr, + st_lsm6dsx_odr_table[id].reg.mask, 0); + if (err < 0) + return err; + + sensor->hw->enable_mask &= ~BIT(id); + + return 0; +} + +static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, + u8 addr, int *val) +{ + int err, delay; + __le16 data; + + err = st_lsm6dsx_sensor_enable(sensor); + if (err < 0) + return err; + + delay = 1000000 / sensor->odr; + usleep_range(delay, 2 * delay); + + err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data), + (u8 *)&data); + if (err < 0) + return err; + + st_lsm6dsx_sensor_disable(sensor); + + *val = (s16)data; + + return IIO_VAL_INT; +} + +static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *ch, + int *val, int *val2, long mask) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(iio_dev); + if (ret) + break; + + ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); + iio_device_release_direct_mode(iio_dev); + break; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = sensor->odr; + ret = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = sensor->gain; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + int err; + + err = iio_device_claim_direct_mode(iio_dev); + if (err) + return err; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + err = st_lsm6dsx_set_full_scale(sensor, val2); + break; + case IIO_CHAN_INFO_SAMP_FREQ: + err = st_lsm6dsx_set_odr(sensor, val); + break; + default: + err = -EINVAL; + break; + } + + iio_device_release_direct_mode(iio_dev); + + return err; +} + +static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + struct st_lsm6dsx_hw *hw = sensor->hw; + int err, max_fifo_len; + + max_fifo_len = hw->settings->max_fifo_size / ST_LSM6DSX_SAMPLE_SIZE; + if (val < 1 || val > max_fifo_len) + return -EINVAL; + + err = st_lsm6dsx_update_watermark(sensor, val); + if (err < 0) + return err; + + sensor->watermark = val; + + return 0; +} + +static ssize_t +st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); + enum st_lsm6dsx_sensor_id id = sensor->id; + int i, len = 0; + + for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) + len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", + st_lsm6dsx_odr_table[id].odr_avl[i].hz); + buf[len - 1] = '\n'; + + return len; +} + +static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); + enum st_lsm6dsx_sensor_id id = sensor->id; + int i, len = 0; + + for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", + st_lsm6dsx_fs_table[id].fs_avl[i].gain); + buf[len - 1] = '\n'; + + return len; +} + +static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); +static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, + st_lsm6dsx_sysfs_scale_avail, NULL, 0); +static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, + st_lsm6dsx_sysfs_scale_avail, NULL, 0); + +static struct attribute *st_lsm6dsx_acc_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_accel_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group st_lsm6dsx_acc_attribute_group = { + .attrs = st_lsm6dsx_acc_attributes, +}; + +static const struct iio_info st_lsm6dsx_acc_info = { + .driver_module = THIS_MODULE, + .attrs = &st_lsm6dsx_acc_attribute_group, + .read_raw = st_lsm6dsx_read_raw, + .write_raw = st_lsm6dsx_write_raw, + .hwfifo_set_watermark = st_lsm6dsx_set_watermark, +}; + +static struct attribute *st_lsm6dsx_gyro_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { + .attrs = st_lsm6dsx_gyro_attributes, +}; + +static const struct iio_info st_lsm6dsx_gyro_info = { + .driver_module = THIS_MODULE, + .attrs = &st_lsm6dsx_gyro_attribute_group, + .read_raw = st_lsm6dsx_read_raw, + .write_raw = st_lsm6dsx_write_raw, + .hwfifo_set_watermark = st_lsm6dsx_set_watermark, +}; + +static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; + +static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) +{ + struct device_node *np = hw->dev->of_node; + int err; + + if (!np) + return -EINVAL; + + err = of_property_read_u32(np, "st,drdy-int-pin", drdy_pin); + if (err == -ENODATA) { + /* if the property has not been specified use default value */ + *drdy_pin = 1; + err = 0; + } + + return err; +} + +static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg) +{ + int err = 0, drdy_pin; + + if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) { + struct st_sensors_platform_data *pdata; + struct device *dev = hw->dev; + + pdata = (struct st_sensors_platform_data *)dev->platform_data; + drdy_pin = pdata ? pdata->drdy_int_pin : 1; + } + + switch (drdy_pin) { + case 1: + *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR; + break; + case 2: + *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR; + break; + default: + dev_err(hw->dev, "unsupported data ready pin\n"); + err = -EINVAL; + break; + } + + return err; +} + +static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) +{ + u8 data, drdy_int_reg; + int err; + + data = ST_LSM6DSX_REG_RESET_MASK; + err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_RESET_ADDR, sizeof(data), + &data); + if (err < 0) + return err; + + msleep(200); + + /* latch interrupts */ + err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_LIR_ADDR, + ST_LSM6DSX_REG_LIR_MASK, 1); + if (err < 0) + return err; + + /* enable Block Data Update */ + err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_BDU_ADDR, + ST_LSM6DSX_REG_BDU_MASK, 1); + if (err < 0) + return err; + + err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_ROUNDING_ADDR, + ST_LSM6DSX_REG_ROUNDING_MASK, 1); + if (err < 0) + return err; + + /* enable FIFO watermak interrupt */ + err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg); + if (err < 0) + return err; + + return st_lsm6dsx_write_with_mask(hw, drdy_int_reg, + ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 1); +} + +static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, + enum st_lsm6dsx_sensor_id id) +{ + struct st_lsm6dsx_sensor *sensor; + struct iio_dev *iio_dev; + + iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); + if (!iio_dev) + return NULL; + + iio_dev->modes = INDIO_DIRECT_MODE; + iio_dev->dev.parent = hw->dev; + iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; + + sensor = iio_priv(iio_dev); + sensor->id = id; + sensor->hw = hw; + sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz; + sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain; + sensor->watermark = 1; + + switch (id) { + case ST_LSM6DSX_ID_ACC: + iio_dev->channels = st_lsm6dsx_acc_channels; + iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels); + iio_dev->name = "lsm6dsx_accel"; + iio_dev->info = &st_lsm6dsx_acc_info; + + sensor->decimator_mask = ST_LSM6DSX_REG_ACC_DEC_MASK; + break; + case ST_LSM6DSX_ID_GYRO: + iio_dev->channels = st_lsm6dsx_gyro_channels; + iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels); + iio_dev->name = "lsm6dsx_gyro"; + iio_dev->info = &st_lsm6dsx_gyro_info; + + sensor->decimator_mask = ST_LSM6DSX_REG_GYRO_DEC_MASK; + break; + default: + return NULL; + } + + return iio_dev; +} + +int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, + const struct st_lsm6dsx_transfer_function *tf_ops) +{ + struct st_lsm6dsx_hw *hw; + int i, err; + + hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); + if (!hw) + return -ENOMEM; + + dev_set_drvdata(dev, (void *)hw); + + mutex_init(&hw->lock); + mutex_init(&hw->fifo_lock); + + hw->dev = dev; + hw->irq = irq; + hw->tf = tf_ops; + + err = st_lsm6dsx_check_whoami(hw, hw_id); + if (err < 0) + return err; + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i); + if (!hw->iio_devs[i]) + return -ENOMEM; + } + + err = st_lsm6dsx_init_device(hw); + if (err < 0) + return err; + + if (hw->irq > 0) { + err = st_lsm6dsx_fifo_setup(hw); + if (err < 0) + return err; + } + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); + if (err) + return err; + } + + return 0; +} +EXPORT_SYMBOL(st_lsm6dsx_probe); + +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c new file mode 100644 index 000000000000..ea3041186e1e --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -0,0 +1,101 @@ +/* + * STMicroelectronics st_lsm6dsx i2c driver + * + * Copyright 2016 STMicroelectronics Inc. + * + * Lorenzo Bianconi <lorenzo.bianconi@st.com> + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/of.h> + +#include "st_lsm6dsx.h" + +static int st_lsm6dsx_i2c_read(struct device *dev, u8 addr, int len, u8 *data) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_msg msg[2]; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].len = 1; + msg[0].buf = &addr; + + msg[1].addr = client->addr; + msg[1].flags = client->flags | I2C_M_RD; + msg[1].len = len; + msg[1].buf = data; + + return i2c_transfer(client->adapter, msg, 2); +} + +static int st_lsm6dsx_i2c_write(struct device *dev, u8 addr, int len, u8 *data) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_msg msg; + u8 send[len + 1]; + + send[0] = addr; + memcpy(&send[1], data, len * sizeof(u8)); + + msg.addr = client->addr; + msg.flags = client->flags; + msg.len = len + 1; + msg.buf = send; + + return i2c_transfer(client->adapter, &msg, 1); +} + +static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = { + .read = st_lsm6dsx_i2c_read, + .write = st_lsm6dsx_i2c_write, +}; + +static int st_lsm6dsx_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + return st_lsm6dsx_probe(&client->dev, client->irq, + (int)id->driver_data, + &st_lsm6dsx_transfer_fn); +} + +static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { + { + .compatible = "st,lsm6ds3", + .data = (void *)ST_LSM6DS3_ID, + }, + { + .compatible = "st,lsm6dsm", + .data = (void *)ST_LSM6DSM_ID, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); + +static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { + { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID }, + { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); + +static struct i2c_driver st_lsm6dsx_driver = { + .driver = { + .name = "st_lsm6dsx_i2c", + .of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match), + }, + .probe = st_lsm6dsx_i2c_probe, + .id_table = st_lsm6dsx_i2c_id_table, +}; +module_i2c_driver(st_lsm6dsx_driver); + +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i2c driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c new file mode 100644 index 000000000000..fbe72470ed1e --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -0,0 +1,118 @@ +/* + * STMicroelectronics st_lsm6dsx spi driver + * + * Copyright 2016 STMicroelectronics Inc. + * + * Lorenzo Bianconi <lorenzo.bianconi@st.com> + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spi/spi.h> +#include <linux/slab.h> +#include <linux/of.h> + +#include "st_lsm6dsx.h" + +#define SENSORS_SPI_READ BIT(7) + +static int st_lsm6dsx_spi_read(struct device *dev, u8 addr, int len, + u8 *data) +{ + struct spi_device *spi = to_spi_device(dev); + struct st_lsm6dsx_hw *hw = spi_get_drvdata(spi); + int err; + + struct spi_transfer xfers[] = { + { + .tx_buf = hw->tb.tx_buf, + .bits_per_word = 8, + .len = 1, + }, + { + .rx_buf = hw->tb.rx_buf, + .bits_per_word = 8, + .len = len, + } + }; + + hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ; + + err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); + if (err < 0) + return err; + + memcpy(data, hw->tb.rx_buf, len * sizeof(u8)); + + return len; +} + +static int st_lsm6dsx_spi_write(struct device *dev, u8 addr, int len, + u8 *data) +{ + struct st_lsm6dsx_hw *hw; + struct spi_device *spi; + + if (len >= ST_LSM6DSX_TX_MAX_LENGTH) + return -ENOMEM; + + spi = to_spi_device(dev); + hw = spi_get_drvdata(spi); + + hw->tb.tx_buf[0] = addr; + memcpy(&hw->tb.tx_buf[1], data, len); + + return spi_write(spi, hw->tb.tx_buf, len + 1); +} + +static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = { + .read = st_lsm6dsx_spi_read, + .write = st_lsm6dsx_spi_write, +}; + +static int st_lsm6dsx_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + + return st_lsm6dsx_probe(&spi->dev, spi->irq, + (int)id->driver_data, + &st_lsm6dsx_transfer_fn); +} + +static const struct of_device_id st_lsm6dsx_spi_of_match[] = { + { + .compatible = "st,lsm6ds3", + .data = (void *)ST_LSM6DS3_ID, + }, + { + .compatible = "st,lsm6dsm", + .data = (void *)ST_LSM6DSM_ID, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); + +static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { + { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID }, + { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID }, + {}, +}; +MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); + +static struct spi_driver st_lsm6dsx_driver = { + .driver = { + .name = "st_lsm6dsx_spi", + .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match), + }, + .probe = st_lsm6dsx_spi_probe, + .id_table = st_lsm6dsx_spi_id_table, +}; +module_spi_driver(st_lsm6dsx_driver); + +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx spi driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index b12830b09c7d..4972986f6455 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -26,6 +26,7 @@ #include "iio_core.h" #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/buffer_impl.h> static const char * const iio_endian_prefix[] = { [IIO_BE] = "be", @@ -209,6 +210,18 @@ void iio_buffer_init(struct iio_buffer *buffer) } EXPORT_SYMBOL(iio_buffer_init); +/** + * iio_buffer_set_attrs - Set buffer specific attributes + * @buffer: The buffer for which we are setting attributes + * @attrs: Pointer to a null terminated list of pointers to attributes + */ +void iio_buffer_set_attrs(struct iio_buffer *buffer, + const struct attribute **attrs) +{ + buffer->attrs = attrs; +} +EXPORT_SYMBOL_GPL(iio_buffer_set_attrs); + static ssize_t iio_show_scan_index(struct device *dev, struct device_attribute *attr, char *buf) @@ -346,6 +359,19 @@ static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) return 0; } +static int iio_scan_mask_query(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit) +{ + if (bit > indio_dev->masklength) + return -EINVAL; + + if (!buffer->scan_mask) + return 0; + + /* Ensure return value is 0 or 1. */ + return !!test_bit(bit, buffer->scan_mask); +}; + static ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -751,6 +777,135 @@ static int iio_verify_update(struct iio_dev *indio_dev, return 0; } +/** + * struct iio_demux_table - table describing demux memcpy ops + * @from: index to copy from + * @to: index to copy to + * @length: how many bytes to copy + * @l: list head used for management + */ +struct iio_demux_table { + unsigned from; + unsigned to; + unsigned length; + struct list_head l; +}; + +static void iio_buffer_demux_free(struct iio_buffer *buffer) +{ + struct iio_demux_table *p, *q; + list_for_each_entry_safe(p, q, &buffer->demux_list, l) { + list_del(&p->l); + kfree(p); + } +} + +static int iio_buffer_add_demux(struct iio_buffer *buffer, + struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc, + unsigned int length) +{ + + if (*p && (*p)->from + (*p)->length == in_loc && + (*p)->to + (*p)->length == out_loc) { + (*p)->length += length; + } else { + *p = kmalloc(sizeof(**p), GFP_KERNEL); + if (*p == NULL) + return -ENOMEM; + (*p)->from = in_loc; + (*p)->to = out_loc; + (*p)->length = length; + list_add_tail(&(*p)->l, &buffer->demux_list); + } + + return 0; +} + +static int iio_buffer_update_demux(struct iio_dev *indio_dev, + struct iio_buffer *buffer) +{ + int ret, in_ind = -1, out_ind, length; + unsigned in_loc = 0, out_loc = 0; + struct iio_demux_table *p = NULL; + + /* Clear out any old demux */ + iio_buffer_demux_free(buffer); + kfree(buffer->demux_bounce); + buffer->demux_bounce = NULL; + + /* First work out which scan mode we will actually have */ + if (bitmap_equal(indio_dev->active_scan_mask, + buffer->scan_mask, + indio_dev->masklength)) + return 0; + + /* Now we have the two masks, work from least sig and build up sizes */ + for_each_set_bit(out_ind, + buffer->scan_mask, + indio_dev->masklength) { + in_ind = find_next_bit(indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind + 1); + while (in_ind != out_ind) { + in_ind = find_next_bit(indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind + 1); + length = iio_storage_bytes_for_si(indio_dev, in_ind); + /* Make sure we are aligned */ + in_loc = roundup(in_loc, length) + length; + } + length = iio_storage_bytes_for_si(indio_dev, in_ind); + out_loc = roundup(out_loc, length); + in_loc = roundup(in_loc, length); + ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); + if (ret) + goto error_clear_mux_table; + out_loc += length; + in_loc += length; + } + /* Relies on scan_timestamp being last */ + if (buffer->scan_timestamp) { + length = iio_storage_bytes_for_timestamp(indio_dev); + out_loc = roundup(out_loc, length); + in_loc = roundup(in_loc, length); + ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); + if (ret) + goto error_clear_mux_table; + out_loc += length; + in_loc += length; + } + buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL); + if (buffer->demux_bounce == NULL) { + ret = -ENOMEM; + goto error_clear_mux_table; + } + return 0; + +error_clear_mux_table: + iio_buffer_demux_free(buffer); + + return ret; +} + +static int iio_update_demux(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer; + int ret; + + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) { + ret = iio_buffer_update_demux(indio_dev, buffer); + if (ret < 0) + goto error_clear_mux_table; + } + return 0; + +error_clear_mux_table: + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) + iio_buffer_demux_free(buffer); + + return ret; +} + static int iio_enable_buffers(struct iio_dev *indio_dev, struct iio_device_config *config) { @@ -1199,34 +1354,6 @@ bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, } EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot); -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) -{ - if (bit > indio_dev->masklength) - return -EINVAL; - - if (!buffer->scan_mask) - return 0; - - /* Ensure return value is 0 or 1. */ - return !!test_bit(bit, buffer->scan_mask); -}; -EXPORT_SYMBOL_GPL(iio_scan_mask_query); - -/** - * struct iio_demux_table - table describing demux memcpy ops - * @from: index to copy from - * @to: index to copy to - * @length: how many bytes to copy - * @l: list head used for management - */ -struct iio_demux_table { - unsigned from; - unsigned to; - unsigned length; - struct list_head l; -}; - static const void *iio_demux(struct iio_buffer *buffer, const void *datain) { @@ -1258,16 +1385,11 @@ static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data) return 0; } -static void iio_buffer_demux_free(struct iio_buffer *buffer) -{ - struct iio_demux_table *p, *q; - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } -} - - +/** + * iio_push_to_buffers() - push to a registered buffer. + * @indio_dev: iio_dev structure for device. + * @data: Full scan. + */ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data) { int ret; @@ -1283,113 +1405,6 @@ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data) } EXPORT_SYMBOL_GPL(iio_push_to_buffers); -static int iio_buffer_add_demux(struct iio_buffer *buffer, - struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc, - unsigned int length) -{ - - if (*p && (*p)->from + (*p)->length == in_loc && - (*p)->to + (*p)->length == out_loc) { - (*p)->length += length; - } else { - *p = kmalloc(sizeof(**p), GFP_KERNEL); - if (*p == NULL) - return -ENOMEM; - (*p)->from = in_loc; - (*p)->to = out_loc; - (*p)->length = length; - list_add_tail(&(*p)->l, &buffer->demux_list); - } - - return 0; -} - -static int iio_buffer_update_demux(struct iio_dev *indio_dev, - struct iio_buffer *buffer) -{ - int ret, in_ind = -1, out_ind, length; - unsigned in_loc = 0, out_loc = 0; - struct iio_demux_table *p = NULL; - - /* Clear out any old demux */ - iio_buffer_demux_free(buffer); - kfree(buffer->demux_bounce); - buffer->demux_bounce = NULL; - - /* First work out which scan mode we will actually have */ - if (bitmap_equal(indio_dev->active_scan_mask, - buffer->scan_mask, - indio_dev->masklength)) - return 0; - - /* Now we have the two masks, work from least sig and build up sizes */ - for_each_set_bit(out_ind, - buffer->scan_mask, - indio_dev->masklength) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - while (in_ind != out_ind) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - length = iio_storage_bytes_for_si(indio_dev, in_ind); - /* Make sure we are aligned */ - in_loc = roundup(in_loc, length) + length; - } - length = iio_storage_bytes_for_si(indio_dev, in_ind); - out_loc = roundup(out_loc, length); - in_loc = roundup(in_loc, length); - ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); - if (ret) - goto error_clear_mux_table; - out_loc += length; - in_loc += length; - } - /* Relies on scan_timestamp being last */ - if (buffer->scan_timestamp) { - length = iio_storage_bytes_for_timestamp(indio_dev); - out_loc = roundup(out_loc, length); - in_loc = roundup(in_loc, length); - ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); - if (ret) - goto error_clear_mux_table; - out_loc += length; - in_loc += length; - } - buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL); - if (buffer->demux_bounce == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - return 0; - -error_clear_mux_table: - iio_buffer_demux_free(buffer); - - return ret; -} - -int iio_update_demux(struct iio_dev *indio_dev) -{ - struct iio_buffer *buffer; - int ret; - - list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) { - ret = iio_buffer_update_demux(indio_dev, buffer); - if (ret < 0) - goto error_clear_mux_table; - } - return 0; - -error_clear_mux_table: - list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) - iio_buffer_demux_free(buffer); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_update_demux); - /** * iio_buffer_release() - Free a buffer's resources * @ref: Pointer to the kref embedded in the iio_buffer struct @@ -1431,3 +1446,19 @@ void iio_buffer_put(struct iio_buffer *buffer) kref_put(&buffer->ref, iio_buffer_release); } EXPORT_SYMBOL_GPL(iio_buffer_put); + +/** + * iio_device_attach_buffer - Attach a buffer to a IIO device + * @indio_dev: The device the buffer should be attached to + * @buffer: The buffer to attach to the device + * + * This function attaches a buffer to a IIO device. The buffer stays attached to + * the device until the device is freed. The function should only be called at + * most once per device. + */ +void iio_device_attach_buffer(struct iio_dev *indio_dev, + struct iio_buffer *buffer) +{ + indio_dev->buffer = iio_buffer_get(buffer); +} +EXPORT_SYMBOL_GPL(iio_device_attach_buffer); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index aaca42862389..d18ded45bedd 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -32,6 +32,7 @@ #include <linux/iio/sysfs.h> #include <linux/iio/events.h> #include <linux/iio/buffer.h> +#include <linux/iio/buffer_impl.h> /* IDA to assign each registered device a unique id */ static DEFINE_IDA(iio_ida); @@ -83,6 +84,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity", [IIO_COUNT] = "count", [IIO_INDEX] = "index", + [IIO_GRAVITY] = "gravity", }; static const char * const iio_modifier_names[] = { diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 978729f6d7c4..978e1592c2a3 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -147,8 +147,7 @@ static struct iio_trigger *__iio_trigger_find_by_name(const char *name) return NULL; } -static struct iio_trigger *iio_trigger_find_by_name(const char *name, - size_t len) +static struct iio_trigger *iio_trigger_acquire_by_name(const char *name) { struct iio_trigger *trig = NULL, *iter; @@ -156,6 +155,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, list_for_each_entry(iter, &iio_trigger_list, list) if (sysfs_streq(iter->name, name)) { trig = iter; + iio_trigger_get(trig); break; } mutex_unlock(&iio_trigger_list_lock); @@ -416,20 +416,22 @@ static ssize_t iio_trigger_write_current(struct device *dev, } mutex_unlock(&indio_dev->mlock); - trig = iio_trigger_find_by_name(buf, len); - if (oldtrig == trig) - return len; + trig = iio_trigger_acquire_by_name(buf); + if (oldtrig == trig) { + ret = len; + goto out_trigger_put; + } if (trig && indio_dev->info->validate_trigger) { ret = indio_dev->info->validate_trigger(indio_dev, trig); if (ret) - return ret; + goto out_trigger_put; } if (trig && trig->ops->validate_device) { ret = trig->ops->validate_device(trig, indio_dev); if (ret) - return ret; + goto out_trigger_put; } indio_dev->trig = trig; @@ -441,13 +443,16 @@ static ssize_t iio_trigger_write_current(struct device *dev, iio_trigger_put(oldtrig); } if (indio_dev->trig) { - iio_trigger_get(indio_dev->trig); if (indio_dev->modes & INDIO_EVENT_TRIGGERED) iio_trigger_attach_poll_func(indio_dev->trig, indio_dev->pollfunc_event); } return len; + +out_trigger_put: + iio_trigger_put(trig); + return ret; } static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, @@ -487,7 +492,7 @@ static void iio_trig_release(struct device *device) kfree(trig); } -static struct device_type iio_trig_type = { +static const struct device_type iio_trig_type = { .release = iio_trig_release, .groups = iio_trig_dev_groups, }; @@ -513,46 +518,45 @@ static void iio_trig_subirqunmask(struct irq_data *d) static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) { struct iio_trigger *trig; + int i; + trig = kzalloc(sizeof *trig, GFP_KERNEL); - if (trig) { - int i; - trig->dev.type = &iio_trig_type; - trig->dev.bus = &iio_bus_type; - device_initialize(&trig->dev); - - mutex_init(&trig->pool_lock); - trig->subirq_base - = irq_alloc_descs(-1, 0, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - 0); - if (trig->subirq_base < 0) { - kfree(trig); - return NULL; - } + if (!trig) + return NULL; - trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); - if (trig->name == NULL) { - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - kfree(trig); - return NULL; - } - trig->subirq_chip.name = trig->name; - trig->subirq_chip.irq_mask = &iio_trig_subirqmask; - trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_set_chip(trig->subirq_base + i, - &trig->subirq_chip); - irq_set_handler(trig->subirq_base + i, - &handle_simple_irq); - irq_modify_status(trig->subirq_base + i, - IRQ_NOREQUEST | IRQ_NOAUTOEN, - IRQ_NOPROBE); - } - get_device(&trig->dev); + trig->dev.type = &iio_trig_type; + trig->dev.bus = &iio_bus_type; + device_initialize(&trig->dev); + + mutex_init(&trig->pool_lock); + trig->subirq_base = irq_alloc_descs(-1, 0, + CONFIG_IIO_CONSUMERS_PER_TRIGGER, + 0); + if (trig->subirq_base < 0) + goto free_trig; + + trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); + if (trig->name == NULL) + goto free_descs; + + trig->subirq_chip.name = trig->name; + trig->subirq_chip.irq_mask = &iio_trig_subirqmask; + trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { + irq_set_chip(trig->subirq_base + i, &trig->subirq_chip); + irq_set_handler(trig->subirq_base + i, &handle_simple_irq); + irq_modify_status(trig->subirq_base + i, + IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); } + get_device(&trig->dev); return trig; + +free_descs: + irq_free_descs(trig->subirq_base, CONFIG_IIO_CONSUMERS_PER_TRIGGER); +free_trig: + kfree(trig); + return NULL; } struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b0f4630a163f..7a13535dc3e9 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -601,8 +601,14 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, scale_type = iio_channel_read(chan, &scale_val, &scale_val2, IIO_CHAN_INFO_SCALE); - if (scale_type < 0) - return scale_type; + if (scale_type < 0) { + /* + * Just pass raw values as processed if no scaling is + * available. + */ + *processed = raw; + return 0; + } switch (scale_type) { case IIO_VAL_INT: diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 298ea5081a96..5f731ead9d46 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -115,6 +115,16 @@ config CM3323 To compile this driver as a module, choose M here: the module will be called cm3323. +config CM3605 + tristate "Capella CM3605 ambient light and proximity sensor" + depends on OF + help + Say Y here if you want to build a driver for Capella CM3605 + ambient light and short range proximity sensor. + + To compile this driver as a module, choose M here: the module will + be called cm3605. + config CM36651 depends on I2C tristate "CM36651 driver" diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 4de520036e6e..c13a2399e6df 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_BH1780) += bh1780.o obj-$(CONFIG_CM32181) += cm32181.o obj-$(CONFIG_CM3232) += cm3232.o obj-$(CONFIG_CM3323) += cm3323.o +obj-$(CONFIG_CM3605) += cm3605.o obj-$(CONFIG_CM36651) += cm36651.o obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index fe89b6823217..263e97235ea0 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -119,7 +119,7 @@ static int cm3232_reg_init(struct cm3232_chip *chip) if (ret < 0) dev_err(&chip->client->dev, "Error writing reg_cmd\n"); - return 0; + return ret; } /** diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c new file mode 100644 index 000000000000..980624e9ffb5 --- /dev/null +++ b/drivers/iio/light/cm3605.c @@ -0,0 +1,330 @@ +/* + * CM3605 Ambient Light and Proximity Sensor + * + * Copyright (C) 2016 Linaro Ltd. + * Author: Linus Walleij <linus.walleij@linaro.org> + * + * This hardware was found in the very first Nexus One handset from Google/HTC + * and an early endavour into mobile light and proximity sensors. + */ + +#include <linux/module.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/consumer.h> /* To get our ADC channel */ +#include <linux/iio/types.h> /* To deal with our ADC channel */ +#include <linux/init.h> +#include <linux/leds.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/math64.h> +#include <linux/pm.h> + +#define CM3605_PROX_CHANNEL 0 +#define CM3605_ALS_CHANNEL 1 +#define CM3605_AOUT_TYP_MAX_MV 1550 +/* It should not go above 1.650V according to the data sheet */ +#define CM3605_AOUT_MAX_MV 1650 + +/** + * struct cm3605 - CM3605 state + * @dev: pointer to parent device + * @vdd: regulator controlling VDD + * @aset: sleep enable GPIO, high = sleep + * @aout: IIO ADC channel to convert the AOUT signal + * @als_max: maximum LUX detection (depends on RSET) + * @dir: proximity direction: start as FALLING + * @led: trigger for the infrared LED used by the proximity sensor + */ +struct cm3605 { + struct device *dev; + struct regulator *vdd; + struct gpio_desc *aset; + struct iio_channel *aout; + s32 als_max; + enum iio_event_direction dir; + struct led_trigger *led; +}; + +static irqreturn_t cm3605_prox_irq(int irq, void *d) +{ + struct iio_dev *indio_dev = d; + struct cm3605 *cm3605 = iio_priv(indio_dev); + u64 ev; + + ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, CM3605_PROX_CHANNEL, + IIO_EV_TYPE_THRESH, cm3605->dir); + iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev)); + + /* Invert the edge for each event */ + if (cm3605->dir == IIO_EV_DIR_RISING) + cm3605->dir = IIO_EV_DIR_FALLING; + else + cm3605->dir = IIO_EV_DIR_RISING; + + return IRQ_HANDLED; +} + +static int cm3605_get_lux(struct cm3605 *cm3605) +{ + int ret, res; + s64 lux; + + ret = iio_read_channel_processed(cm3605->aout, &res); + if (ret < 0) + return ret; + + dev_dbg(cm3605->dev, "read %d mV from ADC\n", res); + + /* + * AOUT has an offset of ~30mV then linear at dark + * then goes from 2.54 up to 650 LUX yielding 1.55V + * (1550 mV) so scale the returned value to this interval + * using simple linear interpolation. + */ + if (res < 30) + return 0; + if (res > CM3605_AOUT_MAX_MV) + dev_err(cm3605->dev, "device out of range\n"); + + /* Remove bias */ + lux = res - 30; + + /* Linear interpolation between 0 and ALS typ max */ + lux *= cm3605->als_max; + lux = div64_s64(lux, CM3605_AOUT_TYP_MAX_MV); + + return lux; +} + +static int cm3605_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct cm3605 *cm3605 = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_LIGHT: + ret = cm3605_get_lux(cm3605); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static const struct iio_info cm3605_info = { + .driver_module = THIS_MODULE, + .read_raw = cm3605_read_raw, +}; + +static const struct iio_event_spec cm3605_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + }, +}; + +static const struct iio_chan_spec cm3605_channels[] = { + { + .type = IIO_PROXIMITY, + .event_spec = cm3605_events, + .num_event_specs = ARRAY_SIZE(cm3605_events), + }, + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .channel = CM3605_ALS_CHANNEL, + }, +}; + +static int cm3605_probe(struct platform_device *pdev) +{ + struct cm3605 *cm3605; + struct iio_dev *indio_dev; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + enum iio_chan_type ch_type; + u32 rset; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*cm3605)); + if (!indio_dev) + return -ENOMEM; + platform_set_drvdata(pdev, indio_dev); + + cm3605 = iio_priv(indio_dev); + cm3605->dev = dev; + cm3605->dir = IIO_EV_DIR_FALLING; + + ret = of_property_read_u32(np, "capella,aset-resistance-ohms", &rset); + if (ret) { + dev_info(dev, "no RSET specified, assuming 100K\n"); + rset = 100000; + } + switch (rset) { + case 50000: + cm3605->als_max = 650; + break; + case 100000: + cm3605->als_max = 300; + break; + case 300000: + cm3605->als_max = 100; + break; + case 600000: + cm3605->als_max = 50; + break; + default: + dev_info(dev, "non-standard resistance\n"); + return -EINVAL; + } + + cm3605->aout = devm_iio_channel_get(dev, "aout"); + if (IS_ERR(cm3605->aout)) { + if (PTR_ERR(cm3605->aout) == -ENODEV) { + dev_err(dev, "no ADC, deferring...\n"); + return -EPROBE_DEFER; + } + dev_err(dev, "failed to get AOUT ADC channel\n"); + return PTR_ERR(cm3605->aout); + } + ret = iio_get_channel_type(cm3605->aout, &ch_type); + if (ret < 0) + return ret; + if (ch_type != IIO_VOLTAGE) { + dev_err(dev, "wrong type of IIO channel specified for AOUT\n"); + return -EINVAL; + } + + cm3605->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(cm3605->vdd)) { + dev_err(dev, "failed to get VDD regulator\n"); + return PTR_ERR(cm3605->vdd); + } + ret = regulator_enable(cm3605->vdd); + if (ret) { + dev_err(dev, "failed to enable VDD regulator\n"); + return ret; + } + + cm3605->aset = devm_gpiod_get(dev, "aset", GPIOD_OUT_HIGH); + if (IS_ERR(cm3605->aset)) { + dev_err(dev, "no ASET GPIO\n"); + ret = PTR_ERR(cm3605->aset); + goto out_disable_vdd; + } + + ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), + cm3605_prox_irq, NULL, 0, "cm3605", indio_dev); + if (ret) { + dev_err(dev, "unable to request IRQ\n"); + goto out_disable_aset; + } + + /* Just name the trigger the same as the driver */ + led_trigger_register_simple("cm3605", &cm3605->led); + led_trigger_event(cm3605->led, LED_FULL); + + indio_dev->dev.parent = dev; + indio_dev->info = &cm3605_info; + indio_dev->name = "cm3605"; + indio_dev->channels = cm3605_channels; + indio_dev->num_channels = ARRAY_SIZE(cm3605_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(indio_dev); + if (ret) + goto out_remove_trigger; + dev_info(dev, "Capella Microsystems CM3605 enabled range 0..%d LUX\n", + cm3605->als_max); + + return 0; + +out_remove_trigger: + led_trigger_event(cm3605->led, LED_OFF); + led_trigger_unregister_simple(cm3605->led); +out_disable_aset: + gpiod_set_value_cansleep(cm3605->aset, 0); +out_disable_vdd: + regulator_disable(cm3605->vdd); + return ret; +} + +static int cm3605_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct cm3605 *cm3605 = iio_priv(indio_dev); + + led_trigger_event(cm3605->led, LED_OFF); + led_trigger_unregister_simple(cm3605->led); + gpiod_set_value_cansleep(cm3605->aset, 0); + iio_device_unregister(indio_dev); + regulator_disable(cm3605->vdd); + + return 0; +} + +static int __maybe_unused cm3605_pm_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cm3605 *cm3605 = iio_priv(indio_dev); + + led_trigger_event(cm3605->led, LED_OFF); + regulator_disable(cm3605->vdd); + + return 0; +} + +static int __maybe_unused cm3605_pm_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct cm3605 *cm3605 = iio_priv(indio_dev); + int ret; + + ret = regulator_enable(cm3605->vdd); + if (ret) + dev_err(dev, "failed to enable regulator in resume path\n"); + led_trigger_event(cm3605->led, LED_FULL); + + return 0; +} + +static const struct dev_pm_ops cm3605_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cm3605_pm_suspend, + cm3605_pm_resume) +}; + +static const struct of_device_id cm3605_of_match[] = { + {.compatible = "capella,cm3605"}, + { }, +}; +MODULE_DEVICE_TABLE(of, cm3605_of_match); + +static struct platform_driver cm3605_driver = { + .driver = { + .name = "cm3605", + .of_match_table = cm3605_of_match, + .pm = &cm3605_dev_pm_ops, + }, + .probe = cm3605_probe, + .remove = cm3605_remove, +}; +module_platform_driver(cm3605_driver); + +MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); +MODULE_DESCRIPTION("CM3605 ambient light and proximity sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 8bb1f90ecd51..059d964772c7 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -31,13 +31,17 @@ #include <linux/iio/triggered_buffer.h> #include "../common/hid-sensors/hid-sensor-trigger.h" -#define CHANNEL_SCAN_INDEX_ILLUM 0 +enum { + CHANNEL_SCAN_INDEX_INTENSITY = 0, + CHANNEL_SCAN_INDEX_ILLUM = 1, + CHANNEL_SCAN_INDEX_MAX +}; struct als_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info als_illum; - u32 illum; + u32 illum[CHANNEL_SCAN_INDEX_MAX]; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -55,6 +59,15 @@ static const struct iio_chan_spec als_channels[] = { BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_INTENSITY, + }, + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_ILLUM, } }; @@ -86,6 +99,7 @@ static int als_read_raw(struct iio_dev *indio_dev, switch (mask) { case 0: switch (chan->scan_index) { + case CHANNEL_SCAN_INDEX_INTENSITY: case CHANNEL_SCAN_INDEX_ILLUM: report_id = als_state->als_illum.report_id; address = @@ -202,10 +216,12 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev, struct iio_dev *indio_dev = platform_get_drvdata(priv); struct als_state *als_state = iio_priv(indio_dev); int ret = -EINVAL; + u32 sample_data = *(u32 *)raw_data; switch (usage_id) { case HID_USAGE_SENSOR_LIGHT_ILLUM: - als_state->illum = *(u32 *)raw_data; + als_state->illum[CHANNEL_SCAN_INDEX_INTENSITY] = sample_data; + als_state->illum[CHANNEL_SCAN_INDEX_ILLUM] = sample_data; ret = 0; break; default: @@ -230,6 +246,8 @@ static int als_parse_report(struct platform_device *pdev, &st->als_illum); if (ret < 0) return ret; + als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_INTENSITY, + st->als_illum.size); als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_ILLUM, st->als_illum.size); diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index 78c9b3a6453a..b91ebc3483ce 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -840,6 +840,7 @@ static const struct of_device_id opt3001_of_match[] = { { .compatible = "ti,opt3001" }, { } }; +MODULE_DEVICE_TABLE(of, opt3001_of_match); static struct i2c_driver opt3001_driver = { .probe = opt3001_probe, diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index ce09d771c1fb..6dd8cbd7ce95 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -278,13 +278,9 @@ static int ak8974_await_drdy(struct ak8974 *ak8974) if (val & AK8974_STATUS_DRDY) return 0; } while (--timeout); - if (!timeout) { - dev_err(&ak8974->i2c->dev, - "timeout waiting for DRDY\n"); - return -ETIMEDOUT; - } - return 0; + dev_err(&ak8974->i2c->dev, "timeout waiting for DRDY\n"); + return -ETIMEDOUT; } static int ak8974_getresult(struct ak8974 *ak8974, __le16 *result) diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index f2b3bd7bf862..b4f643fb3b1e 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -222,29 +222,39 @@ static int mag3110_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct mag3110_data *data = iio_priv(indio_dev); - int rate; + int rate, ret; - if (iio_buffer_enabled(indio_dev)) - return -EBUSY; + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: rate = mag3110_get_samp_freq_index(data, val, val2); - if (rate < 0) - return -EINVAL; + if (rate < 0) { + ret = -EINVAL; + break; + } data->ctrl_reg1 &= ~MAG3110_CTRL_DR_MASK; data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT; - return i2c_smbus_write_byte_data(data->client, + ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, data->ctrl_reg1); + break; case IIO_CHAN_INFO_CALIBBIAS: - if (val < -10000 || val > 10000) - return -EINVAL; - return i2c_smbus_write_word_swapped(data->client, + if (val < -10000 || val > 10000) { + ret = -EINVAL; + break; + } + ret = i2c_smbus_write_word_swapped(data->client, MAG3110_OFF_X + 2 * chan->scan_index, val << 1); + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + iio_device_release_direct_mode(indio_dev); + return ret; } static irqreturn_t mag3110_trigger_handler(int irq, void *p) diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig index 2e9da1cf3297..8bf282510be6 100644 --- a/drivers/iio/potentiometer/Kconfig +++ b/drivers/iio/potentiometer/Kconfig @@ -15,6 +15,17 @@ config DS1803 To compile this driver as a module, choose M here: the module will be called ds1803. +config MAX5481 + tristate "Maxim MAX5481-MAX5484 Digital Potentiometer driver" + depends on SPI + help + Say yes here to build support for the Maxim + MAX5481, MAX5482, MAX5483, MAX5484 digital potentiometer + chips. + + To compile this driver as a module, choose M here: the + module will be called max5481. + config MAX5487 tristate "Maxim MAX5487/MAX5488/MAX5489 Digital Potentiometer driver" depends on SPI diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile index 8adb58f38c0b..2260d40e0936 100644 --- a/drivers/iio/potentiometer/Makefile +++ b/drivers/iio/potentiometer/Makefile @@ -4,6 +4,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_DS1803) += ds1803.o +obj-$(CONFIG_MAX5481) += max5481.o obj-$(CONFIG_MAX5487) += max5487.o obj-$(CONFIG_MCP4131) += mcp4131.o obj-$(CONFIG_MCP4531) += mcp4531.o diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c new file mode 100644 index 000000000000..926554991244 --- /dev/null +++ b/drivers/iio/potentiometer/max5481.c @@ -0,0 +1,223 @@ +/* + * Maxim Integrated MAX5481-MAX5484 digital potentiometer driver + * Copyright 2016 Rockwell Collins + * + * Datasheet: + * http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf + * + * 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/acpi.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/spi/spi.h> + +/* write wiper reg */ +#define MAX5481_WRITE_WIPER (0 << 4) +/* copy wiper reg to NV reg */ +#define MAX5481_COPY_AB_TO_NV (2 << 4) +/* copy NV reg to wiper reg */ +#define MAX5481_COPY_NV_TO_AB (3 << 4) + +#define MAX5481_MAX_POS 1023 + +enum max5481_variant { + max5481, + max5482, + max5483, + max5484, +}; + +struct max5481_cfg { + int kohms; +}; + +static const struct max5481_cfg max5481_cfg[] = { + [max5481] = { .kohms = 10, }, + [max5482] = { .kohms = 50, }, + [max5483] = { .kohms = 10, }, + [max5484] = { .kohms = 50, }, +}; + +struct max5481_data { + struct spi_device *spi; + const struct max5481_cfg *cfg; + u8 msg[3] ____cacheline_aligned; +}; + +#define MAX5481_CHANNEL { \ + .type = IIO_RESISTANCE, \ + .indexed = 1, \ + .output = 1, \ + .channel = 0, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec max5481_channels[] = { + MAX5481_CHANNEL, +}; + +static int max5481_write_cmd(struct max5481_data *data, u8 cmd, u16 val) +{ + struct spi_device *spi = data->spi; + + data->msg[0] = cmd; + + switch (cmd) { + case MAX5481_WRITE_WIPER: + data->msg[1] = val >> 2; + data->msg[2] = (val & 0x3) << 6; + return spi_write(spi, data->msg, 3); + + case MAX5481_COPY_AB_TO_NV: + case MAX5481_COPY_NV_TO_AB: + return spi_write(spi, data->msg, 1); + + default: + return -EIO; + } +} + +static int max5481_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max5481_data *data = iio_priv(indio_dev); + + if (mask != IIO_CHAN_INFO_SCALE) + return -EINVAL; + + *val = 1000 * data->cfg->kohms; + *val2 = MAX5481_MAX_POS; + + return IIO_VAL_FRACTIONAL; +} + +static int max5481_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct max5481_data *data = iio_priv(indio_dev); + + if (mask != IIO_CHAN_INFO_RAW) + return -EINVAL; + + if (val < 0 || val > MAX5481_MAX_POS) + return -EINVAL; + + return max5481_write_cmd(data, MAX5481_WRITE_WIPER, val); +} + +static const struct iio_info max5481_info = { + .read_raw = max5481_read_raw, + .write_raw = max5481_write_raw, + .driver_module = THIS_MODULE, +}; + +#if defined(CONFIG_OF) +static const struct of_device_id max5481_match[] = { + { .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] }, + { .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] }, + { .compatible = "maxim,max5483", .data = &max5481_cfg[max5483] }, + { .compatible = "maxim,max5484", .data = &max5481_cfg[max5484] }, + { } +}; +MODULE_DEVICE_TABLE(of, max5481_match); +#endif + +static int max5481_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct max5481_data *data; + const struct spi_device_id *id = spi_get_device_id(spi); + const struct of_device_id *match; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + dev_set_drvdata(&spi->dev, indio_dev); + data = iio_priv(indio_dev); + + data->spi = spi; + + match = of_match_device(of_match_ptr(max5481_match), &spi->dev); + if (match) + data->cfg = of_device_get_match_data(&spi->dev); + else + data->cfg = &max5481_cfg[id->driver_data]; + + indio_dev->name = id->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* variant specific configuration */ + indio_dev->info = &max5481_info; + indio_dev->channels = max5481_channels; + indio_dev->num_channels = ARRAY_SIZE(max5481_channels); + + /* restore wiper from NV */ + ret = max5481_write_cmd(data, MAX5481_COPY_NV_TO_AB, 0); + if (ret < 0) + return ret; + + return iio_device_register(indio_dev); +} + +static int max5481_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev); + struct max5481_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + /* save wiper reg to NV reg */ + return max5481_write_cmd(data, MAX5481_COPY_AB_TO_NV, 0); +} + +static const struct spi_device_id max5481_id_table[] = { + { "max5481", max5481 }, + { "max5482", max5482 }, + { "max5483", max5483 }, + { "max5484", max5484 }, + { } +}; +MODULE_DEVICE_TABLE(spi, max5481_id_table); + +#if defined(CONFIG_ACPI) +static const struct acpi_device_id max5481_acpi_match[] = { + { "max5481", max5481 }, + { "max5482", max5482 }, + { "max5483", max5483 }, + { "max5484", max5484 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, max5481_acpi_match); +#endif + +static struct spi_driver max5481_driver = { + .driver = { + .name = "max5481", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(max5481_match), + .acpi_match_table = ACPI_PTR(max5481_acpi_match), + }, + .probe = max5481_probe, + .remove = max5481_remove, + .id_table = max5481_id_table, +}; + +module_spi_driver(max5481_driver); + +MODULE_AUTHOR("Maury Anderson <maury.anderson@rockwellcollins.com>"); +MODULE_DESCRIPTION("max5481 SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c index 0d1bcf89ae17..314353d7ab59 100644 --- a/drivers/iio/potentiometer/mcp4531.c +++ b/drivers/iio/potentiometer/mcp4531.c @@ -284,6 +284,7 @@ static const struct of_device_id mcp4531_of_match[] = { MCP4531_COMPATIBLE("microchip,mcp4662-104", MCP466x_104), { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, mcp4531_of_match); #endif static int mcp4531_probe(struct i2c_client *client, diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index bd8d96b96771..5d16b252ab6b 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -42,6 +42,16 @@ config BMP280_SPI depends on SPI_MASTER select REGMAP +config IIO_CROS_EC_BARO + tristate "ChromeOS EC Barometer Sensor" + depends on IIO_CROS_EC_SENSORS_CORE + help + Say yes here to build support for the Barometer sensor when + presented by the ChromeOS EC Sensor hub. + + To compile this driver as a module, choose M here: the module + will be called cros_ec_baro. + config HID_SENSOR_PRESS depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index de3dbc81dc5a..838642789389 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_BMP280) += bmp280.o bmp280-objs := bmp280-core.o bmp280-regmap.o obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o +obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_HP03) += hp03.o obj-$(CONFIG_MPL115) += mpl115.o diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index e5a533cbd53f..4d18826ac63c 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -65,7 +65,7 @@ struct bmp280_data { struct bmp180_calib calib; struct regulator *vddd; struct regulator *vdda; - unsigned int start_up_time; /* in milliseconds */ + unsigned int start_up_time; /* in microseconds */ /* log of base 2 of oversampling rate */ u8 oversampling_press; @@ -935,14 +935,14 @@ int bmp280_common_probe(struct device *dev, data->chip_info = &bmp180_chip_info; data->oversampling_press = ilog2(8); data->oversampling_temp = ilog2(1); - data->start_up_time = 10; + data->start_up_time = 10000; break; case BMP280_CHIP_ID: indio_dev->num_channels = 2; data->chip_info = &bmp280_chip_info; data->oversampling_press = ilog2(16); data->oversampling_temp = ilog2(2); - data->start_up_time = 2; + data->start_up_time = 2000; break; case BME280_CHIP_ID: indio_dev->num_channels = 3; @@ -950,7 +950,7 @@ int bmp280_common_probe(struct device *dev, data->oversampling_press = ilog2(16); data->oversampling_humid = ilog2(16); data->oversampling_temp = ilog2(2); - data->start_up_time = 2; + data->start_up_time = 2000; break; default: return -EINVAL; @@ -979,7 +979,7 @@ int bmp280_common_probe(struct device *dev, goto out_disable_vddd; } /* Wait to make sure we started up properly */ - mdelay(data->start_up_time); + usleep_range(data->start_up_time, data->start_up_time + 100); /* Bring chip out of reset if there is an assigned GPIO line */ gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); @@ -1038,7 +1038,7 @@ int bmp280_common_probe(struct device *dev, * Set autosuspend to two orders of magnitude larger than the * start-up time. */ - pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100); + pm_runtime_set_autosuspend_delay(dev, data->start_up_time / 10); pm_runtime_use_autosuspend(dev); pm_runtime_put(dev); @@ -1101,7 +1101,7 @@ static int bmp280_runtime_resume(struct device *dev) ret = regulator_enable(data->vdda); if (ret) return ret; - msleep(data->start_up_time); + usleep_range(data->start_up_time, data->start_up_time + 100); return data->chip_info->chip_config(data); } #endif /* CONFIG_PM */ diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c new file mode 100644 index 000000000000..48b2a30f57ae --- /dev/null +++ b/drivers/iio/pressure/cros_ec_baro.c @@ -0,0 +1,220 @@ +/* + * cros_ec_baro - Driver for barometer sensor behind CrosEC. + * + * Copyright (C) 2017 Google, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/delay.h> +#include <linux/device.h> +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/kernel.h> +#include <linux/mfd/cros_ec.h> +#include <linux/mfd/cros_ec_commands.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#include "../common/cros_ec_sensors/cros_ec_sensors_core.h" + +/* + * One channel for pressure, the other for timestamp. + */ +#define CROS_EC_BARO_MAX_CHANNELS (1 + 1) + +/* State data for ec_sensors iio driver. */ +struct cros_ec_baro_state { + /* Shared by all sensors */ + struct cros_ec_sensors_core_state core; + + struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS]; +}; + +static int cros_ec_baro_read(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct cros_ec_baro_state *st = iio_priv(indio_dev); + u16 data = 0; + int ret = IIO_VAL_INT; + int idx = chan->scan_index; + + mutex_lock(&st->core.cmd_lock); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (cros_ec_sensors_read_cmd(indio_dev, 1 << idx, + (s16 *)&data) < 0) + ret = -EIO; + *val = data; + break; + case IIO_CHAN_INFO_SCALE: + st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; + st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE; + + if (cros_ec_motion_send_host_cmd(&st->core, 0)) { + ret = -EIO; + break; + } + *val = st->core.resp->sensor_range.ret; + + /* scale * in_pressure_raw --> kPa */ + *val2 = 10 << CROS_EC_SENSOR_BITS; + ret = IIO_VAL_FRACTIONAL; + break; + default: + ret = cros_ec_sensors_core_read(&st->core, chan, val, val2, + mask); + break; + } + + mutex_unlock(&st->core.cmd_lock); + + return ret; +} + +static int cros_ec_baro_write(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct cros_ec_baro_state *st = iio_priv(indio_dev); + int ret = 0; + + mutex_lock(&st->core.cmd_lock); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; + st->core.param.sensor_range.data = val; + + /* Always roundup, so caller gets at least what it asks for. */ + st->core.param.sensor_range.roundup = 1; + + if (cros_ec_motion_send_host_cmd(&st->core, 0)) + ret = -EIO; + break; + default: + ret = cros_ec_sensors_core_write(&st->core, chan, val, val2, + mask); + break; + } + + mutex_unlock(&st->core.cmd_lock); + + return ret; +} + +static const struct iio_info cros_ec_baro_info = { + .read_raw = &cros_ec_baro_read, + .write_raw = &cros_ec_baro_write, + .driver_module = THIS_MODULE, +}; + +static int cros_ec_baro_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); + struct cros_ec_device *ec_device; + struct iio_dev *indio_dev; + struct cros_ec_baro_state *state; + struct iio_chan_spec *channel; + int ret; + + if (!ec_dev || !ec_dev->ec_dev) { + dev_warn(dev, "No CROS EC device found.\n"); + return -EINVAL; + } + ec_device = ec_dev->ec_dev; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + ret = cros_ec_sensors_core_init(pdev, indio_dev, true); + if (ret) + return ret; + + indio_dev->info = &cros_ec_baro_info; + state = iio_priv(indio_dev); + state->core.type = state->core.resp->info.type; + state->core.loc = state->core.resp->info.location; + channel = state->channels; + /* Common part */ + channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + channel->info_mask_shared_by_all = + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_FREQUENCY); + channel->scan_type.realbits = CROS_EC_SENSOR_BITS; + channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; + channel->scan_type.shift = 0; + channel->scan_index = 0; + channel->ext_info = cros_ec_sensors_ext_info; + channel->scan_type.sign = 'u'; + + state->core.calib[0] = 0; + + /* Sensor specific */ + switch (state->core.type) { + case MOTIONSENSE_TYPE_BARO: + channel->type = IIO_PRESSURE; + break; + default: + dev_warn(dev, "Unknown motion sensor\n"); + return -EINVAL; + } + + /* Timestamp */ + channel++; + channel->type = IIO_TIMESTAMP; + channel->channel = -1; + channel->scan_index = 1; + channel->scan_type.sign = 's'; + channel->scan_type.realbits = 64; + channel->scan_type.storagebits = 64; + + indio_dev->channels = state->channels; + indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS; + + state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + cros_ec_sensors_capture, NULL); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct platform_device_id cros_ec_baro_ids[] = { + { + .name = "cros-ec-baro", + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids); + +static struct platform_driver cros_ec_baro_platform_driver = { + .driver = { + .name = "cros-ec-baro", + }, + .probe = cros_ec_baro_probe, + .id_table = cros_ec_baro_ids, +}; +module_platform_driver(cros_ec_baro_platform_driver); + +MODULE_DESCRIPTION("ChromeOS EC barometer sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c index 73f2f0c46e62..8f2bce213248 100644 --- a/drivers/iio/pressure/mpl115.c +++ b/drivers/iio/pressure/mpl115.c @@ -137,6 +137,7 @@ static const struct iio_chan_spec mpl115_channels[] = { { .type = IIO_TEMP, .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/mpl3115.c b/drivers/iio/pressure/mpl3115.c index cc3f84139157..525644a7442d 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -190,7 +190,7 @@ static const struct iio_chan_spec mpl3115_channels[] = { { .type = IIO_PRESSURE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_index = 0, .scan_type = { .sign = 'u', @@ -203,7 +203,7 @@ static const struct iio_chan_spec mpl3115_channels[] = { { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_index = 1, .scan_type = { .sign = 's', diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 6bd53e702667..2a77a2f15752 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -308,6 +308,7 @@ static int ms5611_write_raw(struct iio_dev *indio_dev, { struct ms5611_state *st = iio_priv(indio_dev); const struct ms5611_osr *osr = NULL; + int ret; if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO) return -EINVAL; @@ -321,12 +322,11 @@ static int ms5611_write_raw(struct iio_dev *indio_dev, if (!osr) return -EINVAL; - mutex_lock(&st->lock); + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&st->lock); - return -EBUSY; - } + mutex_lock(&st->lock); if (chan->type == IIO_TEMP) st->temp_osr = osr; @@ -334,6 +334,8 @@ static int ms5611_write_raw(struct iio_dev *indio_dev, st->pressure_osr = osr; mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); + return 0; } diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index 903a21e46874..7d995937adba 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -14,6 +14,14 @@ #include <linux/types.h> #include <linux/iio/common/st_sensors.h> +enum st_press_type { + LPS001WP, + LPS25H, + LPS331AP, + LPS22HB, + ST_PRESS_MAX, +}; + #define LPS001WP_PRESS_DEV_NAME "lps001wp" #define LPS25H_PRESS_DEV_NAME "lps25h" #define LPS331AP_PRESS_DEV_NAME "lps331ap" diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index e19e0787864c..5f2680855552 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -136,20 +136,21 @@ static const struct iio_chan_spec st_press_1_channels[] = { .address = ST_PRESS_1_OUT_XL_ADDR, .scan_index = 0, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 24, .storagebits = 32, .endianness = IIO_LE, }, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, .address = ST_TEMP_1_OUT_L_ADDR, .scan_index = 1, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_LE, @@ -158,6 +159,7 @@ static const struct iio_chan_spec st_press_1_channels[] = { BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, IIO_CHAN_SOFT_TIMESTAMP(2) }; @@ -168,7 +170,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = { .address = ST_PRESS_LPS001WP_OUT_L_ADDR, .scan_index = 0, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_LE, @@ -182,7 +184,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = { .address = ST_TEMP_LPS001WP_OUT_L_ADDR, .scan_index = 1, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_LE, @@ -200,7 +202,7 @@ static const struct iio_chan_spec st_press_lps22hb_channels[] = { .address = ST_PRESS_1_OUT_XL_ADDR, .scan_index = 0, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 24, .storagebits = 32, .endianness = IIO_LE, diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index ed18701c68c9..17417a4d5a5f 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/acpi.h> #include <linux/i2c.h> #include <linux/iio/iio.h> @@ -43,25 +44,56 @@ MODULE_DEVICE_TABLE(of, st_press_of_match); #define st_press_of_match NULL #endif +#ifdef CONFIG_ACPI +static const struct acpi_device_id st_press_acpi_match[] = { + {"SNO9210", LPS22HB}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, st_press_acpi_match); +#else +#define st_press_acpi_match NULL +#endif + +static const struct i2c_device_id st_press_id_table[] = { + { LPS001WP_PRESS_DEV_NAME, LPS001WP }, + { LPS25H_PRESS_DEV_NAME, LPS25H }, + { LPS331AP_PRESS_DEV_NAME, LPS331AP }, + { LPS22HB_PRESS_DEV_NAME, LPS22HB }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, st_press_id_table); + static int st_press_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct iio_dev *indio_dev; struct st_sensor_data *press_data; - int err; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data)); if (!indio_dev) return -ENOMEM; press_data = iio_priv(indio_dev); - st_sensors_of_i2c_probe(client, st_press_of_match); + + if (client->dev.of_node) { + st_sensors_of_i2c_probe(client, st_press_of_match); + } else if (ACPI_HANDLE(&client->dev)) { + ret = st_sensors_match_acpi_device(&client->dev); + if ((ret < 0) || (ret >= ST_PRESS_MAX)) + return -ENODEV; + + strncpy(client->name, st_press_id_table[ret].name, + sizeof(client->name)); + client->name[sizeof(client->name) - 1] = '\0'; + } else if (!id) + return -ENODEV; st_sensors_i2c_configure(indio_dev, client, press_data); - err = st_press_common_probe(indio_dev); - if (err < 0) - return err; + ret = st_press_common_probe(indio_dev); + if (ret < 0) + return ret; return 0; } @@ -73,18 +105,11 @@ static int st_press_i2c_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id st_press_id_table[] = { - { LPS001WP_PRESS_DEV_NAME }, - { LPS25H_PRESS_DEV_NAME }, - { LPS331AP_PRESS_DEV_NAME }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, st_press_id_table); - static struct i2c_driver st_press_driver = { .driver = { .name = "st-press-i2c", .of_match_table = of_match_ptr(st_press_of_match), + .acpi_match_table = ACPI_PTR(st_press_acpi_match), }, .probe = st_press_i2c_probe, .remove = st_press_i2c_remove, diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index ef4c73db5b53..ab96cb7a0054 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -18,7 +18,7 @@ config AS3935 endmenu -menu "Proximity sensors" +menu "Proximity and distance sensors" config LIDAR_LITE_V2 tristate "PulsedLight LIDAR sensor" @@ -45,4 +45,15 @@ config SX9500 To compile this driver as a module, choose M here: the module will be called sx9500. +config SRF08 + tristate "Devantech SRF08 ultrasonic ranger sensor" + depends on I2C + help + Say Y here to build a driver for Devantech SRF08 ultrasonic + ranger sensor. This driver can be used to measure the distance + of objects. + + To compile this driver as a module, choose M here: the + module will be called srf08. + endmenu diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index 9aadd9a8ee99..e914c2a5dd49 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -5,4 +5,5 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AS3935) += as3935.o obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o +obj-$(CONFIG_SRF08) += srf08.o obj-$(CONFIG_SX9500) += sx9500.o diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 1fa9eefa0982..20c16a08c9d9 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -326,12 +326,14 @@ static int lidar_remove(struct i2c_client *client) static const struct i2c_device_id lidar_id[] = { {"lidar-lite-v2", 0}, + {"lidar-lite-v3", 0}, { }, }; MODULE_DEVICE_TABLE(i2c, lidar_id); static const struct of_device_id lidar_dt_ids[] = { { .compatible = "pulsedlight,lidar-lite-v2" }, + { .compatible = "grmn,lidar-lite-v3" }, { } }; MODULE_DEVICE_TABLE(of, lidar_dt_ids); diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c new file mode 100644 index 000000000000..49316cbf7c60 --- /dev/null +++ b/drivers/iio/proximity/srf08.c @@ -0,0 +1,398 @@ +/* + * srf08.c - Support for Devantech SRF08 ultrasonic ranger + * + * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de> + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * For details about the device see: + * http://www.robot-electronics.co.uk/htm/srf08tech.html + */ + +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +/* registers of SRF08 device */ +#define SRF08_WRITE_COMMAND 0x00 /* Command Register */ +#define SRF08_WRITE_MAX_GAIN 0x01 /* Max Gain Register: 0 .. 31 */ +#define SRF08_WRITE_RANGE 0x02 /* Range Register: 0 .. 255 */ +#define SRF08_READ_SW_REVISION 0x00 /* Software Revision */ +#define SRF08_READ_LIGHT 0x01 /* Light Sensor during last echo */ +#define SRF08_READ_ECHO_1_HIGH 0x02 /* Range of first echo received */ +#define SRF08_READ_ECHO_1_LOW 0x03 /* Range of first echo received */ + +#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */ + +#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */ +#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */ + +struct srf08_data { + struct i2c_client *client; + int sensitivity; /* Gain */ + int range_mm; /* max. Range in mm */ + struct mutex lock; +}; + +/* + * in the documentation one can read about the "Gain" of the device + * which is used here for amplifying the signal and filtering out unwanted + * ones. + * But with ADC's this term is already used differently and that's why it + * is called "Sensitivity" here. + */ +static const int srf08_sensitivity[] = { + 94, 97, 100, 103, 107, 110, 114, 118, + 123, 128, 133, 139, 145, 152, 159, 168, + 177, 187, 199, 212, 227, 245, 265, 288, + 317, 352, 395, 450, 524, 626, 777, 1025 }; + +static int srf08_read_ranging(struct srf08_data *data) +{ + struct i2c_client *client = data->client; + int ret, i; + int waittime; + + mutex_lock(&data->lock); + + ret = i2c_smbus_write_byte_data(data->client, + SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM); + if (ret < 0) { + dev_err(&client->dev, "write command - err: %d\n", ret); + mutex_unlock(&data->lock); + return ret; + } + + /* + * we read here until a correct version number shows up as + * suggested by the documentation + * + * with an ultrasonic speed of 343 m/s and a roundtrip of it + * sleep the expected duration and try to read from the device + * if nothing useful is read try it in a shorter grid + * + * polling for not more than 20 ms should be enough + */ + waittime = 1 + data->range_mm / 172; + msleep(waittime); + for (i = 0; i < 4; i++) { + ret = i2c_smbus_read_byte_data(data->client, + SRF08_READ_SW_REVISION); + + /* check if a valid version number is read */ + if (ret < 255 && ret > 0) + break; + msleep(5); + } + + if (ret >= 255 || ret <= 0) { + dev_err(&client->dev, "device not ready\n"); + mutex_unlock(&data->lock); + return -EIO; + } + + ret = i2c_smbus_read_word_swapped(data->client, + SRF08_READ_ECHO_1_HIGH); + if (ret < 0) { + dev_err(&client->dev, "cannot read distance: ret=%d\n", ret); + mutex_unlock(&data->lock); + return ret; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static int srf08_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct srf08_data *data = iio_priv(indio_dev); + int ret; + + if (channel->type != IIO_DISTANCE) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = srf08_read_ranging(data); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* 1 LSB is 1 cm */ + *val = 0; + *val2 = 10000; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static ssize_t srf08_show_range_mm_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "[0.043 0.043 11.008]\n"); +} + +static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO, + srf08_show_range_mm_available, NULL, 0); + +static ssize_t srf08_show_range_mm(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct srf08_data *data = iio_priv(indio_dev); + + return sprintf(buf, "%d.%03d\n", data->range_mm / 1000, + data->range_mm % 1000); +} + +/* + * set the range of the sensor to an even multiple of 43 mm + * which corresponds to 1 LSB in the register + * + * register value corresponding range + * 0x00 43 mm + * 0x01 86 mm + * 0x02 129 mm + * ... + * 0xFF 11008 mm + */ +static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val) +{ + int ret; + struct i2c_client *client = data->client; + unsigned int mod; + u8 regval; + + ret = val / 43 - 1; + mod = val % 43; + + if (mod || (ret < 0) || (ret > 255)) + return -EINVAL; + + regval = ret; + + mutex_lock(&data->lock); + + ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval); + if (ret < 0) { + dev_err(&client->dev, "write_range - err: %d\n", ret); + mutex_unlock(&data->lock); + return ret; + } + + data->range_mm = val; + + mutex_unlock(&data->lock); + + return 0; +} + +static ssize_t srf08_store_range_mm(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct srf08_data *data = iio_priv(indio_dev); + int ret; + int integer, fract; + + ret = iio_str_to_fixpoint(buf, 100, &integer, &fract); + if (ret) + return ret; + + ret = srf08_write_range_mm(data, integer * 1000 + fract); + if (ret < 0) + return ret; + + return len; +} + +static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR, + srf08_show_range_mm, srf08_store_range_mm, 0); + +static ssize_t srf08_show_sensitivity_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) + len += sprintf(buf + len, "%d ", srf08_sensitivity[i]); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO, + srf08_show_sensitivity_available, NULL, 0); + +static ssize_t srf08_show_sensitivity(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct srf08_data *data = iio_priv(indio_dev); + int len; + + len = sprintf(buf, "%d\n", data->sensitivity); + + return len; +} + +static ssize_t srf08_write_sensitivity(struct srf08_data *data, + unsigned int val) +{ + struct i2c_client *client = data->client; + int ret, i; + u8 regval; + + for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) + if (val == srf08_sensitivity[i]) { + regval = i; + break; + } + + if (i >= ARRAY_SIZE(srf08_sensitivity)) + return -EINVAL; + + mutex_lock(&data->lock); + + ret = i2c_smbus_write_byte_data(client, + SRF08_WRITE_MAX_GAIN, regval); + if (ret < 0) { + dev_err(&client->dev, "write_sensitivity - err: %d\n", ret); + mutex_unlock(&data->lock); + return ret; + } + + data->sensitivity = val; + + mutex_unlock(&data->lock); + + return 0; +} + +static ssize_t srf08_store_sensitivity(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct srf08_data *data = iio_priv(indio_dev); + int ret; + unsigned int val; + + ret = kstrtouint(buf, 10, &val); + if (ret) + return ret; + + ret = srf08_write_sensitivity(data, val); + if (ret < 0) + return ret; + + return len; +} + +static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR, + srf08_show_sensitivity, srf08_store_sensitivity, 0); + +static struct attribute *srf08_attributes[] = { + &iio_dev_attr_sensor_max_range.dev_attr.attr, + &iio_dev_attr_sensor_max_range_available.dev_attr.attr, + &iio_dev_attr_sensor_sensitivity.dev_attr.attr, + &iio_dev_attr_sensor_sensitivity_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group srf08_attribute_group = { + .attrs = srf08_attributes, +}; + +static const struct iio_chan_spec srf08_channels[] = { + { + .type = IIO_DISTANCE, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static const struct iio_info srf08_info = { + .read_raw = srf08_read_raw, + .attrs = &srf08_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int srf08_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct srf08_data *data; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + indio_dev->name = "srf08"; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &srf08_info; + indio_dev->channels = srf08_channels; + indio_dev->num_channels = ARRAY_SIZE(srf08_channels); + + mutex_init(&data->lock); + + /* + * set default values of device here + * these register values cannot be read from the hardware + * therefore set driver specific default values + */ + ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE); + if (ret < 0) + return ret; + + ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN); + if (ret < 0) + return ret; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id srf08_id[] = { + { "srf08", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, srf08_id); + +static struct i2c_driver srf08_driver = { + .driver = { + .name = "srf08", + }, + .probe = srf08_probe, + .id_table = srf08_id, +}; +module_i2c_driver(srf08_driver); + +MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); +MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 1f06282ec793..9ea147f1a50d 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -387,14 +387,18 @@ static int sx9500_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct sx9500_data *data = iio_priv(indio_dev); + int ret; switch (chan->type) { case IIO_PROXIMITY: switch (mask) { case IIO_CHAN_INFO_RAW: - if (iio_buffer_enabled(indio_dev)) - return -EBUSY; - return sx9500_read_proximity(data, chan, val); + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = sx9500_read_proximity(data, chan, val); + iio_device_release_direct_mode(indio_dev); + return ret; case IIO_CHAN_INFO_SAMP_FREQ: return sx9500_read_samp_freq(data, val, val2); default: diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig index 5ea77a7e261d..3089e8d0a32d 100644 --- a/drivers/iio/temperature/Kconfig +++ b/drivers/iio/temperature/Kconfig @@ -39,6 +39,16 @@ config TMP006 This driver can also be built as a module. If so, the module will be called tmp006. +config TMP007 + tristate "TMP007 infrared thermopile sensor with Integrated Math Engine" + depends on I2C + help + If you say yes here you get support for the Texas Instruments + TMP007 infrared thermopile sensor with Integrated Math Engine. + + This driver can also be built as a module. If so, the module will + be called tmp007. + config TSYS01 tristate "Measurement Specialties TSYS01 temperature sensor using I2C bus connection" depends on I2C diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile index 78c3de0dc3f0..4c4377480726 100644 --- a/drivers/iio/temperature/Makefile +++ b/drivers/iio/temperature/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o obj-$(CONFIG_MLX90614) += mlx90614.o obj-$(CONFIG_TMP006) += tmp006.o +obj-$(CONFIG_TMP007) += tmp007.o obj-$(CONFIG_TSYS01) += tsys01.o obj-$(CONFIG_TSYS02D) += tsys02d.o diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c new file mode 100644 index 000000000000..f04d0d1f6ac8 --- /dev/null +++ b/drivers/iio/temperature/tmp007.c @@ -0,0 +1,345 @@ +/* + * tmp007.c - Support for TI TMP007 IR thermopile sensor with integrated math engine + * + * Copyright (c) 2017 Manivannan Sadhasivam <manivannanece23@gmail.com> + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * Driver for the Texas Instruments I2C 16-bit IR thermopile sensor + * + * (7-bit I2C slave address (0x40 - 0x47), changeable via ADR pins) + * + * Note: This driver assumes that the sensor has been calibrated beforehand + * + * TODO: ALERT irq, limit threshold events + * + */ + +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/pm.h> +#include <linux/bitops.h> +#include <linux/of.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define TMP007_TDIE 0x01 +#define TMP007_CONFIG 0x02 +#define TMP007_TOBJECT 0x03 +#define TMP007_STATUS 0x04 +#define TMP007_STATUS_MASK 0x05 +#define TMP007_MANUFACTURER_ID 0x1e +#define TMP007_DEVICE_ID 0x1f + +#define TMP007_CONFIG_CONV_EN BIT(12) +#define TMP007_CONFIG_COMP_EN BIT(5) +#define TMP007_CONFIG_TC_EN BIT(6) +#define TMP007_CONFIG_CR_MASK GENMASK(11, 9) +#define TMP007_CONFIG_CR_SHIFT 9 + +#define TMP007_STATUS_CONV_READY BIT(14) +#define TMP007_STATUS_DATA_VALID BIT(9) + +#define TMP007_MANUFACTURER_MAGIC 0x5449 +#define TMP007_DEVICE_MAGIC 0x0078 + +#define TMP007_TEMP_SHIFT 2 + +struct tmp007_data { + struct i2c_client *client; + u16 config; +}; + +static const int tmp007_avgs[5][2] = { {4, 0}, {2, 0}, {1, 0}, + {0, 500000}, {0, 250000} }; + +static int tmp007_read_temperature(struct tmp007_data *data, u8 reg) +{ + s32 ret; + int tries = 50; + + while (tries-- > 0) { + ret = i2c_smbus_read_word_swapped(data->client, + TMP007_STATUS); + if (ret < 0) + return ret; + if ((ret & TMP007_STATUS_CONV_READY) && + !(ret & TMP007_STATUS_DATA_VALID)) + break; + msleep(100); + } + + if (tries < 0) + return -EIO; + + return i2c_smbus_read_word_swapped(data->client, reg); +} + +static int tmp007_powerdown(struct tmp007_data *data) +{ + return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG, + data->config & ~TMP007_CONFIG_CONV_EN); +} + +static int tmp007_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct tmp007_data *data = iio_priv(indio_dev); + s32 ret; + int conv_rate; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (channel->channel2) { + case IIO_MOD_TEMP_AMBIENT: /* LSB: 0.03125 degree Celsius */ + ret = i2c_smbus_read_word_swapped(data->client, TMP007_TDIE); + if (ret < 0) + return ret; + break; + case IIO_MOD_TEMP_OBJECT: + ret = tmp007_read_temperature(data, TMP007_TOBJECT); + if (ret < 0) + return ret; + break; + default: + return -EINVAL; + } + + *val = sign_extend32(ret, 15) >> TMP007_TEMP_SHIFT; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 31; + *val2 = 250000; + + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_SAMP_FREQ: + conv_rate = (data->config & TMP007_CONFIG_CR_MASK) + >> TMP007_CONFIG_CR_SHIFT; + *val = tmp007_avgs[conv_rate][0]; + *val2 = tmp007_avgs[conv_rate][1]; + + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int tmp007_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int val, + int val2, long mask) +{ + struct tmp007_data *data = iio_priv(indio_dev); + int i; + u16 tmp; + + if (mask == IIO_CHAN_INFO_SAMP_FREQ) { + for (i = 0; i < ARRAY_SIZE(tmp007_avgs); i++) { + if ((val == tmp007_avgs[i][0]) && + (val2 == tmp007_avgs[i][1])) { + tmp = data->config & ~TMP007_CONFIG_CR_MASK; + tmp |= (i << TMP007_CONFIG_CR_SHIFT); + + return i2c_smbus_write_word_swapped(data->client, + TMP007_CONFIG, + data->config = tmp); + } + } + } + + return -EINVAL; +} + +static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25"); + +static struct attribute *tmp007_attributes[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp007_attribute_group = { + .attrs = tmp007_attributes, +}; + +static const struct iio_chan_spec tmp007_channels[] = { + { + .type = IIO_TEMP, + .modified = 1, + .channel2 = IIO_MOD_TEMP_AMBIENT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + }, + { + .type = IIO_TEMP, + .modified = 1, + .channel2 = IIO_MOD_TEMP_OBJECT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + } +}; + +static const struct iio_info tmp007_info = { + .read_raw = tmp007_read_raw, + .write_raw = tmp007_write_raw, + .attrs = &tmp007_attribute_group, + .driver_module = THIS_MODULE, +}; + +static bool tmp007_identify(struct i2c_client *client) +{ + int manf_id, dev_id; + + manf_id = i2c_smbus_read_word_swapped(client, TMP007_MANUFACTURER_ID); + if (manf_id < 0) + return false; + + dev_id = i2c_smbus_read_word_swapped(client, TMP007_DEVICE_ID); + if (dev_id < 0) + return false; + + return (manf_id == TMP007_MANUFACTURER_MAGIC && dev_id == TMP007_DEVICE_MAGIC); +} + +static int tmp007_probe(struct i2c_client *client, + const struct i2c_device_id *tmp007_id) +{ + struct tmp007_data *data; + struct iio_dev *indio_dev; + int ret; + u16 status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) + return -EOPNOTSUPP; + + if (!tmp007_identify(client)) { + dev_err(&client->dev, "TMP007 not found\n"); + return -ENODEV; + } + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = "tmp007"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &tmp007_info; + + indio_dev->channels = tmp007_channels; + indio_dev->num_channels = ARRAY_SIZE(tmp007_channels); + + /* + * Set Configuration register: + * 1. Conversion ON + * 2. Comparator mode + * 3. Transient correction enable + */ + + ret = i2c_smbus_read_word_swapped(data->client, TMP007_CONFIG); + if (ret < 0) + return ret; + + data->config = ret; + data->config |= (TMP007_CONFIG_CONV_EN | TMP007_CONFIG_COMP_EN | TMP007_CONFIG_TC_EN); + + ret = i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG, + data->config); + if (ret < 0) + return ret; + + /* + * Set Status Mask register: + * 1. Conversion ready enable + * 2. Data valid enable + */ + + ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS_MASK); + if (ret < 0) + goto error_powerdown; + + status = ret; + status |= (TMP007_STATUS_CONV_READY | TMP007_STATUS_DATA_VALID); + + ret = i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK, status); + if (ret < 0) + goto error_powerdown; + + return iio_device_register(indio_dev); + +error_powerdown: + tmp007_powerdown(data); + + return ret; +} + +static int tmp007_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct tmp007_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + tmp007_powerdown(data); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int tmp007_suspend(struct device *dev) +{ + struct tmp007_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return tmp007_powerdown(data); +} + +static int tmp007_resume(struct device *dev) +{ + struct tmp007_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG, + data->config | TMP007_CONFIG_CONV_EN); +} +#endif + +static SIMPLE_DEV_PM_OPS(tmp007_pm_ops, tmp007_suspend, tmp007_resume); + +static const struct of_device_id tmp007_of_match[] = { + { .compatible = "ti,tmp007", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tmp007_of_match); + +static const struct i2c_device_id tmp007_id[] = { + { "tmp007", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tmp007_id); + +static struct i2c_driver tmp007_driver = { + .driver = { + .name = "tmp007", + .of_match_table = of_match_ptr(tmp007_of_match), + .pm = &tmp007_pm_ops, + }, + .probe = tmp007_probe, + .remove = tmp007_remove, + .id_table = tmp007_id, +}; +module_i2c_driver(tmp007_driver); + +MODULE_AUTHOR("Manivannan Sadhasivam <manivannanece23@gmail.com>"); +MODULE_DESCRIPTION("TI TMP007 IR thermopile sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig index 809b2e7d58fa..e4d4e63434db 100644 --- a/drivers/iio/trigger/Kconfig +++ b/drivers/iio/trigger/Kconfig @@ -24,6 +24,15 @@ config IIO_INTERRUPT_TRIGGER To compile this driver as a module, choose M here: the module will be called iio-trig-interrupt. +config IIO_STM32_TIMER_TRIGGER + tristate "STM32 Timer Trigger" + depends on (ARCH_STM32 && OF && MFD_STM32_TIMERS) || COMPILE_TEST + help + Select this option to enable STM32 Timer Trigger + + To compile this driver as a module, choose M here: the + module will be called stm32-timer-trigger. + config IIO_TIGHTLOOP_TRIGGER tristate "A kthread based hammering loop trigger" depends on IIO_SW_TRIGGER diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile index aab4dc23303d..5c4ecd380653 100644 --- a/drivers/iio/trigger/Makefile +++ b/drivers/iio/trigger/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o +obj-$(CONFIG_IIO_STM32_TIMER_TRIGGER) += stm32-timer-trigger.o obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o obj-$(CONFIG_IIO_TIGHTLOOP_TRIGGER) += iio-trig-loop.o diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c index 572bc6f02ca8..e18f12b74610 100644 --- a/drivers/iio/trigger/iio-trig-interrupt.c +++ b/drivers/iio/trigger/iio-trig-interrupt.c @@ -58,7 +58,7 @@ static int iio_interrupt_trigger_probe(struct platform_device *pdev) trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); if (!trig_info) { ret = -ENOMEM; - goto error_put_trigger; + goto error_free_trigger; } iio_trigger_set_drvdata(trig, trig_info); trig_info->irq = irq; @@ -83,8 +83,8 @@ error_release_irq: free_irq(irq, trig); error_free_trig_info: kfree(trig_info); -error_put_trigger: - iio_trigger_put(trig); +error_free_trigger: + iio_trigger_free(trig); error_ret: return ret; } @@ -99,7 +99,7 @@ static int iio_interrupt_trigger_remove(struct platform_device *pdev) iio_trigger_unregister(trig); free_irq(trig_info->irq, trig); kfree(trig_info); - iio_trigger_put(trig); + iio_trigger_free(trig); return 0; } diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index 3dfab2bc6d69..202e8b89caf2 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -174,7 +174,7 @@ static int iio_sysfs_trigger_probe(int id) return 0; out2: - iio_trigger_put(t->trig); + iio_trigger_free(t->trig); free_t: kfree(t); out1: diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c new file mode 100644 index 000000000000..994b96d19750 --- /dev/null +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -0,0 +1,342 @@ +/* + * Copyright (C) STMicroelectronics 2016 + * + * Author: Benjamin Gaignard <benjamin.gaignard@st.com> + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/timer/stm32-timer-trigger.h> +#include <linux/iio/trigger.h> +#include <linux/mfd/stm32-timers.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#define MAX_TRIGGERS 6 + +/* List the triggers created by each timer */ +static const void *triggers_table[][MAX_TRIGGERS] = { + { TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,}, + { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,}, + { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,}, + { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,}, + { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,}, + { TIM6_TRGO,}, + { TIM7_TRGO,}, + { TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,}, + { TIM9_TRGO, TIM9_CH1, TIM9_CH2,}, + { }, /* timer 10 */ + { }, /* timer 11 */ + { TIM12_TRGO, TIM12_CH1, TIM12_CH2,}, +}; + +struct stm32_timer_trigger { + struct device *dev; + struct regmap *regmap; + struct clk *clk; + u32 max_arr; + const void *triggers; +}; + +static int stm32_timer_start(struct stm32_timer_trigger *priv, + unsigned int frequency) +{ + unsigned long long prd, div; + int prescaler = 0; + u32 ccer, cr1; + + /* Period and prescaler values depends of clock rate */ + div = (unsigned long long)clk_get_rate(priv->clk); + + do_div(div, frequency); + + prd = div; + + /* + * Increase prescaler value until we get a result that fit + * with auto reload register maximum value. + */ + while (div > priv->max_arr) { + prescaler++; + div = prd; + do_div(div, (prescaler + 1)); + } + prd = div; + + if (prescaler > MAX_TIM_PSC) { + dev_err(priv->dev, "prescaler exceeds the maximum value\n"); + return -EINVAL; + } + + /* Check if nobody else use the timer */ + regmap_read(priv->regmap, TIM_CCER, &ccer); + if (ccer & TIM_CCER_CCXE) + return -EBUSY; + + regmap_read(priv->regmap, TIM_CR1, &cr1); + if (!(cr1 & TIM_CR1_CEN)) + clk_enable(priv->clk); + + regmap_write(priv->regmap, TIM_PSC, prescaler); + regmap_write(priv->regmap, TIM_ARR, prd - 1); + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); + + /* Force master mode to update mode */ + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20); + + /* Make sure that registers are updated */ + regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); + + /* Enable controller */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); + + return 0; +} + +static void stm32_timer_stop(struct stm32_timer_trigger *priv) +{ + u32 ccer, cr1; + + regmap_read(priv->regmap, TIM_CCER, &ccer); + if (ccer & TIM_CCER_CCXE) + return; + + regmap_read(priv->regmap, TIM_CR1, &cr1); + if (cr1 & TIM_CR1_CEN) + clk_disable(priv->clk); + + /* Stop timer */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + regmap_write(priv->regmap, TIM_PSC, 0); + regmap_write(priv->regmap, TIM_ARR, 0); + + /* Make sure that registers are updated */ + regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); +} + +static ssize_t stm32_tt_store_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct stm32_timer_trigger *priv = iio_trigger_get_drvdata(trig); + unsigned int freq; + int ret; + + ret = kstrtouint(buf, 10, &freq); + if (ret) + return ret; + + if (freq == 0) { + stm32_timer_stop(priv); + } else { + ret = stm32_timer_start(priv, freq); + if (ret) + return ret; + } + + return len; +} + +static ssize_t stm32_tt_read_frequency(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct stm32_timer_trigger *priv = iio_trigger_get_drvdata(trig); + u32 psc, arr, cr1; + unsigned long long freq = 0; + + regmap_read(priv->regmap, TIM_CR1, &cr1); + regmap_read(priv->regmap, TIM_PSC, &psc); + regmap_read(priv->regmap, TIM_ARR, &arr); + + if (psc && arr && (cr1 & TIM_CR1_CEN)) { + freq = (unsigned long long)clk_get_rate(priv->clk); + do_div(freq, psc); + do_div(freq, arr); + } + + return sprintf(buf, "%d\n", (unsigned int)freq); +} + +static IIO_DEV_ATTR_SAMP_FREQ(0660, + stm32_tt_read_frequency, + stm32_tt_store_frequency); + +static char *master_mode_table[] = { + "reset", + "enable", + "update", + "compare_pulse", + "OC1REF", + "OC2REF", + "OC3REF", + "OC4REF" +}; + +static ssize_t stm32_tt_show_master_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct stm32_timer_trigger *priv = iio_priv(indio_dev); + u32 cr2; + + regmap_read(priv->regmap, TIM_CR2, &cr2); + cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT; + + return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]); +} + +static ssize_t stm32_tt_store_master_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct stm32_timer_trigger *priv = iio_priv(indio_dev); + int i; + + for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) { + if (!strncmp(master_mode_table[i], buf, + strlen(master_mode_table[i]))) { + regmap_update_bits(priv->regmap, TIM_CR2, + TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT); + /* Make sure that registers are updated */ + regmap_update_bits(priv->regmap, TIM_EGR, + TIM_EGR_UG, TIM_EGR_UG); + return len; + } + } + + return -EINVAL; +} + +static IIO_CONST_ATTR(master_mode_available, + "reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF"); + +static IIO_DEVICE_ATTR(master_mode, 0660, + stm32_tt_show_master_mode, + stm32_tt_store_master_mode, + 0); + +static struct attribute *stm32_trigger_attrs[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_master_mode.dev_attr.attr, + &iio_const_attr_master_mode_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group stm32_trigger_attr_group = { + .attrs = stm32_trigger_attrs, +}; + +static const struct attribute_group *stm32_trigger_attr_groups[] = { + &stm32_trigger_attr_group, + NULL, +}; + +static const struct iio_trigger_ops timer_trigger_ops = { + .owner = THIS_MODULE, +}; + +static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) +{ + int ret; + const char * const *cur = priv->triggers; + + while (cur && *cur) { + struct iio_trigger *trig; + + trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur); + if (!trig) + return -ENOMEM; + + trig->dev.parent = priv->dev->parent; + trig->ops = &timer_trigger_ops; + + /* + * sampling frequency and master mode attributes + * should only be available on trgo trigger which + * is always the first in the list. + */ + if (cur == priv->triggers) + trig->dev.groups = stm32_trigger_attr_groups; + + iio_trigger_set_drvdata(trig, priv); + + ret = devm_iio_trigger_register(priv->dev, trig); + if (ret) + return ret; + cur++; + } + + return 0; +} + +/** + * is_stm32_timer_trigger + * @trig: trigger to be checked + * + * return true if the trigger is a valid stm32 iio timer trigger + * either return false + */ +bool is_stm32_timer_trigger(struct iio_trigger *trig) +{ + return (trig->ops == &timer_trigger_ops); +} +EXPORT_SYMBOL(is_stm32_timer_trigger); + +static int stm32_timer_trigger_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct stm32_timer_trigger *priv; + struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + unsigned int index; + int ret; + + if (of_property_read_u32(dev->of_node, "reg", &index)) + return -EINVAL; + + if (index >= ARRAY_SIZE(triggers_table)) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->regmap = ddata->regmap; + priv->clk = ddata->clk; + priv->max_arr = ddata->max_arr; + priv->triggers = triggers_table[index]; + + ret = stm32_setup_iio_triggers(priv); + if (ret) + return ret; + + platform_set_drvdata(pdev, priv); + + return 0; +} + +static const struct of_device_id stm32_trig_of_match[] = { + { .compatible = "st,stm32-timer-trigger", }, + { /* end node */ }, +}; +MODULE_DEVICE_TABLE(of, stm32_trig_of_match); + +static struct platform_driver stm32_timer_trigger_driver = { + .probe = stm32_timer_trigger_probe, + .driver = { + .name = "stm32-timer-trigger", + .of_match_table = stm32_trig_of_match, + }, +}; +module_platform_driver(stm32_timer_trigger_driver); + +MODULE_ALIAS("platform: stm32-timer-trigger"); +MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 4ce3b6f11830..d0c14b88b24e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1621,6 +1621,17 @@ config MFD_STW481X in various ST Microelectronics and ST-Ericsson embedded Nomadik series. +config MFD_STM32_TIMERS + tristate "Support for STM32 Timers" + depends on (ARCH_STM32 && OF) || COMPILE_TEST + select MFD_CORE + select REGMAP + select REGMAP_MMIO + help + Select this option to enable STM32 timers driver used + for PWM and IIO Timer. This driver allow to share the + registers between the others drivers. + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index dda4d4f73ad7..876ca8600c51 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -212,3 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o + +obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c new file mode 100644 index 000000000000..41bd9017f3d0 --- /dev/null +++ b/drivers/mfd/stm32-timers.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) STMicroelectronics 2016 + * + * Author: Benjamin Gaignard <benjamin.gaignard@st.com> + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/mfd/stm32-timers.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/reset.h> + +static const struct regmap_config stm32_timers_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = sizeof(u32), + .max_register = 0x400, +}; + +static void stm32_timers_get_arr_size(struct stm32_timers *ddata) +{ + /* + * Only the available bits will be written so when readback + * we get the maximum value of auto reload register + */ + regmap_write(ddata->regmap, TIM_ARR, ~0L); + regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr); + regmap_write(ddata->regmap, TIM_ARR, 0x0); +} + +static int stm32_timers_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct stm32_timers *ddata; + struct resource *res; + void __iomem *mmio; + + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mmio = devm_ioremap_resource(dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); + + ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio, + &stm32_timers_regmap_cfg); + if (IS_ERR(ddata->regmap)) + return PTR_ERR(ddata->regmap); + + ddata->clk = devm_clk_get(dev, NULL); + if (IS_ERR(ddata->clk)) + return PTR_ERR(ddata->clk); + + stm32_timers_get_arr_size(ddata); + + platform_set_drvdata(pdev, ddata); + + return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); +} + +static const struct of_device_id stm32_timers_of_match[] = { + { .compatible = "st,stm32-timers", }, + { /* end node */ }, +}; +MODULE_DEVICE_TABLE(of, stm32_timers_of_match); + +static struct platform_driver stm32_timers_driver = { + .probe = stm32_timers_probe, + .driver = { + .name = "stm32-timers", + .of_match_table = stm32_timers_of_match, + }, +}; +module_platform_driver(stm32_timers_driver); + +MODULE_DESCRIPTION("STMicroelectronics STM32 Timers"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c index 47268ecedc4d..6f09da4dadb8 100644 --- a/drivers/platform/chrome/cros_ec_dev.c +++ b/drivers/platform/chrome/cros_ec_dev.c @@ -328,6 +328,9 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec) case MOTIONSENSE_TYPE_ACCEL: sensor_cells[id].name = "cros-ec-accel"; break; + case MOTIONSENSE_TYPE_BARO: + sensor_cells[id].name = "cros-ec-baro"; + break; case MOTIONSENSE_TYPE_GYRO: sensor_cells[id].name = "cros-ec-gyro"; break; diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index f92dd41b0395..2d0cfaa6d84c 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -397,6 +397,15 @@ config PWM_STI To compile this driver as a module, choose M here: the module will be called pwm-sti. +config PWM_STM32 + tristate "STMicroelectronics STM32 PWM" + depends on MFD_STM32_TIMERS || COMPILE_TEST + help + Generic PWM framework driver for STM32 SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-stm32. + config PWM_STMPE bool "STMPE expander PWM export" depends on MFD_STMPE diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index a48bdb517792..346a83b00f28 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o +obj-$(CONFIG_PWM_STM32) += pwm-stm32.o obj-$(CONFIG_PWM_STMPE) += pwm-stmpe.o obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c new file mode 100644 index 000000000000..6139512aab7b --- /dev/null +++ b/drivers/pwm/pwm-stm32.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) STMicroelectronics 2016 + * + * Author: Gerald Baeza <gerald.baeza@st.com> + * + * License terms: GNU General Public License (GPL), version 2 + * + * Inspired by timer-stm32.c from Maxime Coquelin + * pwm-atmel.c from Bo Shen + */ + +#include <linux/mfd/stm32-timers.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> + +#define CCMR_CHANNEL_SHIFT 8 +#define CCMR_CHANNEL_MASK 0xFF +#define MAX_BREAKINPUT 2 + +struct stm32_pwm { + struct pwm_chip chip; + struct device *dev; + struct clk *clk; + struct regmap *regmap; + u32 max_arr; + bool have_complementary_output; +}; + +struct stm32_breakinput { + u32 index; + u32 level; + u32 filter; +}; + +static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip) +{ + return container_of(chip, struct stm32_pwm, chip); +} + +static u32 active_channels(struct stm32_pwm *dev) +{ + u32 ccer; + + regmap_read(dev->regmap, TIM_CCER, &ccer); + + return ccer & TIM_CCER_CCXE; +} + +static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value) +{ + switch (ch) { + case 0: + return regmap_write(dev->regmap, TIM_CCR1, value); + case 1: + return regmap_write(dev->regmap, TIM_CCR2, value); + case 2: + return regmap_write(dev->regmap, TIM_CCR3, value); + case 3: + return regmap_write(dev->regmap, TIM_CCR4, value); + } + return -EINVAL; +} + +static int stm32_pwm_config(struct stm32_pwm *priv, int ch, + int duty_ns, int period_ns) +{ + unsigned long long prd, div, dty; + unsigned int prescaler = 0; + u32 ccmr, mask, shift; + + /* Period and prescaler values depends on clock rate */ + div = (unsigned long long)clk_get_rate(priv->clk) * period_ns; + + do_div(div, NSEC_PER_SEC); + prd = div; + + while (div > priv->max_arr) { + prescaler++; + div = prd; + do_div(div, prescaler + 1); + } + + prd = div; + + if (prescaler > MAX_TIM_PSC) + return -EINVAL; + + /* + * All channels share the same prescaler and counter so when two + * channels are active at the same time we can't change them + */ + if (active_channels(priv) & ~(1 << ch * 4)) { + u32 psc, arr; + + regmap_read(priv->regmap, TIM_PSC, &psc); + regmap_read(priv->regmap, TIM_ARR, &arr); + + if ((psc != prescaler) || (arr != prd - 1)) + return -EBUSY; + } + + regmap_write(priv->regmap, TIM_PSC, prescaler); + regmap_write(priv->regmap, TIM_ARR, prd - 1); + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); + + /* Calculate the duty cycles */ + dty = prd * duty_ns; + do_div(dty, period_ns); + + write_ccrx(priv, ch, dty); + + /* Configure output mode */ + shift = (ch & 0x1) * CCMR_CHANNEL_SHIFT; + ccmr = (TIM_CCMR_PE | TIM_CCMR_M1) << shift; + mask = CCMR_CHANNEL_MASK << shift; + + if (ch < 2) + regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr); + else + regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); + + regmap_update_bits(priv->regmap, TIM_BDTR, + TIM_BDTR_MOE | TIM_BDTR_AOE, + TIM_BDTR_MOE | TIM_BDTR_AOE); + + return 0; +} + +static int stm32_pwm_set_polarity(struct stm32_pwm *priv, int ch, + enum pwm_polarity polarity) +{ + u32 mask; + + mask = TIM_CCER_CC1P << (ch * 4); + if (priv->have_complementary_output) + mask |= TIM_CCER_CC1NP << (ch * 4); + + regmap_update_bits(priv->regmap, TIM_CCER, mask, + polarity == PWM_POLARITY_NORMAL ? 0 : mask); + + return 0; +} + +static int stm32_pwm_enable(struct stm32_pwm *priv, int ch) +{ + u32 mask; + int ret; + + ret = clk_enable(priv->clk); + if (ret) + return ret; + + /* Enable channel */ + mask = TIM_CCER_CC1E << (ch * 4); + if (priv->have_complementary_output) + mask |= TIM_CCER_CC1NE << (ch * 4); + + regmap_update_bits(priv->regmap, TIM_CCER, mask, mask); + + /* Make sure that registers are updated */ + regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); + + /* Enable controller */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); + + return 0; +} + +static void stm32_pwm_disable(struct stm32_pwm *priv, int ch) +{ + u32 mask; + + /* Disable channel */ + mask = TIM_CCER_CC1E << (ch * 4); + if (priv->have_complementary_output) + mask |= TIM_CCER_CC1NE << (ch * 4); + + regmap_update_bits(priv->regmap, TIM_CCER, mask, 0); + + /* When all channels are disabled, we can disable the controller */ + if (!active_channels(priv)) + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + + clk_disable(priv->clk); +} + +static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + bool enabled; + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); + int ret; + + enabled = pwm->state.enabled; + + if (enabled && !state->enabled) { + stm32_pwm_disable(priv, pwm->hwpwm); + return 0; + } + + if (state->polarity != pwm->state.polarity) + stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); + + ret = stm32_pwm_config(priv, pwm->hwpwm, + state->duty_cycle, state->period); + if (ret) + return ret; + + if (!enabled && state->enabled) + ret = stm32_pwm_enable(priv, pwm->hwpwm); + + return ret; +} + +static const struct pwm_ops stm32pwm_ops = { + .owner = THIS_MODULE, + .apply = stm32_pwm_apply, +}; + +static int stm32_pwm_set_breakinput(struct stm32_pwm *priv, + int index, int level, int filter) +{ + u32 bke = (index == 0) ? TIM_BDTR_BKE : TIM_BDTR_BK2E; + int shift = (index == 0) ? TIM_BDTR_BKF_SHIFT : TIM_BDTR_BK2F_SHIFT; + u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF + : TIM_BDTR_BK2E | TIM_BDTR_BK2P | TIM_BDTR_BK2F; + u32 bdtr = bke; + + /* + * The both bits could be set since only one will be wrote + * due to mask value. + */ + if (level) + bdtr |= TIM_BDTR_BKP | TIM_BDTR_BK2P; + + bdtr |= (filter & TIM_BDTR_BKF_MASK) << shift; + + regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr); + + regmap_read(priv->regmap, TIM_BDTR, &bdtr); + + return (bdtr & bke) ? 0 : -EINVAL; +} + +static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv, + struct device_node *np) +{ + struct stm32_breakinput breakinput[MAX_BREAKINPUT]; + int nb, ret, i, array_size; + + nb = of_property_count_elems_of_size(np, "st,breakinput", + sizeof(struct stm32_breakinput)); + + /* + * Because "st,breakinput" parameter is optional do not make probe + * failed if it doesn't exist. + */ + if (nb <= 0) + return 0; + + if (nb > MAX_BREAKINPUT) + return -EINVAL; + + array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32); + ret = of_property_read_u32_array(np, "st,breakinput", + (u32 *)breakinput, array_size); + if (ret) + return ret; + + for (i = 0; i < nb && !ret; i++) { + ret = stm32_pwm_set_breakinput(priv, + breakinput[i].index, + breakinput[i].level, + breakinput[i].filter); + } + + return ret; +} + +static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) +{ + u32 ccer; + + /* + * If complementary bit doesn't exist writing 1 will have no + * effect so we can detect it. + */ + regmap_update_bits(priv->regmap, + TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE); + regmap_read(priv->regmap, TIM_CCER, &ccer); + regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0); + + priv->have_complementary_output = (ccer != 0); +} + +static int stm32_pwm_detect_channels(struct stm32_pwm *priv) +{ + u32 ccer; + int npwm = 0; + + /* + * If channels enable bits don't exist writing 1 will have no + * effect so we can detect and count them. + */ + regmap_update_bits(priv->regmap, + TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE); + regmap_read(priv->regmap, TIM_CCER, &ccer); + regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0); + + if (ccer & TIM_CCER_CC1E) + npwm++; + + if (ccer & TIM_CCER_CC2E) + npwm++; + + if (ccer & TIM_CCER_CC3E) + npwm++; + + if (ccer & TIM_CCER_CC4E) + npwm++; + + return npwm; +} + +static int stm32_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + struct stm32_pwm *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = ddata->regmap; + priv->clk = ddata->clk; + priv->max_arr = ddata->max_arr; + + if (!priv->regmap || !priv->clk) + return -EINVAL; + + ret = stm32_pwm_apply_breakinputs(priv, np); + if (ret) + return ret; + + stm32_pwm_detect_complementary(priv); + + priv->chip.base = -1; + priv->chip.dev = dev; + priv->chip.ops = &stm32pwm_ops; + priv->chip.npwm = stm32_pwm_detect_channels(priv); + + ret = pwmchip_add(&priv->chip); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, priv); + + return 0; +} + +static int stm32_pwm_remove(struct platform_device *pdev) +{ + struct stm32_pwm *priv = platform_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < priv->chip.npwm; i++) + pwm_disable(&priv->chip.pwms[i]); + + pwmchip_remove(&priv->chip); + + return 0; +} + +static const struct of_device_id stm32_pwm_of_match[] = { + { .compatible = "st,stm32-pwm", }, + { /* end node */ }, +}; +MODULE_DEVICE_TABLE(of, stm32_pwm_of_match); + +static struct platform_driver stm32_pwm_driver = { + .probe = stm32_pwm_probe, + .remove = stm32_pwm_remove, + .driver = { + .name = "stm32-pwm", + .of_match_table = stm32_pwm_of_match, + }, +}; +module_platform_driver(stm32_pwm_driver); + +MODULE_ALIAS("platform:stm32-pwm"); +MODULE_DESCRIPTION("STMicroelectronics STM32 PWM driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index cd005cd41413..4c360f8071a8 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -96,12 +96,12 @@ source "drivers/staging/wilc1000/Kconfig" source "drivers/staging/most/Kconfig" -source "drivers/staging/i4l/Kconfig" - source "drivers/staging/ks7010/Kconfig" source "drivers/staging/greybus/Kconfig" source "drivers/staging/vc04_services/Kconfig" +source "drivers/staging/bcm2835-audio/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 831e2e891989..29cec5aa2945 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -37,7 +37,8 @@ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/ obj-$(CONFIG_WILC1000) += wilc1000/ obj-$(CONFIG_MOST) += most/ -obj-$(CONFIG_ISDN_I4L) += i4l/ obj-$(CONFIG_KS7010) += ks7010/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ +obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ + diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index 7e7431d8d49f..9ff815ad1cb1 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -111,7 +111,8 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ion_handle *handle; mutex_lock(&client->lock); - handle = ion_handle_get_by_id_nolock(client, data.handle.handle); + handle = ion_handle_get_by_id_nolock(client, + data.handle.handle); if (IS_ERR(handle)) { mutex_unlock(&client->lock); return PTR_ERR(handle); diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 6c7de74bc7ab..6c4068523781 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -24,8 +24,6 @@ #include "ion.h" #include "ion_priv.h" -#define ION_CMA_ALLOCATE_FAILED -1 - struct ion_cma_heap { struct ion_heap heap; struct device *dev; @@ -57,9 +55,9 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, if (align > PAGE_SIZE) return -EINVAL; - info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) - return ION_CMA_ALLOCATE_FAILED; + return -ENOMEM; info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), GFP_HIGHUSER | __GFP_ZERO); @@ -69,7 +67,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, goto err; } - info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + info->table = kmalloc(sizeof(*info->table), GFP_KERNEL); if (!info->table) goto free_mem; @@ -88,7 +86,7 @@ free_mem: dma_free_coherent(dev, len, info->cpu_addr, info->handle); err: kfree(info); - return ION_CMA_ALLOCATE_FAILED; + return -ENOMEM; } static void ion_cma_free(struct ion_buffer *buffer) @@ -142,7 +140,7 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) { struct ion_cma_heap *cma_heap; - cma_heap = kzalloc(sizeof(struct ion_cma_heap), GFP_KERNEL); + cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL); if (!cma_heap) return ERR_PTR(-ENOMEM); diff --git a/drivers/staging/android/ion/ion_of.c b/drivers/staging/android/ion/ion_of.c index 46b2bb99bfd6..7791c705ea31 100644 --- a/drivers/staging/android/ion/ion_of.c +++ b/drivers/staging/android/ion/ion_of.c @@ -161,7 +161,6 @@ static int rmem_ion_device_init(struct reserved_mem *rmem, struct device *dev) static void rmem_ion_device_release(struct reserved_mem *rmem, struct device *dev) { - return; } static const struct reserved_mem_ops rmem_dma_ops = { diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 3c3b3245275d..5b3059c78431 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -54,7 +54,7 @@ * handle, used for debugging * @pid: pid of last client to reference this buffer in a * handle, used for debugging -*/ + */ struct ion_buffer { struct kref ref; union { @@ -287,10 +287,10 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); * some helpers for common operations on buffers using the sg_table * and vaddr fields */ -void *ion_heap_map_kernel(struct ion_heap *, struct ion_buffer *); -void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *); -int ion_heap_map_user(struct ion_heap *, struct ion_buffer *, - struct vm_area_struct *); +void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); +void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); +int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + struct vm_area_struct *vma); int ion_heap_buffer_zero(struct ion_buffer *buffer); int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); @@ -371,21 +371,21 @@ size_t ion_heap_freelist_size(struct ion_heap *heap); * heaps as appropriate. */ -struct ion_heap *ion_heap_create(struct ion_platform_heap *); -void ion_heap_destroy(struct ion_heap *); -struct ion_heap *ion_system_heap_create(struct ion_platform_heap *); -void ion_system_heap_destroy(struct ion_heap *); +struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data); +void ion_heap_destroy(struct ion_heap *heap); +struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused); +void ion_system_heap_destroy(struct ion_heap *heap); -struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *); -void ion_system_contig_heap_destroy(struct ion_heap *); +struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *heap); +void ion_system_contig_heap_destroy(struct ion_heap *heap); -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *); -void ion_carveout_heap_destroy(struct ion_heap *); +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data); +void ion_carveout_heap_destroy(struct ion_heap *heap); -struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *); -void ion_chunk_heap_destroy(struct ion_heap *); -struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *); -void ion_cma_heap_destroy(struct ion_heap *); +struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data); +void ion_chunk_heap_destroy(struct ion_heap *heap); +struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data); +void ion_cma_heap_destroy(struct ion_heap *heap); /** * functions for creating and destroying a heap pool -- allows you @@ -427,9 +427,9 @@ struct ion_page_pool { struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order, bool cached); -void ion_page_pool_destroy(struct ion_page_pool *); -struct page *ion_page_pool_alloc(struct ion_page_pool *); -void ion_page_pool_free(struct ion_page_pool *, struct page *); +void ion_page_pool_destroy(struct ion_page_pool *pool); +struct page *ion_page_pool_alloc(struct ion_page_pool *pool); +void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); /** ion_page_pool_shrink - shrinks the size of the memory cached in the pool * @pool: the pool diff --git a/drivers/staging/bcm2835-audio/Kconfig b/drivers/staging/bcm2835-audio/Kconfig new file mode 100644 index 000000000000..32a2ff9ef9b2 --- /dev/null +++ b/drivers/staging/bcm2835-audio/Kconfig @@ -0,0 +1,7 @@ +config SND_BCM2835 + tristate "BCM2835 ALSA driver" + depends on ARCH_BCM2835 && BCM2835_VCHIQ && SND + select SND_PCM + help + Say Y or M if you want to support BCM2835 Alsa pcm card driver + diff --git a/drivers/staging/bcm2835-audio/Makefile b/drivers/staging/bcm2835-audio/Makefile new file mode 100644 index 000000000000..d7b88d164d15 --- /dev/null +++ b/drivers/staging/bcm2835-audio/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o +snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o + +ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 + diff --git a/drivers/staging/bcm2835-audio/TODO b/drivers/staging/bcm2835-audio/TODO new file mode 100644 index 000000000000..73d41fa631ac --- /dev/null +++ b/drivers/staging/bcm2835-audio/TODO @@ -0,0 +1,29 @@ +***************************************************************************** +* * +* TODO: BCM2835-AUDIO * +* * +***************************************************************************** + + +1) Document the device tree node + +The downstream tree(the tree that the driver was imported from) at +http://www.github.com/raspberrypi/linux uses this node: + +audio: audio { + compatible = "brcm,bcm2835-audio"; + brcm,pwm-channels = <8>; +}; + +Since the driver requires the use of VCHIQ, it may be useful to have a link +in the device tree to the VCHIQ driver. + +2) Gracefully handle the case where VCHIQ is missing from the device tree or +it has not been initialized yet. + +3) Review error handling and remove duplicate code. + +4) Cleanup the logging mechanism. The driver should probably be using the +standard kernel logging mechanisms such as dev_info, dev_dbg, and friends. + +5) Fix the remaining checkpatch.pl errors and warnings. diff --git a/drivers/staging/bcm2835-audio/bcm2835-ctl.c b/drivers/staging/bcm2835-audio/bcm2835-ctl.c new file mode 100644 index 000000000000..a4ffa1bf53e5 --- /dev/null +++ b/drivers/staging/bcm2835-audio/bcm2835-ctl.c @@ -0,0 +1,345 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/jiffies.h> +#include <linux/slab.h> +#include <linux/time.h> +#include <linux/wait.h> +#include <linux/delay.h> +#include <linux/moduleparam.h> +#include <linux/sched.h> + +#include <sound/core.h> +#include <sound/control.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/rawmidi.h> +#include <sound/initval.h> +#include <sound/tlv.h> +#include <sound/asoundef.h> + +#include "bcm2835.h" + +/* volume maximum and minimum in terms of 0.01dB */ +#define CTRL_VOL_MAX 400 +#define CTRL_VOL_MIN -10239 /* originally -10240 */ + +static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + audio_info(" ... IN\n"); + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = CTRL_VOL_MIN; + uinfo->value.integer.max = CTRL_VOL_MAX; /* 2303 */ + } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = AUDIO_DEST_MAX - 1; + } + audio_info(" ... OUT\n"); + return 0; +} + +/* toggles mute on or off depending on the value of nmute, and returns + * 1 if the mute value was changed, otherwise 0 + */ +static int toggle_mute(struct bcm2835_chip *chip, int nmute) +{ + /* if settings are ok, just return 0 */ + if (chip->mute == nmute) + return 0; + + /* if the sound is muted then we need to unmute */ + if (chip->mute == CTRL_VOL_MUTE) { + chip->volume = chip->old_volume; /* copy the old volume back */ + audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); + } else /* otherwise we mute */ { + chip->old_volume = chip->volume; + chip->volume = 26214; /* set volume to minimum level AKA mute */ + audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); + } + + chip->mute = nmute; + return 1; +} + +static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) + ucontrol->value.integer.value[0] = chip2alsa(chip->volume); + else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) + ucontrol->value.integer.value[0] = chip->mute; + else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) + ucontrol->value.integer.value[0] = chip->dest; + + mutex_unlock(&chip->audio_mutex); + return 0; +} + +static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { + audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int) ucontrol->value.integer.value[0]); + if (chip->mute == CTRL_VOL_MUTE) { + /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ + changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ + goto unlock; + } + if (changed + || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { + + chip->volume = alsa2chip(ucontrol->value.integer.value[0]); + changed = 1; + } + + } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { + /* Now implemented */ + audio_info(" Mute attempted\n"); + changed = toggle_mute(chip, ucontrol->value.integer.value[0]); + + } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { + if (ucontrol->value.integer.value[0] != chip->dest) { + chip->dest = ucontrol->value.integer.value[0]; + changed = 1; + } + } + + if (changed) { + if (bcm2835_audio_set_ctls(chip)) + printk(KERN_ERR "Failed to set ALSA controls..\n"); + } + +unlock: + mutex_unlock(&chip->audio_mutex); + return changed; +} + +static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1); + +static struct snd_kcontrol_new snd_bcm2835_ctl[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Volume", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, + .private_value = PCM_PLAYBACK_VOLUME, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, + .count = 1, + .tlv = {.p = snd_bcm2835_db_scale} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Switch", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = PCM_PLAYBACK_MUTE, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, + .count = 1, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Route", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = PCM_PLAYBACK_DEVICE, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, + .count = 1, + }, +}; + +static int snd_bcm2835_spdif_default_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) & 0xff; + + mutex_unlock(&chip->audio_mutex); + return 0; +} + +static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + unsigned int val = 0; + int i, change; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + for (i = 0; i < 4; i++) + val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8); + + change = val != chip->spdif_status; + chip->spdif_status = val; + + mutex_unlock(&chip->audio_mutex); + return change; +} + +static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* bcm2835 supports only consumer mode and sets all other format flags + * automatically. So the only thing left is signalling non-audio + * content */ + ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO; + return 0; +} + +static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) & 0xff; + + mutex_unlock(&chip->audio_mutex); + return 0; +} + +static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + unsigned int val = 0; + int i, change; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + for (i = 0; i < 4; i++) + val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8); + change = val != chip->spdif_status; + chip->spdif_status = val; + + mutex_unlock(&chip->audio_mutex); + return change; +} + +static struct snd_kcontrol_new snd_bcm2835_spdif[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .info = snd_bcm2835_spdif_default_info, + .get = snd_bcm2835_spdif_default_get, + .put = snd_bcm2835_spdif_default_put + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), + .info = snd_bcm2835_spdif_mask_info, + .get = snd_bcm2835_spdif_mask_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), + .info = snd_bcm2835_spdif_stream_info, + .get = snd_bcm2835_spdif_stream_get, + .put = snd_bcm2835_spdif_stream_put, + }, +}; + +int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) +{ + int err; + unsigned int idx; + + strcpy(chip->card->mixername, "Broadcom Mixer"); + for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&snd_bcm2835_ctl[idx], chip)); + if (err < 0) + return err; + } + for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); + if (err < 0) + return err; + } + return 0; +} diff --git a/drivers/staging/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/bcm2835-audio/bcm2835-pcm.c new file mode 100644 index 000000000000..16127e062661 --- /dev/null +++ b/drivers/staging/bcm2835-audio/bcm2835-pcm.c @@ -0,0 +1,554 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#include <linux/interrupt.h> +#include <linux/slab.h> + +#include <sound/asoundef.h> + +#include "bcm2835.h" + +/* hardware definition */ +static struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, + .periods_min = 1, + .periods_max = 128, +}; + +static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 44100, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, + .periods_min = 1, + .periods_max = 128, +}; + +static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime) +{ + audio_info("Freeing up alsa stream here ..\n"); + if (runtime->private_data) + kfree(runtime->private_data); + runtime->private_data = NULL; +} + +void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) +{ + unsigned int consumed = 0; + int new_period = 0; + + audio_info(" .. IN\n"); + + audio_info("alsa_stream=%p substream=%p\n", alsa_stream, + alsa_stream ? alsa_stream->substream : 0); + + if (alsa_stream->open) + consumed = bcm2835_audio_retrieve_buffers(alsa_stream); + + /* We get called only if playback was triggered, So, the number of buffers we retrieve in + * each iteration are the buffers that have been played out already + */ + + if (alsa_stream->period_size) { + if ((alsa_stream->pos / alsa_stream->period_size) != + ((alsa_stream->pos + consumed) / alsa_stream->period_size)) + new_period = 1; + } + audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n", + alsa_stream->pos, + consumed, + alsa_stream->buffer_size, + (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods), + frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr), + new_period); + if (alsa_stream->buffer_size) { + alsa_stream->pos += consumed &~(1 << 30); + alsa_stream->pos %= alsa_stream->buffer_size; + } + + if (alsa_stream->substream) { + if (new_period) + snd_pcm_period_elapsed(alsa_stream->substream); + } else { + audio_warning(" unexpected NULL substream\n"); + } + audio_info(" .. OUT\n"); +} + +/* open callback */ +static int snd_bcm2835_playback_open_generic( + struct snd_pcm_substream *substream, int spdif) +{ + struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream; + int idx; + int err; + + audio_info(" .. IN (%d)\n", substream->number); + + if (mutex_lock_interruptible(&chip->audio_mutex)) { + audio_error("Interrupted whilst waiting for lock\n"); + return -EINTR; + } + audio_info("Alsa open (%d)\n", substream->number); + idx = substream->number; + + if (spdif && chip->opened) { + err = -EBUSY; + goto out; + } else if (!spdif && (chip->opened & (1 << idx))) { + err = -EBUSY; + goto out; + } + if (idx >= MAX_SUBSTREAMS) { + audio_error + ("substream(%d) device doesn't exist max(%d) substreams allowed\n", + idx, MAX_SUBSTREAMS); + err = -ENODEV; + goto out; + } + + /* Check if we are ready */ + if (!(chip->avail_substreams & (1 << idx))) { + /* We are not ready yet */ + audio_error("substream(%d) device is not ready yet\n", idx); + err = -EAGAIN; + goto out; + } + + alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL); + if (!alsa_stream) { + err = -ENOMEM; + goto out; + } + + /* Initialise alsa_stream */ + alsa_stream->chip = chip; + alsa_stream->substream = substream; + alsa_stream->idx = idx; + + sema_init(&alsa_stream->buffers_update_sem, 0); + sema_init(&alsa_stream->control_sem, 0); + spin_lock_init(&alsa_stream->lock); + + err = bcm2835_audio_open(alsa_stream); + if (err) { + kfree(alsa_stream); + goto out; + } + runtime->private_data = alsa_stream; + runtime->private_free = snd_bcm2835_playback_free; + if (spdif) { + runtime->hw = snd_bcm2835_playback_spdif_hw; + } else { + /* clear spdif status, as we are not in spdif mode */ + chip->spdif_status = 0; + runtime->hw = snd_bcm2835_playback_hw; + } + /* minimum 16 bytes alignment (for vchiq bulk transfers) */ + snd_pcm_hw_constraint_step(runtime, + 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 16); + + chip->alsa_stream[idx] = alsa_stream; + + chip->opened |= (1 << idx); + alsa_stream->open = 1; + alsa_stream->draining = 1; + +out: + mutex_unlock(&chip->audio_mutex); + + audio_info(" .. OUT =%d\n", err); + + return err; +} + +static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream) +{ + return snd_bcm2835_playback_open_generic(substream, 0); +} + +static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream) +{ + return snd_bcm2835_playback_open_generic(substream, 1); +} + +/* close callback */ +static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream) +{ + /* the hardware-specific codes will be here */ + + struct bcm2835_chip *chip; + struct snd_pcm_runtime *runtime; + struct bcm2835_alsa_stream *alsa_stream; + + audio_info(" .. IN\n"); + + chip = snd_pcm_substream_chip(substream); + if (mutex_lock_interruptible(&chip->audio_mutex)) { + audio_error("Interrupted whilst waiting for lock\n"); + return -EINTR; + } + runtime = substream->runtime; + alsa_stream = runtime->private_data; + + audio_info("Alsa close\n"); + + /* + * Call stop if it's still running. This happens when app + * is force killed and we don't get a stop trigger. + */ + if (alsa_stream->running) { + int err; + err = bcm2835_audio_stop(alsa_stream); + alsa_stream->running = 0; + if (err) + audio_error(" Failed to STOP alsa device\n"); + } + + alsa_stream->period_size = 0; + alsa_stream->buffer_size = 0; + + if (alsa_stream->open) { + alsa_stream->open = 0; + bcm2835_audio_close(alsa_stream); + } + if (alsa_stream->chip) + alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; + /* + * Do not free up alsa_stream here, it will be freed up by + * runtime->private_free callback we registered in *_open above + */ + + chip->opened &= ~(1 << substream->number); + + mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + + return 0; +} + +/* hw_params callback */ +static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + int err; + + audio_info(" .. IN\n"); + + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + if (err < 0) { + audio_error + (" pcm_lib_malloc failed to allocated pages for buffers\n"); + return err; + } + + alsa_stream->channels = params_channels(params); + alsa_stream->params_rate = params_rate(params); + alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params)); + audio_info(" .. OUT\n"); + + return err; +} + +/* hw_free callback */ +static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) +{ + audio_info(" .. IN\n"); + return snd_pcm_lib_free_pages(substream); +} + +/* prepare callback */ +static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + int channels; + int err; + + audio_info(" .. IN\n"); + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + /* notify the vchiq that it should enter spdif passthrough mode by + * setting channels=0 (see + * https://github.com/raspberrypi/linux/issues/528) */ + if (chip->spdif_status & IEC958_AES0_NONAUDIO) + channels = 0; + else + channels = alsa_stream->channels; + + err = bcm2835_audio_set_params(alsa_stream, channels, + alsa_stream->params_rate, + alsa_stream->pcm_format_width); + if (err < 0) { + audio_error(" error setting hw params\n"); + } + + bcm2835_audio_setup(alsa_stream); + + /* in preparation of the stream, set the controls (volume level) of the stream */ + bcm2835_audio_set_ctls(alsa_stream->chip); + + + memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); + + alsa_stream->pcm_indirect.hw_buffer_size = + alsa_stream->pcm_indirect.sw_buffer_size = + snd_pcm_lib_buffer_bytes(substream); + + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); + alsa_stream->pos = 0; + + audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", + alsa_stream->buffer_size, alsa_stream->period_size, + alsa_stream->pos, runtime->frame_bits); + + mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + return 0; +} + +static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, + struct snd_pcm_indirect *rec, size_t bytes) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + void *src = (void *) (substream->runtime->dma_area + rec->sw_data); + int err; + + err = bcm2835_audio_write(alsa_stream, bytes, src); + if (err) + audio_error(" Failed to transfer to alsa device (%d)\n", err); + +} + +static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; + + pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; + snd_pcm_indirect_playback_transfer(substream, pcm_indirect, + snd_bcm2835_pcm_transfer); + return 0; +} + +/* trigger callback */ +static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + int err = 0; + + audio_info(" .. IN\n"); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n", + alsa_stream->running); + if (!alsa_stream->running) { + err = bcm2835_audio_start(alsa_stream); + if (!err) { + alsa_stream->pcm_indirect.hw_io = + alsa_stream->pcm_indirect.hw_data = + bytes_to_frames(runtime, + alsa_stream->pos); + substream->ops->ack(substream); + alsa_stream->running = 1; + alsa_stream->draining = 1; + } else { + audio_error(" Failed to START alsa device (%d)\n", err); + } + } + break; + case SNDRV_PCM_TRIGGER_STOP: + audio_debug + ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n", + alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING); + if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { + audio_info("DRAINING\n"); + alsa_stream->draining = 1; + } else { + audio_info("DROPPING\n"); + alsa_stream->draining = 0; + } + if (alsa_stream->running) { + err = bcm2835_audio_stop(alsa_stream); + if (err != 0) + audio_error(" Failed to STOP alsa device (%d)\n", err); + alsa_stream->running = 0; + } + break; + default: + err = -EINVAL; + } + + audio_info(" .. OUT\n"); + return err; +} + +/* pointer callback */ +static snd_pcm_uframes_t +snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + + audio_info(" .. IN\n"); + + audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, + frames_to_bytes(runtime, runtime->status->hw_ptr), + frames_to_bytes(runtime, runtime->control->appl_ptr), + alsa_stream->pos); + + audio_info(" .. OUT\n"); + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, + alsa_stream->pos); +} + +static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + int ret = snd_pcm_lib_ioctl(substream, cmd, arg); + + audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream, + cmd, arg, arg ? *(unsigned *) arg : 0, ret); + return ret; +} + +/* operators */ +static struct snd_pcm_ops snd_bcm2835_playback_ops = { + .open = snd_bcm2835_playback_open, + .close = snd_bcm2835_playback_close, + .ioctl = snd_bcm2835_pcm_lib_ioctl, + .hw_params = snd_bcm2835_pcm_hw_params, + .hw_free = snd_bcm2835_pcm_hw_free, + .prepare = snd_bcm2835_pcm_prepare, + .trigger = snd_bcm2835_pcm_trigger, + .pointer = snd_bcm2835_pcm_pointer, + .ack = snd_bcm2835_pcm_ack, +}; + +static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { + .open = snd_bcm2835_playback_spdif_open, + .close = snd_bcm2835_playback_close, + .ioctl = snd_bcm2835_pcm_lib_ioctl, + .hw_params = snd_bcm2835_pcm_hw_params, + .hw_free = snd_bcm2835_pcm_hw_free, + .prepare = snd_bcm2835_pcm_prepare, + .trigger = snd_bcm2835_pcm_trigger, + .pointer = snd_bcm2835_pcm_pointer, + .ack = snd_bcm2835_pcm_ack, +}; + +/* create a pcm device */ +int snd_bcm2835_new_pcm(struct bcm2835_chip *chip) +{ + struct snd_pcm *pcm; + int err; + + audio_info(" .. IN\n"); + mutex_init(&chip->audio_mutex); + if (mutex_lock_interruptible(&chip->audio_mutex)) { + audio_error("Interrupted whilst waiting for lock\n"); + return -EINTR; + } + err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, MAX_SUBSTREAMS, 0, &pcm); + if (err < 0) + goto out; + pcm->private_data = chip; + strcpy(pcm->name, "bcm2835 ALSA"); + chip->pcm = pcm; + chip->dest = AUDIO_DEST_AUTO; + chip->volume = alsa2chip(0); + chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_bcm2835_playback_ops); + + /* pre-allocation of buffers */ + /* NOTE: this may fail */ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + snd_bcm2835_playback_hw.buffer_bytes_max, + snd_bcm2835_playback_hw.buffer_bytes_max); + + +out: + mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + + return 0; +} + +int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip) +{ + struct snd_pcm *pcm; + int err; + + audio_info(" .. IN\n"); + if (mutex_lock_interruptible(&chip->audio_mutex)) { + audio_error("Interrupted whilst waiting for lock\n"); + return -EINTR; + } + err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); + if (err < 0) + goto out; + + pcm->private_data = chip; + strcpy(pcm->name, "bcm2835 IEC958/HDMI"); + chip->pcm_spdif = pcm; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_bcm2835_playback_spdif_ops); + + /* pre-allocation of buffers */ + /* NOTE: this may fail */ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); +out: + mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + + return 0; +} diff --git a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c new file mode 100644 index 000000000000..fa23a13f8d95 --- /dev/null +++ b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c @@ -0,0 +1,912 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#include <linux/device.h> +#include <sound/core.h> +#include <sound/initval.h> +#include <sound/pcm.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/fs.h> +#include <linux/file.h> +#include <linux/mm.h> +#include <linux/syscalls.h> +#include <linux/uaccess.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/atomic.h> +#include <linux/module.h> +#include <linux/completion.h> + +#include "bcm2835.h" + +/* ---- Include Files -------------------------------------------------------- */ + +#include "interface/vchi/vchi.h" +#include "vc_vchi_audioserv_defs.h" + +/* ---- Private Constants and Types ------------------------------------------ */ + +#define BCM2835_AUDIO_STOP 0 +#define BCM2835_AUDIO_START 1 +#define BCM2835_AUDIO_WRITE 2 + +/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ +#ifdef AUDIO_DEBUG_ENABLE +#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +#define LOG_WARN(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +#define LOG_INFO(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +#define LOG_DBG(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +#else +#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +#define LOG_WARN(fmt, arg...) no_printk(fmt, ##arg) +#define LOG_INFO(fmt, arg...) no_printk(fmt, ##arg) +#define LOG_DBG(fmt, arg...) no_printk(fmt, ##arg) +#endif + +struct bcm2835_audio_instance { + unsigned int num_connections; + VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; + struct completion msg_avail_comp; + struct mutex vchi_mutex; + struct bcm2835_alsa_stream *alsa_stream; + int result; + short peer_version; +}; + +static bool force_bulk; + +/* ---- Private Variables ---------------------------------------------------- */ + +/* ---- Private Function Prototypes ------------------------------------------ */ + +/* ---- Private Functions ---------------------------------------------------- */ + +static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream); +static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream); +static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, void *src); + +// Routine to send a message across a service + +static int +bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, + void *data, + unsigned int size) +{ + return vchi_queue_kernel_message(handle, + data, + size); +} + +static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | + 'M' << 8 | 'A'); +static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | + 'T' << 8 | 'A'); + +struct bcm2835_audio_work { + struct work_struct my_work; + struct bcm2835_alsa_stream *alsa_stream; + int cmd; + void *src; + unsigned int count; +}; + +static void my_wq_function(struct work_struct *work) +{ + struct bcm2835_audio_work *w = + container_of(work, struct bcm2835_audio_work, my_work); + int ret = -9; + + LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->cmd); + switch (w->cmd) { + case BCM2835_AUDIO_START: + ret = bcm2835_audio_start_worker(w->alsa_stream); + break; + case BCM2835_AUDIO_STOP: + ret = bcm2835_audio_stop_worker(w->alsa_stream); + break; + case BCM2835_AUDIO_WRITE: + ret = bcm2835_audio_write_worker(w->alsa_stream, w->count, + w->src); + break; + default: + LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd); + break; + } + kfree((void *) work); + LOG_DBG(" .. OUT %d\n", ret); +} + +int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) +{ + int ret = -1; + + LOG_DBG(" .. IN\n"); + if (alsa_stream->my_wq) { + struct bcm2835_audio_work *work; + + work = kmalloc(sizeof(*work), GFP_ATOMIC); + /*--- Queue some work (item 1) ---*/ + if (work) { + INIT_WORK(&work->my_work, my_wq_function); + work->alsa_stream = alsa_stream; + work->cmd = BCM2835_AUDIO_START; + if (queue_work(alsa_stream->my_wq, &work->my_work)) + ret = 0; + } else + LOG_ERR(" .. Error: NULL work kmalloc\n"); + } + LOG_DBG(" .. OUT %d\n", ret); + return ret; +} + +int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) +{ + int ret = -1; + + LOG_DBG(" .. IN\n"); + if (alsa_stream->my_wq) { + struct bcm2835_audio_work *work; + + work = kmalloc(sizeof(*work), GFP_ATOMIC); + /*--- Queue some work (item 1) ---*/ + if (work) { + INIT_WORK(&work->my_work, my_wq_function); + work->alsa_stream = alsa_stream; + work->cmd = BCM2835_AUDIO_STOP; + if (queue_work(alsa_stream->my_wq, &work->my_work)) + ret = 0; + } else + LOG_ERR(" .. Error: NULL work kmalloc\n"); + } + LOG_DBG(" .. OUT %d\n", ret); + return ret; +} + +int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, void *src) +{ + int ret = -1; + + LOG_DBG(" .. IN\n"); + if (alsa_stream->my_wq) { + struct bcm2835_audio_work *work; + + work = kmalloc(sizeof(*work), GFP_ATOMIC); + /*--- Queue some work (item 1) ---*/ + if (work) { + INIT_WORK(&work->my_work, my_wq_function); + work->alsa_stream = alsa_stream; + work->cmd = BCM2835_AUDIO_WRITE; + work->src = src; + work->count = count; + if (queue_work(alsa_stream->my_wq, &work->my_work)) + ret = 0; + } else + LOG_ERR(" .. Error: NULL work kmalloc\n"); + } + LOG_DBG(" .. OUT %d\n", ret); + return ret; +} + +static void my_workqueue_init(struct bcm2835_alsa_stream *alsa_stream) +{ + alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); + return; +} + +static void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream) +{ + if (alsa_stream->my_wq) { + flush_workqueue(alsa_stream->my_wq); + destroy_workqueue(alsa_stream->my_wq); + alsa_stream->my_wq = NULL; + } + return; +} + +static void audio_vchi_callback(void *param, + const VCHI_CALLBACK_REASON_T reason, + void *msg_handle) +{ + struct bcm2835_audio_instance *instance = param; + int status; + int msg_len; + struct vc_audio_msg m; + + LOG_DBG(" .. IN instance=%p, handle=%p, alsa=%p, reason=%d, handle=%p\n", + instance, instance ? instance->vchi_handle[0] : NULL, instance ? instance->alsa_stream : NULL, reason, msg_handle); + + if (reason != VCHI_CALLBACK_MSG_AVAILABLE) { + return; + } + if (!instance) { + LOG_ERR(" .. instance is null\n"); + BUG(); + return; + } + if (!instance->vchi_handle[0]) { + LOG_ERR(" .. instance->vchi_handle[0] is null\n"); + BUG(); + return; + } + status = vchi_msg_dequeue(instance->vchi_handle[0], + &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); + if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { + LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", + instance, m.u.result.success); + instance->result = m.u.result.success; + complete(&instance->msg_avail_comp); + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { + struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream; + + LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", + instance, m.u.complete.count); + if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || + m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) + LOG_ERR(" .. response is corrupt\n"); + else if (alsa_stream) { + atomic_add(m.u.complete.count, + &alsa_stream->retrieved); + bcm2835_playback_fifo(alsa_stream); + } else { + LOG_ERR(" .. unexpected alsa_stream=%p\n", + alsa_stream); + } + } else { + LOG_ERR(" .. unexpected m.type=%d\n", m.type); + } + LOG_DBG(" .. OUT\n"); +} + +static struct bcm2835_audio_instance * +vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, + VCHI_CONNECTION_T **vchi_connections, + unsigned int num_connections) +{ + unsigned int i; + struct bcm2835_audio_instance *instance; + int status; + + LOG_DBG("%s: start", __func__); + + if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { + LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", + __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); + + return NULL; + } + /* Allocate memory for this instance */ + instance = kmalloc(sizeof(*instance), GFP_KERNEL); + if (!instance) + return NULL; + + memset(instance, 0, sizeof(*instance)); + instance->num_connections = num_connections; + + /* Create a lock for exclusive, serialized VCHI connection access */ + mutex_init(&instance->vchi_mutex); + /* Open the VCHI service connections */ + for (i = 0; i < num_connections; i++) { + SERVICE_CREATION_T params = { + VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), + VC_AUDIO_SERVER_NAME, // 4cc service code + vchi_connections[i], // passed in fn pointers + 0, // rx fifo size (unused) + 0, // tx fifo size (unused) + audio_vchi_callback, // service callback + instance, // service callback parameter + 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves + 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits + 0 // want crc check on bulk transfers + }; + + LOG_DBG("%s: about to open %i\n", __func__, i); + status = vchi_service_open(vchi_instance, ¶ms, + &instance->vchi_handle[i]); + LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); + if (status) { + LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", + __func__, status); + + goto err_close_services; + } + /* Finished with the service for now */ + vchi_service_release(instance->vchi_handle[i]); + } + + LOG_DBG("%s: okay\n", __func__); + return instance; + +err_close_services: + for (i = 0; i < instance->num_connections; i++) { + LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); + if (instance->vchi_handle[i]) + vchi_service_close(instance->vchi_handle[i]); + } + + kfree(instance); + LOG_ERR("%s: error\n", __func__); + + return NULL; +} + +static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) +{ + unsigned int i; + + LOG_DBG(" .. IN\n"); + + if (!instance) { + LOG_ERR("%s: invalid handle %p\n", __func__, instance); + + return -1; + } + + LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + + /* Close all VCHI service connections */ + for (i = 0; i < instance->num_connections; i++) { + int status; + + LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); + vchi_service_use(instance->vchi_handle[i]); + + status = vchi_service_close(instance->vchi_handle[i]); + if (status) { + LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", + __func__, status); + } + } + + mutex_unlock(&instance->vchi_mutex); + + kfree(instance); + + LOG_DBG(" .. OUT\n"); + + return 0; +} + +static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) +{ + static VCHI_INSTANCE_T vchi_instance; + static VCHI_CONNECTION_T *vchi_connection; + static int initted; + struct bcm2835_audio_instance *instance = + (struct bcm2835_audio_instance *)alsa_stream->instance; + int ret; + + LOG_DBG(" .. IN\n"); + + LOG_INFO("%s: start\n", __func__); + BUG_ON(instance); + if (instance) { + LOG_ERR("%s: VCHI instance already open (%p)\n", + __func__, instance); + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + ret = 0; // xxx todo -1; + goto err_free_mem; + } + + /* Initialize and create a VCHI connection */ + if (!initted) { + ret = vchi_initialise(&vchi_instance); + if (ret) { + LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + + ret = -EIO; + goto err_free_mem; + } + ret = vchi_connect(NULL, 0, vchi_instance); + if (ret) { + LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + + ret = -EIO; + goto err_free_mem; + } + initted = 1; + } + + /* Initialize an instance of the audio service */ + instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1); + + if (!instance) { + LOG_ERR("%s: failed to initialize audio service\n", __func__); + + ret = -EPERM; + goto err_free_mem; + } + + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + + LOG_DBG(" success !\n"); + ret = 0; +err_free_mem: + LOG_DBG(" .. OUT\n"); + + return ret; +} + +int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) +{ + struct bcm2835_audio_instance *instance; + struct vc_audio_msg m; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + my_workqueue_init(alsa_stream); + + ret = bcm2835_audio_open_connection(alsa_stream); + if (ret) { + ret = -1; + goto exit; + } + instance = alsa_stream->instance; + LOG_DBG(" instance (%p)\n", instance); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_OPEN; + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); +exit: + LOG_DBG(" .. OUT\n"); + return ret; +} + +static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream, + struct bcm2835_chip *chip) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", + chip->dest, chip->volume); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + instance->result = -1; + + m.type = VC_AUDIO_MSG_TYPE_CONTROL; + m.u.control.dest = chip->dest; + m.u.control.volume = chip->volume; + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + + /* We are expecting a reply from the videocore */ + wait_for_completion(&instance->msg_avail_comp); + + if (instance->result) { + LOG_ERR("%s: result=%d\n", __func__, instance->result); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + + LOG_DBG(" .. OUT\n"); + return ret; +} + +int bcm2835_audio_set_ctls(struct bcm2835_chip *chip) +{ + int i; + int ret = 0; + + LOG_DBG(" .. IN\n"); + LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); + + /* change ctls for all substreams */ + for (i = 0; i < MAX_SUBSTREAMS; i++) { + if (chip->avail_substreams & (1 << i)) { + if (!chip->alsa_stream[i]) { + LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams); + ret = 0; + } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { + LOG_ERR("Couldn't set the controls for stream %d\n", i); + ret = -1; + } else { + LOG_DBG(" Controls set for stream %d\n", i); + } + } + } + LOG_DBG(" .. OUT ret=%d\n", ret); + return ret; +} + +int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, + unsigned int channels, unsigned int samplerate, + unsigned int bps) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n", + channels, samplerate, bps); + + /* resend ctls - alsa_stream may not have been open when first send */ + ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip); + if (ret) { + LOG_ERR(" Alsa controls not supported\n"); + return -EINVAL; + } + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + instance->result = -1; + + m.type = VC_AUDIO_MSG_TYPE_CONFIG; + m.u.config.channels = channels; + m.u.config.samplerate = samplerate; + m.u.config.bps = bps; + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + + /* We are expecting a reply from the videocore */ + wait_for_completion(&instance->msg_avail_comp); + + if (instance->result) { + LOG_ERR("%s: result=%d", __func__, instance->result); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + + LOG_DBG(" .. OUT\n"); + return ret; +} + +int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream) +{ + LOG_DBG(" .. IN\n"); + + LOG_DBG(" .. OUT\n"); + + return 0; +} + +static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_START; + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} + +static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_STOP; + m.u.stop.draining = alsa_stream->draining; + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} + +int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + my_workqueue_quit(alsa_stream); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_CLOSE; + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + ret = -1; + goto unlock; + } + + /* We are expecting a reply from the videocore */ + wait_for_completion(&instance->msg_avail_comp); + + if (instance->result) { + LOG_ERR("%s: failed result (result=%d)\n", + __func__, instance->result); + + ret = -1; + goto unlock; + } + + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + + /* Stop the audio service */ + vc_vchi_audio_deinit(instance); + alsa_stream->instance = NULL; + + LOG_DBG(" .. OUT\n"); + return ret; +} + +static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, void *src) +{ + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int status; + int ret; + + LOG_DBG(" .. IN\n"); + + LOG_INFO(" Writing %d bytes from %p\n", count, src); + + if (mutex_lock_interruptible(&instance->vchi_mutex)) { + LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", + instance->num_connections); + return -EINTR; + } + vchi_service_use(instance->vchi_handle[0]); + + if (instance->peer_version == 0 && vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) { + LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); + } + m.type = VC_AUDIO_MSG_TYPE_WRITE; + m.u.write.count = count; + // old version uses bulk, new version uses control + m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000; + m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1; + m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2; + m.u.write.silence = src == NULL; + + /* Send the message to the videocore */ + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + &m, sizeof(m)); + + if (status) { + LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + if (!m.u.write.silence) { + if (!m.u.write.max_packet) { + /* Send the message to the videocore */ + status = vchi_bulk_queue_transmit(instance->vchi_handle[0], + src, count, + 0 * + VCHI_FLAGS_BLOCK_UNTIL_QUEUED + + + 1 * + VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, + NULL); + } else { + while (count > 0) { + int bytes = min((int) m.u.write.max_packet, (int) count); + + status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], + src, bytes); + src = (char *)src + bytes; + count -= bytes; + } + } + if (status) { + LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n", + __func__, status); + + ret = -1; + goto unlock; + } + } + ret = 0; + +unlock: + vchi_service_release(instance->vchi_handle[0]); + mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} + +/** + * Returns all buffers from arm->vc + */ +void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream) +{ + LOG_DBG(" .. IN\n"); + LOG_DBG(" .. OUT\n"); + return; +} + +/** + * Forces VC to flush(drop) its filled playback buffers and + * return them the us. (VC->ARM) + */ +void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream) +{ + LOG_DBG(" .. IN\n"); + LOG_DBG(" .. OUT\n"); +} + +unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) +{ + unsigned int count = atomic_read(&alsa_stream->retrieved); + + atomic_sub(count, &alsa_stream->retrieved); + return count; +} + +module_param(force_bulk, bool, 0444); +MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/drivers/staging/bcm2835-audio/bcm2835.c b/drivers/staging/bcm2835-audio/bcm2835.c new file mode 100644 index 000000000000..3a5e528e0ec6 --- /dev/null +++ b/drivers/staging/bcm2835-audio/bcm2835.c @@ -0,0 +1,250 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#include <linux/platform_device.h> + +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/of.h> + +#include "bcm2835.h" + +/* HACKY global pointers needed for successive probes to work : ssp + * But compared against the changes we will have to do in VC audio_ipc code + * to export 8 audio_ipc devices as a single IPC device and then monitor all + * four devices in a thread, this gets things done quickly and should be easier + * to debug if we run into issues + */ + +static struct snd_card *g_card; +static struct bcm2835_chip *g_chip; + +static int snd_bcm2835_free(struct bcm2835_chip *chip) +{ + kfree(chip); + return 0; +} + +/* component-destructor + * (see "Management of Cards and Components") + */ +static int snd_bcm2835_dev_free(struct snd_device *device) +{ + return snd_bcm2835_free(device->device_data); +} + +/* chip-specific constructor + * (see "Management of Cards and Components") + */ +static int snd_bcm2835_create(struct snd_card *card, + struct platform_device *pdev, + struct bcm2835_chip **rchip) +{ + struct bcm2835_chip *chip; + int err; + static struct snd_device_ops ops = { + .dev_free = snd_bcm2835_dev_free, + }; + + *rchip = NULL; + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->card = card; + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) { + snd_bcm2835_free(chip); + return err; + } + + *rchip = chip; + return 0; +} + +static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm2835_chip *chip; + struct snd_card *card; + u32 numchans; + int err, i; + + err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", + &numchans); + if (err) { + dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); + return err; + } + + if (numchans == 0 || numchans > MAX_SUBSTREAMS) { + numchans = MAX_SUBSTREAMS; + dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", + numchans); + } + + err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); + if (err) { + dev_err(dev, "Failed to create soundcard structure\n"); + return err; + } + + snd_card_set_dev(card, dev); + strcpy(card->driver, "bcm2835"); + strcpy(card->shortname, "bcm2835 ALSA"); + sprintf(card->longname, "%s", card->shortname); + + err = snd_bcm2835_create(card, pdev, &chip); + if (err < 0) { + dev_err(dev, "Failed to create bcm2835 chip\n"); + goto err_free; + } + + err = snd_bcm2835_new_pcm(chip); + if (err < 0) { + dev_err(dev, "Failed to create new bcm2835 pcm device\n"); + goto err_free; + } + + err = snd_bcm2835_new_spdif_pcm(chip); + if (err < 0) { + dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); + goto err_free; + } + + err = snd_bcm2835_new_ctl(chip); + if (err < 0) { + dev_err(dev, "Failed to create new bcm2835 ctl\n"); + goto err_free; + } + + for (i = 0; i < numchans; i++) { + chip->avail_substreams |= (1 << i); + chip->pdev[i] = pdev; + } + + err = snd_card_register(card); + if (err) { + dev_err(dev, "Failed to register bcm2835 ALSA card\n"); + goto err_free; + } + + g_card = card; + g_chip = chip; + platform_set_drvdata(pdev, card); + audio_info("bcm2835 ALSA card created with %u channels\n", numchans); + + return 0; + +err_free: + snd_card_free(card); + + return err; +} + +static int snd_bcm2835_alsa_remove(struct platform_device *pdev) +{ + int idx; + void *drv_data; + + drv_data = platform_get_drvdata(pdev); + + if (drv_data == (void *)g_card) { + /* This is the card device */ + snd_card_free((struct snd_card *)drv_data); + g_card = NULL; + g_chip = NULL; + } else { + idx = (int)(long)drv_data; + if (g_card) { + BUG_ON(!g_chip); + /* We pass chip device numbers in audio ipc devices + * other than the one we registered our card with + */ + idx = (int)(long)drv_data; + BUG_ON(!idx || idx > MAX_SUBSTREAMS); + g_chip->avail_substreams &= ~(1 << idx); + /* There should be atleast one substream registered + * after we are done here, as it wil be removed when + * the *remove* is called for the card device + */ + BUG_ON(!g_chip->avail_substreams); + } + } + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM + +static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, + pm_message_t state) +{ + return 0; +} + +static int snd_bcm2835_alsa_resume(struct platform_device *pdev) +{ + return 0; +} + +#endif + +static const struct of_device_id snd_bcm2835_of_match_table[] = { + { .compatible = "brcm,bcm2835-audio",}, + {}, +}; +MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); + +static struct platform_driver bcm2835_alsa0_driver = { + .probe = snd_bcm2835_alsa_probe_dt, + .remove = snd_bcm2835_alsa_remove, +#ifdef CONFIG_PM + .suspend = snd_bcm2835_alsa_suspend, + .resume = snd_bcm2835_alsa_resume, +#endif + .driver = { + .name = "bcm2835_AUD0", + .owner = THIS_MODULE, + .of_match_table = snd_bcm2835_of_match_table, + }, +}; + +static int bcm2835_alsa_device_init(void) +{ + int retval; + + retval = platform_driver_register(&bcm2835_alsa0_driver); + if (retval) + pr_err("Error registering bcm2835_alsa0_driver %d .\n", retval); + + return retval; +} + +static void bcm2835_alsa_device_exit(void) +{ + platform_driver_unregister(&bcm2835_alsa0_driver); +} + +late_initcall(bcm2835_alsa_device_init); +module_exit(bcm2835_alsa_device_exit); + +MODULE_AUTHOR("Dom Cobley"); +MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/bcm2835-audio/bcm2835.h b/drivers/staging/bcm2835-audio/bcm2835.h new file mode 100644 index 000000000000..36e3ef80e60c --- /dev/null +++ b/drivers/staging/bcm2835-audio/bcm2835.h @@ -0,0 +1,167 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#ifndef __SOUND_ARM_BCM2835_H +#define __SOUND_ARM_BCM2835_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/interrupt.h> +#include <linux/wait.h> +#include <sound/core.h> +#include <sound/initval.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/pcm-indirect.h> +#include <linux/workqueue.h> + +/* +#define AUDIO_DEBUG_ENABLE +#define AUDIO_VERBOSE_DEBUG_ENABLE + */ + +/* Debug macros */ + +#ifdef AUDIO_DEBUG_ENABLE +#ifdef AUDIO_VERBOSE_DEBUG_ENABLE + +#define audio_debug(fmt, arg...) \ + printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) + +#define audio_info(fmt, arg...) \ + printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) + +#else + +#define audio_debug(fmt, arg...) + +#define audio_info(fmt, arg...) + +#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */ + +#else + +#define audio_debug(fmt, arg...) + +#define audio_info(fmt, arg...) + +#endif /* AUDIO_DEBUG_ENABLE */ + +#define audio_error(fmt, arg...) \ + printk(KERN_ERR"%s:%d " fmt, __func__, __LINE__, ##arg) + +#define audio_warning(fmt, arg...) \ + printk(KERN_WARNING"%s:%d " fmt, __func__, __LINE__, ##arg) + +#define audio_alert(fmt, arg...) \ + printk(KERN_ALERT"%s:%d " fmt, __func__, __LINE__, ##arg) + +#define MAX_SUBSTREAMS (8) +#define AVAIL_SUBSTREAMS_MASK (0xff) + +enum { + CTRL_VOL_MUTE, + CTRL_VOL_UNMUTE +}; + +/* macros for alsa2chip and chip2alsa, instead of functions */ + +#define alsa2chip(vol) (uint)(-((vol << 8) / 100)) /* convert alsa to chip volume (defined as macro rather than function call) */ +#define chip2alsa(vol) -((vol * 100) >> 8) /* convert chip to alsa volume */ + +/* Some constants for values .. */ +enum snd_bcm2835_route { + AUDIO_DEST_AUTO = 0, + AUDIO_DEST_HEADPHONES = 1, + AUDIO_DEST_HDMI = 2, + AUDIO_DEST_MAX, +}; + +enum snd_bcm2835_ctrl { + PCM_PLAYBACK_VOLUME, + PCM_PLAYBACK_MUTE, + PCM_PLAYBACK_DEVICE, +}; + +/* definition of the chip-specific record */ +struct bcm2835_chip { + struct snd_card *card; + struct snd_pcm *pcm; + struct snd_pcm *pcm_spdif; + /* Bitmat for valid reg_base and irq numbers */ + unsigned int avail_substreams; + struct platform_device *pdev[MAX_SUBSTREAMS]; + struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; + + int volume; + int old_volume; /* stores the volume value whist muted */ + int dest; + int mute; + + unsigned int opened; + unsigned int spdif_status; + struct mutex audio_mutex; +}; + +struct bcm2835_alsa_stream { + struct bcm2835_chip *chip; + struct snd_pcm_substream *substream; + struct snd_pcm_indirect pcm_indirect; + + struct semaphore buffers_update_sem; + struct semaphore control_sem; + spinlock_t lock; + volatile unsigned int control; + volatile unsigned int status; + + int open; + int running; + int draining; + + int channels; + int params_rate; + int pcm_format_width; + + unsigned int pos; + unsigned int buffer_size; + unsigned int period_size; + + atomic_t retrieved; + struct bcm2835_audio_instance *instance; + struct workqueue_struct *my_wq; + int idx; +}; + +int snd_bcm2835_new_ctl(struct bcm2835_chip *chip); +int snd_bcm2835_new_pcm(struct bcm2835_chip *chip); +int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip); + +int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream); +int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream); +int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, + unsigned int channels, unsigned int samplerate, + unsigned int bps); +int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); +int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); +int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); +int bcm2835_audio_set_ctls(struct bcm2835_chip *chip); +int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, + void *src); +void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); +unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); +void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream); +void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream); + +#endif /* __SOUND_ARM_BCM2835_H */ diff --git a/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h b/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h new file mode 100644 index 000000000000..da96f1bc2516 --- /dev/null +++ b/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h @@ -0,0 +1,108 @@ +/***************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + *****************************************************************************/ + +#ifndef _VC_AUDIO_DEFS_H_ +#define _VC_AUDIO_DEFS_H_ + +#define VC_AUDIOSERV_MIN_VER 1 +#define VC_AUDIOSERV_VER 2 + +/* FourCC code used for VCHI connection */ +#define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") + +/* + * List of screens that are currently supported + * All message types supported for HOST->VC direction + */ + +enum vc_audio_msg_type { + VC_AUDIO_MSG_TYPE_RESULT, // Generic result + VC_AUDIO_MSG_TYPE_COMPLETE, // Generic result + VC_AUDIO_MSG_TYPE_CONFIG, // Configure audio + VC_AUDIO_MSG_TYPE_CONTROL, // Configure audio + VC_AUDIO_MSG_TYPE_OPEN, // Configure audio + VC_AUDIO_MSG_TYPE_CLOSE, // Configure audio + VC_AUDIO_MSG_TYPE_START, // Configure audio + VC_AUDIO_MSG_TYPE_STOP, // Configure audio + VC_AUDIO_MSG_TYPE_WRITE, // Configure audio + VC_AUDIO_MSG_TYPE_MAX +}; + +/* configure the audio */ + +struct vc_audio_config { + u32 channels; + u32 samplerate; + u32 bps; +}; + +struct vc_audio_control { + u32 volume; + u32 dest; +}; + +struct vc_audio_open { + u32 dummy; +}; + +struct vc_audio_close { + u32 dummy; +}; + +struct vc_audio_start { + u32 dummy; +}; + +struct vc_audio_stop { + u32 draining; +}; + +/* configure the write audio samples */ +struct vc_audio_write { + u32 count; // in bytes + u32 cookie1; + u32 cookie2; + s16 silence; + s16 max_packet; +}; + +/* Generic result for a request (VC->HOST) */ +struct vc_audio_result { + s32 success; // Success value +}; + +/* Generic result for a request (VC->HOST) */ +struct vc_audio_complete { + s32 count; // Success value + u32 cookie1; + u32 cookie2; +}; + +/* Message header for all messages in HOST->VC direction */ +struct vc_audio_msg { + s32 type; /* Message type (VC_AUDIO_MSG_TYPE) */ + union { + struct vc_audio_config config; + struct vc_audio_control control; + struct vc_audio_open open; + struct vc_audio_close close; + struct vc_audio_start start; + struct vc_audio_stop stop; + struct vc_audio_write write; + struct vc_audio_result result; + struct vc_audio_complete complete; + } u; +}; + +#endif /* _VC_AUDIO_DEFS_H_ */ diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index e7255f811611..942507754cab 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1025,7 +1025,7 @@ config COMEDI_NI_660X select COMEDI_NI_TIOCMD ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, - PXI-6602, PXI-6608 and PXI-6624. + PXI-6602, PXI-6608, PCI-6624, and PXI-6624. To compile this driver as a module, choose M here: the module will be called ni_660x. @@ -1070,9 +1070,11 @@ config COMEDI_NI_PCIMIO PCI-MIO-16E-4, PCI-6014, PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, - PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, PCI-6229, - PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259, - PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, PCI-6711, PXI-6711, + PCI-6220, PXI-6220, PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225, + PXI-6225, PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251, + PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259, + PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281, + PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711, PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733, PCI-6143, PXI-6143 diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h index 5ce77f3e8c22..0127c1f98bbf 100644 --- a/drivers/staging/comedi/comedi_compat32.h +++ b/drivers/staging/comedi/comedi_compat32.h @@ -25,7 +25,8 @@ #ifdef CONFIG_COMPAT struct file; -long comedi_compat_ioctl(struct file *, unsigned int cmd, unsigned long arg); +long comedi_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); #else /* CONFIG_COMPAT */ diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 64b3966c5f1f..57e8599b54e6 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -28,15 +28,11 @@ #include <linux/delay.h> #include <linux/mm.h> #include <linux/slab.h> -#include <linux/kmod.h> #include <linux/poll.h> -#include <linux/init.h> #include <linux/device.h> -#include <linux/vmalloc.h> #include <linux/fs.h> #include "comedidev.h" #include <linux/cdev.h> -#include <linux/stat.h> #include <linux/io.h> #include <linux/uaccess.h> @@ -2898,9 +2894,6 @@ static int __init comedi_init(void) comedi_class->dev_groups = comedi_dev_groups; - /* XXX requires /proc interface */ - comedi_proc_init(); - /* create devices files for legacy/manual use */ for (i = 0; i < comedi_num_legacy_minors; i++) { struct comedi_device *dev; @@ -2917,6 +2910,9 @@ static int __init comedi_init(void) mutex_unlock(&dev->mutex); } + /* XXX requires /proc interface */ + comedi_proc_init(); + return 0; } module_init(comedi_init); diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index 3f2c88ae6470..534415e331b6 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -44,11 +44,12 @@ extern unsigned int comedi_default_buf_maxsize_kb; extern struct comedi_driver *comedi_drivers; extern struct mutex comedi_drivers_list_lock; -int insn_inval(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); +int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); -void comedi_device_detach(struct comedi_device *); -int comedi_device_attach(struct comedi_device *, struct comedi_devconfig *); +void comedi_device_detach(struct comedi_device *dev); +int comedi_device_attach(struct comedi_device *dev, + struct comedi_devconfig *it); #ifdef CONFIG_PROC_FS diff --git a/drivers/staging/comedi/comedi_pci.h b/drivers/staging/comedi/comedi_pci.h index 4005cc9cf7f1..7dfd892c74b0 100644 --- a/drivers/staging/comedi/comedi_pci.h +++ b/drivers/staging/comedi/comedi_pci.h @@ -34,18 +34,20 @@ #define PCI_VENDOR_ID_RTD 0x1435 #define PCI_VENDOR_ID_HUMUSOFT 0x186c -struct pci_dev *comedi_to_pci_dev(struct comedi_device *); +struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev); -int comedi_pci_enable(struct comedi_device *); -void comedi_pci_disable(struct comedi_device *); -void comedi_pci_detach(struct comedi_device *); +int comedi_pci_enable(struct comedi_device *dev); +void comedi_pci_disable(struct comedi_device *dev); +void comedi_pci_detach(struct comedi_device *dev); -int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *, +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver, unsigned long context); -void comedi_pci_auto_unconfig(struct pci_dev *); +void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); -void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); +int comedi_pci_driver_register(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver); +void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver); /** * module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c index d7072a5c1647..cd4742851c08 100644 --- a/drivers/staging/comedi/comedi_pcmcia.c +++ b/drivers/staging/comedi/comedi_pcmcia.c @@ -78,7 +78,8 @@ static int comedi_pcmcia_conf_check(struct pcmcia_device *link, * or a negative error number from pcmcia_enable_device() if it fails. */ int comedi_pcmcia_enable(struct comedi_device *dev, - int (*conf_check)(struct pcmcia_device *, void *)) + int (*conf_check)(struct pcmcia_device *p_dev, + void *priv_data)) { struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); int ret; diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h index 5a572c200a8b..9e45c7c93278 100644 --- a/drivers/staging/comedi/comedi_pcmcia.h +++ b/drivers/staging/comedi/comedi_pcmcia.h @@ -24,19 +24,21 @@ #include "comedidev.h" -struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *); +struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev); -int comedi_pcmcia_enable(struct comedi_device *, - int (*conf_check)(struct pcmcia_device *, void *)); -void comedi_pcmcia_disable(struct comedi_device *); +int comedi_pcmcia_enable(struct comedi_device *dev, + int (*conf_check)(struct pcmcia_device *p_dev, + void *priv_data)); +void comedi_pcmcia_disable(struct comedi_device *dev); -int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *); -void comedi_pcmcia_auto_unconfig(struct pcmcia_device *); +int comedi_pcmcia_auto_config(struct pcmcia_device *link, + struct comedi_driver *driver); +void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link); -int comedi_pcmcia_driver_register(struct comedi_driver *, - struct pcmcia_driver *); -void comedi_pcmcia_driver_unregister(struct comedi_driver *, - struct pcmcia_driver *); +int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver, + struct pcmcia_driver *pcmcia_driver); +void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver, + struct pcmcia_driver *pcmcia_driver); /** * module_comedi_pcmcia_driver() - Helper macro for registering a comedi diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h index 721128bece3c..132154ec792f 100644 --- a/drivers/staging/comedi/comedi_usb.h +++ b/drivers/staging/comedi/comedi_usb.h @@ -23,15 +23,17 @@ #include "comedidev.h" -struct usb_interface *comedi_to_usb_interface(struct comedi_device *); -struct usb_device *comedi_to_usb_dev(struct comedi_device *); +struct usb_interface *comedi_to_usb_interface(struct comedi_device *dev); +struct usb_device *comedi_to_usb_dev(struct comedi_device *dev); -int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *, - unsigned long context); -void comedi_usb_auto_unconfig(struct usb_interface *); +int comedi_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver, unsigned long context); +void comedi_usb_auto_unconfig(struct usb_interface *intf); -int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *); -void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); +int comedi_usb_driver_register(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver); +void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver); /** * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 0c7c37a8ff33..1bb9986f865e 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -612,12 +612,6 @@ extern const struct comedi_lrange range_unknown; #define range_digital range_unipolar5 -#if __GNUC__ >= 3 -#define GCC_ZERO_LENGTH_ARRAY -#else -#define GCC_ZERO_LENGTH_ARRAY 0 -#endif - /** * struct comedi_lrange - Describes a COMEDI range table * @length: Number of entries in the range table. @@ -631,7 +625,7 @@ extern const struct comedi_lrange range_unknown; */ struct comedi_lrange { int length; - struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY]; + struct comedi_krange range[]; }; /** @@ -982,19 +976,21 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, #define COMEDI_TIMEOUT_MS 1000 -int comedi_timeout(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, - int (*cb)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned long context), +int comedi_timeout(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, + int (*cb)(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned long context), unsigned long context); unsigned int comedi_handle_events(struct comedi_device *dev, struct comedi_subdevice *s); -int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *data, +int comedi_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data, unsigned int mask); -unsigned int comedi_dio_update_state(struct comedi_subdevice *, +unsigned int comedi_dio_update_state(struct comedi_subdevice *s, unsigned int *data); unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s); unsigned int comedi_nscans_left(struct comedi_subdevice *s, @@ -1004,32 +1000,33 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s, void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes); -void *comedi_alloc_devpriv(struct comedi_device *, size_t); -int comedi_alloc_subdevices(struct comedi_device *, int); -int comedi_alloc_subdev_readback(struct comedi_subdevice *); +void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size); +int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices); +int comedi_alloc_subdev_readback(struct comedi_subdevice *s); -int comedi_readback_insn_read(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *data); +int comedi_readback_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); -int comedi_load_firmware(struct comedi_device *, struct device *, +int comedi_load_firmware(struct comedi_device *dev, struct device *hw_dev, const char *name, - int (*cb)(struct comedi_device *, + int (*cb)(struct comedi_device *dev, const u8 *data, size_t size, unsigned long context), unsigned long context); -int __comedi_request_region(struct comedi_device *, +int __comedi_request_region(struct comedi_device *dev, unsigned long start, unsigned long len); -int comedi_request_region(struct comedi_device *, +int comedi_request_region(struct comedi_device *dev, unsigned long start, unsigned long len); -void comedi_legacy_detach(struct comedi_device *); +void comedi_legacy_detach(struct comedi_device *dev); -int comedi_auto_config(struct device *, struct comedi_driver *, - unsigned long context); -void comedi_auto_unconfig(struct device *); +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context); +void comedi_auto_unconfig(struct device *hardware_device); -int comedi_driver_register(struct comedi_driver *); -void comedi_driver_unregister(struct comedi_driver *); +int comedi_driver_register(struct comedi_driver *driver); +void comedi_driver_unregister(struct comedi_driver *driver); /** * module_comedi_driver() - Helper macro for registering a comedi driver diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 57f0f46de0be..1fdc0f8d7e1a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -94,7 +94,7 @@ struct apci3501_private { unsigned char timer_mode; }; -static struct comedi_lrange apci3501_ao_range = { +static const struct comedi_lrange apci3501_ao_range = { 2, { BIP_RANGE(10), UNI_RANGE(10) diff --git a/drivers/staging/comedi/drivers/addi_watchdog.h b/drivers/staging/comedi/drivers/addi_watchdog.h index 3f8e7388bbca..b049cfba9813 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.h +++ b/drivers/staging/comedi/drivers/addi_watchdog.h @@ -4,6 +4,6 @@ struct comedi_subdevice; void addi_watchdog_reset(unsigned long iobase); -int addi_watchdog_init(struct comedi_subdevice *, unsigned long iobase); +int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase); #endif diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 86450c08f291..1cc9b7ef1ff9 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1279,9 +1279,8 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, } else { arg = cmd->convert_arg * cmd->chanlist_len; } - err |= comedi_check_trigger_arg_min(&cmd-> - scan_begin_arg, - arg); + err |= comedi_check_trigger_arg_min( + &cmd->scan_begin_arg, arg); } } diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index cb9c2699277e..efbf27730d71 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -238,7 +238,7 @@ enum daq_atrig_low_4020_contents { EXT_START_TRIG_BNC_BIT = 0x2000, }; -static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold) +static inline u16 analog_trig_low_threshold_bits(u16 threshold) { return threshold & 0xfff; } @@ -280,17 +280,17 @@ enum adc_control1_contents { ADC_MODE_MASK = 0xf000, }; -static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel) +static inline u16 adc_lo_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 8; }; -static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel) +static inline u16 adc_hi_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 10; }; -static inline uint16_t adc_mode_bits(unsigned int mode) +static inline u16 adc_mode_bits(unsigned int mode) { return (mode & 0xf) << 12; }; @@ -318,12 +318,12 @@ enum calibration_contents { * 7 : dac channel 1 */ -static inline uint16_t adc_src_bits(unsigned int source) +static inline u16 adc_src_bits(unsigned int source) { return (source & 0xf) << 3; }; -static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel) +static inline u16 adc_convert_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 8; }; @@ -337,7 +337,7 @@ enum adc_queue_load_contents { QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */ }; -static inline uint16_t adc_chan_bits(unsigned int channel) +static inline u16 adc_chan_bits(unsigned int channel) { return channel & 0x3f; }; @@ -384,22 +384,22 @@ enum hw_status_contents { ADC_STOP_BIT = 0x200, }; -static inline uint16_t pipe_full_bits(uint16_t hw_status_bits) +static inline u16 pipe_full_bits(u16 hw_status_bits) { return (hw_status_bits >> 10) & 0x3; }; -static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits) +static inline unsigned int dma_chain_flag_bits(u16 prepost_bits) { return (prepost_bits >> 6) & 0x3; } -static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits) +static inline unsigned int adc_upper_read_ptr_code(u16 prepost_bits) { return (prepost_bits >> 12) & 0x3; } -static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits) +static inline unsigned int adc_upper_write_ptr_code(u16 prepost_bits) { return (prepost_bits >> 14) & 0x3; } @@ -418,12 +418,12 @@ enum range_cal_i2c_contents { BNC_TRIG_THRESHOLD_0V_BIT = 0x80, }; -static inline uint8_t adc_src_4020_bits(unsigned int source) +static inline u8 adc_src_4020_bits(unsigned int source) { return (source << 4) & ADC_SRC_4020_MASK; }; -static inline uint8_t attenuate_bit(unsigned int channel) +static inline u8 attenuate_bit(unsigned int channel) { /* attenuate channel (+-5V input range) */ return 1 << (channel & 0x3); @@ -443,7 +443,7 @@ static const struct comedi_lrange ai_ranges_64xx = { } }; -static const uint8_t ai_range_code_64xx[8] = { +static const u8 ai_range_code_64xx[8] = { 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */ 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */ }; @@ -461,7 +461,7 @@ static const struct comedi_lrange ai_ranges_64_mx = { } }; -static const uint8_t ai_range_code_64_mx[7] = { +static const u8 ai_range_code_64_mx[7] = { 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */ 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */ }; @@ -476,7 +476,7 @@ static const struct comedi_lrange ai_ranges_60xx = { } }; -static const uint8_t ai_range_code_60xx[4] = { +static const u8 ai_range_code_60xx[4] = { 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */ }; @@ -500,7 +500,7 @@ static const struct comedi_lrange ai_ranges_6030 = { } }; -static const uint8_t ai_range_code_6030[14] = { +static const u8 ai_range_code_6030[14] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */ 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */ }; @@ -526,7 +526,7 @@ static const struct comedi_lrange ai_ranges_6052 = { } }; -static const uint8_t ai_range_code_6052[15] = { +static const u8 ai_range_code_6052[15] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */ 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */ }; @@ -594,7 +594,7 @@ struct hw_fifo_info { unsigned int num_segments; unsigned int max_segment_length; unsigned int sample_packing_ratio; - uint16_t fifo_size_reg_mask; + u16 fifo_size_reg_mask; }; enum pcidas64_boardid { @@ -634,7 +634,7 @@ struct pcidas64_board { int ai_bits; /* analog input resolution */ int ai_speed; /* fastest conversion period in ns */ const struct comedi_lrange *ai_range_table; - const uint8_t *ai_range_code; + const u8 *ai_range_code; int ao_nchan; /* number of analog out channels */ int ao_bits; /* analog output resolution */ int ao_scan_speed; /* analog output scan speed */ @@ -1132,10 +1132,10 @@ struct pcidas64_private { void __iomem *plx9080_iobase; void __iomem *main_iobase; /* local address (used by dma controller) */ - uint32_t local0_iobase; - uint32_t local1_iobase; + u32 local0_iobase; + u32 local1_iobase; /* dma buffers for analog input */ - uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; + u16 *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; /* @@ -1151,7 +1151,7 @@ struct pcidas64_private { */ unsigned int ai_dma_index; /* dma buffers for analog output */ - uint16_t *ao_buffer[AO_DMA_RING_COUNT]; + u16 *ao_buffer[AO_DMA_RING_COUNT]; /* physical addresses of ao dma buffers */ dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; struct plx_dma_desc *ao_dma_desc; @@ -1162,20 +1162,20 @@ struct pcidas64_private { /* last bits sent to INTR_ENABLE_REG register */ unsigned int intr_enable_bits; /* last bits sent to ADC_CONTROL1_REG register */ - uint16_t adc_control1_bits; + u16 adc_control1_bits; /* last bits sent to FIFO_SIZE_REG register */ - uint16_t fifo_size_bits; + u16 fifo_size_bits; /* last bits sent to HW_CONFIG_REG register */ - uint16_t hw_config_bits; - uint16_t dac_control1_bits; + u16 hw_config_bits; + u16 dac_control1_bits; /* last bits written to plx9080 control register */ - uint32_t plx_control_bits; + u32 plx_control_bits; /* last bits written to plx interrupt control and status register */ - uint32_t plx_intcsr_bits; + u32 plx_intcsr_bits; /* index of calibration source readable through ai ch0 */ int calibration_source; /* bits written to i2c calibration/range register */ - uint8_t i2c_cal_range_bits; + u8 i2c_cal_range_bits; /* configure digital triggers to trigger on falling edge */ unsigned int ext_trig_falling; short ai_cmd_running; @@ -1193,7 +1193,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, } static unsigned int hw_revision(const struct comedi_device *dev, - uint16_t hw_status_bits) + u16 hw_status_bits) { const struct pcidas64_board *board = dev->board_ptr; @@ -1204,7 +1204,7 @@ static unsigned int hw_revision(const struct comedi_device *dev, } static void set_dac_range_bits(struct comedi_device *dev, - uint16_t *bits, unsigned int channel, + u16 *bits, unsigned int channel, unsigned int range) { const struct pcidas64_board *board = dev->board_ptr; @@ -1266,7 +1266,7 @@ static void enable_ai_interrupts(struct comedi_device *dev, { const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - uint32_t bits; + u32 bits; unsigned long flags; bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | @@ -1292,7 +1292,7 @@ static void init_plx9080(struct comedi_device *dev) { const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - uint32_t bits; + u32 bits; void __iomem *plx_iobase = devpriv->plx9080_iobase; devpriv->plx_control_bits = @@ -1378,7 +1378,7 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, static const int increment_size = 0x100; const struct hw_fifo_info *const fifo = board->ai_fifo; unsigned int num_increments; - uint16_t bits; + u16 bits; if (num_entries < increment_size) num_entries = increment_size; @@ -1437,7 +1437,7 @@ static void init_stc_registers(struct comedi_device *dev) { const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - uint16_t bits; + u16 bits; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -1657,9 +1657,9 @@ static void i2c_set_scl(struct comedi_device *dev, int state) } } -static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) +static void i2c_write_byte(struct comedi_device *dev, u8 byte) { - uint8_t bit; + u8 bit; unsigned int num_bits = 8; for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { @@ -1700,11 +1700,11 @@ static void i2c_stop(struct comedi_device *dev) } static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length) + const u8 *data, unsigned int length) { struct pcidas64_private *devpriv = dev->private; unsigned int i; - uint8_t bitstream; + u8 bitstream; static const int read_bit = 0x1; /* @@ -1831,7 +1831,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* set start channel, and rest of settings */ writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } else { - uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits; + u8 old_cal_range_bits = devpriv->i2c_cal_range_bits; devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; if (insn->chanspec & CR_ALT_SOURCE) { @@ -1850,7 +1850,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, * as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { - uint8_t i2c_data = devpriv->i2c_cal_range_bits; + u8 i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); @@ -2273,23 +2273,23 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev) num_samples = devpriv->ai_fifo_segment_length * board->ai_fifo->sample_packing_ratio; - if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) - num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); + if (num_samples > DMA_BUFFER_SIZE / sizeof(u16)) + num_samples = DMA_BUFFER_SIZE / sizeof(u16); return num_samples; } -static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev, +static u32 ai_convert_counter_6xxx(const struct comedi_device *dev, const struct comedi_cmd *cmd) { /* supposed to load counter with desired divisor minus 3 */ return cmd->convert_arg / TIMER_BASE - 3; } -static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, +static u32 ai_scan_counter_6xxx(struct comedi_device *dev, struct comedi_cmd *cmd) { - uint32_t count; + u32 count; /* figure out how long we need to delay at end of scan */ switch (cmd->scan_begin_src) { @@ -2307,7 +2307,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, return count - 3; } -static uint32_t ai_convert_counter_4020(struct comedi_device *dev, +static u32 ai_convert_counter_4020(struct comedi_device *dev, struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; @@ -2382,7 +2382,7 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) { const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - uint32_t convert_counter = 0, scan_counter = 0; + u32 convert_counter = 0, scan_counter = 0; check_adc_timing(dev, cmd); @@ -2529,7 +2529,7 @@ static int setup_channel_queue(struct comedi_device *dev, * as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { - uint8_t i2c_data = devpriv->i2c_cal_range_bits; + u8 i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); @@ -2572,7 +2572,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - uint32_t bits; + u32 bits; unsigned int i; unsigned long flags; int retval; @@ -2634,7 +2634,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) for (i = 0; i < ai_dma_ring_count(board); i++) devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(dma_transfer_size(dev) * - sizeof(uint16_t)); + sizeof(u16)); /* give location of first dma descriptor */ load_first_dma_descriptor(dev, 1, @@ -2691,7 +2691,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int i; - uint16_t prepost_bits; + u16 prepost_bits; int read_segment, read_index, write_segment, write_index; int num_samples; @@ -2754,7 +2754,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) struct comedi_subdevice *s = dev->read_subdev; unsigned int nsamples; unsigned int i; - uint32_t fifo_data; + u32 fifo_data; int write_code = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = @@ -2794,7 +2794,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - uint32_t next_transfer_addr; + u32 next_transfer_addr; int j; int num_samples = 0; void __iomem *pci_addr_reg; @@ -2831,7 +2831,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - uint8_t dma1_status; + u8 dma1_status; unsigned long flags; /* check for fifo overrun */ @@ -3008,7 +3008,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, struct comedi_subdevice *s = dev->write_subdev; struct comedi_async *async; struct comedi_cmd *cmd; - uint8_t dma0_status; + u8 dma0_status; unsigned long flags; /* board might not support ao, in which case write_subdev is NULL */ @@ -3056,8 +3056,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) struct comedi_device *dev = d; struct pcidas64_private *devpriv = dev->private; unsigned short status; - uint32_t plx_status; - uint32_t plx_bits; + u32 plx_status; + u32 plx_bits; plx_status = readl(devpriv->plx9080_iobase + PLX_REG_INTCSR); status = readw(devpriv->main_iobase + HW_STATUS_REG); @@ -3180,7 +3180,7 @@ static void set_dac_select_reg(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - uint16_t bits; + u16 bits; unsigned int first_channel, last_channel; first_channel = CR_CHAN(cmd->chanlist[0]); @@ -3523,7 +3523,7 @@ static int dio_60xx_wbits(struct comedi_device *dev, */ static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value) + u8 value) { struct pcidas64_private *devpriv = dev->private; static const int num_caldac_channels = 8; @@ -3558,8 +3558,8 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address, static int caldac_i2c_write(struct comedi_device *dev, unsigned int caldac_channel, unsigned int value) { - uint8_t serial_bytes[3]; - uint8_t i2c_addr; + u8 serial_bytes[3]; + u8 i2c_addr; enum pointer_bits { /* manual has gain and offset bits switched */ OFFSET_0_2 = 0x1, @@ -3708,7 +3708,7 @@ static int cb_pcidas64_ad8402_insn_write(struct comedi_device *dev, return insn->n; } -static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) +static u16 read_eeprom(struct comedi_device *dev, u8 address) { struct pcidas64_private *devpriv = dev->private; static const int bitstream_length = 11; @@ -3717,7 +3717,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) unsigned int bit; void __iomem * const plx_control_addr = devpriv->plx9080_iobase + PLX_REG_CNTRL; - uint16_t value; + u16 value; static const int value_length = 16; static const int eeprom_udelay = 1; @@ -3813,7 +3813,7 @@ static int setup_subdevices(struct comedi_device *dev) s->do_cmdtest = ai_cmdtest; s->cancel = ai_cancel; if (board->layout == LAYOUT_4020) { - uint8_t data; + u8 data; /* * set adc to read from inputs * (not internal calibration sources) @@ -3975,7 +3975,7 @@ static int auto_attach(struct comedi_device *dev, struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pcidas64_board *board = NULL; struct pcidas64_private *devpriv; - uint32_t local_range, local_decode; + u32 local_range, local_decode; int retval; if (context < ARRAY_SIZE(pcidas64_boards)) @@ -4013,13 +4013,13 @@ static int auto_attach(struct comedi_device *dev, PLX_LASRR_MEM_MASK; local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS0BA) & local_range & PLX_LASBA_MEM_MASK; - devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & + devpriv->local0_iobase = ((u32)devpriv->main_phys_iobase & ~local_range) | local_decode; local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS1RR) & PLX_LASRR_MEM_MASK; local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS1BA) & local_range & PLX_LASBA_MEM_MASK; - devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & + devpriv->local1_iobase = ((u32)devpriv->dio_counter_phys_iobase & ~local_range) | local_decode; retval = alloc_and_init_dma_members(dev); diff --git a/drivers/staging/comedi/drivers/comedi_8254.h b/drivers/staging/comedi/drivers/comedi_8254.h index a12c29455d9d..326bd44b063e 100644 --- a/drivers/staging/comedi/drivers/comedi_8254.h +++ b/drivers/staging/comedi/drivers/comedi_8254.h @@ -100,34 +100,36 @@ struct comedi_8254 { unsigned int gate_src[3]; bool busy[3]; - int (*insn_config)(struct comedi_device *, struct comedi_subdevice *s, - struct comedi_insn *, unsigned int *data); + int (*insn_config)(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); }; -unsigned int comedi_8254_status(struct comedi_8254 *, unsigned int counter); -unsigned int comedi_8254_read(struct comedi_8254 *, unsigned int counter); -void comedi_8254_write(struct comedi_8254 *, +unsigned int comedi_8254_status(struct comedi_8254 *i8254, + unsigned int counter); +unsigned int comedi_8254_read(struct comedi_8254 *i8254, unsigned int counter); +void comedi_8254_write(struct comedi_8254 *i8254, unsigned int counter, unsigned int val); -int comedi_8254_set_mode(struct comedi_8254 *, +int comedi_8254_set_mode(struct comedi_8254 *i8254, unsigned int counter, unsigned int mode); -int comedi_8254_load(struct comedi_8254 *, +int comedi_8254_load(struct comedi_8254 *i8254, unsigned int counter, unsigned int val, unsigned int mode); -void comedi_8254_pacer_enable(struct comedi_8254 *, +void comedi_8254_pacer_enable(struct comedi_8254 *i8254, unsigned int counter1, unsigned int counter2, bool enable); -void comedi_8254_update_divisors(struct comedi_8254 *); -void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *, +void comedi_8254_update_divisors(struct comedi_8254 *i8254); +void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *i8254, unsigned int *nanosec, unsigned int flags); -void comedi_8254_ns_to_timer(struct comedi_8254 *, +void comedi_8254_ns_to_timer(struct comedi_8254 *i8254, unsigned int *nanosec, unsigned int flags); -void comedi_8254_set_busy(struct comedi_8254 *, +void comedi_8254_set_busy(struct comedi_8254 *i8254, unsigned int counter, bool busy); -void comedi_8254_subdevice_init(struct comedi_subdevice *, - struct comedi_8254 *); +void comedi_8254_subdevice_init(struct comedi_subdevice *s, + struct comedi_8254 *i8254); struct comedi_8254 *comedi_8254_init(unsigned long iobase, unsigned int osc_base, diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h index 2fb6573ba9e4..a193d3e8d185 100644 --- a/drivers/staging/comedi/drivers/comedi_isadma.h +++ b/drivers/staging/comedi/drivers/comedi_isadma.h @@ -63,18 +63,18 @@ struct comedi_isadma { #if IS_ENABLED(CONFIG_ISA_DMA_API) -void comedi_isadma_program(struct comedi_isadma_desc *); +void comedi_isadma_program(struct comedi_isadma_desc *desc); unsigned int comedi_isadma_disable(unsigned int dma_chan); unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan, unsigned int size); -unsigned int comedi_isadma_poll(struct comedi_isadma *); -void comedi_isadma_set_mode(struct comedi_isadma_desc *, char dma_dir); +unsigned int comedi_isadma_poll(struct comedi_isadma *dma); +void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir); -struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *, +struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev, int n_desc, unsigned int dma_chan1, unsigned int dma_chan2, unsigned int maxsize, char dma_dir); -void comedi_isadma_free(struct comedi_isadma *); +void comedi_isadma_free(struct comedi_isadma *dma); #else /* !IS_ENABLED(CONFIG_ISA_DMA_API) */ diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index ec5b9a23494d..2a063f07fe7b 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -36,7 +36,15 @@ * generate sample waveforms on systems that don't have data acquisition * hardware. * - * Configuration options: + * Auto-configuration is the default mode if no parameter is supplied during + * module loading. Manual configuration requires COMEDI userspace tool. + * To disable auto-configuration mode, pass "noauto=1" parameter for module + * loading. Refer modinfo or MODULE_PARM_DESC description below for details. + * + * Auto-configuration options: + * Refer modinfo or MODULE_PARM_DESC description below for details. + * + * Manual configuration options: * [0] - Amplitude in microvolts for fake waveforms (default 1 volt) * [1] - Period in microseconds for fake waveforms (default 0.1 sec) * @@ -53,8 +61,27 @@ #include <linux/timer.h> #include <linux/ktime.h> #include <linux/jiffies.h> +#include <linux/device.h> +#include <linux/kdev_t.h> #define N_CHANS 8 +#define DEV_NAME "comedi_testd" +#define CLASS_NAME "comedi_test" + +static bool config_mode; +static unsigned int set_amplitude; +static unsigned int set_period; +static struct class *ctcls; +static struct device *ctdev; + +module_param_named(noauto, config_mode, bool, 0444); +MODULE_PARM_DESC(noauto, "Disable auto-configuration: (1=disable [defaults to enable])"); + +module_param_named(amplitude, set_amplitude, uint, 0444); +MODULE_PARM_DESC(amplitude, "Set auto mode wave amplitude in microvolts: (defaults to 1 volt)"); + +module_param_named(period, set_period, uint, 0444); +MODULE_PARM_DESC(period, "Set auto mode wave period in microseconds: (defaults to 0.1 sec)"); /* Data unique to this driver */ struct waveform_private { @@ -607,13 +634,11 @@ static int waveform_ao_insn_write(struct comedi_device *dev, return insn->n; } -static int waveform_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int waveform_common_attach(struct comedi_device *dev, + int amplitude, int period) { struct waveform_private *devpriv; struct comedi_subdevice *s; - int amplitude = it->options[0]; - int period = it->options[1]; int i; int ret; @@ -621,12 +646,6 @@ static int waveform_attach(struct comedi_device *dev, if (!devpriv) return -ENOMEM; - /* set default amplitude and period */ - if (amplitude <= 0) - amplitude = 1000000; /* 1 volt */ - if (period <= 0) - period = 100000; /* 0.1 sec */ - devpriv->wf_amplitude = amplitude; devpriv->wf_period = period; @@ -678,6 +697,36 @@ static int waveform_attach(struct comedi_device *dev, return 0; } +static int waveform_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int amplitude = it->options[0]; + int period = it->options[1]; + + /* set default amplitude and period */ + if (amplitude <= 0) + amplitude = 1000000; /* 1 volt */ + if (period <= 0) + period = 100000; /* 0.1 sec */ + + return waveform_common_attach(dev, amplitude, period); +} + +static int waveform_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + int amplitude = set_amplitude; + int period = set_period; + + /* set default amplitude and period */ + if (!amplitude) + amplitude = 1000000; /* 1 volt */ + if (!period) + period = 100000; /* 0.1 sec */ + + return waveform_common_attach(dev, amplitude, period); +} + static void waveform_detach(struct comedi_device *dev) { struct waveform_private *devpriv = dev->private; @@ -692,9 +741,71 @@ static struct comedi_driver waveform_driver = { .driver_name = "comedi_test", .module = THIS_MODULE, .attach = waveform_attach, + .auto_attach = waveform_auto_attach, .detach = waveform_detach, }; -module_comedi_driver(waveform_driver); + +/* + * For auto-configuration, a device is created to stand in for a + * real hardware device. + */ +static int __init comedi_test_init(void) +{ + int ret; + + ret = comedi_driver_register(&waveform_driver); + if (ret) { + pr_err("comedi_test: unable to register driver\n"); + return ret; + } + + if (!config_mode) { + ctcls = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(ctcls)) { + pr_warn("comedi_test: unable to create class\n"); + goto clean3; + } + + ctdev = device_create(ctcls, NULL, MKDEV(0, 0), NULL, DEV_NAME); + if (IS_ERR(ctdev)) { + pr_warn("comedi_test: unable to create device\n"); + goto clean2; + } + + ret = comedi_auto_config(ctdev, &waveform_driver, 0); + if (ret) { + pr_warn("comedi_test: unable to auto-configure device\n"); + goto clean; + } + } + + return 0; + +clean: + device_destroy(ctcls, MKDEV(0, 0)); +clean2: + class_destroy(ctcls); + ctdev = NULL; +clean3: + ctcls = NULL; + + return 0; +} +module_init(comedi_test_init); + +static void __exit comedi_test_exit(void) +{ + if (ctdev) + comedi_auto_unconfig(ctdev); + + if (ctcls) { + device_destroy(ctcls, MKDEV(0, 0)); + class_destroy(ctcls); + } + + comedi_driver_unregister(&waveform_driver); +} +module_exit(comedi_test_exit); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 0f4eb954aa80..32dd8a857b6b 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -109,28 +109,11 @@ #include "../comedi_pci.h" #include "8255.h" +#include "plx9080.h" -#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin" +#define DB2K_FIRMWARE "daqboard2000_firmware.bin" -#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */ -#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */ - -/* Initialization bits for the Serial EEPROM Control Register */ -#define DB2K_SECR_PROG_PIN_HI 0x8001767e -#define DB2K_SECR_PROG_PIN_LO 0x8000767e -#define DB2K_SECR_LOCAL_BUS_HI 0xc000767e -#define DB2K_SECR_LOCAL_BUS_LO 0x8000767e -#define DB2K_SECR_RELOAD_HI 0xa000767e -#define DB2K_SECR_RELOAD_LO 0x8000767e - -/* SECR status bits */ -#define DAQBOARD2000_EEPROM_PRESENT 0x10000000 - -/* CPLD status bits */ -#define DAQBOARD2000_CPLD_INIT 0x0002 -#define DAQBOARD2000_CPLD_DONE 0x0004 - -static const struct comedi_lrange range_daqboard2000_ai = { +static const struct comedi_lrange db2k_ai_range = { 13, { BIP_RANGE(10), BIP_RANGE(5), @@ -183,6 +166,10 @@ static const struct comedi_lrange range_daqboard2000_ai = { #define DB2K_REG_TRIG_DACS 0xbc /* u16 */ #define DB2K_REG_DIO_P2_EXP_IO_16_BIT(x) (0xc0 + (x) * 2) /* s16 */ +/* CPLD registers */ +#define DB2K_REG_CPLD_STATUS 0x1000 /* u16 (r) */ +#define DB2K_REG_CPLD_WDATA 0x1000 /* u16 (w) */ + /* Scan Sequencer programming */ #define DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST 0x0011 #define DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST 0x0010 @@ -248,33 +235,45 @@ static const struct comedi_lrange range_daqboard2000_ai = { #define DB2K_REF_DACS_SELECT_POS_REF 0x0100 #define DB2K_REF_DACS_SELECT_NEG_REF 0x0000 -struct daq200_boardtype { +/* CPLD status bits */ +#define DB2K_CPLD_STATUS_INIT 0x0002 +#define DB2K_CPLD_STATUS_TXREADY 0x0004 +#define DB2K_CPLD_VERSION_MASK 0xf000 +/* "New CPLD" signature. */ +#define DB2K_CPLD_VERSION_NEW 0x5000 + +enum db2k_boardid { + BOARD_DAQBOARD2000, + BOARD_DAQBOARD2001 +}; + +struct db2k_boardtype { const char *name; - int id; + bool has_2_ao:1; /* false: 4 AO chans; true: 2 AO chans */ }; -static const struct daq200_boardtype boardtypes[] = { - {"ids2", DAQBOARD2000_SUBSYSTEM_IDS2}, - {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4}, +static const struct db2k_boardtype db2k_boardtypes[] = { + [BOARD_DAQBOARD2000] = { + .name = "daqboard2000", + .has_2_ao = true, + }, + [BOARD_DAQBOARD2001] = { + .name = "daqboard2001", + }, }; -struct daqboard2000_private { - enum { - card_daqboard_2000 - } card; +struct db2k_private { void __iomem *plx; }; -static void daqboard2000_write_acq_scan_list_entry(struct comedi_device *dev, - u16 entry) +static void db2k_write_acq_scan_list_entry(struct comedi_device *dev, u16 entry) { writew(entry & 0x00ff, dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO); writew((entry >> 8) & 0x00ff, dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO); } -static void daqboard2000_setup_sampling(struct comedi_device *dev, int chan, - int gain) +static void db2k_setup_sampling(struct comedi_device *dev, int chan, int gain) { u16 word0, word1, word2, word3; @@ -308,16 +307,14 @@ static void daqboard2000_setup_sampling(struct comedi_device *dev, int chan, /* These should be read from EEPROM */ word2 |= 0x0800; /* offset */ word3 |= 0xc000; /* gain */ - daqboard2000_write_acq_scan_list_entry(dev, word0); - daqboard2000_write_acq_scan_list_entry(dev, word1); - daqboard2000_write_acq_scan_list_entry(dev, word2); - daqboard2000_write_acq_scan_list_entry(dev, word3); + db2k_write_acq_scan_list_entry(dev, word0); + db2k_write_acq_scan_list_entry(dev, word1); + db2k_write_acq_scan_list_entry(dev, word2); + db2k_write_acq_scan_list_entry(dev, word3); } -static int daqboard2000_ai_status(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned long context) +static int db2k_ai_status(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned long context) { unsigned int status; @@ -327,10 +324,9 @@ static int daqboard2000_ai_status(struct comedi_device *dev, return -EBUSY; } -static int daqboard2000_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int db2k_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { int gain, chan; int ret; @@ -359,12 +355,12 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, * forced to fix it. --ds */ for (i = 0; i < insn->n; i++) { - daqboard2000_setup_sampling(dev, chan, gain); + db2k_setup_sampling(dev, chan, gain); /* Enable reading from the scanlist FIFO */ writew(DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST, dev->mmio + DB2K_REG_ACQ_CONTROL); - ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status, + ret = comedi_timeout(dev, s, insn, db2k_ai_status, DB2K_ACQ_STATUS_CONFIG_PIPE_FULL); if (ret) return ret; @@ -372,13 +368,13 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, writew(DB2K_ACQ_CONTROL_ADC_PACER_ENABLE, dev->mmio + DB2K_REG_ACQ_CONTROL); - ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status, + ret = comedi_timeout(dev, s, insn, db2k_ai_status, DB2K_ACQ_STATUS_LOGIC_SCANNING); if (ret) return ret; ret = - comedi_timeout(dev, s, insn, daqboard2000_ai_status, + comedi_timeout(dev, s, insn, db2k_ai_status, DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA); if (ret) return ret; @@ -393,10 +389,8 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, return i; } -static int daqboard2000_ao_eoc(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned long context) +static int db2k_ao_eoc(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned long context) { unsigned int chan = CR_CHAN(insn->chanspec); unsigned int status; @@ -407,10 +401,9 @@ static int daqboard2000_ao_eoc(struct comedi_device *dev, return -EBUSY; } -static int daqboard2000_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int db2k_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); int i; @@ -421,7 +414,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, writew(val, dev->mmio + DB2K_REG_DAC_SETTING(chan)); - ret = comedi_timeout(dev, s, insn, daqboard2000_ao_eoc, 0); + ret = comedi_timeout(dev, s, insn, db2k_ao_eoc, 0); if (ret) return ret; @@ -431,49 +424,62 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, return insn->n; } -static void daqboard2000_reset_local_bus(struct comedi_device *dev) +static void db2k_reset_local_bus(struct comedi_device *dev) { - struct daqboard2000_private *devpriv = dev->private; + struct db2k_private *devpriv = dev->private; + u32 cntrl; - writel(DB2K_SECR_LOCAL_BUS_HI, devpriv->plx + 0x6c); + cntrl = readl(devpriv->plx + PLX_REG_CNTRL); + cntrl |= PLX_CNTRL_RESET; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); - writel(DB2K_SECR_LOCAL_BUS_LO, devpriv->plx + 0x6c); + cntrl &= ~PLX_CNTRL_RESET; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); } -static void daqboard2000_reload_plx(struct comedi_device *dev) +static void db2k_reload_plx(struct comedi_device *dev) { - struct daqboard2000_private *devpriv = dev->private; + struct db2k_private *devpriv = dev->private; + u32 cntrl; - writel(DB2K_SECR_RELOAD_LO, devpriv->plx + 0x6c); + cntrl = readl(devpriv->plx + PLX_REG_CNTRL); + cntrl &= ~PLX_CNTRL_EERELOAD; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); - writel(DB2K_SECR_RELOAD_HI, devpriv->plx + 0x6c); + cntrl |= PLX_CNTRL_EERELOAD; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); - writel(DB2K_SECR_RELOAD_LO, devpriv->plx + 0x6c); + cntrl &= ~PLX_CNTRL_EERELOAD; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); } -static void daqboard2000_pulse_prog_pin(struct comedi_device *dev) +static void db2k_pulse_prog_pin(struct comedi_device *dev) { - struct daqboard2000_private *devpriv = dev->private; + struct db2k_private *devpriv = dev->private; + u32 cntrl; - writel(DB2K_SECR_PROG_PIN_HI, devpriv->plx + 0x6c); + cntrl = readl(devpriv->plx + PLX_REG_CNTRL); + cntrl |= PLX_CNTRL_USERO; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); - writel(DB2K_SECR_PROG_PIN_LO, devpriv->plx + 0x6c); + cntrl &= ~PLX_CNTRL_USERO; + writel(cntrl, devpriv->plx + PLX_REG_CNTRL); mdelay(10); /* Not in the original code, but I like symmetry... */ } -static int daqboard2000_poll_cpld(struct comedi_device *dev, int mask) +static int db2k_wait_cpld_init(struct comedi_device *dev) { - int result = 0; + int result = -ETIMEDOUT; int i; - int cpld; + u16 cpld; /* timeout after 50 tries -> 5ms */ for (i = 0; i < 50; i++) { - cpld = readw(dev->mmio + 0x1000); - if ((cpld & mask) == mask) { - result = 1; + cpld = readw(dev->mmio + DB2K_REG_CPLD_STATUS); + if (cpld & DB2K_CPLD_STATUS_INIT) { + result = 0; break; } usleep_range(100, 1000); @@ -482,67 +488,123 @@ static int daqboard2000_poll_cpld(struct comedi_device *dev, int mask) return result; } -static int daqboard2000_write_cpld(struct comedi_device *dev, int data) +static int db2k_wait_cpld_txready(struct comedi_device *dev) +{ + int i; + + for (i = 0; i < 100; i++) { + if (readw(dev->mmio + DB2K_REG_CPLD_STATUS) & + DB2K_CPLD_STATUS_TXREADY) { + return 0; + } + udelay(1); + } + return -ETIMEDOUT; +} + +static int db2k_write_cpld(struct comedi_device *dev, u16 data, bool new_cpld) { int result = 0; - usleep_range(10, 20); - writew(data, dev->mmio + 0x1000); - if ((readw(dev->mmio + 0x1000) & DAQBOARD2000_CPLD_INIT) == - DAQBOARD2000_CPLD_INIT) { - result = 1; + if (new_cpld) { + result = db2k_wait_cpld_txready(dev); + if (result) + return result; + } else { + usleep_range(10, 20); } + writew(data, dev->mmio + DB2K_REG_CPLD_WDATA); + if (!(readw(dev->mmio + DB2K_REG_CPLD_STATUS) & DB2K_CPLD_STATUS_INIT)) + result = -EIO; + return result; } -static int daqboard2000_load_firmware(struct comedi_device *dev, - const u8 *cpld_array, size_t len, - unsigned long context) +static int db2k_wait_fpga_programmed(struct comedi_device *dev) +{ + struct db2k_private *devpriv = dev->private; + int i; + + /* Time out after 200 tries -> 20ms */ + for (i = 0; i < 200; i++) { + u32 cntrl = readl(devpriv->plx + PLX_REG_CNTRL); + /* General Purpose Input (USERI) set on FPGA "DONE". */ + if (cntrl & PLX_CNTRL_USERI) + return 0; + + usleep_range(100, 1000); + } + return -ETIMEDOUT; +} + +static int db2k_load_firmware(struct comedi_device *dev, const u8 *cpld_array, + size_t len, unsigned long context) { - struct daqboard2000_private *devpriv = dev->private; + struct db2k_private *devpriv = dev->private; int result = -EIO; - /* Read the serial EEPROM control register */ - int secr; + u32 cntrl; int retry; size_t i; + bool new_cpld; + + /* Look for FPGA start sequence in firmware. */ + for (i = 0; i + 1 < len; i++) { + if (cpld_array[i] == 0xff && cpld_array[i + 1] == 0x20) + break; + } + if (i + 1 >= len) { + dev_err(dev->class_dev, "bad firmware - no start sequence\n"); + return -EINVAL; + } + /* Check length is even. */ + if ((len - i) & 1) { + dev_err(dev->class_dev, + "bad firmware - odd length (%zu = %zu - %zu)\n", + len - i, len, i); + return -EINVAL; + } + /* Strip firmware header. */ + cpld_array += i; + len -= i; /* Check to make sure the serial eeprom is present on the board */ - secr = readl(devpriv->plx + 0x6c); - if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) + cntrl = readl(devpriv->plx + PLX_REG_CNTRL); + if (!(cntrl & PLX_CNTRL_EEPRESENT)) return -EIO; for (retry = 0; retry < 3; retry++) { - daqboard2000_reset_local_bus(dev); - daqboard2000_reload_plx(dev); - daqboard2000_pulse_prog_pin(dev); - if (daqboard2000_poll_cpld(dev, DAQBOARD2000_CPLD_INIT)) { - for (i = 0; i < len; i++) { - if (cpld_array[i] == 0xff && - cpld_array[i + 1] == 0x20) - break; - } - for (; i < len; i += 2) { - int data = - (cpld_array[i] << 8) + cpld_array[i + 1]; - if (!daqboard2000_write_cpld(dev, data)) - break; - } - if (i >= len) { - daqboard2000_reset_local_bus(dev); - daqboard2000_reload_plx(dev); - result = 0; + db2k_reset_local_bus(dev); + db2k_reload_plx(dev); + db2k_pulse_prog_pin(dev); + result = db2k_wait_cpld_init(dev); + if (result) + continue; + + new_cpld = (readw(dev->mmio + DB2K_REG_CPLD_STATUS) & + DB2K_CPLD_VERSION_MASK) == DB2K_CPLD_VERSION_NEW; + for (; i < len; i += 2) { + u16 data = (cpld_array[i] << 8) + cpld_array[i + 1]; + + result = db2k_write_cpld(dev, data, new_cpld); + if (result) break; - } + } + if (result == 0) + result = db2k_wait_fpga_programmed(dev); + if (result == 0) { + db2k_reset_local_bus(dev); + db2k_reload_plx(dev); + break; } } return result; } -static void daqboard2000_adc_stop_dma_transfer(struct comedi_device *dev) +static void db2k_adc_stop_dma_transfer(struct comedi_device *dev) { } -static void daqboard2000_adc_disarm(struct comedi_device *dev) +static void db2k_adc_disarm(struct comedi_device *dev) { /* Disable hardware triggers */ udelay(2); @@ -563,10 +625,10 @@ static void daqboard2000_adc_disarm(struct comedi_device *dev) dev->mmio + DB2K_REG_ACQ_CONTROL); /* Stop the input dma (abort channel 1) */ - daqboard2000_adc_stop_dma_transfer(dev); + db2k_adc_stop_dma_transfer(dev); } -static void daqboard2000_activate_reference_dacs(struct comedi_device *dev) +static void db2k_activate_reference_dacs(struct comedi_device *dev) { unsigned int val; int timeout; @@ -592,34 +654,33 @@ static void daqboard2000_activate_reference_dacs(struct comedi_device *dev) } } -static void daqboard2000_initialize_ctrs(struct comedi_device *dev) +static void db2k_initialize_ctrs(struct comedi_device *dev) { } -static void daqboard2000_initialize_tmrs(struct comedi_device *dev) +static void db2k_initialize_tmrs(struct comedi_device *dev) { } -static void daqboard2000_dac_disarm(struct comedi_device *dev) +static void db2k_dac_disarm(struct comedi_device *dev) { } -static void daqboard2000_initialize_adc(struct comedi_device *dev) +static void db2k_initialize_adc(struct comedi_device *dev) { - daqboard2000_adc_disarm(dev); - daqboard2000_activate_reference_dacs(dev); - daqboard2000_initialize_ctrs(dev); - daqboard2000_initialize_tmrs(dev); + db2k_adc_disarm(dev); + db2k_activate_reference_dacs(dev); + db2k_initialize_ctrs(dev); + db2k_initialize_tmrs(dev); } -static void daqboard2000_initialize_dac(struct comedi_device *dev) +static void db2k_initialize_dac(struct comedi_device *dev) { - daqboard2000_dac_disarm(dev); + db2k_dac_disarm(dev); } -static int daqboard2000_8255_cb(struct comedi_device *dev, - int dir, int port, int data, - unsigned long iobase) +static int db2k_8255_cb(struct comedi_device *dev, int dir, int port, int data, + unsigned long iobase) { if (dir) { writew(data, dev->mmio + iobase + port * 2); @@ -628,34 +689,18 @@ static int daqboard2000_8255_cb(struct comedi_device *dev, return readw(dev->mmio + iobase + port * 2); } -static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct daq200_boardtype *board; - int i; - - if (pcidev->subsystem_vendor != PCI_VENDOR_ID_IOTECH) - return NULL; - - for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { - board = &boardtypes[i]; - if (pcidev->subsystem_device == board->id) - return board; - } - return NULL; -} - -static int daqboard2000_auto_attach(struct comedi_device *dev, - unsigned long context_unused) +static int db2k_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct daq200_boardtype *board; - struct daqboard2000_private *devpriv; + const struct db2k_boardtype *board; + struct db2k_private *devpriv; struct comedi_subdevice *s; int result; - board = daqboard2000_find_boardinfo(dev, pcidev); - if (!board) + if (context >= ARRAY_SIZE(db2k_boardtypes)) + return -ENODEV; + board = &db2k_boardtypes[context]; + if (!board->name) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; @@ -677,16 +722,13 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, if (result) return result; - readl(devpriv->plx + 0x6c); - result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev, - DAQBOARD2000_FIRMWARE, - daqboard2000_load_firmware, 0); + DB2K_FIRMWARE, db2k_load_firmware, 0); if (result < 0) return result; - daqboard2000_initialize_adc(dev); - daqboard2000_initialize_dac(dev); + db2k_initialize_adc(dev); + db2k_initialize_dac(dev); s = &dev->subdevices[0]; /* ai subdevice */ @@ -694,16 +736,16 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 24; s->maxdata = 0xffff; - s->insn_read = daqboard2000_ai_insn_read; - s->range_table = &range_daqboard2000_ai; + s->insn_read = db2k_ai_insn_read; + s->range_table = &db2k_ai_range; s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = 2; + s->n_chan = board->has_2_ao ? 2 : 4; s->maxdata = 0xffff; - s->insn_write = daqboard2000_ao_insn_write; + s->insn_write = db2k_ao_insn_write; s->range_table = &range_bipolar10; result = comedi_alloc_subdev_readback(s); @@ -711,48 +753,49 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, return result; s = &dev->subdevices[2]; - return subdev_8255_init(dev, s, daqboard2000_8255_cb, + return subdev_8255_init(dev, s, db2k_8255_cb, DB2K_REG_DIO_P2_EXP_IO_8_BIT); } -static void daqboard2000_detach(struct comedi_device *dev) +static void db2k_detach(struct comedi_device *dev) { - struct daqboard2000_private *devpriv = dev->private; + struct db2k_private *devpriv = dev->private; if (devpriv && devpriv->plx) iounmap(devpriv->plx); comedi_pci_detach(dev); } -static struct comedi_driver daqboard2000_driver = { +static struct comedi_driver db2k_driver = { .driver_name = "daqboard2000", .module = THIS_MODULE, - .auto_attach = daqboard2000_auto_attach, - .detach = daqboard2000_detach, + .auto_attach = db2k_auto_attach, + .detach = db2k_detach, }; -static int daqboard2000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int db2k_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &daqboard2000_driver, - id->driver_data); + return comedi_pci_auto_config(dev, &db2k_driver, id->driver_data); } -static const struct pci_device_id daqboard2000_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_IOTECH, 0x0409) }, +static const struct pci_device_id db2k_pci_table[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH, + 0x0002), .driver_data = BOARD_DAQBOARD2000, }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH, + 0x0004), .driver_data = BOARD_DAQBOARD2001, }, { 0 } }; -MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table); +MODULE_DEVICE_TABLE(pci, db2k_pci_table); -static struct pci_driver daqboard2000_pci_driver = { +static struct pci_driver db2k_pci_driver = { .name = "daqboard2000", - .id_table = daqboard2000_pci_table, - .probe = daqboard2000_pci_probe, + .id_table = db2k_pci_table, + .probe = db2k_pci_probe, .remove = comedi_pci_auto_unconfig, }; -module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver); +module_comedi_pci_driver(db2k_driver, db2k_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(DAQBOARD2000_FIRMWARE); +MODULE_FIRMWARE(DB2K_FIRMWARE); diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index b8606ded0623..771cceb71069 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -510,7 +510,7 @@ static int dmm32at_reset(struct comedi_device *dev) outb(DMM32AT_CTRL_RESETA, dev->iobase + DMM32AT_CTRL_REG); /* allow a millisecond to reset */ - udelay(1000); + usleep_range(1000, 3000); /* zero scan and fifo control */ outb(0x0, dev->iobase + DMM32AT_FIFO_CTRL_REG); @@ -526,7 +526,7 @@ static int dmm32at_reset(struct comedi_device *dev) outb(DMM32AT_RANGE_U10, dev->iobase + DMM32AT_AI_CFG_REG); /* should take 10 us to settle, here's a hundred */ - udelay(100); + usleep_range(100, 200); /* read back the values */ ailo = inb(dev->iobase + DMM32AT_AI_LO_CHAN_REG); diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index c2ce1eb87385..30805797a957 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -343,7 +343,7 @@ static int dt2801_reset(struct comedi_device *dev) outb_p(DT_C_STOP, dev->iobase + DT2801_CMD); /* dt2801_wait_for_ready(dev); */ - udelay(100); + usleep_range(100, 200); timeout = 10000; do { stat = inb_p(dev->iobase + DT2801_STATUS); @@ -358,7 +358,7 @@ static int dt2801_reset(struct comedi_device *dev) outb_p(DT_C_RESET, dev->iobase + DT2801_CMD); /* dt2801_writecmd(dev,DT_C_RESET); */ - udelay(100); + usleep_range(100, 200); timeout = 10000; do { stat = inb_p(dev->iobase + DT2801_STATUS); diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 2f903bedcefa..09984a66dba3 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -245,7 +245,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; outb(0, dev->iobase + DT2814_CSR); - udelay(100); + usleep_range(100, 200); if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) { dev_err(dev->class_dev, "reset error (fatal)\n"); return -EIO; diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 0be77cc40a79..ce5571971194 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -188,7 +188,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* This is incredibly slow (approx 20 ms) */ unsigned int status; - udelay(1000); + usleep_range(1000, 3000); status = inb(dev->iobase + DT2815_STATUS); if (status == 4) { unsigned int program; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index c9eb26fab44e..bab7ac9e6237 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -89,7 +89,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, /* trigger conversion */ smp_mb(); outw_p(0x0000 + range + chan, dev->iobase + 2); - udelay(10); + usleep_range(10, 20); ret = comedi_timeout(dev, s, insn, dyna_pci10xx_ai_eoc, 0); if (ret) @@ -125,7 +125,7 @@ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, smp_mb(); /* trigger conversion and write data */ outw_p(data[n], dev->iobase); - udelay(10); + usleep_range(10, 20); } mutex_unlock(&devpriv->mutex); return n; @@ -143,7 +143,7 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, mutex_lock(&devpriv->mutex); smp_mb(); d = inw_p(devpriv->BADR3); - udelay(10); + usleep_range(10, 100); /* on return the data[0] contains output and data[1] contains input */ data[1] = d; @@ -163,7 +163,7 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, if (comedi_dio_update_state(s, data)) { smp_mb(); outw_p(s->state, devpriv->BADR3); - udelay(10); + usleep_range(10, 100); } data[1] = s->state; diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index b6349aed97d0..02a627d3969d 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -60,35 +60,36 @@ struct mite { spinlock_t lock; }; -u32 mite_bytes_in_transit(struct mite_channel *); +u32 mite_bytes_in_transit(struct mite_channel *mite_chan); -void mite_sync_dma(struct mite_channel *, struct comedi_subdevice *); -void mite_ack_linkc(struct mite_channel *, struct comedi_subdevice *s, +void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s); +void mite_ack_linkc(struct mite_channel *mite_chan, struct comedi_subdevice *s, bool sync); -int mite_done(struct mite_channel *); +int mite_done(struct mite_channel *mite_chan); -void mite_dma_arm(struct mite_channel *); -void mite_dma_disarm(struct mite_channel *); +void mite_dma_arm(struct mite_channel *mite_chan); +void mite_dma_disarm(struct mite_channel *mite_chan); -void mite_prep_dma(struct mite_channel *, +void mite_prep_dma(struct mite_channel *mite_chan, unsigned int num_device_bits, unsigned int num_memory_bits); -struct mite_channel *mite_request_channel_in_range(struct mite *, - struct mite_ring *, +struct mite_channel *mite_request_channel_in_range(struct mite *mite, + struct mite_ring *ring, unsigned int min_channel, unsigned int max_channel); -struct mite_channel *mite_request_channel(struct mite *, struct mite_ring *); -void mite_release_channel(struct mite_channel *); +struct mite_channel *mite_request_channel(struct mite *mite, + struct mite_ring *ring); +void mite_release_channel(struct mite_channel *mite_chan); -int mite_init_ring_descriptors(struct mite_ring *, struct comedi_subdevice *, - unsigned int nbytes); -int mite_buf_change(struct mite_ring *, struct comedi_subdevice *); +int mite_init_ring_descriptors(struct mite_ring *ring, + struct comedi_subdevice *s, unsigned int nbytes); +int mite_buf_change(struct mite_ring *ring, struct comedi_subdevice *s); -struct mite_ring *mite_alloc_ring(struct mite *); -void mite_free_ring(struct mite_ring *); +struct mite_ring *mite_alloc_ring(struct mite *mite); +void mite_free_ring(struct mite_ring *ring); -struct mite *mite_attach(struct comedi_device *, bool use_win1); -void mite_detach(struct mite *); +struct mite *mite_attach(struct comedi_device *dev, bool use_win1); +void mite_detach(struct mite *mite); /* * Mite registers (used outside of the mite driver) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 0dcb826a9f1f..6aa755ad3953 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -16,13 +16,13 @@ * Driver: ni_660x * Description: National Instruments 660x counter/timer boards * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, - * PXI-6608, PXI-6624 + * PXI-6608, PCI-6624, PXI-6624 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>, * Herman.Bruyninckx@mech.kuleuven.ac.be, * Wim.Meeussen@mech.kuleuven.ac.be, * Klaas.Gadeyne@mech.kuleuven.ac.be, * Frank Mori Hess <fmhess@users.sourceforge.net> - * Updated: Fri, 15 Mar 2013 10:47:56 +0000 + * Updated: Mon, 16 Jan 2017 14:00:43 +0000 * Status: experimental * * Encoders work. PulseGeneration (both single pulse and pulse train) @@ -211,6 +211,7 @@ enum ni_660x_boardid { BOARD_PCI6602, BOARD_PXI6602, BOARD_PXI6608, + BOARD_PCI6624, BOARD_PXI6624 }; @@ -236,6 +237,10 @@ static const struct ni_660x_board ni_660x_boards[] = { .name = "PXI-6608", .n_chips = 2, }, + [BOARD_PCI6624] = { + .name = "PCI-6624", + .n_chips = 2, + }, [BOARD_PXI6624] = { .name = "PXI-6624", .n_chips = 2, @@ -920,6 +925,7 @@ static const struct pci_device_id ni_660x_pci_table[] = { { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 }, + { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 }, { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 74911dbb2561..1d3ff60efcb8 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -141,7 +141,7 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, /* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ -#define WENAB (1 << 7) /* window enable */ +#define WENAB BIT(7) /* window enable */ static int ni_670x_mite_init(struct pci_dev *pcidev) { diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 5a4dcc6e61d8..c69cd676f357 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -757,7 +757,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (i = 0; i < timeout; i++) { if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0) break; - udelay(1000); + usleep_range(1000, 3000); } if (i == timeout) { dev_err(dev->class_dev, diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index f27aa0e82234..158fa29374fc 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -49,43 +49,43 @@ #define ATAO_CFG2_REG 0x02 #define ATAO_CFG2_CALLD_NOP (0 << 14) #define ATAO_CFG2_CALLD(x) ((((x) >> 3) + 1) << 14) -#define ATAO_CFG2_FFRTEN (1 << 13) +#define ATAO_CFG2_FFRTEN BIT(13) #define ATAO_CFG2_DACS(x) (1 << (((x) / 2) + 8)) #define ATAO_CFG2_LDAC(x) (1 << (((x) / 2) + 3)) -#define ATAO_CFG2_PROMEN (1 << 2) -#define ATAO_CFG2_SCLK (1 << 1) -#define ATAO_CFG2_SDATA (1 << 0) +#define ATAO_CFG2_PROMEN BIT(2) +#define ATAO_CFG2_SCLK BIT(1) +#define ATAO_CFG2_SDATA BIT(0) #define ATAO_CFG3_REG 0x04 -#define ATAO_CFG3_DMAMODE (1 << 6) -#define ATAO_CFG3_CLKOUT (1 << 5) -#define ATAO_CFG3_RCLKEN (1 << 4) -#define ATAO_CFG3_DOUTEN2 (1 << 3) -#define ATAO_CFG3_DOUTEN1 (1 << 2) -#define ATAO_CFG3_EN2_5V (1 << 1) -#define ATAO_CFG3_SCANEN (1 << 0) +#define ATAO_CFG3_DMAMODE BIT(6) +#define ATAO_CFG3_CLKOUT BIT(5) +#define ATAO_CFG3_RCLKEN BIT(4) +#define ATAO_CFG3_DOUTEN2 BIT(3) +#define ATAO_CFG3_DOUTEN1 BIT(2) +#define ATAO_CFG3_EN2_5V BIT(1) +#define ATAO_CFG3_SCANEN BIT(0) #define ATAO_82C53_BASE 0x06 #define ATAO_CFG1_REG 0x0a -#define ATAO_CFG1_EXTINT2EN (1 << 15) -#define ATAO_CFG1_EXTINT1EN (1 << 14) -#define ATAO_CFG1_CNTINT2EN (1 << 13) -#define ATAO_CFG1_CNTINT1EN (1 << 12) -#define ATAO_CFG1_TCINTEN (1 << 11) -#define ATAO_CFG1_CNT1SRC (1 << 10) -#define ATAO_CFG1_CNT2SRC (1 << 9) -#define ATAO_CFG1_FIFOEN (1 << 8) -#define ATAO_CFG1_GRP2WR (1 << 7) -#define ATAO_CFG1_EXTUPDEN (1 << 6) -#define ATAO_CFG1_DMARQ (1 << 5) -#define ATAO_CFG1_DMAEN (1 << 4) +#define ATAO_CFG1_EXTINT2EN BIT(15) +#define ATAO_CFG1_EXTINT1EN BIT(14) +#define ATAO_CFG1_CNTINT2EN BIT(13) +#define ATAO_CFG1_CNTINT1EN BIT(12) +#define ATAO_CFG1_TCINTEN BIT(11) +#define ATAO_CFG1_CNT1SRC BIT(10) +#define ATAO_CFG1_CNT2SRC BIT(9) +#define ATAO_CFG1_FIFOEN BIT(8) +#define ATAO_CFG1_GRP2WR BIT(7) +#define ATAO_CFG1_EXTUPDEN BIT(6) +#define ATAO_CFG1_DMARQ BIT(5) +#define ATAO_CFG1_DMAEN BIT(4) #define ATAO_CFG1_CH(x) (((x) & 0xf) << 0) #define ATAO_STATUS_REG 0x0a -#define ATAO_STATUS_FH (1 << 6) -#define ATAO_STATUS_FE (1 << 5) -#define ATAO_STATUS_FF (1 << 4) -#define ATAO_STATUS_INT2 (1 << 3) -#define ATAO_STATUS_INT1 (1 << 2) -#define ATAO_STATUS_TCINT (1 << 1) -#define ATAO_STATUS_PROMOUT (1 << 0) +#define ATAO_STATUS_FH BIT(6) +#define ATAO_STATUS_FE BIT(5) +#define ATAO_STATUS_FF BIT(4) +#define ATAO_STATUS_INT2 BIT(3) +#define ATAO_STATUS_INT1 BIT(2) +#define ATAO_STATUS_TCINT BIT(1) +#define ATAO_STATUS_PROMOUT BIT(0) #define ATAO_FIFO_WRITE_REG 0x0c #define ATAO_FIFO_CLEAR_REG 0x0c #define ATAO_AO_REG(x) (0x0c + ((x) * 2)) @@ -95,7 +95,7 @@ #define ATAO_2_INT1CLR_REG 0x02 #define ATAO_2_INT2CLR_REG 0x04 #define ATAO_2_RTSISHFT_REG 0x06 -#define ATAO_2_RTSISHFT_RSI (1 << 0) +#define ATAO_2_RTSISHFT_RSI BIT(0) #define ATAO_2_RTSISTRB_REG 0x07 struct atao_board { diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index be8d5cd3f7f0..c2edadc7b3c6 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -52,8 +52,8 @@ struct labpc_private { * function pointers so we can use inb/outb or readb/writeb as * appropriate */ - unsigned int (*read_byte)(struct comedi_device *, unsigned long reg); - void (*write_byte)(struct comedi_device *, + unsigned int (*read_byte)(struct comedi_device *dev, unsigned long reg); + void (*write_byte)(struct comedi_device *dev, unsigned int byte, unsigned long reg); }; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index daeb4ad7a75f..b27345abebe1 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -65,7 +65,7 @@ #define WindowAddressStatus_mask 0x7c #define Master_DMA_And_Interrupt_Control 5 /* W */ -#define InterruptLine(x) ((x)&3) +#define InterruptLine(x) ((x) & 3) #define OpenInt BIT(2) #define Group_Status 5 /* R */ #define DataLeft BIT(0) @@ -100,38 +100,38 @@ #define Chip_ID_I 25 #define Chip_ID_O 26 #define Chip_Version 27 -#define Port_IO(x) (28+(x)) -#define Port_Pin_Directions(x) (32+(x)) -#define Port_Pin_Mask(x) (36+(x)) -#define Port_Pin_Polarities(x) (40+(x)) +#define Port_IO(x) (28 + (x)) +#define Port_Pin_Directions(x) (32 + (x)) +#define Port_Pin_Mask(x) (36 + (x)) +#define Port_Pin_Polarities(x) (40 + (x)) #define Master_Clock_Routing 45 -#define RTSIClocking(x) (((x)&3)<<4) +#define RTSIClocking(x) (((x) & 3) << 4) #define Group_1_Second_Clear 46 /* W */ #define Group_2_Second_Clear 47 /* W */ #define ClearExpired BIT(0) -#define Port_Pattern(x) (48+(x)) +#define Port_Pattern(x) (48 + (x)) #define Data_Path 64 #define FIFOEnableA BIT(0) #define FIFOEnableB BIT(1) #define FIFOEnableC BIT(2) #define FIFOEnableD BIT(3) -#define Funneling(x) (((x)&3)<<4) +#define Funneling(x) (((x) & 3) << 4) #define GroupDirection BIT(7) #define Protocol_Register_1 65 #define OpMode Protocol_Register_1 -#define RunMode(x) ((x)&7) +#define RunMode(x) ((x) & 7) #define Numbered BIT(3) #define Protocol_Register_2 66 #define ClockReg Protocol_Register_2 -#define ClockLine(x) (((x)&3)<<5) +#define ClockLine(x) (((x) & 3) << 5) #define InvertStopTrig BIT(7) -#define DataLatching(x) (((x)&3)<<5) +#define DataLatching(x) (((x) & 3) << 5) #define Protocol_Register_3 67 #define Sequence Protocol_Register_3 @@ -141,13 +141,13 @@ #define Protocol_Register_4 70 #define ReqReg Protocol_Register_4 -#define ReqConditioning(x) (((x)&7)<<3) +#define ReqConditioning(x) (((x) & 7) << 3) #define Protocol_Register_5 71 #define BlockMode Protocol_Register_5 #define FIFO_Control 72 -#define ReadyLevel(x) ((x)&7) +#define ReadyLevel(x) ((x) & 7) #define Protocol_Register_6 73 #define LinePolarities Protocol_Register_6 @@ -160,7 +160,7 @@ #define Protocol_Register_7 74 #define AckSer Protocol_Register_7 -#define AckLine(x) (((x)&3)<<2) +#define AckLine(x) (((x) & 3) << 2) #define ExchangePins BIT(7) #define Interrupt_Control 75 @@ -180,15 +180,15 @@ static inline unsigned int secondary_DMAChannel_bits(unsigned int channel) } #define Transfer_Size_Control 77 -#define TransferWidth(x) ((x)&3) -#define TransferLength(x) (((x)&3)<<3) +#define TransferWidth(x) ((x) & 3) +#define TransferLength(x) (((x) & 3) << 3) #define RequireRLevel BIT(5) #define Protocol_Register_15 79 #define DAQOptions Protocol_Register_15 -#define StartSource(x) ((x)&0x3) +#define StartSource(x) ((x) & 0x3) #define InvertStart BIT(2) -#define StopSource(x) (((x)&0x3)<<3) +#define StopSource(x) (((x) & 0x3) << 3) #define ReqStart BIT(6) #define PreStart BIT(7) @@ -230,6 +230,7 @@ enum pci_6534_firmware_registers { /* 16 bit */ Firmware_Mask_Register = 0x10c, Firmware_Debug_Register = 0x110, }; + /* main fpga registers (32 bit)*/ enum pci_6534_fpga_registers { FPGA_Control1_Register = 0x200, @@ -246,6 +247,7 @@ enum pci_6534_fpga_registers { FPGA_ELC_Read_Register = 0x2b8, FPGA_ELC_Write_Register = 0x2bc, }; + enum FPGA_Control_Bits { FPGA_Enable_Bit = 0x8000, }; @@ -253,9 +255,9 @@ enum FPGA_Control_Bits { #define TIMER_BASE 50 /* nanoseconds */ #ifdef USE_DMA -#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC) +#define IntEn (CountExpired | Waited | PrimaryTC | SecondaryTC) #else -#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC) +#define IntEn (TransferReady | CountExpired | Waited | PrimaryTC | SecondaryTC) #endif enum nidio_boardid { diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index f13a2f7360b3..3a96913c025e 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -25,17 +25,16 @@ * PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, * PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, * PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, - * PCI-6035E, PCI-6052E, - * PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, - * PCI-6225, PXI-6225, PCI-6229, PCI-6250, - * PCI-6251, PXI-6251, PCIe-6251, PXIe-6251, - * PCI-6254, PCI-6259, PCIe-6259, - * PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, - * PCI-6711, PXI-6711, PCI-6713, PXI-6713, - * PXI-6071E, PCI-6070E, PXI-6070E, + * PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, PCI-6220, PXI-6220, + * PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, + * PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251, + * PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259, + * PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281, + * PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711, + * PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, * PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733, * PCI-6143, PXI-6143 - * Updated: Mon, 09 Jan 2012 14:52:48 +0000 + * Updated: Mon, 16 Jan 2017 12:56:04 +0000 * * These boards are almost identical to the AT-MIO E series, except that * they use the PCI bus instead of ISA (i.e., AT). See the notes for the @@ -181,26 +180,36 @@ enum ni_pcimio_boardid { BOARD_PXI6031E, BOARD_PCI6036E, BOARD_PCI6220, + BOARD_PXI6220, BOARD_PCI6221, BOARD_PCI6221_37PIN, + BOARD_PXI6221, BOARD_PCI6224, BOARD_PXI6224, BOARD_PCI6225, BOARD_PXI6225, BOARD_PCI6229, + BOARD_PXI6229, BOARD_PCI6250, + BOARD_PXI6250, BOARD_PCI6251, BOARD_PXI6251, BOARD_PCIE6251, BOARD_PXIE6251, BOARD_PCI6254, + BOARD_PXI6254, BOARD_PCI6259, + BOARD_PXI6259, BOARD_PCIE6259, + BOARD_PXIE6259, BOARD_PCI6280, + BOARD_PXI6280, BOARD_PCI6281, BOARD_PXI6281, BOARD_PCI6284, + BOARD_PXI6284, BOARD_PCI6289, + BOARD_PXI6289, BOARD_PCI6143, BOARD_PXI6143, }; @@ -684,6 +693,16 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_622x, .caldac = { caldac_none }, }, + [BOARD_PXI6220] = { + .name = "pxi-6220", + .n_adchan = 16, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 512, /* FIXME: guess */ + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .reg_type = ni_reg_622x, + .caldac = { caldac_none }, + }, [BOARD_PCI6221] = { .name = "pci-6221", .n_adchan = 16, @@ -714,6 +733,21 @@ static const struct ni_board_struct ni_boards[] = { .ao_speed = 1200, .caldac = { caldac_none }, }, + [BOARD_PXI6221] = { + .name = "pxi-6221", + .n_adchan = 16, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 2, + .ao_maxdata = 0xffff, + .ao_fifo_depth = 8191, + .ao_range_table = &range_bipolar10, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .caldac = { caldac_none }, + }, [BOARD_PCI6224] = { .name = "pci-6224", .n_adchan = 32, @@ -784,6 +818,22 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXI6229] = { + .name = "pxi-6229", + .n_adchan = 32, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 4, + .ao_maxdata = 0xffff, + .ao_fifo_depth = 8191, + .ao_range_table = &range_bipolar10, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCI6250] = { .name = "pci-6250", .n_adchan = 16, @@ -794,6 +844,16 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_625x, .caldac = { caldac_none }, }, + [BOARD_PXI6250] = { + .name = "pxi-6250", + .n_adchan = 16, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .reg_type = ni_reg_625x, + .caldac = { caldac_none }, + }, [BOARD_PCI6251] = { .name = "pci-6251", .n_adchan = 16, @@ -865,6 +925,17 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXI6254] = { + .name = "pxi-6254", + .n_adchan = 32, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .reg_type = ni_reg_625x, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCI6259] = { .name = "pci-6259", .n_adchan = 32, @@ -881,6 +952,22 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXI6259] = { + .name = "pxi-6259", + .n_adchan = 32, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 4, + .ao_maxdata = 0xffff, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCIE6259] = { .name = "pcie-6259", .n_adchan = 32, @@ -897,6 +984,22 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXIE6259] = { + .name = "pxie-6259", + .n_adchan = 32, + .ai_maxdata = 0xffff, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 4, + .ao_maxdata = 0xffff, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCI6280] = { .name = "pci-6280", .n_adchan = 16, @@ -908,6 +1011,17 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_628x, .caldac = { caldac_none }, }, + [BOARD_PXI6280] = { + .name = "pxi-6280", + .n_adchan = 16, + .ai_maxdata = 0x3ffff, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .ao_fifo_depth = 8191, + .reg_type = ni_reg_628x, + .caldac = { caldac_none }, + }, [BOARD_PCI6281] = { .name = "pci-6281", .n_adchan = 16, @@ -949,6 +1063,17 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXI6284] = { + .name = "pxi-6284", + .n_adchan = 32, + .ai_maxdata = 0x3ffff, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .reg_type = ni_reg_628x, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCI6289] = { .name = "pci-6289", .n_adchan = 32, @@ -965,6 +1090,22 @@ static const struct ni_board_struct ni_boards[] = { .has_32dio_chan = 1, .caldac = { caldac_none }, }, + [BOARD_PXI6289] = { + .name = "pxi-6289", + .n_adchan = 32, + .ai_maxdata = 0x3ffff, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .n_aochan = 4, + .ao_maxdata = 0xffff, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_628x_ao, + .reg_type = ni_reg_628x, + .ao_speed = 350, + .has_32dio_chan = 1, + .caldac = { caldac_none }, + }, [BOARD_PCI6143] = { .name = "pci-6143", .n_adchan = 8, @@ -1061,8 +1202,6 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev) resource_size_t daq_phys_addr; static const int Start_Cal_EEPROM = 0x400; static const unsigned int window_size = 10; - static const int serial_number_eeprom_offset = 0x4; - static const int serial_number_eeprom_length = 0x4; unsigned int old_iodwbsr_bits; unsigned int old_iodwbsr1_bits; unsigned int old_iodwcr1_bits; @@ -1080,13 +1219,6 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev) writel(0x1 | old_iodwcr1_bits, mite->mmio + MITE_IODWCR_1); writel(0xf, mite->mmio + 0x30); - BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number)); - for (i = 0; i < serial_number_eeprom_length; ++i) { - char *byte_ptr = (char *)&devpriv->serial_number + i; - *byte_ptr = ni_readb(dev, serial_number_eeprom_offset + i); - } - devpriv->serial_number = be32_to_cpu(devpriv->serial_number); - for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i) devpriv->eeprom_buffer[i] = ni_readb(dev, Start_Cal_EEPROM + i); @@ -1284,14 +1416,24 @@ static const struct pci_device_id ni_pcimio_pci_table[] = { { PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 }, { PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 }, { PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 }, + { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 }, + { PCI_VDEVICE(NI, 0x70ae), BOARD_PXI6220 }, { PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 }, { PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 }, + { PCI_VDEVICE(NI, 0x70b1), BOARD_PXI6229 }, + { PCI_VDEVICE(NI, 0x70b2), BOARD_PXI6259 }, + { PCI_VDEVICE(NI, 0x70b3), BOARD_PXI6289 }, { PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 }, + { PCI_VDEVICE(NI, 0x70b5), BOARD_PXI6221 }, { PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 }, { PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 }, { PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 }, + { PCI_VDEVICE(NI, 0x70b9), BOARD_PXI6250 }, + { PCI_VDEVICE(NI, 0x70ba), BOARD_PXI6254 }, + { PCI_VDEVICE(NI, 0x70bb), BOARD_PXI6280 }, { PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 }, { PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 }, + { PCI_VDEVICE(NI, 0x70be), BOARD_PXI6284 }, { PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 }, { PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 }, { PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 }, @@ -1299,11 +1441,11 @@ static const struct pci_device_id ni_pcimio_pci_table[] = { { PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 }, { PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 }, { PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 }, + { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 }, { PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 }, { PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN }, - { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 }, { PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 }, - { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 }, + { PCI_VDEVICE(NI, 0x72e9), BOARD_PXIE6259 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index f27b545f83eb..61138e86a455 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -1031,7 +1031,6 @@ struct ni_private { unsigned short ai_fifo_buffer[0x2000]; u8 eeprom_buffer[M_SERIES_EEPROM_SIZE]; - __be32 serial_number; struct mite *mite; struct mite_channel *ai_mite_chan; diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 4978358f9b13..2012033414d3 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -110,9 +110,9 @@ struct ni_gpct { struct ni_gpct_device { struct comedi_device *dev; - void (*write)(struct ni_gpct *, unsigned int value, + void (*write)(struct ni_gpct *counter, unsigned int value, enum ni_gpct_register); - unsigned int (*read)(struct ni_gpct *, enum ni_gpct_register); + unsigned int (*read)(struct ni_gpct *counter, enum ni_gpct_register); enum ni_gpct_variant variant; struct ni_gpct *counters; unsigned int num_counters; @@ -121,28 +121,30 @@ struct ni_gpct_device { }; struct ni_gpct_device * -ni_gpct_device_construct(struct comedi_device *, - void (*write)(struct ni_gpct *, +ni_gpct_device_construct(struct comedi_device *dev, + void (*write)(struct ni_gpct *counter, unsigned int value, enum ni_gpct_register), - unsigned int (*read)(struct ni_gpct *, + unsigned int (*read)(struct ni_gpct *counter, enum ni_gpct_register), enum ni_gpct_variant, unsigned int num_counters); -void ni_gpct_device_destroy(struct ni_gpct_device *); -void ni_tio_init_counter(struct ni_gpct *); -int ni_tio_insn_read(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *data); -int ni_tio_insn_config(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *data); -int ni_tio_insn_write(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *data); -int ni_tio_cmd(struct comedi_device *, struct comedi_subdevice *); -int ni_tio_cmdtest(struct comedi_device *, struct comedi_subdevice *, - struct comedi_cmd *); -int ni_tio_cancel(struct ni_gpct *); -void ni_tio_handle_interrupt(struct ni_gpct *, struct comedi_subdevice *); -void ni_tio_set_mite_channel(struct ni_gpct *, struct mite_channel *); -void ni_tio_acknowledge(struct ni_gpct *); +void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev); +void ni_tio_init_counter(struct ni_gpct *counter); +int ni_tio_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +int ni_tio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +int ni_tio_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); +int ni_tio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_cmd *cmd); +int ni_tio_cancel(struct ni_gpct *counter); +void ni_tio_handle_interrupt(struct ni_gpct *counter, + struct comedi_subdevice *s); +void ni_tio_set_mite_channel(struct ni_gpct *counter, + struct mite_channel *mite_chan); +void ni_tio_acknowledge(struct ni_gpct *counter); #endif /* _COMEDI_NI_TIO_H */ diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index b15b10833c42..4e024eb5656b 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -160,8 +160,9 @@ #define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(9) : BIT(6)) #define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(10) : BIT(8)) -void ni_tio_write(struct ni_gpct *, unsigned int value, enum ni_gpct_register); -unsigned int ni_tio_read(struct ni_gpct *, enum ni_gpct_register); +void ni_tio_write(struct ni_gpct *counter, unsigned int value, + enum ni_gpct_register); +unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register); static inline bool ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev) @@ -170,12 +171,13 @@ ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev) return counter_dev->variant != ni_gpct_variant_e_series; } -void ni_tio_set_bits(struct ni_gpct *, enum ni_gpct_register reg, +void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg, unsigned int mask, unsigned int value); -unsigned int ni_tio_get_soft_copy(const struct ni_gpct *, +unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, enum ni_gpct_register reg); -int ni_tio_arm(struct ni_gpct *, bool arm, unsigned int start_trigger); -int ni_tio_set_gate_src(struct ni_gpct *, unsigned int gate, unsigned int src); +int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger); +int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned int gate, + unsigned int src); #endif /* _COMEDI_NI_TIO_INTERNAL_H */ diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 0dd5fe286855..97939b42cc00 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1513,7 +1513,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, for (n = 0; n < insn->n; n++) { /* Delay 10 microseconds for analog input settling. */ - udelay(10); + usleep_range(10, 20); /* Start ADC by pulsing GPIO1 low */ gpio_image = readl(dev->mmio + S626_P_GPIO); diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 91dea25b5724..2644dd4d6143 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -80,15 +80,17 @@ static int comedi_proc_open(struct inode *inode, struct file *file) } static const struct file_operations comedi_proc_fops = { + .owner = THIS_MODULE, .open = comedi_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; -void comedi_proc_init(void) +void __init comedi_proc_init(void) { - proc_create("comedi", 0644, NULL, &comedi_proc_fops); + if (!proc_create("comedi", 0444, NULL, &comedi_proc_fops)) + pr_warn("comedi: unable to create proc entry\n"); } void comedi_proc_cleanup(void) diff --git a/drivers/staging/dgnc/TODO b/drivers/staging/dgnc/TODO index 0e0825bd70ae..e26d1d6a5941 100644 --- a/drivers/staging/dgnc/TODO +++ b/drivers/staging/dgnc/TODO @@ -1,10 +1,9 @@ -* checkpatch fixes * remove unnecessary comments * remove unnecessary error messages. Example kzalloc() has its own error message. Adding an extra one is useless. * use goto statements for error handling when appropriate * there is a lot of unnecessary code in the driver. It was - originally a standalone driver. Remove uneeded code. + originally a standalone driver. Remove unneeded code. Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc: Lidza Louina <lidza.louina@gmail.com> diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 1e10c0fe4745..c63e591631f6 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -971,9 +971,10 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) * touched safely, the close routine will signal the * ch_flags_wait to wake us back up. */ - rc = wait_event_interruptible(ch->ch_flags_wait, - (((ch->ch_tun.un_flags | - ch->ch_pun.un_flags) & UN_CLOSING) == 0)); + rc = wait_event_interruptible( + ch->ch_flags_wait, + (((ch->ch_tun.un_flags | + ch->ch_pun.un_flags) & UN_CLOSING) == 0)); /* If ret is non-zero, user ctrl-c'ed us */ if (rc) @@ -1193,7 +1194,8 @@ static int dgnc_block_til_ready(struct tty_struct *tty, (old_flags != (ch->ch_tun.un_flags | ch->ch_pun.un_flags))); else - retval = wait_event_interruptible(ch->ch_flags_wait, + retval = wait_event_interruptible( + ch->ch_flags_wait, (old_flags != ch->ch_flags)); /* diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 3f42fa8b0bf3..77b242e09932 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -553,28 +553,22 @@ static void _nbu2ss_dma_unmap_single( /*-------------------------------------------------------------------------*/ /* Endpoint 0 OUT Transfer (PIO) */ -static int EP0_out_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length) +static int ep0_out_pio(struct nbu2ss_udc *udc, u8 *buf, u32 length) { u32 i; - int nret = 0; - u32 iWordLength = 0; - union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf; + u32 numreads = length / sizeof(u32); + union usb_reg_access *buf32 = (union usb_reg_access *)buf; - /*------------------------------------------------------------*/ - /* Read Length */ - iWordLength = length / sizeof(u32); + if (!numreads) + return 0; - /*------------------------------------------------------------*/ /* PIO Read */ - if (iWordLength) { - for (i = 0; i < iWordLength; i++) { - pBuf32->dw = _nbu2ss_readl(&udc->p_regs->EP0_READ); - pBuf32++; - } - nret = iWordLength * sizeof(u32); + for (i = 0; i < numreads; i++) { + buf32->dw = _nbu2ss_readl(&udc->p_regs->EP0_READ); + buf32++; } - return nret; + return numreads * sizeof(u32); } /*-------------------------------------------------------------------------*/ @@ -758,7 +752,7 @@ static int _nbu2ss_ep0_out_transfer( pBuffer = (u8 *)req->req.buf; pBuffer += req->req.actual; - result = EP0_out_PIO(udc, pBuffer + result = ep0_out_pio(udc, pBuffer , min(iRemainSize, iRecvLength)); if (result < 0) return result; @@ -3137,7 +3131,7 @@ static const struct { }; /*-------------------------------------------------------------------------*/ -static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) +static void nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) { int i; @@ -3168,7 +3162,7 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) /*-------------------------------------------------------------------------*/ /* platform_driver */ -static int __init nbu2ss_drv_contest_init( +static int nbu2ss_drv_contest_init( struct platform_device *pdev, struct nbu2ss_udc *udc) { diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index a6e3af74a904..4ee76dbd30b5 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -185,9 +185,9 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) buf[i] = (u8)va_arg(args, unsigned int); va_end(args); - fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, - par->info->device, u8, buf, len, "%s: ", __func__); - } + fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device, + u8, buf, len, "%s: ", __func__); +} va_start(args, len); @@ -246,7 +246,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) static void construct_line_bitmap(struct fbtft_par *par, u8 *dest, signed short *src, - int xs, int xe, int y) + int xs, int xe, int y) { int x, i; @@ -361,7 +361,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) /* left half of display */ if (addr_win.xs < par->info->var.xres / 2) { construct_line_bitmap(par, buf, convert_buf, - addr_win.xs, par->info->var.xres / 2, y); + addr_win.xs, + par->info->var.xres / 2, y); len = par->info->var.xres / 2 - addr_win.xs; @@ -382,8 +383,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) /* right half of display */ if (addr_win.xe >= par->info->var.xres / 2) { construct_line_bitmap(par, buf, - convert_buf, par->info->var.xres / 2, - addr_win.xe + 1, y); + convert_buf, + par->info->var.xres / 2, + addr_win.xe + 1, y); len = addr_win.xe + 1 - par->info->var.xres / 2; @@ -413,7 +415,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) static int write(struct fbtft_par *par, void *buf, size_t len) { fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, - "%s(len=%d): ", __func__, len); + "%s(len=%d): ", __func__, len); gpio_set_value(par->RW, 0); /* set write mode */ diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c index 9970ed74bb38..1ca1fcd353d6 100644 --- a/drivers/staging/fbtft/fb_hx8340bn.c +++ b/drivers/staging/fbtft/fb_hx8340bn.c @@ -37,7 +37,7 @@ "3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 " static bool emulate; -module_param(emulate, bool, 0); +module_param(emulate, bool, 0000); MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode"); static int init_display(struct fbtft_par *par) @@ -158,7 +158,7 @@ static int set_var(struct fbtft_par *par) * ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX GC */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07, diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c index 450a61e3f99c..bbf78f8644a8 100644 --- a/drivers/staging/fbtft/fb_hx8347d.c +++ b/drivers/staging/fbtft/fb_hx8347d.c @@ -102,7 +102,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) * VRN0 VRN1 VRN2 VRN3 VRN4 VRN5 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 CGM */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 0x1f, 0x1f, diff --git a/drivers/staging/fbtft/fb_hx8353d.c b/drivers/staging/fbtft/fb_hx8353d.c index 72e4ff8c5553..2c18051a44b3 100644 --- a/drivers/staging/fbtft/fb_hx8353d.c +++ b/drivers/staging/fbtft/fb_hx8353d.c @@ -118,7 +118,7 @@ static int set_var(struct fbtft_par *par) } /* gamma string format: */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { write_reg(par, 0xE0, curves[0], curves[1], curves[2], curves[3], diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 6b8f8b17e9a3..579e17734612 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -202,7 +202,7 @@ static int set_var(struct fbtft_par *par) #ifdef GAMMA_ADJ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int gamma_adj(struct fbtft_par *par, unsigned long *curves) +static int gamma_adj(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index 278e4c7e95e5..20ba86da028b 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -221,7 +221,7 @@ static int set_var(struct fbtft_par *par) * VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5 */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 19e33bab9cac..7189de5ae4b3 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -215,7 +215,7 @@ static int set_var(struct fbtft_par *par) * VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5 */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c index ff35c8624ca3..21a98e9e1a14 100644 --- a/drivers/staging/fbtft/fb_ili9341.c +++ b/drivers/staging/fbtft/fb_ili9341.c @@ -121,7 +121,7 @@ static int set_var(struct fbtft_par *par) * Negative: Par1 Par2 [...] Par15 */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { int i; diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index a4710dc067ef..87f678a314cc 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -33,11 +33,11 @@ #define DEFAULT_GAMMA "40" /* gamma controls the contrast in this driver */ static unsigned int tc; -module_param(tc, uint, 0); +module_param(tc, uint, 0000); MODULE_PARM_DESC(tc, "TC[1:0] Temperature coefficient: 0-3 (default: 0)"); static unsigned int bs = 4; -module_param(bs, uint, 0); +module_param(bs, uint, 0000); MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)"); static int init_display(struct fbtft_par *par) @@ -137,7 +137,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) return ret; } -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { /* apply mask */ curves[0] &= 0x7F; diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 308a244972aa..89d36d6d0cd3 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -33,7 +33,7 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len) struct spi_message m; fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, - "%s(len=%d): ", __func__, len); + "%s(len=%d): ", __func__, len); if (!par->spi) { dev_err(par->info->device, @@ -42,10 +42,6 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len) } spi_message_init(&m); - if (par->txbuf.dma && buf == par->txbuf.buf) { - t.tx_dma = par->txbuf.dma; - m.is_dma_mapped = 1; - } spi_message_add_tail(&t, &m); return spi_sync(par->spi, &m); } @@ -55,9 +51,9 @@ static int init_display(struct fbtft_par *par) gpio_set_value(par->gpio.dc, 1); fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, - "%s()\n", __func__); + "%s()\n", __func__); fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, - "display size %dx%d\n", + "display size %dx%d\n", par->info->var.xres, par->info->var.yres); @@ -215,7 +211,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) buf[i] = (u8)va_arg(args, unsigned int); va_end(args); fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device, - u8, buf, len, "%s: ", __func__); + u8, buf, len, "%s: ", __func__); } va_start(args, len); @@ -266,7 +262,7 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) size_t startbyte_size = 0; fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n", - __func__, offset, len); + __func__, offset, len); remain = len / 2; vmem16 = (u16 *)(par->info->screen_buffer + offset); diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index 9b1d70b218df..3b36ed50d491 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -130,7 +130,7 @@ static int set_var(struct fbtft_par *par) * PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1 */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index 25f9fbe1e76f..c603e1516e64 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -30,7 +30,7 @@ "02 03 2 5 7 5 4 2 4 2" static unsigned int reg11 = 0x6040; -module_param(reg11, uint, 0); +module_param(reg11, uint, 0000); MODULE_PARM_DESC(reg11, "Register 11h value"); static int init_display(struct fbtft_par *par) @@ -136,7 +136,7 @@ static int set_var(struct fbtft_par *par) * VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, diff --git a/drivers/staging/fbtft/fb_ssd1305.c b/drivers/staging/fbtft/fb_ssd1305.c index 4b38c3fadd60..33c03872ca84 100644 --- a/drivers/staging/fbtft/fb_ssd1305.c +++ b/drivers/staging/fbtft/fb_ssd1305.c @@ -148,7 +148,7 @@ static int blank(struct fbtft_par *par, bool on) } /* Gamma is used to control Contrast */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { curves[0] &= 0xFF; /* Set Contrast Control for BANK0 */ diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 80fc57029fee..96c58de85288 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -62,6 +62,8 @@ static int init_display(struct fbtft_par *par) write_reg(par, 0xA8); if (par->info->var.yres == 64) write_reg(par, 0x3F); + else if (par->info->var.yres == 48) + write_reg(par, 0x2F); else write_reg(par, 0x1F); @@ -82,7 +84,7 @@ static int init_display(struct fbtft_par *par) /* Vertical addressing mode */ write_reg(par, 0x01); - /*Set Segment Re-map */ + /* Set Segment Re-map */ /* column address 127 is mapped to SEG0 */ write_reg(par, 0xA0 | 0x1); @@ -95,6 +97,9 @@ static int init_display(struct fbtft_par *par) if (par->info->var.yres == 64) /* A[4]=1b, Alternative COM pin configuration */ write_reg(par, 0x12); + else if (par->info->var.yres == 48) + /* A[4]=1b, Alternative COM pin configuration */ + write_reg(par, 0x12); else /* A[4]=0b, Sequential COM pin configuration */ write_reg(par, 0x02); @@ -124,6 +129,19 @@ static int init_display(struct fbtft_par *par) return 0; } +static void set_addr_win_64x48(struct fbtft_par *par) +{ + /* Set Column Address */ + write_reg(par, 0x21); + write_reg(par, 0x20); + write_reg(par, 0x5F); + + /* Set Page Address */ + write_reg(par, 0x22); + write_reg(par, 0x0); + write_reg(par, 0x5); +} + static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) { /* Set Lower Column Start Address for Page Addressing Mode */ @@ -132,12 +150,15 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) write_reg(par, 0x10 | 0x0); /* Set Display Start Line */ write_reg(par, 0x40 | 0x0); + + if (par->info->var.xres == 64 && par->info->var.yres == 48) + set_addr_win_64x48(par); } static int blank(struct fbtft_par *par, bool on) { fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n", - __func__, on ? "true" : "false"); + __func__, on ? "true" : "false"); if (on) write_reg(par, 0xAE); @@ -147,7 +168,7 @@ static int blank(struct fbtft_par *par, bool on) } /* Gamma is used to control Contrast */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { /* apply mask */ curves[0] &= 0xFF; @@ -162,26 +183,24 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves) static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) { u16 *vmem16 = (u16 *)par->info->screen_buffer; + u32 xres = par->info->var.xres; + u32 yres = par->info->var.yres; u8 *buf = par->txbuf.buf; int x, y, i; int ret = 0; - for (x = 0; x < par->info->var.xres; x++) { - for (y = 0; y < par->info->var.yres/8; y++) { + for (x = 0; x < xres; x++) { + for (y = 0; y < yres / 8; y++) { *buf = 0x00; for (i = 0; i < 8; i++) - *buf |= (vmem16[(y * 8 + i) * - par->info->var.xres + x] ? - 1 : 0) << i; + *buf |= (vmem16[(y * 8 + i) * xres + x] ? 1 : 0) << i; buf++; } } /* Write data */ gpio_set_value(par->gpio.dc, 1); - ret = par->fbtftops.write(par, par->txbuf.buf, - par->info->var.xres * par->info->var.yres / - 8); + ret = par->fbtftops.write(par, par->txbuf.buf, xres * yres / 8); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", ret); diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c index 15078bf2aa4b..b7e40c24f58e 100644 --- a/drivers/staging/fbtft/fb_ssd1325.c +++ b/drivers/staging/fbtft/fb_ssd1325.c @@ -116,7 +116,7 @@ static int blank(struct fbtft_par *par, bool on) * 0 = Setting of GS1 < Setting of GS2 < Setting of GS3.....< * Setting of GS14 < Setting of GS15 */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { int i; diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index 1d74ac1343a8..26f24e32d979 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -122,7 +122,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) * Setting of GS63 has to be > Setting of GS62 +1 * */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long tmp[GAMMA_NUM * GAMMA_LEN]; int i, acc = 0; @@ -145,14 +145,16 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves) } write_reg(par, 0xB8, - tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], - tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15], - tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], tmp[21], tmp[22], tmp[23], - tmp[24], tmp[25], tmp[26], tmp[27], tmp[28], tmp[29], tmp[30], tmp[31], - tmp[32], tmp[33], tmp[34], tmp[35], tmp[36], tmp[37], tmp[38], tmp[39], - tmp[40], tmp[41], tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47], - tmp[48], tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55], - tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], tmp[62]); + tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], + tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], + tmp[14], tmp[15], tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], + tmp[21], tmp[22], tmp[23], tmp[24], tmp[25], tmp[26], tmp[27], + tmp[28], tmp[29], tmp[30], tmp[31], tmp[32], tmp[33], tmp[34], + tmp[35], tmp[36], tmp[37], tmp[38], tmp[39], tmp[40], tmp[41], + tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47], tmp[48], + tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55], + tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], + tmp[62]); return 0; } @@ -160,7 +162,7 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves) static int blank(struct fbtft_par *par, bool on) { fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n", - __func__, on ? "true" : "false"); + __func__, on ? "true" : "false"); if (on) write_reg(par, 0xAE); else diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index 200aa9ba98f9..e62235d4d9e7 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -71,8 +71,8 @@ static int set_var(struct fbtft_par *par) if (par->fbtftops.init_display != init_display) { /* don't risk messing up register A0h */ fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, - "%s: skipping since custom init_display() is used\n", - __func__); + "%s: skipping since custom init_display() is used\n", + __func__); return 0; } @@ -117,7 +117,7 @@ static int set_var(struct fbtft_par *par) * Setting of GS63 has to be > Setting of GS62 +1 * */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { unsigned long tmp[GAMMA_NUM * GAMMA_LEN]; int i, acc = 0; diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c index 710b74bbba97..24d17cdc71ab 100644 --- a/drivers/staging/fbtft/fb_st7735r.c +++ b/drivers/staging/fbtft/fb_st7735r.c @@ -143,7 +143,7 @@ static int set_var(struct fbtft_par *par) * VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N */ #define CURVE(num, idx) curves[num * par->gamma.num_values + idx] -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { int i, j; diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 085e9872c46d..8935a97ec048 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -178,7 +178,7 @@ static int set_var(struct fbtft_par *par) * * Return: 0 on success, < 0 if error occurred. */ -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { int i; int j; diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index ea2ddacb9468..4302e822de3b 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -36,7 +36,7 @@ #define DEFAULT_GAMMA "40" static unsigned int bs = 4; -module_param(bs, uint, 0); +module_param(bs, uint, 0000); MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)"); static int init_display(struct fbtft_par *par) @@ -130,7 +130,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) return ret; } -static int set_gamma(struct fbtft_par *par, unsigned long *curves) +static int set_gamma(struct fbtft_par *par, u32 *curves) { /* apply mask */ curves[0] &= 0x7F; diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index b33b73f17da4..48e3b3fd9fed 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -42,30 +42,30 @@ /* BR -> actual ratio: 0-3 -> 5, 10, 11, 13 */ static unsigned int ratio = 2; -module_param(ratio, uint, 0); +module_param(ratio, uint, 0000); MODULE_PARM_DESC(ratio, "BR[1:0] Bias voltage ratio: 0-3 (default: 2)"); static unsigned int gain = 3; -module_param(gain, uint, 0); +module_param(gain, uint, 0000); MODULE_PARM_DESC(gain, "GN[1:0] Bias voltage gain: 0-3 (default: 3)"); static unsigned int pot = 16; -module_param(pot, uint, 0); +module_param(pot, uint, 0000); MODULE_PARM_DESC(pot, "PM[6:0] Bias voltage pot.: 0-63 (default: 16)"); /* TC -> % compensation per deg C: 0-3 -> -.05, -.10, -.015, -.20 */ static unsigned int temp; -module_param(temp, uint, 0); +module_param(temp, uint, 0000); MODULE_PARM_DESC(temp, "TC[1:0] Temperature compensation: 0-3 (default: 0)"); /* PC[1:0] -> LCD capacitance: 0-3 -> <20nF, 20-28 nF, 29-40 nF, 40-56 nF */ static unsigned int load = 1; -module_param(load, uint, 0); +module_param(load, uint, 0000); MODULE_PARM_DESC(load, "PC[1:0] Panel Loading: 0-3 (default: 1)"); /* PC[3:2] -> V_LCD: 0, 1, 3 -> ext., int. with ratio = 5, int. standard */ static unsigned int pump = 3; -module_param(pump, uint, 0); +module_param(pump, uint, 0000); MODULE_PARM_DESC(pump, "PC[3:2] Pump control: 0,1,3 (default: 3)"); static int init_display(struct fbtft_par *par) diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index a52e28a48825..429304546b44 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -40,7 +40,7 @@ #define COLOR_RGB565 16 static short mode = 565; -module_param(mode, short, 0); +module_param(mode, short, 0000); MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)"); static void write_reg8_bus8(struct fbtft_par *par, int len, ...) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index bbe89c9c4fb9..7c8af29cdb75 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -32,7 +32,6 @@ #include <linux/backlight.h> #include <linux/platform_device.h> #include <linux/spinlock.h> -#include <linux/dma-mapping.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <video/mipi_display.h> @@ -41,15 +40,9 @@ #include "internal.h" static unsigned long debug; -module_param(debug, ulong, 0); +module_param(debug, ulong, 0000); MODULE_PARM_DESC(debug, "override device debug level"); -#ifdef CONFIG_HAS_DMA -static bool dma = true; -module_param(dma, bool, 0); -MODULE_PARM_DESC(dma, "Use DMA buffer"); -#endif - void fbtft_dbg_hex(const struct device *dev, int groupsize, void *buf, size_t len, const char *fmt, ...) { @@ -337,10 +330,10 @@ static void fbtft_reset(struct fbtft_par *par) if (par->gpio.reset == -1) return; fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__); - gpio_set_value(par->gpio.reset, 0); - udelay(20); - gpio_set_value(par->gpio.reset, 1); - mdelay(120); + gpio_set_value_cansleep(par->gpio.reset, 0); + usleep_range(20, 40); + gpio_set_value_cansleep(par->gpio.reset, 1); + msleep(120); } static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line, @@ -668,7 +661,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, int vmem_size, i; s16 *init_sequence = display->init_sequence; char *gamma = display->gamma; - unsigned long *gamma_curves = NULL; + u32 *gamma_curves = NULL; /* sanity check */ if (display->gamma_num * display->gamma_len > @@ -836,17 +829,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, #endif if (txbuflen > 0) { -#ifdef CONFIG_HAS_DMA - if (dma) { - dev->coherent_dma_mask = ~0; - txbuf = dmam_alloc_coherent(dev, txbuflen, - &par->txbuf.dma, GFP_DMA); - } else -#endif - { - txbuf = devm_kzalloc(par->info->device, - txbuflen, GFP_KERNEL); - } + txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL); if (!txbuf) goto alloc_fail; par->txbuf.buf = txbuf; @@ -975,8 +958,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info) fbtft_sysfs_init(par); if (par->txbuf.buf) - sprintf(text1, ", %zu KiB %sbuffer memory", - par->txbuf.len >> 10, par->txbuf.dma ? "DMA " : ""); + sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10); if (spi) sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num, spi->chip_select, spi->max_speed_hz / 1000000); diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index 4dcea2e0b3ae..d86840548b74 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -22,10 +22,6 @@ int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len) } spi_message_init(&m); - if (par->txbuf.dma && buf == par->txbuf.buf) { - t.tx_dma = par->txbuf.dma; - m.is_dma_mapped = 1; - } spi_message_add_tail(&t, &m); return spi_sync(par->spi, &m); } diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c index 8d8bd12b90a1..6b6fbaa794f4 100644 --- a/drivers/staging/fbtft/fbtft-sysfs.c +++ b/drivers/staging/fbtft/fbtft-sysfs.c @@ -4,7 +4,6 @@ static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base) { char *p_val; - int ret; if (!str_p || !(*str_p)) return -EINVAL; @@ -14,14 +13,10 @@ static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base) if (!p_val) return -EINVAL; - ret = kstrtoul(p_val, base, val); - if (ret) - return -EINVAL; - - return 0; + return kstrtoul(p_val, base, val); } -int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves, +int fbtft_gamma_parse_str(struct fbtft_par *par, u32 *curves, const char *str, int size) { char *str_p, *curve_p = NULL; @@ -94,7 +89,7 @@ out: } static ssize_t -sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf) +sprintf_gamma(struct fbtft_par *par, u32 *curves, char *buf) { ssize_t len = 0; unsigned int i, j; @@ -103,7 +98,7 @@ sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf) for (i = 0; i < par->gamma.num_curves; i++) { for (j = 0; j < par->gamma.num_values; j++) len += scnprintf(&buf[len], PAGE_SIZE, - "%04lx ", curves[i * par->gamma.num_values + j]); + "%04x ", curves[i * par->gamma.num_values + j]); buf[len - 1] = '\n'; } mutex_unlock(&par->gamma.lock); @@ -117,7 +112,7 @@ static ssize_t store_gamma_curve(struct device *device, { struct fb_info *fb_info = dev_get_drvdata(device); struct fbtft_par *par = fb_info->par; - unsigned long tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL]; + u32 tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL]; int ret; ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count); diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index aacdde92cc2e..44cf94d160d4 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -92,7 +92,7 @@ struct fbtft_ops { void (*unregister_backlight)(struct fbtft_par *par); int (*set_var)(struct fbtft_par *par); - int (*set_gamma)(struct fbtft_par *par, unsigned long *curves); + int (*set_gamma)(struct fbtft_par *par, u32 *curves); }; /** @@ -209,7 +209,6 @@ struct fbtft_par { u32 pseudo_palette[16]; struct { void *buf; - dma_addr_t dma; size_t len; } txbuf; u8 *buf; @@ -232,7 +231,7 @@ struct fbtft_par { s16 *init_sequence; struct { struct mutex lock; - unsigned long *curves; + u32 *curves; int num_values; int num_curves; } gamma; diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c index de46f8d988d2..9ffb9cecc465 100644 --- a/drivers/staging/fbtft/fbtft_device.c +++ b/drivers/staging/fbtft/fbtft_device.c @@ -29,85 +29,85 @@ static struct spi_device *spi_device; static struct platform_device *p_device; static char *name; -module_param(name, charp, 0); +module_param(name, charp, 0000); MODULE_PARM_DESC(name, "Devicename (required). name=list => list all supported devices."); static unsigned int rotate; -module_param(rotate, uint, 0); +module_param(rotate, uint, 0000); MODULE_PARM_DESC(rotate, "Angle to rotate display counter clockwise: 0, 90, 180, 270"); static unsigned int busnum; -module_param(busnum, uint, 0); +module_param(busnum, uint, 0000); MODULE_PARM_DESC(busnum, "SPI bus number (default=0)"); static unsigned int cs; -module_param(cs, uint, 0); +module_param(cs, uint, 0000); MODULE_PARM_DESC(cs, "SPI chip select (default=0)"); static unsigned int speed; -module_param(speed, uint, 0); +module_param(speed, uint, 0000); MODULE_PARM_DESC(speed, "SPI speed (override device default)"); static int mode = -1; -module_param(mode, int, 0); +module_param(mode, int, 0000); MODULE_PARM_DESC(mode, "SPI mode (override device default)"); static char *gpios; -module_param(gpios, charp, 0); +module_param(gpios, charp, 0000); MODULE_PARM_DESC(gpios, "List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)"); static unsigned int fps; -module_param(fps, uint, 0); +module_param(fps, uint, 0000); MODULE_PARM_DESC(fps, "Frames per second (override driver default)"); static char *gamma; -module_param(gamma, charp, 0); +module_param(gamma, charp, 0000); MODULE_PARM_DESC(gamma, "String representation of Gamma Curve(s). Driver specific."); static int txbuflen; -module_param(txbuflen, int, 0); +module_param(txbuflen, int, 0000); MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)"); static int bgr = -1; -module_param(bgr, int, 0); +module_param(bgr, int, 0000); MODULE_PARM_DESC(bgr, "BGR bit (supported by some drivers)."); static unsigned int startbyte; -module_param(startbyte, uint, 0); +module_param(startbyte, uint, 0000); MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays."); static bool custom; -module_param(custom, bool, 0); +module_param(custom, bool, 0000); MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device"); static unsigned int width; -module_param(width, uint, 0); +module_param(width, uint, 0000); MODULE_PARM_DESC(width, "Display width, used with the custom argument"); static unsigned int height; -module_param(height, uint, 0); +module_param(height, uint, 0000); MODULE_PARM_DESC(height, "Display height, used with the custom argument"); static unsigned int buswidth = 8; -module_param(buswidth, uint, 0); +module_param(buswidth, uint, 0000); MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument"); static s16 init[FBTFT_MAX_INIT_SEQUENCE]; static int init_num; -module_param_array(init, short, &init_num, 0); +module_param_array(init, short, &init_num, 0000); MODULE_PARM_DESC(init, "Init sequence, used with the custom argument"); static unsigned long debug; -module_param(debug, ulong, 0); +module_param(debug, ulong, 0000); MODULE_PARM_DESC(debug, "level: 0-7 (the remaining 29 bits is for advanced usage)"); static unsigned int verbose = 3; -module_param(verbose, uint, 0); +module_param(verbose, uint, 0000); MODULE_PARM_DESC(verbose, "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)"); diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index ded10718712b..af8422e18780 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -27,40 +27,40 @@ #define DRVNAME "flexfb" static char *chip; -module_param(chip, charp, 0); +module_param(chip, charp, 0000); MODULE_PARM_DESC(chip, "LCD controller"); static unsigned int width; -module_param(width, uint, 0); +module_param(width, uint, 0000); MODULE_PARM_DESC(width, "Display width"); static unsigned int height; -module_param(height, uint, 0); +module_param(height, uint, 0000); MODULE_PARM_DESC(height, "Display height"); static s16 init[512]; static int init_num; -module_param_array(init, short, &init_num, 0); +module_param_array(init, short, &init_num, 0000); MODULE_PARM_DESC(init, "Init sequence"); static unsigned int setaddrwin; -module_param(setaddrwin, uint, 0); +module_param(setaddrwin, uint, 0000); MODULE_PARM_DESC(setaddrwin, "Which set_addr_win() implementation to use"); static unsigned int buswidth = 8; -module_param(buswidth, uint, 0); +module_param(buswidth, uint, 0000); MODULE_PARM_DESC(buswidth, "Width of databus (default: 8)"); static unsigned int regwidth = 8; -module_param(regwidth, uint, 0); +module_param(regwidth, uint, 0000); MODULE_PARM_DESC(regwidth, "Width of controller register (default: 8)"); static bool nobacklight; -module_param(nobacklight, bool, 0); +module_param(nobacklight, bool, 0000); MODULE_PARM_DESC(nobacklight, "Turn off backlight functionality."); static bool latched; -module_param(latched, bool, 0); +module_param(latched, bool, 0000); MODULE_PARM_DESC(latched, "Use with latched 16-bit databus"); static s16 *initp; @@ -418,22 +418,6 @@ static const struct flexfb_lcd_controller flexfb_chip_table[] = { .init_seq_sz = ARRAY_SIZE(ili9225_init), }, { - .name = "ili9225", - .width = 176, - .height = 220, - .regwidth = 16, - .init_seq = ili9225_init, - .init_seq_sz = ARRAY_SIZE(ili9225_init), - }, - { - .name = "ili9225", - .width = 176, - .height = 220, - .regwidth = 16, - .init_seq = ili9225_init, - .init_seq_sz = ARRAY_SIZE(ili9225_init), - }, - { .name = "ili9320", .width = 240, .height = 320, diff --git a/drivers/staging/fbtft/internal.h b/drivers/staging/fbtft/internal.h index eea0ec5ff4d3..25b9bf6f54bb 100644 --- a/drivers/staging/fbtft/internal.h +++ b/drivers/staging/fbtft/internal.h @@ -19,7 +19,7 @@ void fbtft_sysfs_init(struct fbtft_par *par); void fbtft_sysfs_exit(struct fbtft_par *par); void fbtft_expand_debug_value(unsigned long *debug); -int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves, +int fbtft_gamma_parse_str(struct fbtft_par *par, u32 *curves, const char *str, int size); #endif /* __LINUX_FBTFT_INTERNAL_H */ diff --git a/drivers/staging/fsl-mc/bus/dpbp-cmd.h b/drivers/staging/fsl-mc/bus/dpbp-cmd.h index 7d86539b5414..8aa65452c872 100644 --- a/drivers/staging/fsl-mc/bus/dpbp-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpbp-cmd.h @@ -45,8 +45,6 @@ /* Command IDs */ #define DPBP_CMDID_CLOSE DPBP_CMD(0x800) #define DPBP_CMDID_OPEN DPBP_CMD(0x804) -#define DPBP_CMDID_CREATE DPBP_CMD(0x904) -#define DPBP_CMDID_DESTROY DPBP_CMD(0x984) #define DPBP_CMDID_GET_API_VERSION DPBP_CMD(0xa04) #define DPBP_CMDID_ENABLE DPBP_CMD(0x002) @@ -55,18 +53,6 @@ #define DPBP_CMDID_RESET DPBP_CMD(0x005) #define DPBP_CMDID_IS_ENABLED DPBP_CMD(0x006) -#define DPBP_CMDID_SET_IRQ DPBP_CMD(0x010) -#define DPBP_CMDID_GET_IRQ DPBP_CMD(0x011) -#define DPBP_CMDID_SET_IRQ_ENABLE DPBP_CMD(0x012) -#define DPBP_CMDID_GET_IRQ_ENABLE DPBP_CMD(0x013) -#define DPBP_CMDID_SET_IRQ_MASK DPBP_CMD(0x014) -#define DPBP_CMDID_GET_IRQ_MASK DPBP_CMD(0x015) -#define DPBP_CMDID_GET_IRQ_STATUS DPBP_CMD(0x016) -#define DPBP_CMDID_CLEAR_IRQ_STATUS DPBP_CMD(0x017) - -#define DPBP_CMDID_SET_NOTIFICATIONS DPBP_CMD(0x01b0) -#define DPBP_CMDID_GET_NOTIFICATIONS DPBP_CMD(0x01b1) - struct dpbp_cmd_open { __le32 dpbp_id; }; @@ -81,76 +67,6 @@ struct dpbp_rsp_is_enabled { u8 enabled; }; -struct dpbp_cmd_set_irq { - /* cmd word 0 */ - u8 irq_index; - u8 pad[3]; - __le32 irq_val; - /* cmd word 1 */ - __le64 irq_addr; - /* cmd word 2 */ - __le32 irq_num; -}; - -struct dpbp_cmd_get_irq { - __le32 pad; - u8 irq_index; -}; - -struct dpbp_rsp_get_irq { - /* response word 0 */ - __le32 irq_val; - __le32 pad; - /* response word 1 */ - __le64 irq_addr; - /* response word 2 */ - __le32 irq_num; - __le32 type; -}; - -struct dpbp_cmd_set_irq_enable { - u8 enable; - u8 pad[3]; - u8 irq_index; -}; - -struct dpbp_cmd_get_irq_enable { - __le32 pad; - u8 irq_index; -}; - -struct dpbp_rsp_get_irq_enable { - u8 enabled; -}; - -struct dpbp_cmd_set_irq_mask { - __le32 mask; - u8 irq_index; -}; - -struct dpbp_cmd_get_irq_mask { - __le32 pad; - u8 irq_index; -}; - -struct dpbp_rsp_get_irq_mask { - __le32 mask; -}; - -struct dpbp_cmd_get_irq_status { - __le32 status; - u8 irq_index; -}; - -struct dpbp_rsp_get_irq_status { - __le32 status; -}; - -struct dpbp_cmd_clear_irq_status { - __le32 status; - u8 irq_index; -}; - struct dpbp_rsp_get_attributes { /* response word 0 */ __le16 pad; @@ -161,36 +77,4 @@ struct dpbp_rsp_get_attributes { __le16 version_minor; }; -struct dpbp_cmd_set_notifications { - /* cmd word 0 */ - __le32 depletion_entry; - __le32 depletion_exit; - /* cmd word 1 */ - __le32 surplus_entry; - __le32 surplus_exit; - /* cmd word 2 */ - __le16 options; - __le16 pad[3]; - /* cmd word 3 */ - __le64 message_ctx; - /* cmd word 4 */ - __le64 message_iova; -}; - -struct dpbp_rsp_get_notifications { - /* response word 0 */ - __le32 depletion_entry; - __le32 depletion_exit; - /* response word 1 */ - __le32 surplus_entry; - __le32 surplus_exit; - /* response word 2 */ - __le16 options; - __le16 pad[3]; - /* response word 3 */ - __le64 message_ctx; - /* response word 4 */ - __le64 message_iova; -}; - #endif /* _FSL_DPBP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c index cf4782f6a049..d9e450a6bad6 100644 --- a/drivers/staging/fsl-mc/bus/dpbp.c +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -106,77 +106,6 @@ int dpbp_close(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dpbp_close); /** - * dpbp_create() - Create the DPBP object. - * @mc_io: Pointer to MC portal's I/O object - * @dprc_token: Parent container token; '0' for default container - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @cfg: Configuration structure - * @obj_id: Returned object id; use in subsequent API calls - * - * Create the DPBP object, allocate required resources and - * perform required initialization. - * - * This function accepts an authentication token of a parent - * container that this object should be assigned to and returns - * an object id. This object_id will be used in all subsequent calls to - * this specific object. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_create(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - const struct dpbp_cfg *cfg, - u32 *obj_id) -{ - struct mc_command cmd = { 0 }; - int err; - - (void)(cfg); /* unused */ - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE, - cmd_flags, dprc_token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - *obj_id = mc_cmd_read_object_id(&cmd); - - return 0; -} - -/** - * dpbp_destroy() - Destroy the DPBP object and release all its resources. - * @mc_io: Pointer to MC portal's I/O object - * @dprc_token: Parent container token; '0' for default container - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @obj_id: ID of DPBP object - * - * Return: '0' on Success; error code otherwise. - */ -int dpbp_destroy(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - u32 obj_id) -{ - struct dpbp_cmd_destroy *cmd_params; - struct mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY, - cmd_flags, dprc_token); - cmd_params = (struct dpbp_cmd_destroy *)cmd.params; - cmd_params->object_id = cpu_to_le32(obj_id); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** * dpbp_enable() - Enable the DPBP. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -254,6 +183,7 @@ int dpbp_is_enabled(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dpbp_is_enabled); /** * dpbp_reset() - Reset the DPBP, returns the object to initial state. @@ -276,310 +206,7 @@ int dpbp_reset(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } - -/** - * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: Identifies the interrupt index to configure - * @irq_cfg: IRQ configuration - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_set_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - struct dpbp_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_set_irq *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_set_irq *)cmd.params; - cmd_params->irq_index = irq_index; - cmd_params->irq_val = cpu_to_le32(irq_cfg->val); - cmd_params->irq_addr = cpu_to_le64(irq_cfg->addr); - cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpbp_get_irq() - Get IRQ information from the DPBP. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @type: Interrupt type: 0 represents message interrupt - * type (both irq_addr and irq_val are valid) - * @irq_cfg: IRQ attributes - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dpbp_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_get_irq *cmd_params; - struct dpbp_rsp_get_irq *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_get_irq *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpbp_rsp_get_irq *)cmd.params; - irq_cfg->val = le32_to_cpu(rsp_params->irq_val); - irq_cfg->addr = le64_to_cpu(rsp_params->irq_addr); - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num); - *type = le32_to_cpu(rsp_params->type); - - return 0; -} - -/** - * dpbp_set_irq_enable() - Set overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @en: Interrupt state - enable = 1, disable = 0 - * - * Allows GPP software to control when interrupts are generated. - * Each interrupt can have up to 32 causes. The enable/disable control's the - * overall interrupt state. if the interrupt is disabled no causes will cause - * an interrupt. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 en) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_set_irq_enable *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_set_irq_enable *)cmd.params; - cmd_params->enable = en & DPBP_ENABLE; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpbp_get_irq_enable() - Get overall interrupt state - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_get_irq_enable *cmd_params; - struct dpbp_rsp_get_irq_enable *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_get_irq_enable *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpbp_rsp_get_irq_enable *)cmd.params; - *en = rsp_params->enabled & DPBP_ENABLE; - return 0; -} - -/** - * dpbp_set_irq_mask() - Set interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @mask: Event mask to trigger interrupt; - * each bit: - * 0 = ignore event - * 1 = consider event for asserting IRQ - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 mask) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_set_irq_mask *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_set_irq_mask *)cmd.params; - cmd_params->mask = cpu_to_le32(mask); - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpbp_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_get_irq_mask *cmd_params; - struct dpbp_rsp_get_irq_mask *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_get_irq_mask *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpbp_rsp_get_irq_mask *)cmd.params; - *mask = le32_to_cpu(rsp_params->mask); - - return 0; -} - -/** - * dpbp_get_irq_status() - Get the current status of any pending interrupts. - * - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @status: Returned interrupts status - one bit per cause: - * 0 = no interrupt pending - * 1 = interrupt pending - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_get_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *status) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_get_irq_status *cmd_params; - struct dpbp_rsp_get_irq_status *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_get_irq_status *)cmd.params; - cmd_params->status = cpu_to_le32(*status); - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpbp_rsp_get_irq_status *)cmd.params; - *status = le32_to_cpu(rsp_params->status); - - return 0; -} - -/** - * dpbp_clear_irq_status() - Clear a pending interrupt's status - * - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @status: Bits to clear (W1C) - one bit per cause: - * 0 = don't change - * 1 = clear status bit - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 status) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_clear_irq_status *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_clear_irq_status *)cmd.params; - cmd_params->status = cpu_to_le32(status); - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} +EXPORT_SYMBOL(dpbp_reset); /** * dpbp_get_attributes - Retrieve DPBP attributes. @@ -619,80 +246,6 @@ int dpbp_get_attributes(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dpbp_get_attributes); /** - * dpbp_set_notifications() - Set notifications towards software - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @cfg: notifications configuration - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_set_notifications(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpbp_notification_cfg *cfg) -{ - struct mc_command cmd = { 0 }; - struct dpbp_cmd_set_notifications *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_NOTIFICATIONS, - cmd_flags, token); - cmd_params = (struct dpbp_cmd_set_notifications *)cmd.params; - cmd_params->depletion_entry = cpu_to_le32(cfg->depletion_entry); - cmd_params->depletion_exit = cpu_to_le32(cfg->depletion_exit); - cmd_params->surplus_entry = cpu_to_le32(cfg->surplus_entry); - cmd_params->surplus_exit = cpu_to_le32(cfg->surplus_exit); - cmd_params->options = cpu_to_le16(cfg->options); - cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx); - cmd_params->message_iova = cpu_to_le64(cfg->message_iova); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpbp_get_notifications() - Get the notifications configuration - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPBP object - * @cfg: notifications configuration - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_get_notifications(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpbp_notification_cfg *cfg) -{ - struct mc_command cmd = { 0 }; - struct dpbp_rsp_get_notifications *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_NOTIFICATIONS, - cmd_flags, - token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpbp_rsp_get_notifications *)cmd.params; - cfg->depletion_entry = le32_to_cpu(rsp_params->depletion_entry); - cfg->depletion_exit = le32_to_cpu(rsp_params->depletion_exit); - cfg->surplus_entry = le32_to_cpu(rsp_params->surplus_entry); - cfg->surplus_exit = le32_to_cpu(rsp_params->surplus_exit); - cfg->options = le16_to_cpu(rsp_params->options); - cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx); - cfg->message_iova = le64_to_cpu(rsp_params->message_iova); - - return 0; -} - -/** * dpbp_get_api_version - Get Data Path Buffer Pool API version * @mc_io: Pointer to Mc portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -723,3 +276,4 @@ int dpbp_get_api_version(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dpbp_get_api_version); diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h index 7cb514963c26..384a13d0b07f 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h @@ -45,107 +45,12 @@ /* Command IDs */ #define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) #define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) -#define DPMCP_CMDID_CREATE DPMCP_CMD(0x90b) -#define DPMCP_CMDID_DESTROY DPMCP_CMD(0x98b) #define DPMCP_CMDID_GET_API_VERSION DPMCP_CMD(0xa0b) -#define DPMCP_CMDID_GET_ATTR DPMCP_CMD(0x004) #define DPMCP_CMDID_RESET DPMCP_CMD(0x005) -#define DPMCP_CMDID_SET_IRQ DPMCP_CMD(0x010) -#define DPMCP_CMDID_GET_IRQ DPMCP_CMD(0x011) -#define DPMCP_CMDID_SET_IRQ_ENABLE DPMCP_CMD(0x012) -#define DPMCP_CMDID_GET_IRQ_ENABLE DPMCP_CMD(0x013) -#define DPMCP_CMDID_SET_IRQ_MASK DPMCP_CMD(0x014) -#define DPMCP_CMDID_GET_IRQ_MASK DPMCP_CMD(0x015) -#define DPMCP_CMDID_GET_IRQ_STATUS DPMCP_CMD(0x016) - struct dpmcp_cmd_open { __le32 dpmcp_id; }; -struct dpmcp_cmd_create { - __le32 portal_id; -}; - -struct dpmcp_cmd_destroy { - __le32 object_id; -}; - -struct dpmcp_cmd_set_irq { - /* cmd word 0 */ - u8 irq_index; - u8 pad[3]; - __le32 irq_val; - /* cmd word 1 */ - __le64 irq_addr; - /* cmd word 2 */ - __le32 irq_num; -}; - -struct dpmcp_cmd_get_irq { - __le32 pad; - u8 irq_index; -}; - -struct dpmcp_rsp_get_irq { - /* cmd word 0 */ - __le32 irq_val; - __le32 pad; - /* cmd word 1 */ - __le64 irq_paddr; - /* cmd word 2 */ - __le32 irq_num; - __le32 type; -}; - -#define DPMCP_ENABLE 0x1 - -struct dpmcp_cmd_set_irq_enable { - u8 enable; - u8 pad[3]; - u8 irq_index; -}; - -struct dpmcp_cmd_get_irq_enable { - __le32 pad; - u8 irq_index; -}; - -struct dpmcp_rsp_get_irq_enable { - u8 enabled; -}; - -struct dpmcp_cmd_set_irq_mask { - __le32 mask; - u8 irq_index; -}; - -struct dpmcp_cmd_get_irq_mask { - __le32 pad; - u8 irq_index; -}; - -struct dpmcp_rsp_get_irq_mask { - __le32 mask; -}; - -struct dpmcp_cmd_get_irq_status { - __le32 status; - u8 irq_index; -}; - -struct dpmcp_rsp_get_irq_status { - __le32 status; -}; - -struct dpmcp_rsp_get_attributes { - /* response word 0 */ - __le32 pad; - __le32 id; - /* response word 1 */ - __le16 version_major; - __le16 version_minor; -}; - #endif /* _FSL_DPMCP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c index e4d16519bcb4..ad4c8b43f065 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.c +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -104,82 +104,6 @@ int dpmcp_close(struct fsl_mc_io *mc_io, } /** - * dpmcp_create() - Create the DPMCP object. - * @mc_io: Pointer to MC portal's I/O object - * @dprc_token: Parent container token; '0' for default container - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @cfg: Configuration structure - * @obj_id: Returned object id; use in subsequent API calls - * - * Create the DPMCP object, allocate required resources and - * perform required initialization. - * - * The object can be created either by declaring it in the - * DPL file, or by calling this function. - - * This function accepts an authentication token of a parent - * container that this object should be assigned to and returns - * an object id. This object_id will be used in all subsequent calls to - * this specific object. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_create(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - const struct dpmcp_cfg *cfg, - u32 *obj_id) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_create *cmd_params; - - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE, - cmd_flags, dprc_token); - cmd_params = (struct dpmcp_cmd_create *)cmd.params; - cmd_params->portal_id = cpu_to_le32(cfg->portal_id); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - *obj_id = mc_cmd_read_object_id(&cmd); - - return 0; -} - -/** - * dpmcp_destroy() - Destroy the DPMCP object and release all its resources. - * @mc_io: Pointer to MC portal's I/O object - * @dprc_token: Parent container token; '0' for default container - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @obj_id: ID of DPMCP object - * - * Return: '0' on Success; error code otherwise. - */ -int dpmcp_destroy(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - u32 obj_id) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_destroy *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY, - cmd_flags, dprc_token); - cmd_params = (struct dpmcp_cmd_destroy *)cmd.params; - cmd_params->object_id = cpu_to_le32(obj_id); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** * dpmcp_reset() - Reset the DPMCP, returns the object to initial state. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -202,312 +126,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, } /** - * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: Identifies the interrupt index to configure - * @irq_cfg: IRQ configuration - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_set_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - struct dpmcp_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_set_irq *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_set_irq *)cmd.params; - cmd_params->irq_index = irq_index; - cmd_params->irq_val = cpu_to_le32(irq_cfg->val); - cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); - cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpmcp_get_irq() - Get IRQ information from the DPMCP. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @type: Interrupt type: 0 represents message interrupt - * type (both irq_addr and irq_val are valid) - * @irq_cfg: IRQ attributes - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dpmcp_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_get_irq *cmd_params; - struct dpmcp_rsp_get_irq *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_get_irq *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpmcp_rsp_get_irq *)cmd.params; - irq_cfg->val = le32_to_cpu(rsp_params->irq_val); - irq_cfg->paddr = le64_to_cpu(rsp_params->irq_paddr); - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num); - *type = le32_to_cpu(rsp_params->type); - return 0; -} - -/** - * dpmcp_set_irq_enable() - Set overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @en: Interrupt state - enable = 1, disable = 0 - * - * Allows GPP software to control when interrupts are generated. - * Each interrupt can have up to 32 causes. The enable/disable control's the - * overall interrupt state. if the interrupt is disabled no causes will cause - * an interrupt. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 en) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_set_irq_enable *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_set_irq_enable *)cmd.params; - cmd_params->enable = en & DPMCP_ENABLE; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpmcp_get_irq_enable() - Get overall interrupt state - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_get_irq_enable *cmd_params; - struct dpmcp_rsp_get_irq_enable *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_get_irq_enable *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpmcp_rsp_get_irq_enable *)cmd.params; - *en = rsp_params->enabled & DPMCP_ENABLE; - return 0; -} - -/** - * dpmcp_set_irq_mask() - Set interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @mask: Event mask to trigger interrupt; - * each bit: - * 0 = ignore event - * 1 = consider event for asserting IRQ - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 mask) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_set_irq_mask *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_set_irq_mask *)cmd.params; - cmd_params->mask = cpu_to_le32(mask); - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dpmcp_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_get_irq_mask *cmd_params; - struct dpmcp_rsp_get_irq_mask *rsp_params; - - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_get_irq_mask *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpmcp_rsp_get_irq_mask *)cmd.params; - *mask = le32_to_cpu(rsp_params->mask); - - return 0; -} - -/** - * dpmcp_get_irq_status() - Get the current status of any pending interrupts. - * - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @status: Returned interrupts status - one bit per cause: - * 0 = no interrupt pending - * 1 = interrupt pending - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *status) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_cmd_get_irq_status *cmd_params; - struct dpmcp_rsp_get_irq_status *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS, - cmd_flags, token); - cmd_params = (struct dpmcp_cmd_get_irq_status *)cmd.params; - cmd_params->status = cpu_to_le32(*status); - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpmcp_rsp_get_irq_status *)cmd.params; - *status = le32_to_cpu(rsp_params->status); - - return 0; -} - -/** - * dpmcp_get_attributes - Retrieve DPMCP attributes. - * - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPMCP object - * @attr: Returned object's attributes - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_attributes(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpmcp_attr *attr) -{ - struct mc_command cmd = { 0 }; - struct dpmcp_rsp_get_attributes *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR, - cmd_flags, token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dpmcp_rsp_get_attributes *)cmd.params; - attr->id = le32_to_cpu(rsp_params->id); - - return 0; -} - -/** * dpmcp_get_api_version - Get Data Path Management Command Portal API version * @mc_io: Pointer to Mc portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h index 98a100d543f6..f616031e3e59 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.h +++ b/drivers/staging/fsl-mc/bus/dpmcp.h @@ -44,109 +44,17 @@ int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, u16 *token); -/* Get portal ID from pool */ -#define DPMCP_GET_PORTAL_ID_FROM_POOL (-1) - int dpmcp_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -/** - * struct dpmcp_cfg - Structure representing DPMCP configuration - * @portal_id: Portal ID; 'DPMCP_GET_PORTAL_ID_FROM_POOL' to get the portal ID - * from pool - */ -struct dpmcp_cfg { - int portal_id; -}; - -int dpmcp_create(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - const struct dpmcp_cfg *cfg, - u32 *obj_id); - -int dpmcp_destroy(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - u32 obj_id); +int dpmcp_get_api_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *major_ver, + u16 *minor_ver); int dpmcp_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -/* IRQ */ -/* IRQ Index */ -#define DPMCP_IRQ_INDEX 0 -/* irq event - Indicates that the link state changed */ -#define DPMCP_IRQ_EVENT_CMD_DONE 0x00000001 - -/** - * struct dpmcp_irq_cfg - IRQ configuration - * @paddr: Address that must be written to signal a message-based interrupt - * @val: Value to write into irq_addr address - * @irq_num: A user defined number associated with this IRQ - */ -struct dpmcp_irq_cfg { - u64 paddr; - u32 val; - int irq_num; -}; - -int dpmcp_set_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - struct dpmcp_irq_cfg *irq_cfg); - -int dpmcp_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dpmcp_irq_cfg *irq_cfg); - -int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 en); - -int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en); - -int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 mask); - -int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask); - -int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *status); - -/** - * struct dpmcp_attr - Structure representing DPMCP attributes - * @id: DPMCP object ID - */ -struct dpmcp_attr { - int id; -}; - -int dpmcp_get_attributes(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpmcp_attr *attr); - #endif /* __FSL_DPMCP_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h index 588b8cafdbc7..e9fdca41f324 100644 --- a/drivers/staging/fsl-mc/bus/dprc-cmd.h +++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h @@ -53,11 +53,9 @@ /* Command IDs */ #define DPRC_CMDID_CLOSE DPRC_CMD(0x800) #define DPRC_CMDID_OPEN DPRC_CMD(0x805) -#define DPRC_CMDID_CREATE DPRC_CMD(0x905) #define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) #define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) -#define DPRC_CMDID_RESET_CONT DPRC_CMD(0x005) #define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) #define DPRC_CMDID_GET_IRQ DPRC_CMD(0x011) @@ -68,29 +66,13 @@ #define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016) #define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017) -#define DPRC_CMDID_CREATE_CONT DPRC_CMD(0x151) -#define DPRC_CMDID_DESTROY_CONT DPRC_CMD(0x152) #define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830) -#define DPRC_CMDID_SET_RES_QUOTA DPRC_CMD(0x155) -#define DPRC_CMDID_GET_RES_QUOTA DPRC_CMD(0x156) -#define DPRC_CMDID_ASSIGN DPRC_CMD(0x157) -#define DPRC_CMDID_UNASSIGN DPRC_CMD(0x158) #define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159) #define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A) #define DPRC_CMDID_GET_RES_COUNT DPRC_CMD(0x15B) -#define DPRC_CMDID_GET_RES_IDS DPRC_CMD(0x15C) #define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E) #define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) #define DPRC_CMDID_GET_OBJ_IRQ DPRC_CMD(0x160) -#define DPRC_CMDID_SET_OBJ_LABEL DPRC_CMD(0x161) -#define DPRC_CMDID_GET_OBJ_DESC DPRC_CMD(0x162) - -#define DPRC_CMDID_CONNECT DPRC_CMD(0x167) -#define DPRC_CMDID_DISCONNECT DPRC_CMD(0x168) -#define DPRC_CMDID_GET_POOL DPRC_CMD(0x169) -#define DPRC_CMDID_GET_POOL_COUNT DPRC_CMD(0x16A) - -#define DPRC_CMDID_GET_CONNECTION DPRC_CMD(0x16C) struct dprc_cmd_open { __le32 container_id; diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index 4e416d89b736..e4b0341d42d7 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -188,6 +188,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev); if (child_dev) { check_plugged_state_change(child_dev, obj_desc); + put_device(&child_dev->dev); continue; } diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c index 572edd4c066e..fcf7b4767dc0 100644 --- a/drivers/staging/fsl-mc/bus/dprc.c +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -100,133 +100,6 @@ int dprc_close(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_close); /** - * dprc_create_container() - Create child container - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @cfg: Child container configuration - * @child_container_id: Returned child container ID - * @child_portal_offset: Returned child portal offset from MC portal base - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_create_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dprc_cfg *cfg, - int *child_container_id, - u64 *child_portal_offset) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_create_container *cmd_params; - struct dprc_rsp_create_container *rsp_params; - int err; - - /* prepare command */ - cmd_params = (struct dprc_cmd_create_container *)cmd.params; - cmd_params->options = cpu_to_le32(cfg->options); - cmd_params->icid = cpu_to_le16(cfg->icid); - cmd_params->portal_id = cpu_to_le32(cfg->portal_id); - strncpy(cmd_params->label, cfg->label, 16); - cmd_params->label[15] = '\0'; - - cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT, - cmd_flags, token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_create_container *)cmd.params; - *child_container_id = le32_to_cpu(rsp_params->child_container_id); - *child_portal_offset = le64_to_cpu(rsp_params->child_portal_addr); - - return 0; -} - -/** - * dprc_destroy_container() - Destroy child container. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @child_container_id: ID of the container to destroy - * - * This function terminates the child container, so following this call the - * child container ID becomes invalid. - * - * Notes: - * - All resources and objects of the destroyed container are returned to the - * parent container or destroyed if were created be the destroyed container. - * - This function destroy all the child containers of the specified - * container prior to destroying the container itself. - * - * warning: Only the parent container is allowed to destroy a child policy - * Container 0 can't be destroyed - * - * Return: '0' on Success; Error code otherwise. - * - */ -int dprc_destroy_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_destroy_container *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT, - cmd_flags, token); - cmd_params = (struct dprc_cmd_destroy_container *)cmd.params; - cmd_params->child_container_id = cpu_to_le32(child_container_id); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_reset_container - Reset child container. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @child_container_id: ID of the container to reset - * - * In case a software context crashes or becomes non-responsive, the parent - * may wish to reset its resources container before the software context is - * restarted. - * - * This routine informs all objects assigned to the child container that the - * container is being reset, so they may perform any cleanup operations that are - * needed. All objects handles that were owned by the child container shall be - * closed. - * - * Note that such request may be submitted even if the child software context - * has not crashed, but the resulting object cleanup operations will not be - * aware of that. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_reset_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_reset_container *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, - cmd_flags, token); - cmd_params = (struct dprc_cmd_reset_container *)cmd.params; - cmd_params->child_container_id = cpu_to_le32(child_container_id); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** * dprc_get_irq() - Get IRQ information from the DPRC. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -570,277 +443,6 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, } /** - * dprc_set_res_quota() - Set allocation policy for a specific resource/object - * type in a child container - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @child_container_id: ID of the child container - * @type: Resource/object type - * @quota: Sets the maximum number of resources of the selected type - * that the child container is allowed to allocate from its parent; - * when quota is set to -1, the policy is the same as container's - * general policy. - * - * Allocation policy determines whether or not a container may allocate - * resources from its parent. Each container has a 'global' allocation policy - * that is set when the container is created. - * - * This function sets allocation policy for a specific resource type. - * The default policy for all resource types matches the container's 'global' - * allocation policy. - * - * Return: '0' on Success; Error code otherwise. - * - * @warning Only the parent container is allowed to change a child policy. - */ -int dprc_set_res_quota(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - char *type, - u16 quota) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_set_res_quota *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA, - cmd_flags, token); - cmd_params = (struct dprc_cmd_set_res_quota *)cmd.params; - cmd_params->child_container_id = cpu_to_le32(child_container_id); - cmd_params->quota = cpu_to_le16(quota); - strncpy(cmd_params->type, type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_get_res_quota() - Gets the allocation policy of a specific - * resource/object type in a child container - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @child_container_id; ID of the child container - * @type: resource/object type - * @quota: Returnes the maximum number of resources of the selected type - * that the child container is allowed to allocate from the parent; - * when quota is set to -1, the policy is the same as container's - * general policy. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_res_quota(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - char *type, - u16 *quota) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_res_quota *cmd_params; - struct dprc_rsp_get_res_quota *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA, - cmd_flags, token); - cmd_params = (struct dprc_cmd_get_res_quota *)cmd.params; - cmd_params->child_container_id = cpu_to_le32(child_container_id); - strncpy(cmd_params->type, type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_res_quota *)cmd.params; - *quota = le16_to_cpu(rsp_params->quota); - - return 0; -} - -/** - * dprc_assign() - Assigns objects or resource to a child container. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @container_id: ID of the child container - * @res_req: Describes the type and amount of resources to - * assign to the given container - * - * Assignment is usually done by a parent (this DPRC) to one of its child - * containers. - * - * According to the DPRC allocation policy, the assigned resources may be taken - * (allocated) from the container's ancestors, if not enough resources are - * available in the container itself. - * - * The type of assignment depends on the dprc_res_req options, as follows: - * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have - * the explicit base ID specified at the id_base_align field of res_req. - * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be - * aligned to the value given at id_base_align field of res_req. - * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment, - * and indicates that the object must be set to the plugged state. - * - * A container may use this function with its own ID in order to change a - * object state to plugged or unplugged. - * - * If IRQ information has been set in the child DPRC, it will signal an - * interrupt following every change in its object assignment. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_assign(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int container_id, - struct dprc_res_req *res_req) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_assign *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN, - cmd_flags, token); - cmd_params = (struct dprc_cmd_assign *)cmd.params; - cmd_params->container_id = cpu_to_le32(container_id); - cmd_params->options = cpu_to_le32(res_req->options); - cmd_params->num = cpu_to_le32(res_req->num); - cmd_params->id_base_align = cpu_to_le32(res_req->id_base_align); - strncpy(cmd_params->type, res_req->type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_unassign() - Un-assigns objects or resources from a child container - * and moves them into this (parent) DPRC. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @child_container_id: ID of the child container - * @res_req: Describes the type and amount of resources to un-assign from - * the child container - * - * Un-assignment of objects can succeed only if the object is not in the - * plugged or opened state. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_unassign(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - struct dprc_res_req *res_req) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_unassign *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_unassign *)cmd.params; - cmd_params->child_container_id = cpu_to_le32(child_container_id); - cmd_params->options = cpu_to_le32(res_req->options); - cmd_params->num = cpu_to_le32(res_req->num); - cmd_params->id_base_align = cpu_to_le32(res_req->id_base_align); - strncpy(cmd_params->type, res_req->type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_get_pool_count() - Get the number of dprc's pools - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @pool_count: Returned number of resource pools in the dprc - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_pool_count(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int *pool_count) -{ - struct mc_command cmd = { 0 }; - struct dprc_rsp_get_pool_count *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT, - cmd_flags, token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_pool_count *)cmd.params; - *pool_count = le32_to_cpu(rsp_params->pool_count); - - return 0; -} - -/** - * dprc_get_pool() - Get the type (string) of a certain dprc's pool - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @pool_index; Index of the pool to be queried (< pool_count) - * @type: The type of the pool - * - * The pool types retrieved one by one by incrementing - * pool_index up to (not including) the value of pool_count returned - * from dprc_get_pool_count(). dprc_get_pool_count() must - * be called prior to dprc_get_pool(). - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_pool(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int pool_index, - char *type) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_pool *cmd_params; - struct dprc_rsp_get_pool *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_get_pool *)cmd.params; - cmd_params->pool_index = cpu_to_le32(pool_index); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_pool *)cmd.params; - strncpy(type, rsp_params->type, 16); - type[15] = '\0'; - - return 0; -} - -/** * dprc_get_obj_count() - Obtains the number of objects in the DPRC * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -932,64 +534,6 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_get_obj); /** - * dprc_get_obj_desc() - Get object descriptor. - * - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @obj_type: The type of the object to get its descriptor. - * @obj_id: The id of the object to get its descriptor - * @obj_desc: The returned descriptor to fill and return to the user - * - * Return: '0' on Success; Error code otherwise. - * - */ -int dprc_get_obj_desc(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - struct dprc_obj_desc *obj_desc) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_obj_desc *cmd_params; - struct dprc_rsp_get_obj_desc *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_DESC, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_get_obj_desc *)cmd.params; - cmd_params->obj_id = cpu_to_le32(obj_id); - strncpy(cmd_params->type, obj_type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_obj_desc *)cmd.params; - obj_desc->id = le32_to_cpu(rsp_params->id); - obj_desc->vendor = le16_to_cpu(rsp_params->vendor); - obj_desc->irq_count = rsp_params->irq_count; - obj_desc->region_count = rsp_params->region_count; - obj_desc->state = le32_to_cpu(rsp_params->state); - obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); - obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); - obj_desc->flags = le16_to_cpu(rsp_params->flags); - strncpy(obj_desc->type, rsp_params->type, 16); - obj_desc->type[15] = '\0'; - strncpy(obj_desc->label, rsp_params->label, 16); - obj_desc->label[15] = '\0'; - - return 0; -} -EXPORT_SYMBOL(dprc_get_obj_desc); - -/** * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -1128,52 +672,6 @@ int dprc_get_res_count(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_get_res_count); /** - * dprc_get_res_ids() - Obtains IDs of free resources in the container - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @type: pool type - * @range_desc: range descriptor - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_res_ids(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *type, - struct dprc_res_ids_range_desc *range_desc) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_res_ids *cmd_params; - struct dprc_rsp_get_res_ids *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS, - cmd_flags, token); - cmd_params = (struct dprc_cmd_get_res_ids *)cmd.params; - cmd_params->iter_status = range_desc->iter_status; - cmd_params->base_id = cpu_to_le32(range_desc->base_id); - cmd_params->last_id = cpu_to_le32(range_desc->last_id); - strncpy(cmd_params->type, type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_res_ids *)cmd.params; - range_desc->iter_status = rsp_params->iter_status; - range_desc->base_id = le32_to_cpu(rsp_params->base_id); - range_desc->last_id = le32_to_cpu(rsp_params->last_id); - - return 0; -} -EXPORT_SYMBOL(dprc_get_res_ids); - -/** * dprc_get_obj_region() - Get region information for a specified object. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -1222,170 +720,6 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_get_obj_region); /** - * dprc_set_obj_label() - Set object label. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @obj_type: Object's type - * @obj_id: Object's ID - * @label: The required label. The maximum length is 16 chars. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_set_obj_label(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - char *label) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_set_obj_label *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_LABEL, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_set_obj_label *)cmd.params; - cmd_params->obj_id = cpu_to_le32(obj_id); - strncpy(cmd_params->label, label, 16); - cmd_params->label[15] = '\0'; - strncpy(cmd_params->obj_type, obj_type, 16); - cmd_params->obj_type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} -EXPORT_SYMBOL(dprc_set_obj_label); - -/** - * dprc_connect() - Connect two endpoints to create a network link between them - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @endpoint1: Endpoint 1 configuration parameters - * @endpoint2: Endpoint 2 configuration parameters - * @cfg: Connection configuration. The connection configuration is ignored for - * connections made to DPMAC objects, where rate is retrieved from the - * MAC configuration. - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_connect(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint1, - const struct dprc_endpoint *endpoint2, - const struct dprc_connection_cfg *cfg) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_connect *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_connect *)cmd.params; - cmd_params->ep1_id = cpu_to_le32(endpoint1->id); - cmd_params->ep1_interface_id = cpu_to_le32(endpoint1->if_id); - cmd_params->ep2_id = cpu_to_le32(endpoint2->id); - cmd_params->ep2_interface_id = cpu_to_le32(endpoint2->if_id); - strncpy(cmd_params->ep1_type, endpoint1->type, 16); - cmd_params->ep1_type[15] = '\0'; - cmd_params->max_rate = cpu_to_le32(cfg->max_rate); - cmd_params->committed_rate = cpu_to_le32(cfg->committed_rate); - strncpy(cmd_params->ep2_type, endpoint2->type, 16); - cmd_params->ep2_type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_disconnect() - Disconnect one endpoint to remove its network connection - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @endpoint: Endpoint configuration parameters - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_disconnect(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_disconnect *cmd_params; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_disconnect *)cmd.params; - cmd_params->id = cpu_to_le32(endpoint->id); - cmd_params->interface_id = cpu_to_le32(endpoint->if_id); - strncpy(cmd_params->type, endpoint->type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -/** - * dprc_get_connection() - Get connected endpoint and link status if connection - * exists. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @endpoint1: Endpoint 1 configuration parameters - * @endpoint2: Returned endpoint 2 configuration parameters - * @state: Returned link state: - * 1 - link is up; - * 0 - link is down; - * -1 - no connection (endpoint2 information is irrelevant) - * - * Return: '0' on Success; -ENAVAIL if connection does not exist. - */ -int dprc_get_connection(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint1, - struct dprc_endpoint *endpoint2, - int *state) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_connection *cmd_params; - struct dprc_rsp_get_connection *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_get_connection *)cmd.params; - cmd_params->ep1_id = cpu_to_le32(endpoint1->id); - cmd_params->ep1_interface_id = cpu_to_le32(endpoint1->if_id); - strncpy(cmd_params->ep1_type, endpoint1->type, 16); - cmd_params->ep1_type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_connection *)cmd.params; - endpoint2->id = le32_to_cpu(rsp_params->ep2_id); - endpoint2->if_id = le32_to_cpu(rsp_params->ep2_interface_id); - strncpy(endpoint2->type, rsp_params->ep2_type, 16); - endpoint2->type[15] = '\0'; - *state = le32_to_cpu(rsp_params->state); - - return 0; -} - -/** * dprc_get_api_version - Get Data Path Resource Container API version * @mc_io: Pointer to Mc portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c index 5ac373c0c716..47acb0a29842 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c @@ -27,8 +27,6 @@ #include "fsl-mc-private.h" #include "dprc-cmd.h" -static struct kmem_cache *mc_dev_cache; - /** * Default DMA mask for devices on a fsl-mc bus */ @@ -77,9 +75,6 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv); bool found = false; - if (WARN_ON(!fsl_mc_bus_exists())) - goto out; - if (!mc_drv->match_id_table) goto out; @@ -149,8 +144,6 @@ struct bus_type fsl_mc_bus_type = { }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); -static atomic_t root_dprc_count = ATOMIC_INIT(0); - static int fsl_mc_driver_probe(struct device *dev) { struct fsl_mc_driver *mc_drv; @@ -246,15 +239,6 @@ void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver) EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister); /** - * fsl_mc_bus_exists - check if a root dprc exists - */ -bool fsl_mc_bus_exists(void) -{ - return atomic_read(&root_dprc_count) > 0; -} -EXPORT_SYMBOL_GPL(fsl_mc_bus_exists); - -/** * fsl_mc_get_root_dprc - function to traverse to the root dprc */ void fsl_mc_get_root_dprc(struct device *dev, @@ -433,6 +417,22 @@ bool fsl_mc_is_root_dprc(struct device *dev) return dev == root_dprc_dev; } +static void fsl_mc_device_release(struct device *dev) +{ + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + struct fsl_mc_bus *mc_bus = NULL; + + kfree(mc_dev->regions); + + if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) + mc_bus = to_fsl_mc_bus(mc_dev); + + if (mc_bus) + kfree(mc_bus); + else + kfree(mc_dev); +} + /** * Add a newly discovered fsl-mc device to be visible in Linux */ @@ -455,7 +455,7 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, /* * Allocate an MC bus device object: */ - mc_bus = devm_kzalloc(parent_dev, sizeof(*mc_bus), GFP_KERNEL); + mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL); if (!mc_bus) return -ENOMEM; @@ -464,7 +464,7 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, /* * Allocate a regular fsl_mc_device object: */ - mc_dev = kmem_cache_zalloc(mc_dev_cache, GFP_KERNEL); + mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL); if (!mc_dev) return -ENOMEM; } @@ -474,6 +474,7 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, device_initialize(&mc_dev->dev); mc_dev->dev.parent = parent_dev; mc_dev->dev.bus = &fsl_mc_bus_type; + mc_dev->dev.release = fsl_mc_device_release; dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id); if (strcmp(obj_desc->type, "dprc") == 0) { @@ -506,8 +507,6 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, } mc_io2 = mc_io; - - atomic_inc(&root_dprc_count); } error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); @@ -553,7 +552,6 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, goto error_cleanup_dev; } - (void)get_device(&mc_dev->dev); dev_dbg(parent_dev, "added %s\n", dev_name(&mc_dev->dev)); *new_mc_dev = mc_dev; @@ -562,9 +560,9 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, error_cleanup_dev: kfree(mc_dev->regions); if (mc_bus) - devm_kfree(parent_dev, mc_bus); + kfree(mc_bus); else - kmem_cache_free(mc_dev_cache, mc_dev); + kfree(mc_dev); return error; } @@ -578,31 +576,11 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add); */ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) { - struct fsl_mc_bus *mc_bus = NULL; - - kfree(mc_dev->regions); - /* * The device-specific remove callback will get invoked by device_del() */ device_del(&mc_dev->dev); put_device(&mc_dev->dev); - - if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) { - mc_bus = to_fsl_mc_bus(mc_dev); - - if (fsl_mc_is_root_dprc(&mc_dev->dev)) { - if (atomic_read(&root_dprc_count) > 0) - atomic_dec(&root_dprc_count); - else - WARN_ON(1); - } - } - - if (mc_bus) - devm_kfree(mc_dev->dev.parent, mc_bus); - else - kmem_cache_free(mc_dev_cache, mc_dev); } EXPORT_SYMBOL_GPL(fsl_mc_device_remove); @@ -774,7 +752,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) error = dprc_get_container_id(mc_io, 0, &container_id); if (error < 0) { dev_err(&pdev->dev, - "dpmng_get_container_id() failed: %d\n", error); + "dprc_get_container_id() failed: %d\n", error); goto error_cleanup_mc_io; } @@ -843,14 +821,6 @@ static int __init fsl_mc_bus_driver_init(void) { int error; - mc_dev_cache = kmem_cache_create("fsl_mc_device", - sizeof(struct fsl_mc_device), 0, 0, - NULL); - if (!mc_dev_cache) { - pr_err("Could not create fsl_mc_device cache\n"); - return -ENOMEM; - } - error = bus_register(&fsl_mc_bus_type); if (error < 0) { pr_err("bus type registration failed: %d\n", error); @@ -890,7 +860,6 @@ error_cleanup_bus: bus_unregister(&fsl_mc_bus_type); error_cleanup_cache: - kmem_cache_destroy(mc_dev_cache); return error; } postcore_initcall(fsl_mc_bus_driver_init); diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c index 7975c6e6fee3..b8b2c86e63d4 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c @@ -17,6 +17,7 @@ #include <linux/irqdomain.h> #include <linux/msi.h> #include "../include/mc-bus.h" +#include "fsl-mc-private.h" /* * Generate a unique ID identifying the interrupt (only used within the MSI diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c index 6b1cd574644f..87e44712b56c 100644 --- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c @@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/of_irq.h> #include "../include/mc-bus.h" +#include "fsl-mc-private.h" static struct irq_chip its_msi_irq_chip = { .name = "ITS-fMSI", @@ -51,7 +52,7 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); } -static struct msi_domain_ops its_fsl_mc_msi_ops = { +static struct msi_domain_ops its_fsl_mc_msi_ops __ro_after_init = { .msi_prepare = its_fsl_mc_msi_prepare, }; diff --git a/drivers/staging/fsl-mc/include/dpbp.h b/drivers/staging/fsl-mc/include/dpbp.h index bf34b1e0e730..e9e04ccea82b 100644 --- a/drivers/staging/fsl-mc/include/dpbp.h +++ b/drivers/staging/fsl-mc/include/dpbp.h @@ -49,25 +49,6 @@ int dpbp_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -/** - * struct dpbp_cfg - Structure representing DPBP configuration - * @options: place holder - */ -struct dpbp_cfg { - u32 options; -}; - -int dpbp_create(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - const struct dpbp_cfg *cfg, - u32 *obj_id); - -int dpbp_destroy(struct fsl_mc_io *mc_io, - u16 dprc_token, - u32 cmd_flags, - u32 obj_id); - int dpbp_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); @@ -86,67 +67,6 @@ int dpbp_reset(struct fsl_mc_io *mc_io, u16 token); /** - * struct dpbp_irq_cfg - IRQ configuration - * @addr: Address that must be written to signal a message-based interrupt - * @val: Value to write into irq_addr address - * @irq_num: A user defined number associated with this IRQ - */ -struct dpbp_irq_cfg { - u64 addr; - u32 val; - int irq_num; -}; - -int dpbp_set_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - struct dpbp_irq_cfg *irq_cfg); - -int dpbp_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dpbp_irq_cfg *irq_cfg); - -int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 en); - -int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en); - -int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 mask); - -int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask); - -int dpbp_get_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *status); - -int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 status); - -/** * struct dpbp_attr - Structure representing DPBP attributes * @id: DPBP object ID * @bpid: Hardware buffer pool ID; should be used as an argument in @@ -162,58 +82,9 @@ int dpbp_get_attributes(struct fsl_mc_io *mc_io, u16 token, struct dpbp_attr *attr); -/** - * DPBP notifications options - */ - -/** - * BPSCN write will attempt to allocate into a cache (coherent write) - */ -#define DPBP_NOTIF_OPT_COHERENT_WRITE 0x00000001 - -/** - * struct dpbp_notification_cfg - Structure representing DPBP notifications - * towards software - * @depletion_entry: below this threshold the pool is "depleted"; - * set it to '0' to disable it - * @depletion_exit: greater than or equal to this threshold the pool exit its - * "depleted" state - * @surplus_entry: above this threshold the pool is in "surplus" state; - * set it to '0' to disable it - * @surplus_exit: less than or equal to this threshold the pool exit its - * "surplus" state - * @message_iova: MUST be given if either 'depletion_entry' or 'surplus_entry' - * is not '0' (enable); I/O virtual address (must be in DMA-able memory), - * must be 16B aligned. - * @message_ctx: The context that will be part of the BPSCN message and will - * be written to 'message_iova' - * @options: Mask of available options; use 'DPBP_NOTIF_OPT_<X>' values - */ -struct dpbp_notification_cfg { - u32 depletion_entry; - u32 depletion_exit; - u32 surplus_entry; - u32 surplus_exit; - u64 message_iova; - u64 message_ctx; - u16 options; -}; - -int dpbp_set_notifications(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpbp_notification_cfg *cfg); - -int dpbp_get_notifications(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dpbp_notification_cfg *cfg); - int dpbp_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 *major_ver, u16 *minor_ver); -/** @} */ - #endif /* __FSL_DPBP_H */ diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h index 7d8e255da578..170c07dd376a 100644 --- a/drivers/staging/fsl-mc/include/dpmng.h +++ b/drivers/staging/fsl-mc/include/dpmng.h @@ -64,8 +64,4 @@ int mc_get_version(struct fsl_mc_io *mc_io, u32 cmd_flags, struct mc_version *mc_ver_info); -int dpmng_get_container_id(struct fsl_mc_io *mc_io, - u32 cmd_flags, - int *container_id); - #endif /* __FSL_DPMNG_H */ diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h index f9ea769ccfab..dc985cc1246f 100644 --- a/drivers/staging/fsl-mc/include/dprc.h +++ b/drivers/staging/fsl-mc/include/dprc.h @@ -42,20 +42,6 @@ struct fsl_mc_io; -/** - * Set this value as the icid value in dprc_cfg structure when creating a - * container, in case the ICID is not selected by the user and should be - * allocated by the DPRC from the pool of ICIDs. - */ -#define DPRC_GET_ICID_FROM_POOL (u16)(~(0)) - -/** - * Set this value as the portal_id value in dprc_cfg structure when creating a - * container, in case the portal ID is not specifically selected by the - * user and should be allocated by the DPRC from the pool of portal ids. - */ -#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0)) - int dprc_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int container_id, @@ -65,79 +51,6 @@ int dprc_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -/** - * Container general options - * - * These options may be selected at container creation by the container creator - * and can be retrieved using dprc_get_attributes() - */ - -/* - * Spawn Policy Option allowed - Indicates that the new container is allowed - * to spawn and have its own child containers. - */ -#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001 - -/* - * General Container allocation policy - Indicates that the new container is - * allowed to allocate requested resources from its parent container; if not - * set, the container is only allowed to use resources in its own pools; Note - * that this is a container's global policy, but the parent container may - * override it and set specific quota per resource type. - */ -#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002 - -/* - * Object initialization allowed - software context associated with this - * container is allowed to invoke object initialization operations. - */ -#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 - -/* - * Topology change allowed - software context associated with this - * container is allowed to invoke topology operations, such as attach/detach - * of network objects. - */ -#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008 - -/* AIOP - Indicates that container belongs to AIOP. */ -#define DPRC_CFG_OPT_AIOP 0x00000020 - -/* IRQ Config - Indicates that the container allowed to configure its IRQs. */ -#define DPRC_CFG_OPT_IRQ_CFG_ALLOWED 0x00000040 - -/** - * struct dprc_cfg - Container configuration options - * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free - * ICID value is allocated by the DPRC - * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free - * portal ID is allocated by the DPRC - * @options: Combination of 'DPRC_CFG_OPT_<X>' options - * @label: Object's label - */ -struct dprc_cfg { - u16 icid; - int portal_id; - u64 options; - char label[16]; -}; - -int dprc_create_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dprc_cfg *cfg, - int *child_container_id, - u64 *child_portal_offset); - -int dprc_destroy_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id); - -int dprc_reset_container(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id); /* IRQ */ @@ -252,90 +165,6 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, u16 token, struct dprc_attributes *attributes); -int dprc_set_res_quota(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - char *type, - u16 quota); - -int dprc_get_res_quota(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - char *type, - u16 *quota); - -/* Resource request options */ - -/* - * Explicit resource ID request - The requested objects/resources - * are explicit and sequential (in case of resources). - * The base ID is given at res_req at base_align field - */ -#define DPRC_RES_REQ_OPT_EXPLICIT 0x00000001 - -/* - * Aligned resources request - Relevant only for resources - * request (and not objects). Indicates that resources base ID should be - * sequential and aligned to the value given at dprc_res_req base_align field - */ -#define DPRC_RES_REQ_OPT_ALIGNED 0x00000002 - -/* - * Plugged Flag - Relevant only for object assignment request. - * Indicates that after all objects assigned. An interrupt will be invoked at - * the relevant GPP. The assigned object will be marked as plugged. - * plugged objects can't be assigned from their container - */ -#define DPRC_RES_REQ_OPT_PLUGGED 0x00000004 - -/** - * struct dprc_res_req - Resource request descriptor, to be used in assignment - * or un-assignment of resources and objects. - * @type: Resource/object type: Represent as a NULL terminated string. - * This string may received by using dprc_get_pool() to get resource - * type and dprc_get_obj() to get object type; - * Note: it is not possible to assign/un-assign DPRC objects - * @num: Number of resources - * @options: Request options: combination of DPRC_RES_REQ_OPT_ options - * @id_base_align: In case of explicit assignment (DPRC_RES_REQ_OPT_EXPLICIT - * is set at option), this field represents the required base ID - * for resource allocation; In case of aligned assignment - * (DPRC_RES_REQ_OPT_ALIGNED is set at option), this field - * indicates the required alignment for the resource ID(s) - - * use 0 if there is no alignment or explicit ID requirements - */ -struct dprc_res_req { - char type[16]; - u32 num; - u32 options; - int id_base_align; -}; - -int dprc_assign(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int container_id, - struct dprc_res_req *res_req); - -int dprc_unassign(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int child_container_id, - struct dprc_res_req *res_req); - -int dprc_get_pool_count(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int *pool_count); - -int dprc_get_pool(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int pool_index, - char *type); - int dprc_get_obj_count(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, @@ -430,27 +259,6 @@ enum dprc_iter_status { DPRC_ITER_STATUS_LAST = 2 }; -/** - * struct dprc_res_ids_range_desc - Resource ID range descriptor - * @base_id: Base resource ID of this range - * @last_id: Last resource ID of this range - * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at - * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE, - * additional iterations are needed, until the returned marker is - * DPRC_ITER_STATUS_LAST - */ -struct dprc_res_ids_range_desc { - int base_id; - int last_id; - enum dprc_iter_status iter_status; -}; - -int dprc_get_res_ids(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *type, - struct dprc_res_ids_range_desc *range_desc); - /* Region flags */ /* Cacheable - Indicates that region should be mapped as cacheable */ #define DPRC_REGION_CACHEABLE 0x00000001 @@ -490,57 +298,6 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, u8 region_index, struct dprc_region_desc *region_desc); -int dprc_set_obj_label(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - char *label); - -/** - * struct dprc_endpoint - Endpoint description for link connect/disconnect - * operations - * @type: Endpoint object type: NULL terminated string - * @id: Endpoint object ID - * @if_id: Interface ID; should be set for endpoints with multiple - * interfaces ("dpsw", "dpdmux"); for others, always set to 0 - */ -struct dprc_endpoint { - char type[16]; - int id; - int if_id; -}; - -/** - * struct dprc_connection_cfg - Connection configuration. - * Used for virtual connections only - * @committed_rate: Committed rate (Mbits/s) - * @max_rate: Maximum rate (Mbits/s) - */ -struct dprc_connection_cfg { - u32 committed_rate; - u32 max_rate; -}; - -int dprc_connect(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint1, - const struct dprc_endpoint *endpoint2, - const struct dprc_connection_cfg *cfg); - -int dprc_disconnect(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint); - -int dprc_get_connection(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - const struct dprc_endpoint *endpoint1, - struct dprc_endpoint *endpoint2, - int *state); - int dprc_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 *major_ver, diff --git a/drivers/staging/gdm724x/gdm_endian.c b/drivers/staging/gdm724x/gdm_endian.c index d7144e7afa32..d0b43e20ec06 100644 --- a/drivers/staging/gdm724x/gdm_endian.c +++ b/drivers/staging/gdm724x/gdm_endian.c @@ -22,34 +22,34 @@ void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian) ed->dev_ed = ENDIANNESS_LITTLE; } -u16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x) +__dev16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x) { if (ed->dev_ed == ENDIANNESS_LITTLE) - return cpu_to_le16(x); + return (__force __dev16)cpu_to_le16(x); else - return cpu_to_be16(x); + return (__force __dev16)cpu_to_be16(x); } -u16 gdm_dev16_to_cpu(struct gdm_endian *ed, u16 x) +u16 gdm_dev16_to_cpu(struct gdm_endian *ed, __dev16 x) { if (ed->dev_ed == ENDIANNESS_LITTLE) - return le16_to_cpu(x); + return le16_to_cpu((__force __le16)x); else - return be16_to_cpu(x); + return be16_to_cpu((__force __be16)x); } -u32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x) +__dev32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x) { if (ed->dev_ed == ENDIANNESS_LITTLE) - return cpu_to_le32(x); + return (__force __dev32)cpu_to_le32(x); else - return cpu_to_be32(x); + return (__force __dev32)cpu_to_be32(x); } -u32 gdm_dev32_to_cpu(struct gdm_endian *ed, u32 x) +u32 gdm_dev32_to_cpu(struct gdm_endian *ed, __dev32 x) { if (ed->dev_ed == ENDIANNESS_LITTLE) - return le32_to_cpu(x); + return le32_to_cpu((__force __le32)x); else - return be32_to_cpu(x); + return be32_to_cpu((__force __be32)x); } diff --git a/drivers/staging/gdm724x/gdm_endian.h b/drivers/staging/gdm724x/gdm_endian.h index 6177870830e5..a785f30bb369 100644 --- a/drivers/staging/gdm724x/gdm_endian.h +++ b/drivers/staging/gdm724x/gdm_endian.h @@ -16,6 +16,13 @@ #include <linux/types.h> +/* + * For data in "device-endian" byte order (device endianness is model + * dependent). Analogous to __leXX or __beXX. + */ +typedef __u32 __bitwise __dev32; +typedef __u16 __bitwise __dev16; + enum { ENDIANNESS_MIN = 0, ENDIANNESS_UNKNOWN, @@ -30,9 +37,9 @@ struct gdm_endian { }; void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian); -u16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x); -u16 gdm_dev16_to_cpu(struct gdm_endian *ed, u16 x); -u32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x); -u32 gdm_dev32_to_cpu(struct gdm_endian *ed, u32 x); +__dev16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x); +u16 gdm_dev16_to_cpu(struct gdm_endian *ed, __dev16 x); +__dev32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x); +u32 gdm_dev32_to_cpu(struct gdm_endian *ed, __dev32 x); #endif /*__GDM_ENDIAN_H__*/ diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index e72dfa9699f3..a3e046c3f65c 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -198,7 +198,7 @@ static int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len) memset(&pseudo_header, 0, sizeof(pseudo_header)); memcpy(&pseudo_header.ph.ph_src, &ipv6->saddr.in6_u.u6_addr8, 16); memcpy(&pseudo_header.ph.ph_dst, &ipv6->daddr.in6_u.u6_addr8, 16); - pseudo_header.ph.ph_len = ipv6->payload_len; + pseudo_header.ph.ph_len = be16_to_cpu(ipv6->payload_len); pseudo_header.ph.ph_nxt = ipv6->nexthdr; w = (u16 *)&pseudo_header; @@ -560,13 +560,13 @@ void gdm_lte_event_exit(void) } } -static u8 find_dev_index(u32 nic_type) +static int find_dev_index(u32 nic_type) { u8 index; index = (u8)(nic_type & 0x0000000f); - if (index > MAX_NIC_TYPE) - index = 0; + if (index >= MAX_NIC_TYPE) + return -EINVAL; return index; } @@ -688,28 +688,24 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) struct net_device *dev; struct multi_sdu *multi_sdu = (struct multi_sdu *)buf; struct sdu *sdu = NULL; + struct gdm_endian *endian = phy_dev->get_endian(phy_dev->priv_dev); u8 *data = (u8 *)multi_sdu->data; u16 i = 0; u16 num_packet; u16 hci_len; u16 cmd_evt; u32 nic_type; - u8 index; + int index; - hci_len = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev), - multi_sdu->len); - num_packet = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev), - multi_sdu->num_packet); + hci_len = gdm_dev16_to_cpu(endian, multi_sdu->len); + num_packet = gdm_dev16_to_cpu(endian, multi_sdu->num_packet); for (i = 0; i < num_packet; i++) { sdu = (struct sdu *)data; - cmd_evt = gdm_dev16_to_cpu(phy_dev-> - get_endian(phy_dev->priv_dev), sdu->cmd_evt); - hci_len = gdm_dev16_to_cpu(phy_dev-> - get_endian(phy_dev->priv_dev), sdu->len); - nic_type = gdm_dev32_to_cpu(phy_dev-> - get_endian(phy_dev->priv_dev), sdu->nic_type); + cmd_evt = gdm_dev16_to_cpu(endian, sdu->cmd_evt); + hci_len = gdm_dev16_to_cpu(endian, sdu->len); + nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type); if (cmd_evt != LTE_RX_SDU) { pr_err("rx sdu wrong hci %04x\n", cmd_evt); @@ -721,13 +717,13 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) } index = find_dev_index(nic_type); - if (index < MAX_NIC_TYPE) { - dev = phy_dev->dev[index]; - gdm_lte_netif_rx(dev, (char *)sdu->data, - (int)(hci_len - 12), nic_type); - } else { + if (index < 0) { pr_err("rx sdu invalid nic_type :%x\n", nic_type); + return; } + dev = phy_dev->dev[index]; + gdm_lte_netif_rx(dev, (char *)sdu->data, + (int)(hci_len - 12), nic_type); data += ((hci_len + 3) & 0xfffc) + HCI_HEADER_SIZE; } @@ -761,18 +757,18 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len) { struct hci_packet *hci = (struct hci_packet *)buf; struct hci_pdn_table_ind *pdn_table = (struct hci_pdn_table_ind *)buf; + struct gdm_endian *endian = phy_dev->get_endian(phy_dev->priv_dev); struct sdu *sdu; struct net_device *dev; int ret = 0; u16 cmd_evt; u32 nic_type; - u8 index; + int index; if (!len) return ret; - cmd_evt = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev), - hci->cmd_evt); + cmd_evt = gdm_dev16_to_cpu(endian, hci->cmd_evt); dev = phy_dev->dev[0]; if (!dev) @@ -781,9 +777,10 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len) switch (cmd_evt) { case LTE_RX_SDU: sdu = (struct sdu *)hci->data; - nic_type = gdm_dev32_to_cpu(phy_dev-> - get_endian(phy_dev->priv_dev), sdu->nic_type); + nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type); index = find_dev_index(nic_type); + if (index < 0) + return index; dev = phy_dev->dev[index]; gdm_lte_netif_rx(dev, hci->data, len, nic_type); break; @@ -797,10 +794,10 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len) break; case LTE_PDN_TABLE_IND: pdn_table = (struct hci_pdn_table_ind *)buf; - nic_type = gdm_dev32_to_cpu(phy_dev-> - get_endian(phy_dev->priv_dev), - pdn_table->nic_type); + nic_type = gdm_dev32_to_cpu(endian, pdn_table->nic_type); index = find_dev_index(nic_type); + if (index < 0) + return index; dev = phy_dev->dev[index]; gdm_lte_pdn_table(dev, buf, len); /* Fall through */ diff --git a/drivers/staging/gdm724x/hci_packet.h b/drivers/staging/gdm724x/hci_packet.h index 4644f84038c9..22ce8b9477b6 100644 --- a/drivers/staging/gdm724x/hci_packet.h +++ b/drivers/staging/gdm724x/hci_packet.h @@ -36,8 +36,8 @@ #define NIC_TYPE_F_VLAN 0x00100000 struct hci_packet { - u16 cmd_evt; - u16 len; + __dev16 cmd_evt; + __dev16 len; u8 data[0]; } __packed; @@ -48,45 +48,45 @@ struct tlv { } __packed; struct sdu_header { - u16 cmd_evt; - u16 len; - u32 dftEpsId; - u32 bearer_ID; - u32 nic_type; + __dev16 cmd_evt; + __dev16 len; + __dev32 dftEpsId; + __dev32 bearer_ID; + __dev32 nic_type; } __packed; struct sdu { - u16 cmd_evt; - u16 len; - u32 dft_eps_ID; - u32 bearer_ID; - u32 nic_type; + __dev16 cmd_evt; + __dev16 len; + __dev32 dft_eps_ID; + __dev32 bearer_ID; + __dev32 nic_type; u8 data[0]; } __packed; struct multi_sdu { - u16 cmd_evt; - u16 len; - u16 num_packet; - u16 reserved; + __dev16 cmd_evt; + __dev16 len; + __dev16 num_packet; + __dev16 reserved; u8 data[0]; } __packed; struct hci_pdn_table_ind { - u16 cmd_evt; - u16 len; + __dev16 cmd_evt; + __dev16 len; u8 activate; - u32 dft_eps_id; - u32 nic_type; + __dev32 dft_eps_id; + __dev32 nic_type; u8 pdn_type; u8 ipv4_addr[4]; u8 ipv6_intf_id[8]; } __packed; struct hci_connect_ind { - u16 cmd_evt; - u16 len; - u32 connect; + __dev16 cmd_evt; + __dev16 len; + __dev32 connect; } __packed; #endif /* _HCI_PACKET_H_ */ diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index f337b7b70782..b26b9a35bdd5 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -10,9 +10,7 @@ greybus-y := core.o \ control.o \ svc.o \ svc_watchdog.o \ - operation.o \ - timesync.o \ - timesync_platform.o + operation.o obj-$(CONFIG_GREYBUS) += greybus.o diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index 3fda0cd6bb42..02243b4fd898 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -168,7 +168,10 @@ static int standby_boot_seq(struct platform_device *pdev) if (apb->init_disabled) return 0; - /* Even if it is in OFF state, then we do not want to change the state */ + /* + * Even if it is in OFF state, + * then we do not want to change the state + */ if (apb->state == ARCHE_PLATFORM_STATE_STANDBY || apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; @@ -461,7 +464,7 @@ static int arche_apb_ctrl_remove(struct platform_device *pdev) return 0; } -static int arche_apb_ctrl_suspend(struct device *dev) +static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev) { /* * If timing profile permits, we may shutdown bridge @@ -475,7 +478,7 @@ static int arche_apb_ctrl_suspend(struct device *dev) return 0; } -static int arche_apb_ctrl_resume(struct device *dev) +static int __maybe_unused arche_apb_ctrl_resume(struct device *dev) { /* * Atleast for ES2 we have to meet the delay requirement between diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 338c2d3ee842..aac1145f1983 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -312,9 +312,11 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) if (arche_pdata->wake_detect_state == WD_STATE_IDLE) { arche_pdata->wake_detect_start = jiffies; /* - * In the begining, when wake/detect goes low (first time), we assume - * it is meant for coldboot and set the flag. If wake/detect line stays low - * beyond 30msec, then it is coldboot else fallback to standby boot. + * In the begining, when wake/detect goes low + * (first time), we assume it is meant for coldboot + * and set the flag. If wake/detect line stays low + * beyond 30msec, then it is coldboot else fallback + * to standby boot. */ arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_BOOT_INIT); @@ -330,7 +332,8 @@ exit: /* * Requires arche_pdata->platform_state_mutex to be held */ -static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) +static int +arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) { int ret; @@ -364,7 +367,8 @@ static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdat /* * Requires arche_pdata->platform_state_mutex to be held */ -static int arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) +static int +arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) { int ret; @@ -398,7 +402,8 @@ static int arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_p /* * Requires arche_pdata->platform_state_mutex to be held */ -static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) +static void +arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) { unsigned long flags; @@ -561,14 +566,17 @@ static int arche_platform_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; int ret; - arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), GFP_KERNEL); + arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), + GFP_KERNEL); if (!arche_pdata) return -ENOMEM; /* setup svc reset gpio */ arche_pdata->is_reset_act_hi = of_property_read_bool(np, "svc,reset-active-high"); - arche_pdata->svc_reset_gpio = of_get_named_gpio(np, "svc,reset-gpio", 0); + arche_pdata->svc_reset_gpio = of_get_named_gpio(np, + "svc,reset-gpio", + 0); if (arche_pdata->svc_reset_gpio < 0) { dev_err(dev, "failed to get reset-gpio\n"); return arche_pdata->svc_reset_gpio; @@ -610,7 +618,8 @@ static int arche_platform_probe(struct platform_device *pdev) dev_err(dev, "failed to get svc clock-req gpio\n"); return arche_pdata->svc_refclk_req; } - ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, "svc-clk-req"); + ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, + "svc-clk-req"); if (ret) { dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret); return ret; @@ -634,13 +643,16 @@ static int arche_platform_probe(struct platform_device *pdev) arche_pdata->num_apbs = of_get_child_count(np); dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); - arche_pdata->wake_detect_gpio = of_get_named_gpio(np, "svc,wake-detect-gpio", 0); + arche_pdata->wake_detect_gpio = of_get_named_gpio(np, + "svc,wake-detect-gpio", + 0); if (arche_pdata->wake_detect_gpio < 0) { dev_err(dev, "failed to get wake detect gpio\n"); return arche_pdata->wake_detect_gpio; } - ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, "wake detect"); + ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, + "wake detect"); if (ret) { dev_err(dev, "Failed requesting wake_detect gpio %d\n", arche_pdata->wake_detect_gpio); @@ -658,10 +670,11 @@ static int arche_platform_probe(struct platform_device *pdev) gpio_to_irq(arche_pdata->wake_detect_gpio); ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, - arche_platform_wd_irq, - arche_platform_wd_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - dev_name(dev), arche_pdata); + arche_platform_wd_irq, + arche_platform_wd_irq_thread, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + dev_name(dev), arche_pdata); if (ret) { dev_err(dev, "failed to request wake detect IRQ %d\n", ret); return ret; diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h index bd12345b82a2..c0591df9b9d6 100644 --- a/drivers/staging/greybus/arche_platform.h +++ b/drivers/staging/greybus/arche_platform.h @@ -10,8 +10,6 @@ #ifndef __ARCHE_PLATFORM_H #define __ARCHE_PLATFORM_H -#include "timesync.h" - enum arche_platform_state { ARCHE_PLATFORM_STATE_OFF, ARCHE_PLATFORM_STATE_ACTIVE, diff --git a/drivers/staging/greybus/arpc.h b/drivers/staging/greybus/arpc.h index 7fbddfc40d83..c0b63c0130c5 100644 --- a/drivers/staging/greybus/arpc.h +++ b/drivers/staging/greybus/arpc.h @@ -74,7 +74,6 @@ struct arpc_response_message { __u8 result; /* Result of RPC */ } __packed; - /* ARPC requests */ #define ARPC_TYPE_CPORT_CONNECTED 0x01 #define ARPC_TYPE_CPORT_QUIESCE 0x02 diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index f8862c6d7102..25c8bb4cb0de 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -496,6 +496,11 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream, gb_pm_runtime_put_noidle(bundle); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sig_bits = dai->driver->playback.sig_bits; + else + sig_bits = dai->driver->capture.sig_bits; + params->state = GBAUDIO_CODEC_HWPARAMS; params->format = format; params->rate = rate; @@ -689,6 +694,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .rate_min = 48000, .channels_min = 1, .channels_max = 2, + .sig_bits = 16, }, .capture = { .stream_name = "I2S 0 Capture", @@ -698,6 +704,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .rate_min = 48000, .channels_min = 1, .channels_max = 2, + .sig_bits = 16, }, .ops = &gbcodec_dai_ops, }, @@ -831,7 +838,10 @@ int gbaudio_register_module(struct gbaudio_module_info *module) snd_soc_dapm_link_component_dai_widgets(codec->card, &codec->dapm); #ifdef CONFIG_SND_JACK - /* register jack devices for this module from codec->jack_list */ + /* + * register jack devices for this module + * from codec->jack_list + */ list_for_each_entry(jack, &codec->jack_list, list) { if ((jack == &module->headset_jack) || (jack == &module->button_jack)) @@ -1019,47 +1029,16 @@ static int gbcodec_remove(struct snd_soc_codec *codec) return 0; } -static u8 gbcodec_reg[GBCODEC_REG_COUNT] = { - [GBCODEC_CTL_REG] = GBCODEC_CTL_REG_DEFAULT, - [GBCODEC_MUTE_REG] = GBCODEC_MUTE_REG_DEFAULT, - [GBCODEC_PB_LVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT, - [GBCODEC_PB_RVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT, - [GBCODEC_CAP_LVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT, - [GBCODEC_CAP_RVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT, - [GBCODEC_APB1_MUX_REG] = GBCODEC_APB1_MUX_REG_DEFAULT, - [GBCODEC_APB2_MUX_REG] = GBCODEC_APB2_MUX_REG_DEFAULT, -}; - static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - int ret = 0; - - if (reg == SND_SOC_NOPM) - return 0; - - BUG_ON(reg >= GBCODEC_REG_COUNT); - - gbcodec_reg[reg] = value; - dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, value); - - return ret; + return 0; } static unsigned int gbcodec_read(struct snd_soc_codec *codec, unsigned int reg) { - unsigned int val = 0; - - if (reg == SND_SOC_NOPM) - return 0; - - BUG_ON(reg >= GBCODEC_REG_COUNT); - - val = gbcodec_reg[reg]; - dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, val); - - return val; + return 0; } static struct snd_soc_codec_driver soc_codec_dev_gbaudio = { @@ -1069,10 +1048,6 @@ static struct snd_soc_codec_driver soc_codec_dev_gbaudio = { .read = gbcodec_read, .write = gbcodec_write, - .reg_cache_size = GBCODEC_REG_COUNT, - .reg_cache_default = gbcodec_reg_defaults, - .reg_word_size = 1, - .idle_bias_off = true, .ignore_pmdown_time = 1, }; diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h index 62fd93939a1f..6fb064c69a36 100644 --- a/drivers/staging/greybus/audio_codec.h +++ b/drivers/staging/greybus/audio_codec.h @@ -24,18 +24,6 @@ enum { NUM_CODEC_DAIS, }; -enum gbcodec_reg_index { - GBCODEC_CTL_REG, - GBCODEC_MUTE_REG, - GBCODEC_PB_LVOL_REG, - GBCODEC_PB_RVOL_REG, - GBCODEC_CAP_LVOL_REG, - GBCODEC_CAP_RVOL_REG, - GBCODEC_APB1_MUX_REG, - GBCODEC_APB2_MUX_REG, - GBCODEC_REG_COUNT -}; - /* device_type should be same as defined in audio.h (Android media layer) */ enum { GBAUDIO_DEVICE_NONE = 0x0, @@ -51,42 +39,9 @@ enum { GBAUDIO_DEVICE_IN_WIRED_HEADSET = GBAUDIO_DEVICE_BIT_IN | 0x10, }; -/* bit 0-SPK, 1-HP, 2-DAC, - * 4-MIC, 5-HSMIC, 6-MIC2 - */ -#define GBCODEC_CTL_REG_DEFAULT 0x00 - -/* bit 0,1 - APB1-PB-L/R - * bit 2,3 - APB2-PB-L/R - * bit 4,5 - APB1-Cap-L/R - * bit 6,7 - APB2-Cap-L/R - */ -#define GBCODEC_MUTE_REG_DEFAULT 0x00 - -/* 0-127 steps */ -#define GBCODEC_PB_VOL_REG_DEFAULT 0x00 -#define GBCODEC_CAP_VOL_REG_DEFAULT 0x00 - -/* bit 0,1,2 - PB stereo, left, right - * bit 8,9,10 - Cap stereo, left, right - */ -#define GBCODEC_APB1_MUX_REG_DEFAULT 0x00 -#define GBCODEC_APB2_MUX_REG_DEFAULT 0x00 - #define GBCODEC_JACK_MASK 0x0000FFFF #define GBCODEC_JACK_BUTTON_MASK 0xFFFF0000 -static const u8 gbcodec_reg_defaults[GBCODEC_REG_COUNT] = { - GBCODEC_CTL_REG_DEFAULT, - GBCODEC_MUTE_REG_DEFAULT, - GBCODEC_PB_VOL_REG_DEFAULT, - GBCODEC_PB_VOL_REG_DEFAULT, - GBCODEC_CAP_VOL_REG_DEFAULT, - GBCODEC_CAP_VOL_REG_DEFAULT, - GBCODEC_APB1_MUX_REG_DEFAULT, - GBCODEC_APB2_MUX_REG_DEFAULT, -}; - enum gbaudio_codec_state { GBAUDIO_CODEC_SHUTDOWN = 0, GBAUDIO_CODEC_STARTUP, @@ -116,7 +71,6 @@ struct gbaudio_codec_info { /* to maintain runtime stream params for each DAI */ struct list_head dai_list; struct mutex lock; - u8 reg[GBCODEC_REG_COUNT]; }; struct gbaudio_widget { diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c index 42f287dd7b84..7884d8482dc0 100644 --- a/drivers/staging/greybus/audio_gb.c +++ b/drivers/staging/greybus/audio_gb.c @@ -108,7 +108,7 @@ int gb_audio_gb_disable_widget(struct gb_connection *connection, EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget); int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport, - uint32_t *format, uint32_t *rate, u8 *channels, + u32 *format, u32 *rate, u8 *channels, u8 *sig_bits) { struct gb_audio_get_pcm_request req; @@ -132,7 +132,7 @@ int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport, EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm); int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport, - uint32_t format, uint32_t rate, u8 channels, + u32 format, u32 rate, u8 channels, u8 sig_bits) { struct gb_audio_set_pcm_request req; diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 17a9948b1ba1..094c3be79b33 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module, struct gb_audio_streaming_event_request *req) { dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n", - req->data_cport, req->event); + le16_to_cpu(req->data_cport), req->event); return 0; } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 8b216ca99cf9..07fac3948f3a 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, { const char **strings; int i; + unsigned int items; __u8 *data; - strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items, - GFP_KERNEL); + items = le32_to_cpu(gbenum->items); + strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL); data = gbenum->names; - for (i = 0; i < gbenum->items; i++) { + for (i = 0; i < items; i++) { strings[i] = (const char *)data; while (*data != '\0') data++; @@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: - uinfo->value.integer.min = info->value.integer.min; - uinfo->value.integer.max = info->value.integer.max; + uinfo->value.integer.min = le32_to_cpu(info->value.integer.min); + uinfo->value.integer.max = le32_to_cpu(info->value.integer.max); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: - max = info->value.enumerated.items; + max = le32_to_cpu(info->value.enumerated.items); uinfo->value.enumerated.items = max; if (uinfo->value.enumerated.item > max - 1) uinfo->value.enumerated.item = max - 1; @@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: ucontrol->value.integer.value[0] = - gbvalue.value.integer_value[0]; + le32_to_cpu(gbvalue.value.integer_value[0]); if (data->vcount == 2) ucontrol->value.integer.value[1] = - gbvalue.value.integer_value[1]; + le32_to_cpu(gbvalue.value.integer_value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: ucontrol->value.enumerated.item[0] = - gbvalue.value.enumerated_item[0]; + le32_to_cpu(gbvalue.value.enumerated_item[0]); if (data->vcount == 2) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); break; default: dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", @@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: gbvalue.value.integer_value[0] = - ucontrol->value.integer.value[0]; + cpu_to_le32(ucontrol->value.integer.value[0]); if (data->vcount == 2) gbvalue.value.integer_value[1] = - ucontrol->value.integer.value[1]; + cpu_to_le32(ucontrol->value.integer.value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: gbvalue.value.enumerated_item[0] = - ucontrol->value.enumerated.item[0]; + cpu_to_le32(ucontrol->value.enumerated.item[0]); if (data->vcount == 2) gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); break; default: dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", @@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol, info = (struct gb_audio_ctl_elem_info *)data->info; /* update uinfo */ - platform_max = info->value.integer.max; - platform_min = info->value.integer.min; + platform_max = le32_to_cpu(info->value.integer.max); + platform_min = le32_to_cpu(info->value.integer.min); if (platform_max == 1 && !strnstr(kcontrol->id.name, " Volume", NAME_SIZE)) @@ -371,12 +372,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = data->vcount; - uinfo->value.integer.min = 0; - if (info->value.integer.min < 0 && - (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER)) - uinfo->value.integer.max = platform_max - platform_min; - else - uinfo->value.integer.max = platform_max; + uinfo->value.integer.min = platform_min; + uinfo->value.integer.max = platform_max; return 0; } @@ -424,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, return ret; } /* update ucontrol */ - ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0]; + ucontrol->value.integer.value[0] = + le32_to_cpu(gbvalue.value.integer_value[0]); return ret; } @@ -458,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, "GB: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); - max = info->value.integer.max; + max = le32_to_cpu(info->value.integer.max); mask = (1 << fls(max)) - 1; val = ucontrol->value.integer.value[0] & mask; connect = !!val; @@ -474,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, connect); } gbvalue.value.integer_value[0] = - ucontrol->value.integer.value[0]; + cpu_to_le32(ucontrol->value.integer.value[0]); ret = gb_pm_runtime_get_sync(bundle); if (ret) @@ -588,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol, return ret; } - ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; + ucontrol->value.enumerated.item[0] = + le32_to_cpu(gbvalue.value.enumerated_item[0]); if (e->shift_l != e->shift_r) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); return 0; } @@ -617,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; - gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0]; + gbvalue.value.enumerated_item[0] = + cpu_to_le32(ucontrol->value.enumerated.item[0]); if (e->shift_l != e->shift_r) { if (ucontrol->value.enumerated.item[1] > e->max - 1) return -EINVAL; gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); } bundle = to_gb_bundle(module->dev); @@ -660,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated; /* since count=1, and reg is dummy */ - gbe->max = gb_enum->items; + gbe->max = le32_to_cpu(gb_enum->items); gbe->texts = gb_generate_enum_strings(gb, gb_enum); /* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); *kctl = (struct snd_kcontrol_new) @@ -695,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; ctldata->ctl_id = ctl->id; - ctldata->data_cport = ctl->data_cport; + ctldata->data_cport = le16_to_cpu(ctl->data_cport); ctldata->access = ctl->access; ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -869,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated; /* since count=1, and reg is dummy */ - gbe->max = gb_enum->items; + gbe->max = le32_to_cpu(gb_enum->items); gbe->texts = gb_generate_enum_strings(gb, gb_enum); /* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); *kctl = (struct snd_kcontrol_new) @@ -895,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; ctldata->ctl_id = ctl->id; - ctldata->data_cport = ctl->data_cport; + ctldata->data_cport = le16_to_cpu(ctl->data_cport); ctldata->access = ctl->access; ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -1041,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module, csize = offsetof(struct gb_audio_control, info); csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -1189,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module, csize = offsetof(struct gb_audio_control, info); csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -1312,7 +1312,7 @@ static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module, goto error; } dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink, - (dapm_routes->control) ? dapm_routes->control:"NULL", + (dapm_routes->control) ? dapm_routes->control : "NULL", dapm_routes->source); dapm_routes++; curr++; @@ -1335,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module, /* update block offset */ module->dai_offset = (unsigned long)&tplg_data->data; - module->control_offset = module->dai_offset + tplg_data->size_dais; + module->control_offset = module->dai_offset + + le32_to_cpu(tplg_data->size_dais); module->widget_offset = module->control_offset + - tplg_data->size_controls; + le32_to_cpu(tplg_data->size_controls); module->route_offset = module->widget_offset + - tplg_data->size_widgets; + le32_to_cpu(tplg_data->size_widgets); dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset); dev_dbg(module->dev, "control offset is %lx\n", @@ -1357,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, struct gb_audio_control *controls; struct gb_audio_widget *widgets; struct gb_audio_route *routes; + unsigned int jack_type; if (!tplg_data) return -EINVAL; @@ -1399,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, dev_dbg(module->dev, "Route parsing finished\n"); /* parse jack capabilities */ - if (tplg_data->jack_type) { - module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK; - module->button_mask = tplg_data->jack_type & - GBCODEC_JACK_BUTTON_MASK; + jack_type = le32_to_cpu(tplg_data->jack_type); + if (jack_type) { + module->jack_mask = jack_type & GBCODEC_JACK_MASK; + module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK; } return ret; diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index 168626ba0c03..6c5dcb1c226b 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -16,7 +16,6 @@ #include "greybus_authentication.h" #include "firmware.h" -#include "greybus.h" #define CAP_TIMEOUT_MS 1000 diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index 5f90721bcc51..06df0ce03150 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -53,7 +53,8 @@ static void free_firmware(struct gb_bootrom *bootrom) static void gb_bootrom_timedout(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork); + struct gb_bootrom *bootrom = container_of(dwork, + struct gb_bootrom, dwork); struct device *dev = &bootrom->connection->bundle->dev; const char *reason; @@ -187,7 +188,8 @@ static int find_firmware(struct gb_bootrom *bootrom, u8 stage) static int gb_bootrom_firmware_size_request(struct gb_operation *op) { struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); - struct gb_bootrom_firmware_size_request *size_request = op->request->payload; + struct gb_bootrom_firmware_size_request *size_request = + op->request->payload; struct gb_bootrom_firmware_size_response *size_response; struct device *dev = &op->connection->bundle->dev; int ret; @@ -220,7 +222,8 @@ static int gb_bootrom_firmware_size_request(struct gb_operation *op) size_response = op->response->payload; size_response->size = cpu_to_le32(bootrom->fw->size); - dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size); + dev_dbg(dev, "%s: firmware size %d bytes\n", + __func__, size_response->size); unlock: mutex_unlock(&bootrom->mutex); @@ -287,8 +290,8 @@ static int gb_bootrom_get_firmware(struct gb_operation *op) firmware_response = op->response->payload; memcpy(firmware_response->data, fw->data + offset, size); - dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset, - size); + dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", + offset, size); unlock: mutex_unlock(&bootrom->mutex); diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 0ee291ca2c72..a64517eabff4 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -1067,22 +1067,22 @@ struct gb_camera_debugfs_entry { static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = { { .name = "capabilities", - .mask = S_IFREG | S_IRUGO, + .mask = S_IFREG | 0444, .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES, .execute = gb_camera_debugfs_capabilities, }, { .name = "configure_streams", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS, .execute = gb_camera_debugfs_configure_streams, }, { .name = "capture", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE, .execute = gb_camera_debugfs_capture, }, { .name = "flush", - .mask = S_IFREG | S_IRUGO | S_IWUGO, + .mask = S_IFREG | 0666, .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH, .execute = gb_camera_debugfs_flush, }, @@ -1097,7 +1097,7 @@ static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf, ssize_t ret; /* For read-only entries the operation is triggered by a read. */ - if (!(op->mask & S_IWUGO)) { + if (!(op->mask & 0222)) { ret = op->execute(gcam, NULL, 0); if (ret < 0) return ret; diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 557075147f2d..1bf0ee403106 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -357,6 +357,9 @@ static int gb_connection_hd_cport_quiesce(struct gb_connection *connection) size_t peer_space; int ret; + if (!hd->driver->cport_quiesce) + return 0; + peer_space = sizeof(struct gb_operation_msg_hdr) + sizeof(struct gb_cport_shutdown_request); @@ -380,6 +383,9 @@ static int gb_connection_hd_cport_clear(struct gb_connection *connection) struct gb_host_device *hd = connection->hd; int ret; + if (!hd->driver->cport_clear) + return 0; + ret = hd->driver->cport_clear(hd, connection->hd_cport_id); if (ret) { dev_err(&hd->dev, "%s: failed to clear host cport: %d\n", diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index 4716190e740a..5b30be30a3a4 100644 --- a/drivers/staging/greybus/control.c +++ b/drivers/staging/greybus/control.c @@ -198,56 +198,6 @@ int gb_control_mode_switch_operation(struct gb_control *control) return ret; } -int gb_control_timesync_enable(struct gb_control *control, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk) -{ - struct gb_control_timesync_enable_request request; - - request.count = count; - request.frame_time = cpu_to_le64(frame_time); - request.strobe_delay = cpu_to_le32(strobe_delay); - request.refclk = cpu_to_le32(refclk); - return gb_operation_sync(control->connection, - GB_CONTROL_TYPE_TIMESYNC_ENABLE, &request, - sizeof(request), NULL, 0); -} - -int gb_control_timesync_disable(struct gb_control *control) -{ - return gb_operation_sync(control->connection, - GB_CONTROL_TYPE_TIMESYNC_DISABLE, NULL, 0, - NULL, 0); -} - -int gb_control_timesync_get_last_event(struct gb_control *control, - u64 *frame_time) -{ - struct gb_control_timesync_get_last_event_response response; - int ret; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT, - NULL, 0, &response, sizeof(response)); - if (!ret) - *frame_time = le64_to_cpu(response.frame_time); - return ret; -} - -int gb_control_timesync_authoritative(struct gb_control *control, - u64 *frame_time) -{ - struct gb_control_timesync_authoritative_request request; - int i; - - for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++) - request.frame_time[i] = cpu_to_le64(frame_time[i]); - - return gb_operation_sync(control->connection, - GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE, - &request, sizeof(request), - NULL, 0); -} - static int gb_control_bundle_pm_status_map(u8 status) { switch (status) { diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h index f9a60daf9a72..4dcaec8b9cfe 100644 --- a/drivers/staging/greybus/control.h +++ b/drivers/staging/greybus/control.h @@ -48,13 +48,6 @@ void gb_control_mode_switch_complete(struct gb_control *control); int gb_control_get_manifest_size_operation(struct gb_interface *intf); int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest, size_t size); -int gb_control_timesync_enable(struct gb_control *control, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk); -int gb_control_timesync_disable(struct gb_control *control); -int gb_control_timesync_get_last_event(struct gb_control *control, - u64 *frame_time); -int gb_control_timesync_authoritative(struct gb_control *control, - u64 *frame_time); int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id); int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id); int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id); diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 1049e9c0edb0..ba761905b790 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -218,8 +218,6 @@ static int greybus_probe(struct device *dev) return retval; } - gb_timesync_schedule_synchronous(bundle->intf); - pm_runtime_put(&bundle->intf->dev); return 0; @@ -326,16 +324,8 @@ static int __init gb_init(void) pr_err("gb_operation_init failed (%d)\n", retval); goto error_operation; } - - retval = gb_timesync_init(); - if (retval) { - pr_err("gb_timesync_init failed\n"); - goto error_timesync; - } return 0; /* Success */ -error_timesync: - gb_operation_exit(); error_operation: gb_hd_exit(); error_hd: @@ -349,7 +339,6 @@ module_init(gb_init); static void __exit gb_exit(void) { - gb_timesync_exit(); gb_operation_exit(); gb_hd_exit(); bus_unregister(&greybus_bus_type); diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c index c1929dfa9b31..f7b24e0eaa6f 100644 --- a/drivers/staging/greybus/es2.c +++ b/drivers/staging/greybus/es2.c @@ -127,29 +127,6 @@ struct es2_ap_dev { struct list_head arpcs; }; -/** - * timesync_enable_request - Enable timesync in an APBridge - * @count: number of TimeSync Pulses to expect - * @frame_time: the initial FrameTime at the first TimeSync Pulse - * @strobe_delay: the expected delay in microseconds between each TimeSync Pulse - * @refclk: The AP mandated reference clock to run FrameTime at - */ -struct timesync_enable_request { - __u8 count; - __le64 frame_time; - __le32 strobe_delay; - __le32 refclk; -} __packed; - -/** - * timesync_authoritative_request - Transmit authoritative FrameTime to APBridge - * @frame_time: An array of authoritative FrameTimes provided by the SVC - * and relayed to the APBridge by the AP - */ -struct timesync_authoritative_request { - __le64 frame_time[GB_TIMESYNC_MAX_STROBES]; -} __packed; - struct arpc { struct list_head list; struct arpc_request_message *req; @@ -754,111 +731,6 @@ static int latency_tag_disable(struct gb_host_device *hd, u16 cport_id) return retval; } -static int timesync_enable(struct gb_host_device *hd, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk) -{ - int retval; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - struct gb_control_timesync_enable_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (!request) - return -ENOMEM; - - request->count = count; - request->frame_time = cpu_to_le64(frame_time); - request->strobe_delay = cpu_to_le32(strobe_delay); - request->refclk = cpu_to_le32(refclk); - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_TIMESYNC_ENABLE, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, 0, 0, request, - sizeof(*request), ES2_USB_CTRL_TIMEOUT); - if (retval < 0) - dev_err(&udev->dev, "Cannot enable timesync %d\n", retval); - - kfree(request); - return retval; -} - -static int timesync_disable(struct gb_host_device *hd) -{ - int retval; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_TIMESYNC_DISABLE, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, 0, 0, NULL, - 0, ES2_USB_CTRL_TIMEOUT); - if (retval < 0) - dev_err(&udev->dev, "Cannot disable timesync %d\n", retval); - - return retval; -} - -static int timesync_authoritative(struct gb_host_device *hd, u64 *frame_time) -{ - int retval, i; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - struct timesync_authoritative_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (!request) - return -ENOMEM; - - for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++) - request->frame_time[i] = cpu_to_le64(frame_time[i]); - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, 0, 0, request, - sizeof(*request), ES2_USB_CTRL_TIMEOUT); - if (retval < 0) - dev_err(&udev->dev, "Cannot timesync authoritative out %d\n", retval); - - kfree(request); - return retval; -} - -static int timesync_get_last_event(struct gb_host_device *hd, u64 *frame_time) -{ - int retval; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - __le64 *response_frame_time; - - response_frame_time = kzalloc(sizeof(*response_frame_time), GFP_KERNEL); - if (!response_frame_time) - return -ENOMEM; - - retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, 0, 0, response_frame_time, - sizeof(*response_frame_time), - ES2_USB_CTRL_TIMEOUT); - - if (retval != sizeof(*response_frame_time)) { - dev_err(&udev->dev, "Cannot get last TimeSync event: %d\n", - retval); - - if (retval >= 0) - retval = -EIO; - - goto out; - } - *frame_time = le64_to_cpu(*response_frame_time); - retval = 0; -out: - kfree(response_frame_time); - return retval; -} - static struct gb_hd_driver es2_driver = { .hd_priv_size = sizeof(struct es2_ap_dev), .message_send = message_send, @@ -874,10 +746,6 @@ static struct gb_hd_driver es2_driver = { .latency_tag_enable = latency_tag_enable, .latency_tag_disable = latency_tag_disable, .output = output, - .timesync_enable = timesync_enable, - .timesync_disable = timesync_disable, - .timesync_authoritative = timesync_authoritative, - .timesync_get_last_event = timesync_get_last_event, }; /* Common function to report consistent warnings based on URB status */ @@ -1217,7 +1085,8 @@ static void apb_log_get(struct es2_ap_dev *es2, char *buf) retval = usb_control_msg(es2->usb_dev, usb_rcvctrlpipe(es2->usb_dev, 0), GB_APB_REQUEST_LOG, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_INTERFACE, 0x00, 0x00, buf, APB1_LOG_MSG_SIZE, @@ -1283,7 +1152,7 @@ static void usb_log_enable(struct es2_ap_dev *es2) if (IS_ERR(es2->apb_log_task)) return; /* XXX We will need to rename this per APB */ - es2->apb_log_dentry = debugfs_create_file("apb_log", S_IRUGO, + es2->apb_log_dentry = debugfs_create_file("apb_log", 0444, gb_debugfs_get(), es2, &apb_log_fops); } @@ -1540,7 +1409,7 @@ static int ap_probe(struct usb_interface *interface, /* XXX We will need to rename this per APB */ es2->apb_log_enable_dentry = debugfs_create_file("apb_log_enable", - (S_IWUSR | S_IRUGO), + 0644, gb_debugfs_get(), es2, &apb_log_enable_fops); diff --git a/drivers/staging/greybus/fw-download.c b/drivers/staging/greybus/fw-download.c index 2d7246887547..8a1a413c6cb3 100644 --- a/drivers/staging/greybus/fw-download.c +++ b/drivers/staging/greybus/fw-download.c @@ -130,7 +130,8 @@ static void free_firmware(struct fw_download *fw_download, static void fw_request_timedout(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct fw_request *fw_req = container_of(dwork, struct fw_request, dwork); + struct fw_request *fw_req = container_of(dwork, + struct fw_request, dwork); struct fw_download *fw_download = fw_req->fw_download; dev_err(fw_download->parent, @@ -239,7 +240,8 @@ static int fw_download_find_firmware(struct gb_operation *op) tag = (const char *)request->firmware_tag; /* firmware_tag must be null-terminated */ - if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) == GB_FIRMWARE_TAG_MAX_SIZE) { + if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) == + GB_FIRMWARE_TAG_MAX_SIZE) { dev_err(fw_download->parent, "firmware-tag is not null-terminated\n"); return -EINVAL; diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index bcde7c9a0f17..64a1eb93ec96 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -104,7 +104,8 @@ static int gbphy_dev_uevent(struct device *dev, struct kobj_uevent_env *env) } static const struct gbphy_device_id * -gbphy_dev_match_id(struct gbphy_device *gbphy_dev, struct gbphy_driver *gbphy_drv) +gbphy_dev_match_id(struct gbphy_device *gbphy_dev, + struct gbphy_driver *gbphy_drv) { const struct gbphy_device_id *id = gbphy_drv->id_table; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index 51384bdde450..ee5f998b174f 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -410,21 +410,21 @@ static int gb_gpio_request_handler(struct gb_operation *op) return 0; } -static int gb_gpio_request(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_activate_operation(ggc, (u8)offset); } -static void gb_gpio_free(struct gpio_chip *chip, unsigned offset) +static void gb_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_deactivate_operation(ggc, (u8)offset); } -static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; @@ -438,22 +438,22 @@ static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset) return ggc->lines[which].direction ? 1 : 0; } -static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_in_operation(ggc, (u8)offset); } -static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value); } -static int gb_gpio_get(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); u8 which; @@ -467,14 +467,14 @@ static int gb_gpio_get(struct gpio_chip *chip, unsigned offset) return ggc->lines[which].value; } -static void gb_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); gb_gpio_set_value_operation(ggc, (u8)offset, !!value); } -static int gb_gpio_set_config(struct gpio_chip *chip, unsigned offset, +static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); @@ -560,7 +560,8 @@ static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc) /* Remove all IRQ mappings and delete the domain */ if (ggc->irqdomain) { for (offset = 0; offset < (ggc->line_max + 1); offset++) - irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, offset)); + irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, + offset)); irq_domain_remove(ggc->irqdomain); } @@ -596,7 +597,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip, { struct gb_gpio_controller *ggc; unsigned int offset; - unsigned irq_base; + unsigned int irq_base; if (!chip || !irqchip) return -EINVAL; @@ -628,7 +629,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip, return 0; } -static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) { struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index 12526887ae2e..c9bb93f23927 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -33,7 +33,6 @@ #include "bundle.h" #include "connection.h" #include "operation.h" -#include "timesync.h" /* Matches up with the Greybus Protocol specification document */ #define GREYBUS_VERSION_MAJOR 0x00 diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 639578309c2a..b1be0b0af464 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -173,26 +173,6 @@ struct gb_control_disconnected_request { } __packed; /* Control protocol [dis]connected response has no payload */ -#define GB_TIMESYNC_MAX_STROBES 0x04 - -struct gb_control_timesync_enable_request { - __u8 count; - __le64 frame_time; - __le32 strobe_delay; - __le32 refclk; -} __packed; -/* timesync enable response has no payload */ - -struct gb_control_timesync_authoritative_request { - __le64 frame_time[GB_TIMESYNC_MAX_STROBES]; -} __packed; -/* timesync authoritative response has no payload */ - -/* timesync get_last_event_request has no payload */ -struct gb_control_timesync_get_last_event_response { - __le64 frame_time; -} __packed; - /* * All Bundle power management operations use the same request and response * layout and status codes. @@ -1169,33 +1149,6 @@ struct gb_svc_intf_unipro_response { #define GB_SVC_INTF_UNIPRO_NOT_OFF 0x03 } __packed; -struct gb_svc_timesync_enable_request { - __u8 count; - __le64 frame_time; - __le32 strobe_delay; - __le32 refclk; -} __packed; -/* timesync enable response has no payload */ - -/* timesync authoritative request has no payload */ -struct gb_svc_timesync_authoritative_response { - __le64 frame_time[GB_TIMESYNC_MAX_STROBES]; -}; - -struct gb_svc_timesync_wake_pins_acquire_request { - __le32 strobe_mask; -}; - -/* timesync wake pins acquire response has no payload */ - -/* timesync wake pins release request has no payload */ -/* timesync wake pins release response has no payload */ - -/* timesync svc ping request has no payload */ -struct gb_svc_timesync_ping_response { - __le64 frame_time; -} __packed; - #define GB_SVC_UNIPRO_FAST_MODE 0x01 #define GB_SVC_UNIPRO_SLOW_MODE 0x02 #define GB_SVC_UNIPRO_FAST_AUTO_MODE 0x04 diff --git a/drivers/staging/greybus/greybus_trace.h b/drivers/staging/greybus/greybus_trace.h index 6f8692da9ec8..f8feae4dc3b5 100644 --- a/drivers/staging/greybus/greybus_trace.h +++ b/drivers/staging/greybus/greybus_trace.h @@ -488,34 +488,6 @@ DEFINE_HD_EVENT(gb_hd_in); #undef DEFINE_HD_EVENT -/* - * Occurs on a TimeSync synchronization event or a TimeSync ping event. - */ -TRACE_EVENT(gb_timesync_irq, - - TP_PROTO(u8 ping, u8 strobe, u8 count, u64 frame_time), - - TP_ARGS(ping, strobe, count, frame_time), - - TP_STRUCT__entry( - __field(u8, ping) - __field(u8, strobe) - __field(u8, count) - __field(u64, frame_time) - ), - - TP_fast_assign( - __entry->ping = ping; - __entry->strobe = strobe; - __entry->count = count; - __entry->frame_time = frame_time; - ), - - TP_printk("%s %d/%d frame-time %llu\n", - __entry->ping ? "ping" : "strobe", __entry->strobe, - __entry->count, __entry->frame_time) -); - #endif /* _TRACE_GREYBUS_H */ /* This part must be outside protection */ diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h index c4250cfe595f..e7927bb1761c 100644 --- a/drivers/staging/greybus/hd.h +++ b/drivers/staging/greybus/hd.h @@ -37,13 +37,6 @@ struct gb_hd_driver { int (*latency_tag_disable)(struct gb_host_device *hd, u16 cport_id); int (*output)(struct gb_host_device *hd, void *req, u16 size, u8 cmd, bool async); - int (*timesync_enable)(struct gb_host_device *hd, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk); - int (*timesync_disable)(struct gb_host_device *hd); - int (*timesync_authoritative)(struct gb_host_device *hd, - u64 *frame_time); - int (*timesync_get_last_event)(struct gb_host_device *hd, - u64 *frame_time); }; struct gb_host_device { diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index 546b090e2d51..a4fd51632232 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -702,14 +702,12 @@ static void gb_interface_release(struct device *dev) static int gb_interface_suspend(struct device *dev) { struct gb_interface *intf = to_gb_interface(dev); - int ret, timesync_ret; + int ret; ret = gb_control_interface_suspend_prepare(intf->control); if (ret) return ret; - gb_timesync_interface_remove(intf); - ret = gb_control_suspend(intf->control); if (ret) goto err_hibernate_abort; @@ -730,12 +728,6 @@ static int gb_interface_suspend(struct device *dev) err_hibernate_abort: gb_control_interface_hibernate_abort(intf->control); - timesync_ret = gb_timesync_interface_add(intf); - if (timesync_ret) { - dev_err(dev, "failed to add to timesync: %d\n", timesync_ret); - return timesync_ret; - } - return ret; } @@ -757,18 +749,6 @@ static int gb_interface_resume(struct device *dev) if (ret) return ret; - ret = gb_timesync_interface_add(intf); - if (ret) { - dev_err(dev, "failed to add to timesync: %d\n", ret); - return ret; - } - - ret = gb_timesync_schedule_synchronous(intf); - if (ret) { - dev_err(dev, "failed to synchronize FrameTime: %d\n", ret); - return ret; - } - return 0; } @@ -1152,16 +1132,10 @@ int gb_interface_enable(struct gb_interface *intf) if (ret) goto err_destroy_bundles; - ret = gb_timesync_interface_add(intf); - if (ret) { - dev_err(&intf->dev, "failed to add to timesync: %d\n", ret); - goto err_destroy_bundles; - } - /* Register the control device and any bundles */ ret = gb_control_add(intf->control); if (ret) - goto err_remove_timesync; + goto err_destroy_bundles; pm_runtime_use_autosuspend(&intf->dev); pm_runtime_get_noresume(&intf->dev); @@ -1186,8 +1160,6 @@ int gb_interface_enable(struct gb_interface *intf) return 0; -err_remove_timesync: - gb_timesync_interface_remove(intf); err_destroy_bundles: list_for_each_entry_safe(bundle, tmp, &intf->bundles, links) gb_bundle_destroy(bundle); @@ -1230,7 +1202,6 @@ void gb_interface_disable(struct gb_interface *intf) gb_control_interface_deactivate_prepare(intf->control); gb_control_del(intf->control); - gb_timesync_interface_remove(intf); gb_control_disable(intf->control); gb_control_put(intf->control); intf->control = NULL; @@ -1243,29 +1214,6 @@ void gb_interface_disable(struct gb_interface *intf) pm_runtime_put_noidle(&intf->dev); } -/* Enable TimeSync on an Interface control connection. */ -int gb_interface_timesync_enable(struct gb_interface *intf, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk) -{ - return gb_control_timesync_enable(intf->control, count, - frame_time, strobe_delay, - refclk); -} - -/* Disable TimeSync on an Interface control connection. */ -int gb_interface_timesync_disable(struct gb_interface *intf) -{ - return gb_control_timesync_disable(intf->control); -} - -/* Transmit the Authoritative FrameTime via an Interface control connection. */ -int gb_interface_timesync_authoritative(struct gb_interface *intf, - u64 *frame_time) -{ - return gb_control_timesync_authoritative(intf->control, - frame_time); -} - /* Register an interface. */ int gb_interface_add(struct gb_interface *intf) { diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index 03299d2a8be5..bd31b8c18d5b 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -72,11 +72,6 @@ int gb_interface_activate(struct gb_interface *intf); void gb_interface_deactivate(struct gb_interface *intf); int gb_interface_enable(struct gb_interface *intf); void gb_interface_disable(struct gb_interface *intf); -int gb_interface_timesync_enable(struct gb_interface *intf, u8 count, - u64 frame_time, u32 strobe_delay, u32 refclk); -int gb_interface_timesync_authoritative(struct gb_interface *intf, - u64 *frame_time); -int gb_interface_timesync_disable(struct gb_interface *intf); int gb_interface_add(struct gb_interface *intf); void gb_interface_del(struct gb_interface *intf); void gb_interface_put(struct gb_interface *intf); diff --git a/drivers/staging/greybus/log.c b/drivers/staging/greybus/log.c index 1a18ab1ff8aa..5c5bedaf69a6 100644 --- a/drivers/staging/greybus/log.c +++ b/drivers/staging/greybus/log.c @@ -37,9 +37,9 @@ static int gb_log_request_handler(struct gb_operation *op) } receive = op->request->payload; len = le16_to_cpu(receive->len); - if (len != (int)(op->request->payload_size - sizeof(*receive))) { - dev_err(dev, "log request wrong size %d vs %d\n", len, - (int)(op->request->payload_size - sizeof(*receive))); + if (len != (op->request->payload_size - sizeof(*receive))) { + dev_err(dev, "log request wrong size %d vs %zu\n", len, + (op->request->payload_size - sizeof(*receive))); return -EINVAL; } if (len == 0) { diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 7882306adeca..aaf29a5fac83 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -124,7 +124,7 @@ static DEFINE_IDA(loopback_ida); #define GB_LOOPBACK_FIFO_DEFAULT 8192 -static unsigned kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT; +static unsigned int kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT; module_param(kfifo_depth, uint, 0444); /* Maximum size of any one send data buffer we support */ @@ -629,6 +629,7 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type, mutex_lock(&gb->mutex); ret = gb_operation_request_send(operation, gb_loopback_async_operation_callback, + 0, GFP_KERNEL); if (ret) goto error; @@ -1008,11 +1009,22 @@ static int gb_loopback_fn(void *data) /* Optionally terminate */ if (gb->send_count == gb->iteration_max) { + mutex_unlock(&gb->mutex); + + /* Wait for synchronous and asynchronus completion */ + gb_loopback_async_wait_all(gb); + + /* Mark complete unless user-space has poked us */ + mutex_lock(&gb->mutex); if (gb->iteration_count == gb->iteration_max) { gb->type = 0; gb->send_count = 0; sysfs_notify(&gb->dev->kobj, NULL, "iteration_count"); + dev_dbg(&bundle->dev, "load test complete\n"); + } else { + dev_dbg(&bundle->dev, + "continuing on with new test set\n"); } mutex_unlock(&gb->mutex); continue; @@ -1026,13 +1038,12 @@ static int gb_loopback_fn(void *data) /* Else operations to perform */ if (gb->async) { - if (type == GB_LOOPBACK_TYPE_PING) { + if (type == GB_LOOPBACK_TYPE_PING) error = gb_loopback_async_ping(gb); - } else if (type == GB_LOOPBACK_TYPE_TRANSFER) { + else if (type == GB_LOOPBACK_TYPE_TRANSFER) error = gb_loopback_async_transfer(gb, size); - } else if (type == GB_LOOPBACK_TYPE_SINK) { + else if (type == GB_LOOPBACK_TYPE_SINK) error = gb_loopback_async_sink(gb, size); - } if (error) gb->error++; @@ -1051,8 +1062,13 @@ static int gb_loopback_fn(void *data) gb_loopback_calculate_stats(gb, !!error); } gb->send_count++; - if (us_wait) - udelay(us_wait); + + if (us_wait) { + if (us_wait < 20000) + usleep_range(us_wait, us_wait + 100); + else + msleep(us_wait / 1000); + } } gb_pm_runtime_put_autosuspend(bundle); @@ -1199,7 +1215,7 @@ static int gb_loopback_probe(struct gb_bundle *bundle, /* Create per-connection sysfs and debugfs data-points */ snprintf(name, sizeof(name), "raw_latency_%s", dev_name(&connection->bundle->dev)); - gb->file = debugfs_create_file(name, S_IFREG | S_IRUGO, gb_dev.root, gb, + gb->file = debugfs_create_file(name, S_IFREG | 0444, gb_dev.root, gb, &gb_loopback_debugfs_latency_ops); gb->id = ida_simple_get(&loopback_ida, 0, 0, GFP_KERNEL); diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 0123109a1070..3023012808d9 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -273,18 +273,40 @@ static void gb_operation_request_handle(struct gb_operation *operation) static void gb_operation_work(struct work_struct *work) { struct gb_operation *operation; + int ret; operation = container_of(work, struct gb_operation, work); - if (gb_operation_is_incoming(operation)) + if (gb_operation_is_incoming(operation)) { gb_operation_request_handle(operation); - else + } else { + ret = del_timer_sync(&operation->timer); + if (!ret) { + /* Cancel request message if scheduled by timeout. */ + if (gb_operation_result(operation) == -ETIMEDOUT) + gb_message_cancel(operation->request); + } + operation->callback(operation); + } gb_operation_put_active(operation); gb_operation_put(operation); } +static void gb_operation_timeout(unsigned long arg) +{ + struct gb_operation *operation = (void *)arg; + + if (gb_operation_result_set(operation, -ETIMEDOUT)) { + /* + * A stuck request message will be cancelled from the + * workqueue. + */ + queue_work(gb_operation_completion_wq, &operation->work); + } +} + static void gb_operation_message_init(struct gb_host_device *hd, struct gb_message *message, u16 operation_id, size_t payload_size, u8 type) @@ -518,6 +540,9 @@ gb_operation_create_common(struct gb_connection *connection, u8 type, gfp_flags)) { goto err_request; } + + setup_timer(&operation->timer, gb_operation_timeout, + (unsigned long)operation); } operation->flags = op_flags; @@ -679,6 +704,7 @@ static void gb_operation_sync_callback(struct gb_operation *operation) * gb_operation_request_send() - send an operation request message * @operation: the operation to initiate * @callback: the operation completion callback + * @timeout: operation timeout in milliseconds, or zero for no timeout * @gfp: the memory flags to use for any allocations * * The caller has filled in any payload so the request message is ready to go. @@ -693,6 +719,7 @@ static void gb_operation_sync_callback(struct gb_operation *operation) */ int gb_operation_request_send(struct gb_operation *operation, gb_operation_callback callback, + unsigned int timeout, gfp_t gfp) { struct gb_connection *connection = operation->connection; @@ -742,6 +769,11 @@ int gb_operation_request_send(struct gb_operation *operation, if (ret) goto err_put_active; + if (timeout) { + operation->timer.expires = jiffies + msecs_to_jiffies(timeout); + add_timer(&operation->timer); + } + return 0; err_put_active: @@ -763,26 +795,16 @@ int gb_operation_request_send_sync_timeout(struct gb_operation *operation, unsigned int timeout) { int ret; - unsigned long timeout_jiffies; ret = gb_operation_request_send(operation, gb_operation_sync_callback, - GFP_KERNEL); + timeout, GFP_KERNEL); if (ret) return ret; - if (timeout) - timeout_jiffies = msecs_to_jiffies(timeout); - else - timeout_jiffies = MAX_SCHEDULE_TIMEOUT; - - ret = wait_for_completion_interruptible_timeout(&operation->completion, - timeout_jiffies); + ret = wait_for_completion_interruptible(&operation->completion); if (ret < 0) { /* Cancel the operation if interrupted */ gb_operation_cancel(operation, -ECANCELED); - } else if (ret == 0) { - /* Cancel the operation if op timed out */ - gb_operation_cancel(operation, -ETIMEDOUT); } return gb_operation_result(operation); diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index de09a2c7de54..7529f01b2529 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -98,6 +98,7 @@ struct gb_operation { struct work_struct work; gb_operation_callback callback; struct completion completion; + struct timer_list timer; struct kref kref; atomic_t waiters; @@ -164,6 +165,7 @@ bool gb_operation_response_alloc(struct gb_operation *operation, int gb_operation_request_send(struct gb_operation *operation, gb_operation_callback callback, + unsigned int timeout, gfp_t gfp); int gb_operation_request_send_sync_timeout(struct gb_operation *operation, unsigned int timeout); diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index 66b37ea29ef0..101ca5097fc9 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c @@ -52,7 +52,7 @@ struct gb_sdio_host { static inline bool single_op(struct mmc_command *cmd) { - uint32_t opcode = cmd->opcode; + u32 opcode = cmd->opcode; return opcode == MMC_WRITE_BLOCK || opcode == MMC_READ_SINGLE_BLOCK; diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index 8779270cadc1..516f827e5ed9 100644 --- a/drivers/staging/greybus/svc.c +++ b/drivers/staging/greybus/svc.c @@ -518,85 +518,6 @@ void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id, } } -int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time, - u32 strobe_delay, u32 refclk) -{ - struct gb_connection *connection = svc->connection; - struct gb_svc_timesync_enable_request request; - - request.count = count; - request.frame_time = cpu_to_le64(frame_time); - request.strobe_delay = cpu_to_le32(strobe_delay); - request.refclk = cpu_to_le32(refclk); - return gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_ENABLE, - &request, sizeof(request), NULL, 0); -} - -int gb_svc_timesync_disable(struct gb_svc *svc) -{ - struct gb_connection *connection = svc->connection; - - return gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_DISABLE, - NULL, 0, NULL, 0); -} - -int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time) -{ - struct gb_connection *connection = svc->connection; - struct gb_svc_timesync_authoritative_response response; - int ret, i; - - ret = gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE, NULL, 0, - &response, sizeof(response)); - if (ret < 0) - return ret; - - for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++) - frame_time[i] = le64_to_cpu(response.frame_time[i]); - return 0; -} - -int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time) -{ - struct gb_connection *connection = svc->connection; - struct gb_svc_timesync_ping_response response; - int ret; - - ret = gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_PING, - NULL, 0, - &response, sizeof(response)); - if (ret < 0) - return ret; - - *frame_time = le64_to_cpu(response.frame_time); - return 0; -} - -int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask) -{ - struct gb_connection *connection = svc->connection; - struct gb_svc_timesync_wake_pins_acquire_request request; - - request.strobe_mask = cpu_to_le32(strobe_mask); - return gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE, - &request, sizeof(request), - NULL, 0); -} - -int gb_svc_timesync_wake_pins_release(struct gb_svc *svc) -{ - struct gb_connection *connection = svc->connection; - - return gb_operation_sync(connection, - GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE, - NULL, 0, NULL, 0); -} - /* Creates bi-directional routes between the devices */ int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id, u8 intf2_id, u8 dev2_id) @@ -757,7 +678,8 @@ static int gb_svc_version_request(struct gb_operation *op) static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -780,7 +702,8 @@ static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf, static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -803,7 +726,8 @@ static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf, static ssize_t pwr_debugfs_power_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { - struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private; + struct svc_debugfs_pwrmon_rail *pwrmon_rails = + file_inode(file)->i_private; struct gb_svc *svc = pwrmon_rails->svc; int ret, desc; u32 value; @@ -879,11 +803,11 @@ static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc) rail->svc = svc; dir = debugfs_create_dir(fname, dent); - debugfs_create_file("voltage_now", S_IRUGO, dir, rail, + debugfs_create_file("voltage_now", 0444, dir, rail, &pwrmon_debugfs_voltage_fops); - debugfs_create_file("current_now", S_IRUGO, dir, rail, + debugfs_create_file("current_now", 0444, dir, rail, &pwrmon_debugfs_current_fops); - debugfs_create_file("power_now", S_IRUGO, dir, rail, + debugfs_create_file("power_now", 0444, dir, rail, &pwrmon_debugfs_power_fops); } @@ -945,13 +869,6 @@ static int gb_svc_hello(struct gb_operation *op) gb_svc_debugfs_init(svc); - ret = gb_timesync_svc_add(svc); - if (ret) { - dev_err(&svc->dev, "failed to add SVC to timesync: %d\n", ret); - gb_svc_debugfs_exit(svc); - goto err_unregister_device; - } - return gb_svc_queue_deferred_request(op); err_unregister_device: @@ -1010,14 +927,15 @@ static void gb_svc_process_hello_deferred(struct gb_operation *operation) * Power Mode Changes is resolved. */ ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - GB_SVC_SMALL_AMPLITUDE, GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - 0, 0, - NULL, NULL); + GB_SVC_UNIPRO_HS_SERIES_A, + GB_SVC_UNIPRO_SLOW_AUTO_MODE, + 2, 1, + GB_SVC_SMALL_AMPLITUDE, + GB_SVC_NO_DE_EMPHASIS, + GB_SVC_UNIPRO_SLOW_AUTO_MODE, + 2, 1, + 0, 0, + NULL, NULL); if (ret) dev_warn(&svc->dev, @@ -1467,7 +1385,6 @@ void gb_svc_del(struct gb_svc *svc) * The SVC device may have been registered from the request handler. */ if (device_is_registered(&svc->dev)) { - gb_timesync_svc_remove(svc); gb_svc_debugfs_exit(svc); gb_svc_watchdog_destroy(svc); device_del(&svc->dev); diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h index d1d7ef967385..226c2a396fc8 100644 --- a/drivers/staging/greybus/svc.h +++ b/drivers/staging/greybus/svc.h @@ -95,13 +95,6 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc); bool gb_svc_watchdog_enabled(struct gb_svc *svc); int gb_svc_watchdog_enable(struct gb_svc *svc); int gb_svc_watchdog_disable(struct gb_svc *svc); -int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time, - u32 strobe_delay, u32 refclk); -int gb_svc_timesync_disable(struct gb_svc *svc); -int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time); -int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time); -int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask); -int gb_svc_timesync_wake_pins_release(struct gb_svc *svc); int gb_svc_protocol_init(void); void gb_svc_protocol_exit(void); diff --git a/drivers/staging/greybus/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c index 12cef5c06e27..779fbea5d4ba 100644 --- a/drivers/staging/greybus/svc_watchdog.c +++ b/drivers/staging/greybus/svc_watchdog.c @@ -11,7 +11,7 @@ #include <linux/workqueue.h> #include "greybus.h" -#define SVC_WATCHDOG_PERIOD (2*HZ) +#define SVC_WATCHDOG_PERIOD (2 * HZ) struct gb_svc_watchdog { struct delayed_work work; @@ -56,7 +56,7 @@ static void greybus_reset(struct work_struct *work) NULL, }; - printk(KERN_ERR "svc_watchdog: calling \"%s %s\" to reset greybus network!\n", + pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n", argv[0], argv[1]); call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC); } diff --git a/drivers/staging/greybus/timesync.c b/drivers/staging/greybus/timesync.c deleted file mode 100644 index 29e6c1c12807..000000000000 --- a/drivers/staging/greybus/timesync.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * TimeSync API driver. - * - * Copyright 2016 Google Inc. - * Copyright 2016 Linaro Ltd. - * - * Released under the GPLv2 only. - */ -#include <linux/debugfs.h> -#include <linux/hrtimer.h> -#include "greybus.h" -#include "timesync.h" -#include "greybus_trace.h" - -/* - * Minimum inter-strobe value of one millisecond is chosen because it - * just-about fits the common definition of a jiffy. - * - * Maximum value OTOH is constrained by the number of bits the SVC can fit - * into a 16 bit up-counter. The SVC configures the timer in microseconds - * so the maximum allowable value is 65535 microseconds. We clip that value - * to 10000 microseconds for the sake of using nice round base 10 numbers - * and since right-now there's no imaginable use-case requiring anything - * other than a one millisecond inter-strobe time, let alone something - * higher than ten milliseconds. - */ -#define GB_TIMESYNC_STROBE_DELAY_US 1000 -#define GB_TIMESYNC_DEFAULT_OFFSET_US 1000 - -/* Work queue timers long, short and SVC strobe timeout */ -#define GB_TIMESYNC_DELAYED_WORK_LONG msecs_to_jiffies(10) -#define GB_TIMESYNC_DELAYED_WORK_SHORT msecs_to_jiffies(1) -#define GB_TIMESYNC_MAX_WAIT_SVC msecs_to_jiffies(5000) -#define GB_TIMESYNC_KTIME_UPDATE msecs_to_jiffies(1000) -#define GB_TIMESYNC_MAX_KTIME_CONVERSION 15 - -/* Maximum number of times we'll retry a failed synchronous sync */ -#define GB_TIMESYNC_MAX_RETRIES 5 - -/* Reported nanoseconds/femtoseconds per clock */ -static u64 gb_timesync_ns_per_clock; -static u64 gb_timesync_fs_per_clock; - -/* Maximum difference we will accept converting FrameTime to ktime */ -static u32 gb_timesync_max_ktime_diff; - -/* Reported clock rate */ -static unsigned long gb_timesync_clock_rate; - -/* Workqueue */ -static void gb_timesync_worker(struct work_struct *work); - -/* List of SVCs with one FrameTime per SVC */ -static LIST_HEAD(gb_timesync_svc_list); - -/* Synchronize parallel contexts accessing a valid timesync_svc pointer */ -static DEFINE_MUTEX(gb_timesync_svc_list_mutex); - -/* Structure to convert from FrameTime to timespec/ktime */ -struct gb_timesync_frame_time_data { - u64 frame_time; - struct timespec ts; -}; - -struct gb_timesync_svc { - struct list_head list; - struct list_head interface_list; - struct gb_svc *svc; - struct gb_timesync_host_device *timesync_hd; - - spinlock_t spinlock; /* Per SVC spinlock to sync with ISR */ - struct mutex mutex; /* Per SVC mutex for regular synchronization */ - - struct dentry *frame_time_dentry; - struct dentry *frame_ktime_dentry; - struct workqueue_struct *work_queue; - wait_queue_head_t wait_queue; - struct delayed_work delayed_work; - struct timer_list ktime_timer; - - /* The current local FrameTime */ - u64 frame_time_offset; - struct gb_timesync_frame_time_data strobe_data[GB_TIMESYNC_MAX_STROBES]; - struct gb_timesync_frame_time_data ktime_data; - - /* The SVC FrameTime and relative AP FrameTime @ last TIMESYNC_PING */ - u64 svc_ping_frame_time; - u64 ap_ping_frame_time; - - /* Transitory settings */ - u32 strobe_mask; - bool offset_down; - bool print_ping; - bool capture_ping; - int strobe; - - /* Current state */ - int state; -}; - -struct gb_timesync_host_device { - struct list_head list; - struct gb_host_device *hd; - u64 ping_frame_time; -}; - -struct gb_timesync_interface { - struct list_head list; - struct gb_interface *interface; - u64 ping_frame_time; -}; - -enum gb_timesync_state { - GB_TIMESYNC_STATE_INVALID = 0, - GB_TIMESYNC_STATE_INACTIVE = 1, - GB_TIMESYNC_STATE_INIT = 2, - GB_TIMESYNC_STATE_WAIT_SVC = 3, - GB_TIMESYNC_STATE_AUTHORITATIVE = 4, - GB_TIMESYNC_STATE_PING = 5, - GB_TIMESYNC_STATE_ACTIVE = 6, -}; - -static void gb_timesync_ktime_timer_fn(unsigned long data); - -static u64 gb_timesync_adjust_count(struct gb_timesync_svc *timesync_svc, - u64 counts) -{ - if (timesync_svc->offset_down) - return counts - timesync_svc->frame_time_offset; - else - return counts + timesync_svc->frame_time_offset; -} - -/* - * This function provides the authoritative FrameTime to a calling function. It - * is designed to be lockless and should remain that way the caller is assumed - * to be state-aware. - */ -static u64 __gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc) -{ - u64 clocks = gb_timesync_platform_get_counter(); - - return gb_timesync_adjust_count(timesync_svc, clocks); -} - -static void gb_timesync_schedule_svc_timeout(struct gb_timesync_svc - *timesync_svc) -{ - queue_delayed_work(timesync_svc->work_queue, - ×ync_svc->delayed_work, - GB_TIMESYNC_MAX_WAIT_SVC); -} - -static void gb_timesync_set_state(struct gb_timesync_svc *timesync_svc, - int state) -{ - switch (state) { - case GB_TIMESYNC_STATE_INVALID: - timesync_svc->state = state; - wake_up(×ync_svc->wait_queue); - break; - case GB_TIMESYNC_STATE_INACTIVE: - timesync_svc->state = state; - wake_up(×ync_svc->wait_queue); - break; - case GB_TIMESYNC_STATE_INIT: - if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) { - timesync_svc->strobe = 0; - timesync_svc->frame_time_offset = 0; - timesync_svc->state = state; - cancel_delayed_work(×ync_svc->delayed_work); - queue_delayed_work(timesync_svc->work_queue, - ×ync_svc->delayed_work, - GB_TIMESYNC_DELAYED_WORK_LONG); - } - break; - case GB_TIMESYNC_STATE_WAIT_SVC: - if (timesync_svc->state == GB_TIMESYNC_STATE_INIT) - timesync_svc->state = state; - break; - case GB_TIMESYNC_STATE_AUTHORITATIVE: - if (timesync_svc->state == GB_TIMESYNC_STATE_WAIT_SVC) { - timesync_svc->state = state; - cancel_delayed_work(×ync_svc->delayed_work); - queue_delayed_work(timesync_svc->work_queue, - ×ync_svc->delayed_work, 0); - } - break; - case GB_TIMESYNC_STATE_PING: - if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE) { - timesync_svc->state = state; - queue_delayed_work(timesync_svc->work_queue, - ×ync_svc->delayed_work, - GB_TIMESYNC_DELAYED_WORK_SHORT); - } - break; - case GB_TIMESYNC_STATE_ACTIVE: - if (timesync_svc->state == GB_TIMESYNC_STATE_AUTHORITATIVE || - timesync_svc->state == GB_TIMESYNC_STATE_PING) { - timesync_svc->state = state; - wake_up(×ync_svc->wait_queue); - } - break; - } - - if (WARN_ON(timesync_svc->state != state)) { - pr_err("Invalid state transition %d=>%d\n", - timesync_svc->state, state); - } -} - -static void gb_timesync_set_state_atomic(struct gb_timesync_svc *timesync_svc, - int state) -{ - unsigned long flags; - - spin_lock_irqsave(×ync_svc->spinlock, flags); - gb_timesync_set_state(timesync_svc, state); - spin_unlock_irqrestore(×ync_svc->spinlock, flags); -} - -static u64 gb_timesync_diff(u64 x, u64 y) -{ - if (x > y) - return x - y; - else - return y - x; -} - -static void gb_timesync_adjust_to_svc(struct gb_timesync_svc *svc, - u64 svc_frame_time, u64 ap_frame_time) -{ - if (svc_frame_time > ap_frame_time) { - svc->frame_time_offset = svc_frame_time - ap_frame_time; - svc->offset_down = false; - } else { - svc->frame_time_offset = ap_frame_time - svc_frame_time; - svc->offset_down = true; - } -} - -/* - * Associate a FrameTime with a ktime timestamp represented as struct timespec - * Requires the calling context to hold timesync_svc->mutex - */ -static void gb_timesync_store_ktime(struct gb_timesync_svc *timesync_svc, - struct timespec ts, u64 frame_time) -{ - timesync_svc->ktime_data.ts = ts; - timesync_svc->ktime_data.frame_time = frame_time; -} - -/* - * Find the two pulses that best-match our expected inter-strobe gap and - * then calculate the difference between the SVC time at the second pulse - * to the local time at the second pulse. - */ -static void gb_timesync_collate_frame_time(struct gb_timesync_svc *timesync_svc, - u64 *frame_time) -{ - int i = 0; - u64 delta, ap_frame_time; - u64 strobe_delay_ns = GB_TIMESYNC_STROBE_DELAY_US * NSEC_PER_USEC; - u64 least = 0; - - for (i = 1; i < GB_TIMESYNC_MAX_STROBES; i++) { - delta = timesync_svc->strobe_data[i].frame_time - - timesync_svc->strobe_data[i - 1].frame_time; - delta *= gb_timesync_ns_per_clock; - delta = gb_timesync_diff(delta, strobe_delay_ns); - - if (!least || delta < least) { - least = delta; - gb_timesync_adjust_to_svc(timesync_svc, frame_time[i], - timesync_svc->strobe_data[i].frame_time); - - ap_frame_time = timesync_svc->strobe_data[i].frame_time; - ap_frame_time = gb_timesync_adjust_count(timesync_svc, - ap_frame_time); - gb_timesync_store_ktime(timesync_svc, - timesync_svc->strobe_data[i].ts, - ap_frame_time); - - pr_debug("adjust %s local %llu svc %llu delta %llu\n", - timesync_svc->offset_down ? "down" : "up", - timesync_svc->strobe_data[i].frame_time, - frame_time[i], delta); - } - } -} - -static void gb_timesync_teardown(struct gb_timesync_svc *timesync_svc) -{ - struct gb_timesync_interface *timesync_interface; - struct gb_svc *svc = timesync_svc->svc; - struct gb_interface *interface; - struct gb_host_device *hd; - int ret; - - list_for_each_entry(timesync_interface, - ×ync_svc->interface_list, list) { - interface = timesync_interface->interface; - ret = gb_interface_timesync_disable(interface); - if (ret) { - dev_err(&interface->dev, - "interface timesync_disable %d\n", ret); - } - } - - hd = timesync_svc->timesync_hd->hd; - ret = hd->driver->timesync_disable(hd); - if (ret < 0) { - dev_err(&hd->dev, "host timesync_disable %d\n", - ret); - } - - gb_svc_timesync_wake_pins_release(svc); - gb_svc_timesync_disable(svc); - gb_timesync_platform_unlock_bus(); - - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE); -} - -static void gb_timesync_platform_lock_bus_fail(struct gb_timesync_svc - *timesync_svc, int ret) -{ - if (ret == -EAGAIN) { - gb_timesync_set_state(timesync_svc, timesync_svc->state); - } else { - pr_err("Failed to lock timesync bus %d\n", ret); - gb_timesync_set_state(timesync_svc, GB_TIMESYNC_STATE_INACTIVE); - } -} - -static void gb_timesync_enable(struct gb_timesync_svc *timesync_svc) -{ - struct gb_svc *svc = timesync_svc->svc; - struct gb_host_device *hd; - struct gb_timesync_interface *timesync_interface; - struct gb_interface *interface; - u64 init_frame_time; - unsigned long clock_rate = gb_timesync_clock_rate; - int ret; - - /* - * Get access to the wake pins in the AP and SVC - * Release these pins either in gb_timesync_teardown() or in - * gb_timesync_authoritative() - */ - ret = gb_timesync_platform_lock_bus(timesync_svc); - if (ret < 0) { - gb_timesync_platform_lock_bus_fail(timesync_svc, ret); - return; - } - ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask); - if (ret) { - dev_err(&svc->dev, - "gb_svc_timesync_wake_pins_acquire %d\n", ret); - gb_timesync_teardown(timesync_svc); - return; - } - - /* Choose an initial time in the future */ - init_frame_time = __gb_timesync_get_frame_time(timesync_svc) + 100000UL; - - /* Send enable command to all relevant participants */ - list_for_each_entry(timesync_interface, ×ync_svc->interface_list, - list) { - interface = timesync_interface->interface; - ret = gb_interface_timesync_enable(interface, - GB_TIMESYNC_MAX_STROBES, - init_frame_time, - GB_TIMESYNC_STROBE_DELAY_US, - clock_rate); - if (ret) { - dev_err(&interface->dev, - "interface timesync_enable %d\n", ret); - } - } - - hd = timesync_svc->timesync_hd->hd; - ret = hd->driver->timesync_enable(hd, GB_TIMESYNC_MAX_STROBES, - init_frame_time, - GB_TIMESYNC_STROBE_DELAY_US, - clock_rate); - if (ret < 0) { - dev_err(&hd->dev, "host timesync_enable %d\n", - ret); - } - - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_WAIT_SVC); - ret = gb_svc_timesync_enable(svc, GB_TIMESYNC_MAX_STROBES, - init_frame_time, - GB_TIMESYNC_STROBE_DELAY_US, - clock_rate); - if (ret) { - dev_err(&svc->dev, - "gb_svc_timesync_enable %d\n", ret); - gb_timesync_teardown(timesync_svc); - return; - } - - /* Schedule a timeout waiting for SVC to complete strobing */ - gb_timesync_schedule_svc_timeout(timesync_svc); -} - -static void gb_timesync_authoritative(struct gb_timesync_svc *timesync_svc) -{ - struct gb_svc *svc = timesync_svc->svc; - struct gb_host_device *hd; - struct gb_timesync_interface *timesync_interface; - struct gb_interface *interface; - u64 svc_frame_time[GB_TIMESYNC_MAX_STROBES]; - int ret; - - /* Get authoritative time from SVC and adjust local clock */ - ret = gb_svc_timesync_authoritative(svc, svc_frame_time); - if (ret) { - dev_err(&svc->dev, - "gb_svc_timesync_authoritative %d\n", ret); - gb_timesync_teardown(timesync_svc); - return; - } - gb_timesync_collate_frame_time(timesync_svc, svc_frame_time); - - /* Transmit authoritative time to downstream slaves */ - hd = timesync_svc->timesync_hd->hd; - ret = hd->driver->timesync_authoritative(hd, svc_frame_time); - if (ret < 0) - dev_err(&hd->dev, "host timesync_authoritative %d\n", ret); - - list_for_each_entry(timesync_interface, - ×ync_svc->interface_list, list) { - interface = timesync_interface->interface; - ret = gb_interface_timesync_authoritative( - interface, - svc_frame_time); - if (ret) { - dev_err(&interface->dev, - "interface timesync_authoritative %d\n", ret); - } - } - - /* Release wake pins */ - gb_svc_timesync_wake_pins_release(svc); - gb_timesync_platform_unlock_bus(); - - /* Transition to state ACTIVE */ - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE); - - /* Schedule a ping to verify the synchronized system time */ - timesync_svc->print_ping = true; - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_PING); -} - -static int __gb_timesync_get_status(struct gb_timesync_svc *timesync_svc) -{ - int ret = -EINVAL; - - switch (timesync_svc->state) { - case GB_TIMESYNC_STATE_INVALID: - case GB_TIMESYNC_STATE_INACTIVE: - ret = -ENODEV; - break; - case GB_TIMESYNC_STATE_INIT: - case GB_TIMESYNC_STATE_WAIT_SVC: - case GB_TIMESYNC_STATE_AUTHORITATIVE: - ret = -EAGAIN; - break; - case GB_TIMESYNC_STATE_PING: - case GB_TIMESYNC_STATE_ACTIVE: - ret = 0; - break; - } - return ret; -} - -/* - * This routine takes a FrameTime and derives the difference with-respect - * to a reference FrameTime/ktime pair. It then returns the calculated - * ktime based on the difference between the supplied FrameTime and - * the reference FrameTime. - * - * The time difference is calculated to six decimal places. Taking 19.2MHz - * as an example this means we have 52.083333~ nanoseconds per clock or - * 52083333~ femtoseconds per clock. - * - * Naively taking the count difference and converting to - * seconds/nanoseconds would quickly see the 0.0833 component produce - * noticeable errors. For example a time difference of one second would - * loose 19200000 * 0.08333x nanoseconds or 1.59 seconds. - * - * In contrast calculating in femtoseconds the same example of 19200000 * - * 0.000000083333x nanoseconds per count of error is just 1.59 nanoseconds! - * - * Continuing the example of 19.2 MHz we cap the maximum error difference - * at a worst-case 0.3 microseconds over a potential calculation window of - * abount 15 seconds, meaning you can convert a FrameTime that is <= 15 - * seconds older/younger than the reference time with a maximum error of - * 0.2385 useconds. Note 19.2MHz is an example frequency not a requirement. - */ -static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc, - u64 frame_time, struct timespec *ts) -{ - unsigned long flags; - u64 delta_fs, counts, sec, nsec; - bool add; - int ret = 0; - - memset(ts, 0x00, sizeof(*ts)); - mutex_lock(×ync_svc->mutex); - spin_lock_irqsave(×ync_svc->spinlock, flags); - - ret = __gb_timesync_get_status(timesync_svc); - if (ret) - goto done; - - /* Support calculating ktime upwards or downwards from the reference */ - if (frame_time < timesync_svc->ktime_data.frame_time) { - add = false; - counts = timesync_svc->ktime_data.frame_time - frame_time; - } else { - add = true; - counts = frame_time - timesync_svc->ktime_data.frame_time; - } - - /* Enforce the .23 of a usecond boundary @ 19.2MHz */ - if (counts > gb_timesync_max_ktime_diff) { - ret = -EINVAL; - goto done; - } - - /* Determine the time difference in femtoseconds */ - delta_fs = counts * gb_timesync_fs_per_clock; - - /* Convert to seconds */ - sec = delta_fs; - do_div(sec, NSEC_PER_SEC); - do_div(sec, 1000000UL); - - /* Get the nanosecond remainder */ - nsec = do_div(delta_fs, sec); - do_div(nsec, 1000000UL); - - if (add) { - /* Add the calculated offset - overflow nanoseconds upwards */ - ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec + sec; - ts->tv_nsec = timesync_svc->ktime_data.ts.tv_nsec + nsec; - if (ts->tv_nsec >= NSEC_PER_SEC) { - ts->tv_sec++; - ts->tv_nsec -= NSEC_PER_SEC; - } - } else { - /* Subtract the difference over/underflow as necessary */ - if (nsec > timesync_svc->ktime_data.ts.tv_nsec) { - sec++; - nsec = nsec + timesync_svc->ktime_data.ts.tv_nsec; - nsec = do_div(nsec, NSEC_PER_SEC); - } else { - nsec = timesync_svc->ktime_data.ts.tv_nsec - nsec; - } - /* Cannot return a negative second value */ - if (sec > timesync_svc->ktime_data.ts.tv_sec) { - ret = -EINVAL; - goto done; - } - ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec - sec; - ts->tv_nsec = nsec; - } -done: - spin_unlock_irqrestore(×ync_svc->spinlock, flags); - mutex_unlock(×ync_svc->mutex); - return ret; -} - -static size_t gb_timesync_log_frame_time(struct gb_timesync_svc *timesync_svc, - char *buf, size_t buflen) -{ - struct gb_svc *svc = timesync_svc->svc; - struct gb_host_device *hd; - struct gb_timesync_interface *timesync_interface; - struct gb_interface *interface; - unsigned int len; - size_t off; - - /* AP/SVC */ - off = snprintf(buf, buflen, "%s frametime: ap=%llu %s=%llu ", - greybus_bus_type.name, - timesync_svc->ap_ping_frame_time, dev_name(&svc->dev), - timesync_svc->svc_ping_frame_time); - len = buflen - off; - - /* APB/GPB */ - if (len < buflen) { - hd = timesync_svc->timesync_hd->hd; - off += snprintf(&buf[off], len, "%s=%llu ", dev_name(&hd->dev), - timesync_svc->timesync_hd->ping_frame_time); - len = buflen - off; - } - - list_for_each_entry(timesync_interface, - ×ync_svc->interface_list, list) { - if (len < buflen) { - interface = timesync_interface->interface; - off += snprintf(&buf[off], len, "%s=%llu ", - dev_name(&interface->dev), - timesync_interface->ping_frame_time); - len = buflen - off; - } - } - if (len < buflen) - off += snprintf(&buf[off], len, "\n"); - return off; -} - -static size_t gb_timesync_log_frame_ktime(struct gb_timesync_svc *timesync_svc, - char *buf, size_t buflen) -{ - struct gb_svc *svc = timesync_svc->svc; - struct gb_host_device *hd; - struct gb_timesync_interface *timesync_interface; - struct gb_interface *interface; - struct timespec ts; - unsigned int len; - size_t off; - - /* AP */ - gb_timesync_to_timespec(timesync_svc, timesync_svc->ap_ping_frame_time, - &ts); - off = snprintf(buf, buflen, "%s frametime: ap=%lu.%lu ", - greybus_bus_type.name, ts.tv_sec, ts.tv_nsec); - len = buflen - off; - if (len >= buflen) - goto done; - - /* SVC */ - gb_timesync_to_timespec(timesync_svc, timesync_svc->svc_ping_frame_time, - &ts); - off += snprintf(&buf[off], len, "%s=%lu.%lu ", dev_name(&svc->dev), - ts.tv_sec, ts.tv_nsec); - len = buflen - off; - if (len >= buflen) - goto done; - - /* APB/GPB */ - hd = timesync_svc->timesync_hd->hd; - gb_timesync_to_timespec(timesync_svc, - timesync_svc->timesync_hd->ping_frame_time, - &ts); - off += snprintf(&buf[off], len, "%s=%lu.%lu ", - dev_name(&hd->dev), - ts.tv_sec, ts.tv_nsec); - len = buflen - off; - if (len >= buflen) - goto done; - - list_for_each_entry(timesync_interface, - ×ync_svc->interface_list, list) { - interface = timesync_interface->interface; - gb_timesync_to_timespec(timesync_svc, - timesync_interface->ping_frame_time, - &ts); - off += snprintf(&buf[off], len, "%s=%lu.%lu ", - dev_name(&interface->dev), - ts.tv_sec, ts.tv_nsec); - len = buflen - off; - if (len >= buflen) - goto done; - } - off += snprintf(&buf[off], len, "\n"); -done: - return off; -} - -/* - * Send an SVC initiated wake 'ping' to each TimeSync participant. - * Get the FrameTime from each participant associated with the wake - * ping. - */ -static void gb_timesync_ping(struct gb_timesync_svc *timesync_svc) -{ - struct gb_svc *svc = timesync_svc->svc; - struct gb_host_device *hd; - struct gb_timesync_interface *timesync_interface; - struct gb_control *control; - u64 *ping_frame_time; - int ret; - - /* Get access to the wake pins in the AP and SVC */ - ret = gb_timesync_platform_lock_bus(timesync_svc); - if (ret < 0) { - gb_timesync_platform_lock_bus_fail(timesync_svc, ret); - return; - } - ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask); - if (ret) { - dev_err(&svc->dev, - "gb_svc_timesync_wake_pins_acquire %d\n", ret); - gb_timesync_teardown(timesync_svc); - return; - } - - /* Have SVC generate a timesync ping */ - timesync_svc->capture_ping = true; - timesync_svc->svc_ping_frame_time = 0; - ret = gb_svc_timesync_ping(svc, ×ync_svc->svc_ping_frame_time); - timesync_svc->capture_ping = false; - if (ret) { - dev_err(&svc->dev, - "gb_svc_timesync_ping %d\n", ret); - gb_timesync_teardown(timesync_svc); - return; - } - - /* Get the ping FrameTime from each APB/GPB */ - hd = timesync_svc->timesync_hd->hd; - timesync_svc->timesync_hd->ping_frame_time = 0; - ret = hd->driver->timesync_get_last_event(hd, - ×ync_svc->timesync_hd->ping_frame_time); - if (ret) - dev_err(&hd->dev, "host timesync_get_last_event %d\n", ret); - - list_for_each_entry(timesync_interface, - ×ync_svc->interface_list, list) { - control = timesync_interface->interface->control; - timesync_interface->ping_frame_time = 0; - ping_frame_time = ×ync_interface->ping_frame_time; - ret = gb_control_timesync_get_last_event(control, - ping_frame_time); - if (ret) { - dev_err(×ync_interface->interface->dev, - "gb_control_timesync_get_last_event %d\n", ret); - } - } - - /* Ping success - move to timesync active */ - gb_svc_timesync_wake_pins_release(svc); - gb_timesync_platform_unlock_bus(); - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE); -} - -static void gb_timesync_log_ping_time(struct gb_timesync_svc *timesync_svc) -{ - char *buf; - - if (!timesync_svc->print_ping) - return; - - buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE); - dev_dbg(×ync_svc->svc->dev, "%s", buf); - kfree(buf); - } -} - -/* - * Perform the actual work of scheduled TimeSync logic. - */ -static void gb_timesync_worker(struct work_struct *work) -{ - struct delayed_work *delayed_work = to_delayed_work(work); - struct gb_timesync_svc *timesync_svc = - container_of(delayed_work, struct gb_timesync_svc, delayed_work); - - mutex_lock(×ync_svc->mutex); - - switch (timesync_svc->state) { - case GB_TIMESYNC_STATE_INIT: - gb_timesync_enable(timesync_svc); - break; - - case GB_TIMESYNC_STATE_WAIT_SVC: - dev_err(×ync_svc->svc->dev, - "timeout SVC strobe completion %d/%d\n", - timesync_svc->strobe, GB_TIMESYNC_MAX_STROBES); - gb_timesync_teardown(timesync_svc); - break; - - case GB_TIMESYNC_STATE_AUTHORITATIVE: - gb_timesync_authoritative(timesync_svc); - break; - - case GB_TIMESYNC_STATE_PING: - gb_timesync_ping(timesync_svc); - gb_timesync_log_ping_time(timesync_svc); - break; - - default: - pr_err("Invalid state %d for delayed work\n", - timesync_svc->state); - break; - } - - mutex_unlock(×ync_svc->mutex); -} - -/* - * Schedule a new TimeSync INIT or PING operation serialized w/r to - * gb_timesync_worker(). - */ -static int gb_timesync_schedule(struct gb_timesync_svc *timesync_svc, int state) -{ - int ret = 0; - - if (state != GB_TIMESYNC_STATE_INIT && state != GB_TIMESYNC_STATE_PING) - return -EINVAL; - - mutex_lock(×ync_svc->mutex); - if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) - gb_timesync_set_state_atomic(timesync_svc, state); - else - ret = -ENODEV; - - mutex_unlock(×ync_svc->mutex); - return ret; -} - -static int __gb_timesync_schedule_synchronous( - struct gb_timesync_svc *timesync_svc, int state) -{ - unsigned long flags; - int ret; - - ret = gb_timesync_schedule(timesync_svc, state); - if (ret) - return ret; - - ret = wait_event_interruptible(timesync_svc->wait_queue, - (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE || - timesync_svc->state == GB_TIMESYNC_STATE_INACTIVE || - timesync_svc->state == GB_TIMESYNC_STATE_INVALID)); - if (ret) - return ret; - - mutex_lock(×ync_svc->mutex); - spin_lock_irqsave(×ync_svc->spinlock, flags); - - ret = __gb_timesync_get_status(timesync_svc); - - spin_unlock_irqrestore(×ync_svc->spinlock, flags); - mutex_unlock(×ync_svc->mutex); - - return ret; -} - -static struct gb_timesync_svc *gb_timesync_find_timesync_svc( - struct gb_host_device *hd) -{ - struct gb_timesync_svc *timesync_svc; - - list_for_each_entry(timesync_svc, &gb_timesync_svc_list, list) { - if (timesync_svc->svc == hd->svc) - return timesync_svc; - } - return NULL; -} - -static struct gb_timesync_interface *gb_timesync_find_timesync_interface( - struct gb_timesync_svc *timesync_svc, - struct gb_interface *interface) -{ - struct gb_timesync_interface *timesync_interface; - - list_for_each_entry(timesync_interface, ×ync_svc->interface_list, list) { - if (timesync_interface->interface == interface) - return timesync_interface; - } - return NULL; -} - -int gb_timesync_schedule_synchronous(struct gb_interface *interface) -{ - int ret; - struct gb_timesync_svc *timesync_svc; - int retries; - - if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC)) - return 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - for (retries = 0; retries < GB_TIMESYNC_MAX_RETRIES; retries++) { - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) { - ret = -ENODEV; - goto done; - } - - ret = __gb_timesync_schedule_synchronous(timesync_svc, - GB_TIMESYNC_STATE_INIT); - if (!ret) - break; - } - if (ret && retries == GB_TIMESYNC_MAX_RETRIES) - ret = -ETIMEDOUT; -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_schedule_synchronous); - -void gb_timesync_schedule_asynchronous(struct gb_interface *interface) -{ - struct gb_timesync_svc *timesync_svc; - - if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC)) - return; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) - goto done; - - gb_timesync_schedule(timesync_svc, GB_TIMESYNC_STATE_INIT); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return; -} -EXPORT_SYMBOL_GPL(gb_timesync_schedule_asynchronous); - -static ssize_t gb_timesync_ping_read(struct file *file, char __user *ubuf, - size_t len, loff_t *offset, bool ktime) -{ - struct gb_timesync_svc *timesync_svc = file_inode(file)->i_private; - char *buf; - ssize_t ret = 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - mutex_lock(×ync_svc->mutex); - if (list_empty(×ync_svc->interface_list)) - ret = -ENODEV; - timesync_svc->print_ping = false; - mutex_unlock(×ync_svc->mutex); - if (ret) - goto done; - - ret = __gb_timesync_schedule_synchronous(timesync_svc, - GB_TIMESYNC_STATE_PING); - if (ret) - goto done; - - buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; - goto done; - } - - if (ktime) - ret = gb_timesync_log_frame_ktime(timesync_svc, buf, PAGE_SIZE); - else - ret = gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE); - if (ret > 0) - ret = simple_read_from_buffer(ubuf, len, offset, buf, ret); - kfree(buf); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} - -static ssize_t gb_timesync_ping_read_frame_time(struct file *file, - char __user *buf, - size_t len, loff_t *offset) -{ - return gb_timesync_ping_read(file, buf, len, offset, false); -} - -static ssize_t gb_timesync_ping_read_frame_ktime(struct file *file, - char __user *buf, - size_t len, loff_t *offset) -{ - return gb_timesync_ping_read(file, buf, len, offset, true); -} - -static const struct file_operations gb_timesync_debugfs_frame_time_ops = { - .read = gb_timesync_ping_read_frame_time, -}; - -static const struct file_operations gb_timesync_debugfs_frame_ktime_ops = { - .read = gb_timesync_ping_read_frame_ktime, -}; - -static int gb_timesync_hd_add(struct gb_timesync_svc *timesync_svc, - struct gb_host_device *hd) -{ - struct gb_timesync_host_device *timesync_hd; - - timesync_hd = kzalloc(sizeof(*timesync_hd), GFP_KERNEL); - if (!timesync_hd) - return -ENOMEM; - - WARN_ON(timesync_svc->timesync_hd); - timesync_hd->hd = hd; - timesync_svc->timesync_hd = timesync_hd; - - return 0; -} - -static void gb_timesync_hd_remove(struct gb_timesync_svc *timesync_svc, - struct gb_host_device *hd) -{ - if (timesync_svc->timesync_hd->hd == hd) { - kfree(timesync_svc->timesync_hd); - timesync_svc->timesync_hd = NULL; - return; - } - WARN_ON(1); -} - -int gb_timesync_svc_add(struct gb_svc *svc) -{ - struct gb_timesync_svc *timesync_svc; - int ret; - - timesync_svc = kzalloc(sizeof(*timesync_svc), GFP_KERNEL); - if (!timesync_svc) - return -ENOMEM; - - timesync_svc->work_queue = - create_singlethread_workqueue("gb-timesync-work_queue"); - - if (!timesync_svc->work_queue) { - kfree(timesync_svc); - return -ENOMEM; - } - - mutex_lock(&gb_timesync_svc_list_mutex); - INIT_LIST_HEAD(×ync_svc->interface_list); - INIT_DELAYED_WORK(×ync_svc->delayed_work, gb_timesync_worker); - mutex_init(×ync_svc->mutex); - spin_lock_init(×ync_svc->spinlock); - init_waitqueue_head(×ync_svc->wait_queue); - - timesync_svc->svc = svc; - timesync_svc->frame_time_offset = 0; - timesync_svc->capture_ping = false; - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE); - - timesync_svc->frame_time_dentry = - debugfs_create_file("frame-time", S_IRUGO, svc->debugfs_dentry, - timesync_svc, - &gb_timesync_debugfs_frame_time_ops); - timesync_svc->frame_ktime_dentry = - debugfs_create_file("frame-ktime", S_IRUGO, svc->debugfs_dentry, - timesync_svc, - &gb_timesync_debugfs_frame_ktime_ops); - - list_add(×ync_svc->list, &gb_timesync_svc_list); - ret = gb_timesync_hd_add(timesync_svc, svc->hd); - if (ret) { - list_del(×ync_svc->list); - debugfs_remove(timesync_svc->frame_ktime_dentry); - debugfs_remove(timesync_svc->frame_time_dentry); - destroy_workqueue(timesync_svc->work_queue); - kfree(timesync_svc); - goto done; - } - - init_timer(×ync_svc->ktime_timer); - timesync_svc->ktime_timer.function = gb_timesync_ktime_timer_fn; - timesync_svc->ktime_timer.expires = jiffies + GB_TIMESYNC_KTIME_UPDATE; - timesync_svc->ktime_timer.data = (unsigned long)timesync_svc; - add_timer(×ync_svc->ktime_timer); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_svc_add); - -void gb_timesync_svc_remove(struct gb_svc *svc) -{ - struct gb_timesync_svc *timesync_svc; - struct gb_timesync_interface *timesync_interface; - struct gb_timesync_interface *next; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(svc->hd); - if (!timesync_svc) - goto done; - - cancel_delayed_work_sync(×ync_svc->delayed_work); - - mutex_lock(×ync_svc->mutex); - - gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INVALID); - del_timer_sync(×ync_svc->ktime_timer); - gb_timesync_teardown(timesync_svc); - - gb_timesync_hd_remove(timesync_svc, svc->hd); - list_for_each_entry_safe(timesync_interface, next, - ×ync_svc->interface_list, list) { - list_del(×ync_interface->list); - kfree(timesync_interface); - } - debugfs_remove(timesync_svc->frame_ktime_dentry); - debugfs_remove(timesync_svc->frame_time_dentry); - destroy_workqueue(timesync_svc->work_queue); - list_del(×ync_svc->list); - - mutex_unlock(×ync_svc->mutex); - - kfree(timesync_svc); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); -} -EXPORT_SYMBOL_GPL(gb_timesync_svc_remove); - -/* - * Add a Greybus Interface to the set of TimeSync Interfaces. - */ -int gb_timesync_interface_add(struct gb_interface *interface) -{ - struct gb_timesync_svc *timesync_svc; - struct gb_timesync_interface *timesync_interface; - int ret = 0; - - if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC)) - return 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) { - ret = -ENODEV; - goto done; - } - - timesync_interface = kzalloc(sizeof(*timesync_interface), GFP_KERNEL); - if (!timesync_interface) { - ret = -ENOMEM; - goto done; - } - - mutex_lock(×ync_svc->mutex); - timesync_interface->interface = interface; - list_add(×ync_interface->list, ×ync_svc->interface_list); - timesync_svc->strobe_mask |= 1 << interface->interface_id; - mutex_unlock(×ync_svc->mutex); - -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_interface_add); - -/* - * Remove a Greybus Interface from the set of TimeSync Interfaces. - */ -void gb_timesync_interface_remove(struct gb_interface *interface) -{ - struct gb_timesync_svc *timesync_svc; - struct gb_timesync_interface *timesync_interface; - - if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC)) - return; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) - goto done; - - timesync_interface = gb_timesync_find_timesync_interface(timesync_svc, - interface); - if (!timesync_interface) - goto done; - - mutex_lock(×ync_svc->mutex); - timesync_svc->strobe_mask &= ~(1 << interface->interface_id); - list_del(×ync_interface->list); - kfree(timesync_interface); - mutex_unlock(×ync_svc->mutex); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); -} -EXPORT_SYMBOL_GPL(gb_timesync_interface_remove); - -/* - * Give the authoritative FrameTime to the calling function. Returns zero if we - * are not in GB_TIMESYNC_STATE_ACTIVE. - */ -static u64 gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc) -{ - unsigned long flags; - u64 ret; - - spin_lock_irqsave(×ync_svc->spinlock, flags); - if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE) - ret = __gb_timesync_get_frame_time(timesync_svc); - else - ret = 0; - spin_unlock_irqrestore(×ync_svc->spinlock, flags); - return ret; -} - -u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface) -{ - struct gb_timesync_svc *timesync_svc; - u64 ret = 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) - goto done; - - ret = gb_timesync_get_frame_time(timesync_svc); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_interface); - -u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc) -{ - struct gb_timesync_svc *timesync_svc; - u64 ret = 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(svc->hd); - if (!timesync_svc) - goto done; - - ret = gb_timesync_get_frame_time(timesync_svc); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_svc); - -/* Incrementally updates the conversion base from FrameTime to ktime */ -static void gb_timesync_ktime_timer_fn(unsigned long data) -{ - struct gb_timesync_svc *timesync_svc = - (struct gb_timesync_svc *)data; - unsigned long flags; - u64 frame_time; - struct timespec ts; - - spin_lock_irqsave(×ync_svc->spinlock, flags); - - if (timesync_svc->state != GB_TIMESYNC_STATE_ACTIVE) - goto done; - - ktime_get_ts(&ts); - frame_time = __gb_timesync_get_frame_time(timesync_svc); - gb_timesync_store_ktime(timesync_svc, ts, frame_time); - -done: - spin_unlock_irqrestore(×ync_svc->spinlock, flags); - mod_timer(×ync_svc->ktime_timer, - jiffies + GB_TIMESYNC_KTIME_UPDATE); -} - -int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time, - struct timespec *ts) -{ - struct gb_timesync_svc *timesync_svc; - int ret = 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(svc->hd); - if (!timesync_svc) { - ret = -ENODEV; - goto done; - } - ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_svc); - -int gb_timesync_to_timespec_by_interface(struct gb_interface *interface, - u64 frame_time, struct timespec *ts) -{ - struct gb_timesync_svc *timesync_svc; - int ret = 0; - - mutex_lock(&gb_timesync_svc_list_mutex); - timesync_svc = gb_timesync_find_timesync_svc(interface->hd); - if (!timesync_svc) { - ret = -ENODEV; - goto done; - } - - ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts); -done: - mutex_unlock(&gb_timesync_svc_list_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_interface); - -void gb_timesync_irq(struct gb_timesync_svc *timesync_svc) -{ - unsigned long flags; - u64 strobe_time; - bool strobe_is_ping = true; - struct timespec ts; - - ktime_get_ts(&ts); - strobe_time = __gb_timesync_get_frame_time(timesync_svc); - - spin_lock_irqsave(×ync_svc->spinlock, flags); - - if (timesync_svc->state == GB_TIMESYNC_STATE_PING) { - if (!timesync_svc->capture_ping) - goto done_nolog; - timesync_svc->ap_ping_frame_time = strobe_time; - goto done_log; - } else if (timesync_svc->state != GB_TIMESYNC_STATE_WAIT_SVC) { - goto done_nolog; - } - - timesync_svc->strobe_data[timesync_svc->strobe].frame_time = strobe_time; - timesync_svc->strobe_data[timesync_svc->strobe].ts = ts; - - if (++timesync_svc->strobe == GB_TIMESYNC_MAX_STROBES) { - gb_timesync_set_state(timesync_svc, - GB_TIMESYNC_STATE_AUTHORITATIVE); - } - strobe_is_ping = false; -done_log: - trace_gb_timesync_irq(strobe_is_ping, timesync_svc->strobe, - GB_TIMESYNC_MAX_STROBES, strobe_time); -done_nolog: - spin_unlock_irqrestore(×ync_svc->spinlock, flags); -} -EXPORT_SYMBOL(gb_timesync_irq); - -int __init gb_timesync_init(void) -{ - int ret = 0; - - ret = gb_timesync_platform_init(); - if (ret) { - pr_err("timesync platform init fail!\n"); - return ret; - } - - gb_timesync_clock_rate = gb_timesync_platform_get_clock_rate(); - - /* Calculate nanoseconds and femtoseconds per clock */ - gb_timesync_fs_per_clock = FSEC_PER_SEC; - do_div(gb_timesync_fs_per_clock, gb_timesync_clock_rate); - gb_timesync_ns_per_clock = NSEC_PER_SEC; - do_div(gb_timesync_ns_per_clock, gb_timesync_clock_rate); - - /* Calculate the maximum number of clocks we will convert to ktime */ - gb_timesync_max_ktime_diff = - GB_TIMESYNC_MAX_KTIME_CONVERSION * gb_timesync_clock_rate; - - pr_info("Time-Sync @ %lu Hz max ktime conversion +/- %d seconds\n", - gb_timesync_clock_rate, GB_TIMESYNC_MAX_KTIME_CONVERSION); - return 0; -} - -void gb_timesync_exit(void) -{ - gb_timesync_platform_exit(); -} diff --git a/drivers/staging/greybus/timesync.h b/drivers/staging/greybus/timesync.h deleted file mode 100644 index 72fc9a35a002..000000000000 --- a/drivers/staging/greybus/timesync.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * TimeSync API driver. - * - * Copyright 2016 Google Inc. - * Copyright 2016 Linaro Ltd. - * - * Released under the GPLv2 only. - */ - -#ifndef __TIMESYNC_H -#define __TIMESYNC_H - -struct gb_svc; -struct gb_interface; -struct gb_timesync_svc; - -/* Platform */ -u64 gb_timesync_platform_get_counter(void); -u32 gb_timesync_platform_get_clock_rate(void); -int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata); -void gb_timesync_platform_unlock_bus(void); - -int gb_timesync_platform_init(void); -void gb_timesync_platform_exit(void); - -/* Core API */ -int gb_timesync_interface_add(struct gb_interface *interface); -void gb_timesync_interface_remove(struct gb_interface *interface); -int gb_timesync_svc_add(struct gb_svc *svc); -void gb_timesync_svc_remove(struct gb_svc *svc); - -u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface); -u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc); -int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time, - struct timespec *ts); -int gb_timesync_to_timespec_by_interface(struct gb_interface *interface, - u64 frame_time, struct timespec *ts); - -int gb_timesync_schedule_synchronous(struct gb_interface *intf); -void gb_timesync_schedule_asynchronous(struct gb_interface *intf); -void gb_timesync_irq(struct gb_timesync_svc *timesync_svc); -int gb_timesync_init(void); -void gb_timesync_exit(void); - -#endif /* __TIMESYNC_H */ diff --git a/drivers/staging/greybus/timesync_platform.c b/drivers/staging/greybus/timesync_platform.c deleted file mode 100644 index 27f75b17679b..000000000000 --- a/drivers/staging/greybus/timesync_platform.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * TimeSync API driver. - * - * Copyright 2016 Google Inc. - * Copyright 2016 Linaro Ltd. - * - * Released under the GPLv2 only. - * - * This code reads directly from an ARMv7 memory-mapped timer that lives in - * MMIO space. Since this counter lives inside of MMIO space its shared between - * cores and that means we don't have to worry about issues like TSC on x86 - * where each time-stamp-counter (TSC) is local to a particular core. - * - * Register-level access code is based on - * drivers/clocksource/arm_arch_timer.c - */ -#include <linux/cpufreq.h> -#include <linux/of_platform.h> - -#include "greybus.h" -#include "arche_platform.h" - -#define DEFAULT_FRAMETIME_CLOCK_HZ 19200000 - -static u32 gb_timesync_clock_frequency; -int (*arche_platform_change_state_cb)(enum arche_platform_state state, - struct gb_timesync_svc *pdata); -EXPORT_SYMBOL_GPL(arche_platform_change_state_cb); - -u64 gb_timesync_platform_get_counter(void) -{ - return (u64)get_cycles(); -} - -u32 gb_timesync_platform_get_clock_rate(void) -{ - if (unlikely(!gb_timesync_clock_frequency)) { - gb_timesync_clock_frequency = cpufreq_get(0); - if (!gb_timesync_clock_frequency) - gb_timesync_clock_frequency = DEFAULT_FRAMETIME_CLOCK_HZ; - } - - return gb_timesync_clock_frequency; -} - -int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata) -{ - if (!arche_platform_change_state_cb) - return 0; - - return arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_TIME_SYNC, - pdata); -} - -void gb_timesync_platform_unlock_bus(void) -{ - if (!arche_platform_change_state_cb) - return; - - arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_ACTIVE, NULL); -} - -static const struct of_device_id arch_timer_of_match[] = { - { .compatible = "google,greybus-frame-time-counter", }, - {}, -}; - -int __init gb_timesync_platform_init(void) -{ - struct device_node *np; - - np = of_find_matching_node(NULL, arch_timer_of_match); - if (!np) { - /* Tolerate not finding to allow BBB etc to continue */ - pr_warn("Unable to find a compatible ARMv7 timer\n"); - return 0; - } - - if (of_property_read_u32(np, "clock-frequency", - &gb_timesync_clock_frequency)) { - pr_err("Unable to find timer clock-frequency\n"); - return -ENODEV; - } - - return 0; -} - -void gb_timesync_platform_exit(void) {} diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index f7f4cd6fb55b..18d7a3d1f3c7 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -168,7 +168,7 @@ GET_AVG(latency_avg); GET_AVG(apbridge_unipro_latency_avg); GET_AVG(gbphy_firmware_latency_avg); -void abort() +void abort(void) { _exit(1); } @@ -521,7 +521,6 @@ static int log_results(struct loopback_test *t) int fd, i, len, ret; struct tm tm; time_t local_time; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; char file_name[MAX_SYSFS_PATH]; char data[CSV_MAX_LINE]; @@ -538,7 +537,7 @@ static int log_results(struct loopback_test *t) snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv", t->test_name, t->size, t->iteration_max); - fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode); + fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd < 0) { fprintf(stderr, "unable to open %s for appendation\n", file_name); abort(); diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 6d39f4a04754..ab0dbf5cab5a 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -624,14 +624,14 @@ static int get_serial_info(struct gb_tty *gb_tty, struct serial_struct tmp; memset(&tmp, 0, sizeof(tmp)); - tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST; tmp.type = PORT_16550A; tmp.line = gb_tty->minor; tmp.xmit_fifo_size = 16; tmp.baud_base = 9600; tmp.close_delay = gb_tty->port.close_delay / 10; - tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; + tmp.closing_wait = + gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; if (copy_to_user(info, &tmp, sizeof(tmp))) return -EFAULT; @@ -1000,7 +1000,8 @@ static int gb_tty_init(void) gb_tty_driver->subtype = SERIAL_TYPE_NORMAL; gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; gb_tty_driver->init_termios = tty_std_termios; - gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | + CREAD | HUPCL | CLOCAL; tty_set_operations(gb_tty_driver, &gb_ops); retval = tty_register_driver(gb_tty_driver); diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index 4ba0e168930f..77a2365a55e6 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -70,7 +70,9 @@ static void gb_vibrator_worker(struct work_struct *work) { struct delayed_work *delayed_work = to_delayed_work(work); struct gb_vibrator_device *vib = - container_of(delayed_work, struct gb_vibrator_device, delayed_work); + container_of(delayed_work, + struct gb_vibrator_device, + delayed_work); turn_off(vib); } diff --git a/drivers/staging/i4l/Documentation/README.act2000 b/drivers/staging/i4l/Documentation/README.act2000 deleted file mode 100644 index ce7115e7f4ce..000000000000 --- a/drivers/staging/i4l/Documentation/README.act2000 +++ /dev/null @@ -1,104 +0,0 @@ -$Id: README.act2000,v 1.3 2000/08/06 09:22:51 armin Exp $ - -This document describes the ACT2000 driver for the -IBM Active 2000 ISDN card. - -There are 3 Types of this card available. A ISA-, MCA-, and PCMCIA-Bus -Version. Currently, only the ISA-Bus version of the card is supported. -However MCA and PCMCIA will follow soon. - -The ISA-Bus Version uses 8 IO-ports. The base port address has to be set -manually using the DIP switches. - -Setting up the DIP switches for the IBM Active 2000 ISDN card: - - Note: S5 and S6 always set off! - - S1 S2 S3 S4 Base-port - on on on on 0x0200 (Factory default) - off on on on 0x0240 - on off on on 0x0280 - off off on on 0x02c0 - on on off on 0x0300 - off on off on 0x0340 - on off off on 0x0380 - on on on off 0xcfe0 - off on on off 0xcfa0 - on off on off 0xcf60 - off off on off 0xcf20 - on on off off 0xcee0 - off on off off 0xcea0 - on off off off 0xce60 - off off off off Card disabled - -IRQ is configured by software. Possible values are: - - 3, 5, 7, 10, 11, 12, 15 and none (polled mode) - - -The ACT2000 driver may either be built into the kernel or as a module. -Initialization depends on how the driver is built: - -Driver built into the kernel: - - The ACT2000 driver can be configured using the commandline-feature while - loading the kernel with LILO or LOADLIN. It accepts the following syntax: - - act2000=b,p,i[,idstring] - - where - - b = Bus-Type (1=ISA, 2=MCA, 3=PCMCIA) - p = portbase (-1 means autoprobe) - i = Interrupt (-1 means use next free IRQ, 0 means polled mode) - - The idstring is an arbitrary string used for referencing the card - by the actctrl tool later. - - Defaults used, when no parameters given at all: - - 1,-1,-1,"" - - which means: Autoprobe for an ISA card, use next free IRQ, let the - ISDN linklevel fill the IdString (usually "line0" for the first card). - - If you like to use more than one card, you can use the program - "actctrl" from the utility-package to configure additional cards. - - Using the "actctrl"-utility, portbase and irq can also be changed - during runtime. The D-channel protocol is configured by the "dproto" - option of the "actctrl"-utility after loading the firmware into the - card's memory using the "actctrl"-utility. - -Driver built as module: - - The module act2000.o can be configured during modprobe (insmod) by - appending its parameters to the modprobe resp. insmod commandline. - The following syntax is accepted: - - act_bus=b act_port=p act_irq=i act_id=idstring - - where b, p, i and idstring have the same meanings as the parameters - described for the builtin version above. - - Using the "actctrl"-utility, the same features apply to the modularized - version as to the kernel-builtin one. (i.e. loading of firmware and - configuring the D-channel protocol) - -Loading the firmware into the card: - - The firmware is supplied together with the isdn4k-utils package. It - can be found in the subdirectory act2000/firmware/ - - Assuming you have installed the utility-package correctly, the firmware - will be downloaded into the card using the following command: - - actctrl -d idstring load /etc/isdn/bip11.btl - - where idstring is the Name of the card, given during insmod-time or - (for kernel-builtin driver) on the kernel commandline. If only one - ISDN card is used, the -d isdstrin may be omitted. - - For further documentation (adding more IBM Active 2000 cards), refer to - the manpage actctrl.8 which is included in the isdn4k-utils package. - diff --git a/drivers/staging/i4l/Documentation/README.icn b/drivers/staging/i4l/Documentation/README.icn deleted file mode 100644 index 13f833d4e910..000000000000 --- a/drivers/staging/i4l/Documentation/README.icn +++ /dev/null @@ -1,148 +0,0 @@ -$Id: README.icn,v 1.7 2000/08/06 09:22:51 armin Exp $ - -You can get the ICN-ISDN-card from: - -Thinking Objects Software GmbH -Versbacher Röthe 159 -97078 Würzburg -Tel: +49 931 2877950 -Fax: +49 931 2877951 - -email info@think.de -WWW http:/www.think.de - - -The card communicates with the PC by two interfaces: - 1. A range of 4 successive port-addresses, whose base address can be - configured with the switches. - 2. A memory window with 16KB-256KB size, which can be setup in 16k steps - over the whole range of 16MB. Isdn4linux only uses a 16k window. - The base address of the window can be configured when loading - the lowlevel-module (see README). If using more than one card, - all cards are mapped to the same window and activated as needed. - -Setting up the IO-address dipswitches for the ICN-ISDN-card: - - Two types of cards exist, one with dip-switches and one with - hook-switches. - - 1. Setting for the card with hook-switches: - - (0 = switch closed, 1 = switch open) - - S3 S2 S1 Base-address - 0 0 0 0x300 - 0 0 1 0x310 - 0 1 0 0x320 (Default for isdn4linux) - 0 1 1 0x330 - 1 0 0 0x340 - 1 0 1 0x350 - 1 1 0 0x360 - 1 1 1 NOT ALLOWED! - - 2. Setting for the card with dip-switches: - - (0 = switch closed, 1 = switch open) - - S1 S2 S3 S4 Base-Address - 0 0 0 0 0x300 - 0 0 0 1 0x310 - 0 0 1 0 0x320 (Default for isdn4linux) - 0 0 1 1 0x330 - 0 1 0 0 0x340 - 0 1 0 1 0x350 - 0 1 1 0 0x360 - 0 1 1 1 NOT ALLOWED! - 1 0 0 0 0x308 - 1 0 0 1 0x318 - 1 0 1 0 0x328 - 1 0 1 1 0x338 - 1 1 0 0 0x348 - 1 1 0 1 0x358 - 1 1 1 0 0x368 - 1 1 1 1 NOT ALLOWED! - -The ICN driver may be built into the kernel or as a module. Initialization -depends on how the driver is built: - -Driver built into the kernel: - - The ICN driver can be configured using the commandline-feature while - loading the kernel with LILO or LOADLIN. It accepts the following syntax: - - icn=p,m[,idstring1[,idstring2]] - - where - - p = portbase (default: 0x320) - m = shared memory (default: 0xd0000) - - When using the ICN double card (4B), you MUST define TWO idstrings. - idstring must start with a character! There is no way for the driver - to distinguish between a 2B and 4B type card. Therefore, by supplying - TWO idstrings, you tell the driver that you have a 4B installed. - - If you like to use more than one card, you can use the program - "icnctrl" from the utility-package to configure additional cards. - You need to configure shared memory only once, since the icn-driver - maps all cards into the same address-space. - - Using the "icnctrl"-utility, portbase and shared memory can also be - changed during runtime. - - The D-channel protocol is configured by loading different firmware - into the card's memory using the "icnctrl"-utility. - - -Driver built as module: - - The module icn.o can be configured during "insmod'ing" it by - appending its parameters to the insmod-commandline. The following - syntax is accepted: - - portbase=p membase=m icn_id=idstring [icn_id2=idstring2] - - where p, m, idstring1 and idstring2 have the same meanings as the - parameters described for the kernel-version above. - - When using the ICN double card (4B), you MUST define TWO idstrings. - idstring must start with a character! There is no way for the driver - to distinguish between a 2B and 4B type card. Therefore, by supplying - TWO idstrings, you tell the driver that you have a 4B installed. - - Using the "icnctrl"-utility, the same features apply to the modularized - version like to the kernel-builtin one. - - The D-channel protocol is configured by loading different firmware - into the card's memory using the "icnctrl"-utility. - -Loading the firmware into the card: - - The firmware is supplied together with the isdn4k-utils package. It - can be found in the subdirectory icnctrl/firmware/ - - There are 3 files: - - loadpg.bin - Image of the bootstrap loader. - pc_1t_ca.bin - Image of firmware for german 1TR6 protocol. - pc_eu_ca.bin - Image if firmware for EDSS1 (Euro-ISDN) protocol. - - Assuming you have installed the utility-package correctly, the firmware - will be downloaded into the 2B-card using the following command: - - icnctrl -d Idstring load /etc/isdn/loadpg.bin /etc/isdn/pc_XX_ca.bin - - where XX is either "1t" or "eu", depending on the D-Channel protocol - used on your S0-bus and Idstring is the Name of the card, given during - insmod-time or (for kernel-builtin driver) on the kernel commandline. - - To load a 4B-card, the same command is used, except a second firmware - file is appended to the commandline of icnctrl. - - -> After downloading firmware, the two LEDs at the back cover of the card - (ICN-4B: 4 LEDs) must be blinking intermittently now. If a connection - is up, the corresponding led is lit continuously. - - For further documentation (adding more ICN-cards), refer to the manpage - icnctrl.8 which is included in the isdn4k-utils package. - diff --git a/drivers/staging/i4l/Documentation/README.pcbit b/drivers/staging/i4l/Documentation/README.pcbit deleted file mode 100644 index 5125002282e5..000000000000 --- a/drivers/staging/i4l/Documentation/README.pcbit +++ /dev/null @@ -1,40 +0,0 @@ ------------------------------------------------------------------------------- - README file for the PCBIT-D Device Driver. ------------------------------------------------------------------------------- - -The PCBIT is a Euro ISDN adapter manufactured in Portugal by Octal and -developed in cooperation with Portugal Telecom and Inesc. -The driver interfaces with the standard kernel isdn facilities -originally developed by Fritz Elfert in the isdn4linux project. - -The common versions of the pcbit board require a firmware that is -distributed (and copyrighted) by the manufacturer. To load this -firmware you need "pcbitctl" available on the standard isdn4k-utils -package or in the pcbit package available in: - -ftp://ftp.di.fc.ul.pt/pub/systems/Linux/isdn - -Known Limitations: - -- The board reset procedure is at the moment incorrect and will only -allow you to load the firmware after a hard reset. - -- Only HDLC in B-channels is supported at the moment. There is no -current support for X.25 in B or D channels nor LAPD in B -channels. The main reason is that these two other protocol modes have, -to my knowledge, very little use. If you want to see them implemented -*do* send me a mail. - -- The driver often triggers errors in the board that I and the -manufacturer believe to be caused by bugs in the firmware. The current -version includes several procedures for error recovery that should -allow normal operation. Plans for the future include cooperation with -the manufacturer in order to solve this problem. - -Information/hints/help can be obtained in the linux isdn -mailing list (isdn4linux@listserv.isdn4linux.de) or directly from me. - -regards, - Pedro. - -<roque@di.fc.ul.pt> diff --git a/drivers/staging/i4l/Documentation/README.sc b/drivers/staging/i4l/Documentation/README.sc deleted file mode 100644 index 1153cd926059..000000000000 --- a/drivers/staging/i4l/Documentation/README.sc +++ /dev/null @@ -1,281 +0,0 @@ -Welcome to Beta Release 2 of the combination ISDN driver for SpellCaster's -ISA ISDN adapters. Please note this release 2 includes support for the -DataCommute/BRI and TeleCommute/BRI adapters only and any other use is -guaranteed to fail. If you have a DataCommute/PRI installed in the test -computer, we recommend removing it as it will be detected but will not -be usable. To see what we have done to Beta Release 2, see section 3. - -Speaking of guarantees, THIS IS BETA SOFTWARE and as such contains -bugs and defects either known or unknown. Use this software at your own -risk. There is NO SUPPORT for this software. Some help may be available -through the web site or the mailing list but such support is totally at -our own option and without warranty. If you choose to assume all and -total risk by using this driver, we encourage you to join the beta -mailing list. - -To join the Linux beta mailing list, send a message to: -majordomo@spellcast.com with the words "subscribe linux-beta" as the only -contents of the message. Do not include a signature. If you choose to -remove yourself from this list at a later date, send another message to -the same address with the words "unsubscribe linux-beta" as its only -contents. - -TABLE OF CONTENTS ------------------ - 1. Introduction - 1.1 What is ISDN4Linux? - 1.2 What is different between this driver and previous drivers? - 1.3 How do I setup my system with the correct software to use - this driver release? - - 2. Basic Operations - 2.1 Unpacking and installing the driver - 2.2 Read the man pages!!! - 2.3 Installing the driver - 2.4 Removing the driver - 2.5 What to do if it doesn't load - 2.6 How to setup ISDN4Linux with the driver - - 3. Beta Change Summaries and Miscellaneous Notes - -1. Introduction ---------------- - -The revision 2 Linux driver for SpellCaster ISA ISDN adapters is built -upon ISDN4Linux available separately or as included in Linux 2.0 and later. -The driver will support a maximum of 4 adapters in any one system of any -type including DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI for a -maximum of 92 channels for host. The driver is supplied as a module in -source form and needs to be complied before it can be used. It has been -tested on Linux 2.0.20. - -1.1 What Is ISDN4Linux - -ISDN4Linux is a driver and set of tools used to access and use ISDN devices -on a Linux platform in a common and standard way. It supports HDLC and PPP -protocols and offers channel bundling and MLPPP support. To use ISDN4Linux -you need to configure your kernel for ISDN support and get the ISDN4Linux -tool kit from our web site. - -ISDN4Linux creates a channel pool from all of the available ISDN channels -and therefore can function across adapters. When an ISDN4Linux compliant -driver (such as ours) is loaded, all of the channels go into a pool and -are used on a first-come first-served basis. In addition, individual -channels can be specifically bound to particular interfaces. - -1.2 What is different between this driver and previous drivers? - -The revision 2 driver besides adopting the ISDN4Linux architecture has many -subtle and not so subtle functional differences from previous releases. These -include: - - More efficient shared memory management combined with a simpler - configuration. All adapters now use only 16Kbytes of shared RAM - versus between 16K and 64K. New methods for using the shared RAM - allow us to utilize all of the available RAM on the adapter through - only one 16K page. - - Better detection of available upper memory. The probing routines - have been improved to better detect available shared RAM pages and - used pages are now locked. - - Decreased loading time and a wider range of I/O ports probed. - We have significantly reduced the amount of time it takes to load - the driver and at the same time doubled the number of I/O ports - probed increasing the likelihood of finding an adapter. - - We now support all ISA adapter models with a single driver instead - of separate drivers for each model. The revision 2 driver supports - the DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI in any - combination up to a maximum of four adapters per system. - - On board PPP protocol support has been removed in favour of the - sync-PPP support used in ISDN4Linux. This means more control of - the protocol parameters, faster negotiation time and a more - familiar interface. - -1.3 How do I setup my system with the correct software to use - this driver release? - -Before you can compile, install and use the SpellCaster ISA ISDN driver, you -must ensure that the following software is installed, configured and running: - - - Linux kernel 2.0.20 or later with the required init and ps - versions. Please see your distribution vendor for the correct - utility packages. The latest kernel is available from - ftp://sunsite.unc.edu/pub/Linux/kernel/v2.0/ - - - The latest modules package (modules-2.0.0.tar.gz) from - ftp://sunsite.unc.edu/pub/Linux/kernel/modules-2.0.0.tar.gz - - - The ISDN4Linux tools available from - ftp://ftp.franken.de/pub/isdn4linux/v2.0/isdn4k-utils-2.0.tar.gz - This package may fail to compile for you so you can alternatively - get a pre-compiled version from - ftp://ftp.spellcast.com/pub/drivers/isdn4linux/isdn4k-bin-2.0.tar.gz - - -2. Basic Operations -------------------- - -2.1 Unpacking and installing the driver - - 1. As root, create a directory in a convenient place. We suggest - /usr/src/spellcaster. - - 2. Unpack the archive with : - tar xzf sc-n.nn.tar.gz -C /usr/src/spellcaster - - 3. Change directory to /usr/src/spellcaster - - 4. Read the README and RELNOTES files. - - 5. Run 'make' and if all goes well, run 'make install'. - -2.2 Read the man pages!!! - -Make sure you read the scctrl(8) and sc(4) manual pages before continuing -any further. Type 'man 8 scctrl' and 'man 4 sc'. - -2.3 Installing the driver - -To install the driver, type '/sbin/insmod sc' as root. sc(4) details options -you can specify but you shouldn't need to use any unless this doesn't work. - -Make sure the driver loaded and detected all of the adapters by typing -'dmesg'. - -The driver can be configured so that it is loaded upon startup. To do this, -edit the file "/etc/modules/'uname -f'/'uname -v'" and insert the driver name -"sc" into this file. - -2.4 Removing the driver - -To remove the driver, delete any interfaces that may exist (see isdnctrl(8) -for more on this) and then type '/sbin/rmmod sc'. - -2.5 What to do if it doesn't load - -If, when you try to install the driver, you get a message mentioning -'register_isdn' then you do not have the ISDN4Linux system installed. Please -make sure that ISDN support is configured in the kernel. - -If you get a message that says 'initialization of sc failed', then the -driver failed to detect an adapter or failed to find resources needed such -as a free IRQ line or shared memory segment. If you are sure there are free -resources available, use the insmod options detailed in sc(4) to override -the probing function. - -Upon testing, the following problem was noted, the driver would load without -problems, but the board would not respond beyond that point. When a check was -done with 'cat /proc/interrupts' the interrupt count for sc was 0. In the event -of this problem, change the BIOS settings so that the interrupts in question are -reserved for ISA use only. - - -2.6 How to setup ISDN4Linux with the driver - -There are three main configurations which you can use with the driver: - -A) Basic HDLC connection -B) PPP connection -C) MLPPP connection - -It should be mentioned here that you may also use a tty connection if you -desire. The Documentation directory of the isdn4linux subsystem offers good -documentation on this feature. - -A) 10 steps to the establishment of a basic HDLC connection ------------------------------------------------------------ - -- please open the isdn-hdlc file in the examples directory and follow along... - - This file is a script used to configure a BRI ISDN TA to establish a - basic HDLC connection between its two channels. Two network - interfaces are created and two routes added between the channels. - - i) using the isdnctrl utility, add an interface with "addif" and - name it "isdn0" - ii) add the outgoing and inbound telephone numbers - iii) set the Layer 2 protocol to hdlc - iv) set the eaz of the interface to be the phone number of that - specific channel - v) to turn the callback features off, set the callback to "off" and - the callback delay (cbdelay) to 0. - vi) the hangup timeout can be set to a specified number of seconds - vii) the hangup upon incoming call can be set on or off - viii) use the ifconfig command to bring up the network interface with - a specific IP address and point to point address - ix) add a route to the IP address through the isdn0 interface - x) a ping should result in the establishment of the connection - - -B) Establishment of a PPP connection ------------------------------------- - -- please open the isdn-ppp file in the examples directory and follow along... - - This file is a script used to configure a BRI ISDN TA to establish a - PPP connection between the two channels. The file is almost - identical to the HDLC connection example except that the packet - encapsulation type has to be set. - - use the same procedure as in the HDLC connection from steps i) to - iii) then, after the Layer 2 protocol is set, set the encapsulation - "encap" to syncppp. With this done, the rest of the steps, iv) to x) - can be followed from above. - - Then, the ipppd (ippp daemon) must be setup: - - xi) use the ipppd function found in /sbin/ipppd to set the following: - xii) take out (minus) VJ compression and bsd compression - xiii) set the mru size to 2000 - xiv) link the two /dev interfaces to the daemon - -NOTE: A "*" in the inbound telephone number specifies that a call can be -accepted on any number. - -C) Establishment of a MLPPP connection --------------------------------------- - -- please open the isdn-mppp file in the examples directory and follow along... - - This file is a script used to configure a BRI ISDN TA to accept a - Multi Link PPP connection. - - i) using the isdnctrl utility, add an interface with "addif" and - name it "ippp0" - ii) add the inbound telephone number - iii) set the Layer 2 protocol to hdlc and the Layer 3 protocol to - trans (transparent) - iv) set the packet encapsulation to syncppp - v) set the eaz of the interface to be the phone number of that - specific channel - vi) to turn the callback features off, set the callback to "off" and - the callback delay (cbdelay) to 0. - vi) the hangup timeout can be set to a specified number of seconds - vii) the hangup upon incoming call can be set on or off - viii) add a slave interface and name it "ippp32" for example - ix) set the similar parameters for the ippp32 interface - x) use the ifconfig command to bring-up the ippp0 interface with a - specific IP address and point to point address - xi) add a route to the IP address through the ippp0 interface - xii) use the ipppd function found in /sbin/ipppd to set the following: - xiii) take out (minus) bsd compression - xiv) set the mru size to 2000 - xv) add (+) the multi-link function "+mp" - xvi) link the two /dev interfaces to the daemon - -NOTE: To use the MLPPP connection to dial OUT to a MLPPP connection, change -the inbound telephone numbers to the outgoing telephone numbers of the MLPPP -host. - - -3. Beta Change Summaries and Miscellaneous Notes ------------------------------------------------- -When using the "scctrl" utility to upload firmware revisions on the board, -please note that the byte count displayed at the end of the operation may be -different from the total number of bytes in the "dcbfwn.nn.sr" file. Please -disregard the displayed byte count. - -It was noted that in Beta Release 1, the module would fail to load and result -in a segmentation fault when 'insmod'ed. This problem was created when one of -the isdn4linux parameters, (isdn_ctrl, data field) was filled in. In some -cases, this data field was NULL, and was left unchecked, so when it was -referenced... segv. The bug has been fixed around line 63-68 of event.c. - diff --git a/drivers/staging/i4l/Kconfig b/drivers/staging/i4l/Kconfig deleted file mode 100644 index 920216e88de7..000000000000 --- a/drivers/staging/i4l/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# -# Old ISDN4Linux config -# -menu "Old ISDN4Linux (deprecated)" - depends on ISDN_I4L - -source "drivers/staging/i4l/icn/Kconfig" - -source "drivers/staging/i4l/pcbit/Kconfig" - -source "drivers/staging/i4l/act2000/Kconfig" - -endmenu diff --git a/drivers/staging/i4l/Makefile b/drivers/staging/i4l/Makefile deleted file mode 100644 index 158b87093db5..000000000000 --- a/drivers/staging/i4l/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# Makefile for the old ISDN I4L subsystem and device drivers. - -obj-$(CONFIG_ISDN_DRV_ICN) += icn/ -obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit/ -obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000/ diff --git a/drivers/staging/i4l/TODO b/drivers/staging/i4l/TODO deleted file mode 100644 index 6fe2c08bec7a..000000000000 --- a/drivers/staging/i4l/TODO +++ /dev/null @@ -1,3 +0,0 @@ -* The icn, pcbit and act2000 drivers are dead, remove them in 2017 - after another longterm kernel has been released, just in the - unlikely case someone still has this hardware. diff --git a/drivers/staging/i4l/act2000/Kconfig b/drivers/staging/i4l/act2000/Kconfig deleted file mode 100644 index fa2673fc69c2..000000000000 --- a/drivers/staging/i4l/act2000/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config ISDN_DRV_ACT2000 - tristate "IBM Active 2000 support" - depends on ISA - help - Say Y here if you have an IBM Active 2000 ISDN card. In order to use - this card, additional firmware is necessary, which has to be loaded - into the card using a utility which is part of the latest - isdn4k-utils package. Please read the file - <file:Documentation/isdn/README.act2000> for more information. diff --git a/drivers/staging/i4l/act2000/Makefile b/drivers/staging/i4l/act2000/Makefile deleted file mode 100644 index 05e582fb5c00..000000000000 --- a/drivers/staging/i4l/act2000/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for the act2000 ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000.o - -# Multipart objects. - -act2000-y := module.o capi.o act2000_isa.o diff --git a/drivers/staging/i4l/act2000/act2000.h b/drivers/staging/i4l/act2000/act2000.h deleted file mode 100644 index 321d437f579e..000000000000 --- a/drivers/staging/i4l/act2000/act2000.h +++ /dev/null @@ -1,202 +0,0 @@ -/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef act2000_h -#define act2000_h - -#include <linux/compiler.h> - -#define ACT2000_IOCTL_SETPORT 1 -#define ACT2000_IOCTL_GETPORT 2 -#define ACT2000_IOCTL_SETIRQ 3 -#define ACT2000_IOCTL_GETIRQ 4 -#define ACT2000_IOCTL_SETBUS 5 -#define ACT2000_IOCTL_GETBUS 6 -#define ACT2000_IOCTL_SETPROTO 7 -#define ACT2000_IOCTL_GETPROTO 8 -#define ACT2000_IOCTL_SETMSN 9 -#define ACT2000_IOCTL_GETMSN 10 -#define ACT2000_IOCTL_LOADBOOT 11 -#define ACT2000_IOCTL_ADDCARD 12 - -#define ACT2000_IOCTL_TEST 98 -#define ACT2000_IOCTL_DEBUGVAR 99 - -#define ACT2000_BUS_ISA 1 -#define ACT2000_BUS_MCA 2 -#define ACT2000_BUS_PCMCIA 3 - -/* Struct for adding new cards */ -typedef struct act2000_cdef { - int bus; - int port; - int irq; - char id[10]; -} act2000_cdef; - -/* Struct for downloading firmware */ -typedef struct act2000_ddef { - int length; /* Length of code */ - char __user *buffer; /* Ptr. to code */ -} act2000_ddef; - -typedef struct act2000_fwid { - char isdn[4]; - char revlen[2]; - char revision[504]; -} act2000_fwid; - -#if defined(__KERNEL__) || defined(__DEBUGVAR__) - -#ifdef __KERNEL__ -/* Kernel includes */ - -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/workqueue.h> -#include <linux/interrupt.h> -#include <linux/skbuff.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <asm/io.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/ioport.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/ctype.h> -#include <linux/isdnif.h> - -#endif /* __KERNEL__ */ - -#define ACT2000_PORTLEN 8 - -#define ACT2000_FLAGS_RUNNING 1 /* Cards driver activated */ -#define ACT2000_FLAGS_PVALID 2 /* Cards port is valid */ -#define ACT2000_FLAGS_IVALID 4 /* Cards irq is valid */ -#define ACT2000_FLAGS_LOADED 8 /* Firmware loaded */ - -#define ACT2000_BCH 2 /* # of channels per card */ - -/* D-Channel states */ -#define ACT2000_STATE_NULL 0 -#define ACT2000_STATE_ICALL 1 -#define ACT2000_STATE_OCALL 2 -#define ACT2000_STATE_IWAIT 3 -#define ACT2000_STATE_OWAIT 4 -#define ACT2000_STATE_IBWAIT 5 -#define ACT2000_STATE_OBWAIT 6 -#define ACT2000_STATE_BWAIT 7 -#define ACT2000_STATE_BHWAIT 8 -#define ACT2000_STATE_BHWAIT2 9 -#define ACT2000_STATE_DHWAIT 10 -#define ACT2000_STATE_DHWAIT2 11 -#define ACT2000_STATE_BSETUP 12 -#define ACT2000_STATE_ACTIVE 13 - -#define ACT2000_MAX_QUEUED 8000 /* 2 * maxbuff */ - -#define ACT2000_LOCK_TX 0 -#define ACT2000_LOCK_RX 1 - -typedef struct act2000_chan { - unsigned short callref; /* Call Reference */ - unsigned short fsm_state; /* Current D-Channel state */ - unsigned short eazmask; /* EAZ-Mask for this Channel */ - short queued; /* User-Data Bytes in TX queue */ - unsigned short plci; - unsigned short ncci; - unsigned char l2prot; /* Layer 2 protocol */ - unsigned char l3prot; /* Layer 3 protocol */ -} act2000_chan; - -typedef struct msn_entry { - char eaz; - char msn[16]; - struct msn_entry *next; -} msn_entry; - -typedef struct irq_data_isa { - __u8 *rcvptr; - __u16 rcvidx; - __u16 rcvlen; - struct sk_buff *rcvskb; - __u8 rcvignore; - __u8 rcvhdr[8]; -} irq_data_isa; - -typedef union act2000_irq_data { - irq_data_isa isa; -} act2000_irq_data; - -/* - * Per card driver data - */ -typedef struct act2000_card { - unsigned short port; /* Base-port-address */ - unsigned short irq; /* Interrupt */ - u_char ptype; /* Protocol type (1TR6 or Euro) */ - u_char bus; /* Cardtype (ISA, MCA, PCMCIA) */ - struct act2000_card *next; /* Pointer to next device struct */ - spinlock_t lock; /* protect critical operations */ - int myid; /* Driver-Nr. assigned by linklevel */ - unsigned long flags; /* Statusflags */ - unsigned long ilock; /* Semaphores for IRQ-Routines */ - struct sk_buff_head rcvq; /* Receive-Message queue */ - struct sk_buff_head sndq; /* Send-Message queue */ - struct sk_buff_head ackq; /* Data-Ack-Message queue */ - u_char *ack_msg; /* Ptr to User Data in User skb */ - __u16 need_b3ack; /* Flag: Need ACK for current skb */ - struct sk_buff *sbuf; /* skb which is currently sent */ - struct timer_list ptimer; /* Poll timer */ - struct work_struct snd_tq; /* Task struct for xmit bh */ - struct work_struct rcv_tq; /* Task struct for rcv bh */ - struct work_struct poll_tq; /* Task struct for polled rcv bh */ - msn_entry *msn_list; - unsigned short msgnum; /* Message number for sending */ - spinlock_t mnlock; /* lock for msgnum */ - act2000_chan bch[ACT2000_BCH]; /* B-Channel status/control */ - char status_buf[256]; /* Buffer for status messages */ - char *status_buf_read; - char *status_buf_write; - char *status_buf_end; - act2000_irq_data idat; /* Data used for IRQ handler */ - isdn_if interface; /* Interface to upper layer */ - char regname[35]; /* Name used for request_region */ -} act2000_card; - -static inline void act2000_schedule_tx(act2000_card *card) -{ - schedule_work(&card->snd_tq); -} - -static inline void act2000_schedule_rx(act2000_card *card) -{ - schedule_work(&card->rcv_tq); -} - -static inline void act2000_schedule_poll(act2000_card *card) -{ - schedule_work(&card->poll_tq); -} - -extern char *act2000_find_eaz(act2000_card *, char); - -#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */ -#endif /* act2000_h */ diff --git a/drivers/staging/i4l/act2000/act2000_isa.c b/drivers/staging/i4l/act2000/act2000_isa.c deleted file mode 100644 index 76ff5de65781..000000000000 --- a/drivers/staging/i4l/act2000/act2000_isa.c +++ /dev/null @@ -1,444 +0,0 @@ -/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "act2000_isa.h" -#include "capi.h" - -/* - * Reset Controller, then try to read the Card's signature. - + Return: - * 1 = Signature found. - * 0 = Signature not found. - */ -static int -act2000_isa_reset(unsigned short portbase) -{ - unsigned char reg; - int i; - int found; - int serial = 0; - - found = 0; - reg = inb(portbase + ISA_COR); - if (reg != 0xff) { - outb(reg | ISA_COR_RESET, portbase + ISA_COR); - mdelay(10); - outb(reg, portbase + ISA_COR); - mdelay(10); - - for (i = 0; i < 16; i++) { - if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL) - serial |= 0x10000; - serial >>= 1; - } - if (serial == ISA_SER_ID) - found++; - } - return found; -} - -int -act2000_isa_detect(unsigned short portbase) -{ - int ret = 0; - - if (request_region(portbase, ACT2000_PORTLEN, "act2000isa")) { - ret = act2000_isa_reset(portbase); - release_region(portbase, ISA_REGION); - } - return ret; -} - -static irqreturn_t -act2000_isa_interrupt(int dummy, void *dev_id) -{ - act2000_card *card = dev_id; - u_char istatus; - - istatus = (inb(ISA_PORT_ISR) & 0x07); - if (istatus & ISA_ISR_OUT) { - /* RX fifo has data */ - istatus &= ISA_ISR_OUT_MASK; - outb(0, ISA_PORT_SIS); - act2000_isa_receive(card); - outb(ISA_SIS_INT, ISA_PORT_SIS); - } - if (istatus & ISA_ISR_ERR) { - /* Error Interrupt */ - istatus &= ISA_ISR_ERR_MASK; - printk(KERN_WARNING "act2000: errIRQ\n"); - } - if (istatus) - printk(KERN_DEBUG "act2000: ?IRQ %d %02x\n", card->irq, istatus); - return IRQ_HANDLED; -} - -static void -act2000_isa_select_irq(act2000_card *card) -{ - unsigned char reg; - - reg = (inb(ISA_PORT_COR) & ~ISA_COR_IRQOFF) | ISA_COR_PERR; - switch (card->irq) { - case 3: - reg = ISA_COR_IRQ03; - break; - case 5: - reg = ISA_COR_IRQ05; - break; - case 7: - reg = ISA_COR_IRQ07; - break; - case 10: - reg = ISA_COR_IRQ10; - break; - case 11: - reg = ISA_COR_IRQ11; - break; - case 12: - reg = ISA_COR_IRQ12; - break; - case 15: - reg = ISA_COR_IRQ15; - break; - } - outb(reg, ISA_PORT_COR); -} - -static void -act2000_isa_enable_irq(act2000_card *card) -{ - act2000_isa_select_irq(card); - /* Enable READ irq */ - outb(ISA_SIS_INT, ISA_PORT_SIS); -} - -/* - * Install interrupt handler, enable irq on card. - * If irq is -1, choose next free irq, else irq is given explicitly. - */ -int -act2000_isa_config_irq(act2000_card *card, short irq) -{ - int old_irq; - - if (card->flags & ACT2000_FLAGS_IVALID) - free_irq(card->irq, card); - - card->flags &= ~ACT2000_FLAGS_IVALID; - outb(ISA_COR_IRQOFF, ISA_PORT_COR); - if (!irq) - return 0; - - old_irq = card->irq; - card->irq = irq; - if (request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) { - card->irq = old_irq; - card->flags |= ACT2000_FLAGS_IVALID; - printk(KERN_WARNING - "act2000: Could not request irq %d\n", irq); - return -EBUSY; - } else { - act2000_isa_select_irq(card); - /* Disable READ and WRITE irq */ - outb(0, ISA_PORT_SIS); - outb(0, ISA_PORT_SOS); - } - return 0; -} - -int -act2000_isa_config_port(act2000_card *card, unsigned short portbase) -{ - if (card->flags & ACT2000_FLAGS_PVALID) { - release_region(card->port, ISA_REGION); - card->flags &= ~ACT2000_FLAGS_PVALID; - } - if (!request_region(portbase, ACT2000_PORTLEN, card->regname)) - return -EBUSY; - else { - card->port = portbase; - card->flags |= ACT2000_FLAGS_PVALID; - return 0; - } -} - -/* - * Release resources, used by an adaptor. - */ -void -act2000_isa_release(act2000_card *card) -{ - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - if (card->flags & ACT2000_FLAGS_IVALID) - free_irq(card->irq, card); - - card->flags &= ~ACT2000_FLAGS_IVALID; - if (card->flags & ACT2000_FLAGS_PVALID) - release_region(card->port, ISA_REGION); - card->flags &= ~ACT2000_FLAGS_PVALID; - spin_unlock_irqrestore(&card->lock, flags); -} - -static int -act2000_isa_writeb(act2000_card *card, u_char data) -{ - u_char timeout = 40; - - while (timeout) { - if (inb(ISA_PORT_SOS) & ISA_SOS_READY) { - outb(data, ISA_PORT_SDO); - return 0; - } else { - timeout--; - udelay(10); - } - } - return 1; -} - -static int -act2000_isa_readb(act2000_card *card, u_char *data) -{ - u_char timeout = 40; - - while (timeout) { - if (inb(ISA_PORT_SIS) & ISA_SIS_READY) { - *data = inb(ISA_PORT_SDI); - return 0; - } else { - timeout--; - udelay(10); - } - } - return 1; -} - -void -act2000_isa_receive(act2000_card *card) -{ - u_char c; - - if (test_and_set_bit(ACT2000_LOCK_RX, (void *)&card->ilock) != 0) - return; - while (!act2000_isa_readb(card, &c)) { - if (card->idat.isa.rcvidx < 8) { - card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c; - if (card->idat.isa.rcvidx == 8) { - int valid = actcapi_chkhdr(card, (actcapi_msghdr *)&card->idat.isa.rcvhdr); - - if (valid) { - card->idat.isa.rcvlen = ((actcapi_msghdr *)&card->idat.isa.rcvhdr)->len; - card->idat.isa.rcvskb = dev_alloc_skb(card->idat.isa.rcvlen); - if (!card->idat.isa.rcvskb) { - card->idat.isa.rcvignore = 1; - printk(KERN_WARNING - "act2000_isa_receive: no memory\n"); - test_and_clear_bit(ACT2000_LOCK_RX, (void *)&card->ilock); - return; - } - memcpy(skb_put(card->idat.isa.rcvskb, 8), card->idat.isa.rcvhdr, 8); - card->idat.isa.rcvptr = skb_put(card->idat.isa.rcvskb, card->idat.isa.rcvlen - 8); - } else { - card->idat.isa.rcvidx = 0; - printk(KERN_WARNING - "act2000_isa_receive: Invalid CAPI msg\n"); - { - int i; __u8 *p; __u8 *t; __u8 tmp[30]; - - for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++) - t += sprintf(t, "%02x ", *(p++)); - printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp); - } - } - } - } else { - if (!card->idat.isa.rcvignore) - *card->idat.isa.rcvptr++ = c; - if (++card->idat.isa.rcvidx >= card->idat.isa.rcvlen) { - if (!card->idat.isa.rcvignore) { - skb_queue_tail(&card->rcvq, card->idat.isa.rcvskb); - act2000_schedule_rx(card); - } - card->idat.isa.rcvidx = 0; - card->idat.isa.rcvlen = 8; - card->idat.isa.rcvignore = 0; - card->idat.isa.rcvskb = NULL; - card->idat.isa.rcvptr = card->idat.isa.rcvhdr; - } - } - } - if (!(card->flags & ACT2000_FLAGS_IVALID)) { - /* In polling mode, schedule myself */ - if ((card->idat.isa.rcvidx) && - (card->idat.isa.rcvignore || - (card->idat.isa.rcvidx < card->idat.isa.rcvlen))) - act2000_schedule_poll(card); - } - test_and_clear_bit(ACT2000_LOCK_RX, (void *)&card->ilock); -} - -void -act2000_isa_send(act2000_card *card) -{ - unsigned long flags; - struct sk_buff *skb; - actcapi_msg *msg; - int l; - - if (test_and_set_bit(ACT2000_LOCK_TX, (void *)&card->ilock) != 0) - return; - while (1) { - spin_lock_irqsave(&card->lock, flags); - if (!(card->sbuf)) { - card->sbuf = skb_dequeue(&card->sndq); - if (card->sbuf) { - card->ack_msg = card->sbuf->data; - msg = (actcapi_msg *)card->sbuf->data; - if ((msg->hdr.cmd.cmd == 0x86) && - (msg->hdr.cmd.subcmd == 0)) { - /* Save flags in message */ - card->need_b3ack = msg->msg.data_b3_req.flags; - msg->msg.data_b3_req.flags = 0; - } - } - } - spin_unlock_irqrestore(&card->lock, flags); - if (!(card->sbuf)) { - /* No more data to send */ - test_and_clear_bit(ACT2000_LOCK_TX, (void *)&card->ilock); - return; - } - skb = card->sbuf; - l = 0; - while (skb->len) { - if (act2000_isa_writeb(card, *(skb->data))) { - /* Fifo is full, but more data to send */ - test_and_clear_bit(ACT2000_LOCK_TX, (void *)&card->ilock); - /* Schedule myself */ - act2000_schedule_tx(card); - return; - } - skb_pull(skb, 1); - l++; - } - msg = (actcapi_msg *)card->ack_msg; - if ((msg->hdr.cmd.cmd == 0x86) && - (msg->hdr.cmd.subcmd == 0)) { - /* - * If it's user data, reset data-ptr - * and put skb into ackq. - */ - skb->data = card->ack_msg; - /* Restore flags in message */ - msg->msg.data_b3_req.flags = card->need_b3ack; - skb_queue_tail(&card->ackq, skb); - } else - dev_kfree_skb(skb); - card->sbuf = NULL; - } -} - -/* - * Get firmware ID, check for 'ISDN' signature. - */ -static int -act2000_isa_getid(act2000_card *card) -{ - act2000_fwid fid; - u_char *p = (u_char *)&fid; - int count = 0; - - while (1) { - if (count > 510) - return -EPROTO; - if (act2000_isa_readb(card, p++)) - break; - count++; - } - if (count <= 20) { - printk(KERN_WARNING "act2000: No Firmware-ID!\n"); - return -ETIME; - } - *p = '\0'; - fid.revlen[0] = '\0'; - if (strcmp(fid.isdn, "ISDN")) { - printk(KERN_WARNING "act2000: Wrong Firmware-ID!\n"); - return -EPROTO; - } - p = strchr(fid.revision, '\n'); - if (p) - *p = '\0'; - printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision); - if (card->flags & ACT2000_FLAGS_IVALID) { - printk(KERN_DEBUG "Enabling Interrupts ...\n"); - act2000_isa_enable_irq(card); - } - return 0; -} - -/* - * Download microcode into card, check Firmware signature. - */ -int -act2000_isa_download(act2000_card *card, act2000_ddef __user *cb) -{ - unsigned int length; - int l; - int c; - u_char *b; - u_char __user *p; - u_char *buf; - act2000_ddef cblock; - - if (!act2000_isa_reset(card->port)) - return -ENXIO; - msleep_interruptible(500); - if (copy_from_user(&cblock, cb, sizeof(cblock))) - return -EFAULT; - length = cblock.length; - p = cblock.buffer; - if (!access_ok(VERIFY_READ, p, length)) - return -EFAULT; - buf = kmalloc(1024, GFP_KERNEL); - if (!buf) - return -ENOMEM; - while (length) { - l = (length > 1024) ? 1024 : length; - c = 0; - b = buf; - if (copy_from_user(buf, p, l)) { - kfree(buf); - return -EFAULT; - } - while (c < l) { - if (act2000_isa_writeb(card, *b++)) { - printk(KERN_WARNING - "act2000: loader timed out" - " len=%d c=%d\n", length, c); - kfree(buf); - return -ETIME; - } - c++; - } - length -= l; - p += l; - } - kfree(buf); - msleep_interruptible(500); - return act2000_isa_getid(card); -} diff --git a/drivers/staging/i4l/act2000/act2000_isa.h b/drivers/staging/i4l/act2000/act2000_isa.h deleted file mode 100644 index 1a728984ede1..000000000000 --- a/drivers/staging/i4l/act2000/act2000_isa.h +++ /dev/null @@ -1,136 +0,0 @@ -/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef act2000_isa_h -#define act2000_isa_h - -#define ISA_POLL_LOOP 40 /* Try to read-write before give up */ - -typedef enum { - INT_NO_CHANGE = 0, /* Do not change the Mask */ - INT_ON = 1, /* Set to Enable */ - INT_OFF = 2, /* Set to Disable */ -} ISA_INT_T; - -/**************************************************************************/ -/* Configuration Register COR (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* Soft Res| IRQM | IRQ Select | N/A | WAIT |Proc err */ -/**************************************************************************/ -#define ISA_COR 0 /* Offset for ISA config register */ -#define ISA_COR_PERR 0x01 /* Processor Error Enabled */ -#define ISA_COR_WS 0x02 /* Insert Wait State if 1 */ -#define ISA_COR_IRQOFF 0x38 /* No Interrupt */ -#define ISA_COR_IRQ07 0x30 /* IRQ 7 Enable */ -#define ISA_COR_IRQ05 0x28 /* IRQ 5 Enable */ -#define ISA_COR_IRQ03 0x20 /* IRQ 3 Enable */ -#define ISA_COR_IRQ10 0x18 /* IRQ 10 Enable */ -#define ISA_COR_IRQ11 0x10 /* IRQ 11 Enable */ -#define ISA_COR_IRQ12 0x08 /* IRQ 12 Enable */ -#define ISA_COR_IRQ15 0x00 /* IRQ 15 Enable */ -#define ISA_COR_IRQPULSE 0x40 /* 0 = Level 1 = Pulse Interrupt */ -#define ISA_COR_RESET 0x80 /* Soft Reset for Transputer */ - -/**************************************************************************/ -/* Interrupt Source Register ISR (RO) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A |Err sig |Ser ID |IN Intr |Out Intr| Error */ -/**************************************************************************/ -#define ISA_ISR 1 /* Offset for Interrupt Register */ -#define ISA_ISR_ERR 0x01 /* Error Interrupt */ -#define ISA_ISR_OUT 0x02 /* Output Interrupt */ -#define ISA_ISR_INP 0x04 /* Input Interrupt */ -#define ISA_ISR_SERIAL 0x08 /* Read out Serial ID after Reset */ -#define ISA_ISR_ERRSIG 0x10 /* Error Signal Input */ -#define ISA_ISR_ERR_MASK 0xfe /* Mask Error Interrupt */ -#define ISA_ISR_OUT_MASK 0xfd /* Mask Output Interrupt */ -#define ISA_ISR_INP_MASK 0xfb /* Mask Input Interrupt */ - -/* Signature delivered after Reset at ISA_ISR_SERIAL (LSB first) */ -#define ISA_SER_ID 0x0201 /* ID for ISA Card */ - -/**************************************************************************/ -/* EEPROM Register EPR (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A |ROM Hold| ROM CS |ROM CLK | ROM IN |ROM Out */ -/**************************************************************************/ -#define ISA_EPR 2 /* Offset for this Register */ -#define ISA_EPR_OUT 0x01 /* Rome Register Out (RO) */ -#define ISA_EPR_IN 0x02 /* Rom Register In (WR) */ -#define ISA_EPR_CLK 0x04 /* Rom Clock (WR) */ -#define ISA_EPR_CS 0x08 /* Rom Cip Select (WR) */ -#define ISA_EPR_HOLD 0x10 /* Rom Hold Signal (WR) */ - -/**************************************************************************/ -/* EEPROM enable Register EER (unused) */ -/**************************************************************************/ -#define ISA_EER 3 /* Offset for this Register */ - -/**************************************************************************/ -/* SLC Data Input SDI (RO) */ -/**************************************************************************/ -#define ISA_SDI 4 /* Offset for this Register */ - -/**************************************************************************/ -/* SLC Data Output SDO (WO) */ -/**************************************************************************/ -#define ISA_SDO 5 /* Offset for this Register */ - -/**************************************************************************/ -/* IMS C011 Mode 2 Input Status Register for INMOS CPU SIS (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Data Pre */ -/**************************************************************************/ -#define ISA_SIS 6 /* Offset for this Register */ -#define ISA_SIS_READY 0x01 /* If 1 : data is available */ -#define ISA_SIS_INT 0x02 /* Enable Interrupt for READ */ - -/**************************************************************************/ -/* IMS C011 Mode 2 Output Status Register from INMOS CPU SOS (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Out Rdy */ -/**************************************************************************/ -#define ISA_SOS 7 /* Offset for this Register */ -#define ISA_SOS_READY 0x01 /* If 1 : we can write Data */ -#define ISA_SOS_INT 0x02 /* Enable Interrupt for WRITE */ - -#define ISA_REGION 8 /* Number of Registers */ - - -/* Macros for accessing ports */ -#define ISA_PORT_COR (card->port + ISA_COR) -#define ISA_PORT_ISR (card->port + ISA_ISR) -#define ISA_PORT_EPR (card->port + ISA_EPR) -#define ISA_PORT_EER (card->port + ISA_EER) -#define ISA_PORT_SDI (card->port + ISA_SDI) -#define ISA_PORT_SDO (card->port + ISA_SDO) -#define ISA_PORT_SIS (card->port + ISA_SIS) -#define ISA_PORT_SOS (card->port + ISA_SOS) - -/* Prototypes */ - -extern int act2000_isa_detect(unsigned short portbase); -extern int act2000_isa_config_irq(act2000_card *card, short irq); -extern int act2000_isa_config_port(act2000_card *card, unsigned short portbase); -extern int act2000_isa_download(act2000_card *card, act2000_ddef __user *cb); -extern void act2000_isa_release(act2000_card *card); -extern void act2000_isa_receive(act2000_card *card); -extern void act2000_isa_send(act2000_card *card); - -#endif /* act2000_isa_h */ diff --git a/drivers/staging/i4l/act2000/capi.c b/drivers/staging/i4l/act2000/capi.c deleted file mode 100644 index 61386a78fb91..000000000000 --- a/drivers/staging/i4l/act2000/capi.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * CAPI encoder/decoder - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "capi.h" - -static actcapi_msgdsc valid_msg[] = { - {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */ - {{ 0x86, 0x01}, "DATA_B3_CONF"}, - {{ 0x02, 0x01}, "CONNECT_CONF"}, - {{ 0x02, 0x02}, "CONNECT_IND"}, - {{ 0x09, 0x01}, "CONNECT_INFO_CONF"}, - {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"}, - {{ 0x04, 0x01}, "DISCONNECT_CONF"}, - {{ 0x04, 0x02}, "DISCONNECT_IND"}, - {{ 0x05, 0x01}, "LISTEN_CONF"}, - {{ 0x06, 0x01}, "GET_PARAMS_CONF"}, - {{ 0x07, 0x01}, "INFO_CONF"}, - {{ 0x07, 0x02}, "INFO_IND"}, - {{ 0x08, 0x01}, "DATA_CONF"}, - {{ 0x08, 0x02}, "DATA_IND"}, - {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"}, - {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"}, - {{ 0x81, 0x01}, "LISTEN_B3_CONF"}, - {{ 0x82, 0x01}, "CONNECT_B3_CONF"}, - {{ 0x82, 0x02}, "CONNECT_B3_IND"}, - {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"}, - {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"}, - {{ 0x84, 0x02}, "DISCONNECT_B3_IND"}, - {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"}, - {{ 0x01, 0x01}, "RESET_B3_CONF"}, - {{ 0x01, 0x02}, "RESET_B3_IND"}, - /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */ - {{ 0xff, 0x01}, "MANUFACTURER_CONF"}, - {{ 0xff, 0x02}, "MANUFACTURER_IND"}, -#ifdef DEBUG_MSG - /* Requests */ - {{ 0x01, 0x00}, "RESET_B3_REQ"}, - {{ 0x02, 0x00}, "CONNECT_REQ"}, - {{ 0x04, 0x00}, "DISCONNECT_REQ"}, - {{ 0x05, 0x00}, "LISTEN_REQ"}, - {{ 0x06, 0x00}, "GET_PARAMS_REQ"}, - {{ 0x07, 0x00}, "INFO_REQ"}, - {{ 0x08, 0x00}, "DATA_REQ"}, - {{ 0x09, 0x00}, "CONNECT_INFO_REQ"}, - {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"}, - {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"}, - {{ 0x81, 0x00}, "LISTEN_B3_REQ"}, - {{ 0x82, 0x00}, "CONNECT_B3_REQ"}, - {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"}, - {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"}, - {{ 0x86, 0x00}, "DATA_B3_REQ"}, - {{ 0xff, 0x00}, "MANUFACTURER_REQ"}, - /* Responses */ - {{ 0x01, 0x03}, "RESET_B3_RESP"}, - {{ 0x02, 0x03}, "CONNECT_RESP"}, - {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"}, - {{ 0x04, 0x03}, "DISCONNECT_RESP"}, - {{ 0x07, 0x03}, "INFO_RESP"}, - {{ 0x08, 0x03}, "DATA_RESP"}, - {{ 0x82, 0x03}, "CONNECT_B3_RESP"}, - {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"}, - {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"}, - {{ 0x86, 0x03}, "DATA_B3_RESP"}, - {{ 0xff, 0x03}, "MANUFACTURER_RESP"}, -#endif - {{ 0x00, 0x00}, NULL}, -}; -#define num_valid_imsg 27 /* MANUFACTURER_IND */ - -/* - * Check for a valid incoming CAPI message. - * Return: - * 0 = Invalid message - * 1 = Valid message, no B-Channel-data - * 2 = Valid message, B-Channel-data - */ -int -actcapi_chkhdr(act2000_card *card, actcapi_msghdr *hdr) -{ - int i; - - if (hdr->applicationID != 1) - return 0; - if (hdr->len < 9) - return 0; - for (i = 0; i < num_valid_imsg; i++) - if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) && - (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) { - return i ? 1 : 2; - } - return 0; -} - -#define ACTCAPI_MKHDR(l, c, s) { \ - skb = alloc_skb(l + 8, GFP_ATOMIC); \ - if (skb) { \ - m = (actcapi_msg *)skb_put(skb, l + 8); \ - m->hdr.len = l + 8; \ - m->hdr.applicationID = 1; \ - m->hdr.cmd.cmd = c; \ - m->hdr.cmd.subcmd = s; \ - m->hdr.msgnum = actcapi_nextsmsg(card); \ - } else { \ - m = NULL; \ - } \ - } - -#define ACTCAPI_CHKSKB if (!skb) { \ - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \ - return; \ - } - -#define ACTCAPI_QUEUE_TX { \ - actcapi_debug_msg(skb, 1); \ - skb_queue_tail(&card->sndq, skb); \ - act2000_schedule_tx(card); \ - } - -int -actcapi_listen_req(act2000_card *card) -{ - __u16 eazmask = 0; - int i; - actcapi_msg *m; - struct sk_buff *skb; - - for (i = 0; i < ACT2000_BCH; i++) - eazmask |= card->bch[i].eazmask; - ACTCAPI_MKHDR(9, 0x05, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.listen_req.controller = 0; - m->msg.listen_req.infomask = 0x3f; /* All information */ - m->msg.listen_req.eazmask = eazmask; - m->msg.listen_req.simask = (eazmask) ? 0x86 : 0; /* All SI's */ - ACTCAPI_QUEUE_TX; - return 0; -} - -int -actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone, - char eaz, int si1, int si2) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - chan->fsm_state = ACT2000_STATE_NULL; - return -ENOMEM; - } - m->msg.connect_req.controller = 0; - m->msg.connect_req.bchan = 0x83; - m->msg.connect_req.infomask = 0x3f; - m->msg.connect_req.si1 = si1; - m->msg.connect_req.si2 = si2; - m->msg.connect_req.eaz = eaz ? eaz : '0'; - m->msg.connect_req.addr.len = strlen(phone) + 1; - m->msg.connect_req.addr.tnp = 0x81; - memcpy(m->msg.connect_req.addr.num, phone, strlen(phone)); - chan->callref = m->hdr.msgnum; - ACTCAPI_QUEUE_TX; - return 0; -} - -static void -actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x82, 0x00); - ACTCAPI_CHKSKB; - m->msg.connect_b3_req.plci = chan->plci; - memset(&m->msg.connect_b3_req.ncpi, 0, - sizeof(m->msg.connect_b3_req.ncpi)); - m->msg.connect_b3_req.ncpi.len = 13; - m->msg.connect_b3_req.ncpi.modulo = 8; - ACTCAPI_QUEUE_TX; -} - -/* - * Set net type (1TR6) or (EDSS1) - */ -int -actcapi_manufacturer_req_net(act2000_card *card) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(5, 0xff, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_net.manuf_msg = 0x11; - m->msg.manufacturer_req_net.controller = 1; - m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO) ? 1 : 0; - ACTCAPI_QUEUE_TX; - printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n", - card->interface.id, (card->ptype == ISDN_PTYPE_EURO) ? "euro" : "1tr6"); - card->interface.features &= - ~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6); - card->interface.features |= - ((card->ptype == ISDN_PTYPE_EURO) ? ISDN_FEATURE_P_EURO : ISDN_FEATURE_P_1TR6); - return 0; -} - -/* - * Switch V.42 on or off - */ -#if 0 -int -actcapi_manufacturer_req_v42(act2000_card *card, ulong arg) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(8, 0xff, 0x00); - if (!skb) { - - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_v42.manuf_msg = 0x10; - m->msg.manufacturer_req_v42.controller = 0; - m->msg.manufacturer_req_v42.v42control = (arg ? 1 : 0); - ACTCAPI_QUEUE_TX; - return 0; -} -#endif /* 0 */ - -/* - * Set error-handler - */ -int -actcapi_manufacturer_req_errh(act2000_card *card) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(4, 0xff, 0x00); - if (!skb) { - - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_err.manuf_msg = 0x03; - m->msg.manufacturer_req_err.controller = 0; - ACTCAPI_QUEUE_TX; - return 0; -} - -/* - * Set MSN-Mapping. - */ -int -actcapi_manufacturer_req_msn(act2000_card *card) -{ - msn_entry *p = card->msn_list; - actcapi_msg *m; - struct sk_buff *skb; - int len; - - while (p) { - int i; - - len = strlen(p->msn); - for (i = 0; i < 2; i++) { - ACTCAPI_MKHDR(6 + len, 0xff, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i; - m->msg.manufacturer_req_msn.controller = 0; - m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz; - m->msg.manufacturer_req_msn.msnmap.len = len; - memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len); - ACTCAPI_QUEUE_TX; - } - p = p->next; - } - return 0; -} - -void -actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(10, 0x40, 0x00); - ACTCAPI_CHKSKB; - m->msg.select_b2_protocol_req.plci = chan->plci; - memset(&m->msg.select_b2_protocol_req.dlpd, 0, - sizeof(m->msg.select_b2_protocol_req.dlpd)); - m->msg.select_b2_protocol_req.dlpd.len = 6; - switch (chan->l2prot) { - case ISDN_PROTO_L2_TRANS: - m->msg.select_b2_protocol_req.protocol = 0x03; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - break; - case ISDN_PROTO_L2_HDLC: - m->msg.select_b2_protocol_req.protocol = 0x02; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - break; - case ISDN_PROTO_L2_X75I: - case ISDN_PROTO_L2_X75UI: - case ISDN_PROTO_L2_X75BUI: - m->msg.select_b2_protocol_req.protocol = 0x01; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - m->msg.select_b2_protocol_req.dlpd.laa = 3; - m->msg.select_b2_protocol_req.dlpd.lab = 1; - m->msg.select_b2_protocol_req.dlpd.win = 7; - m->msg.select_b2_protocol_req.dlpd.modulo = 8; - break; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x80, 0x00); - ACTCAPI_CHKSKB; - m->msg.select_b3_protocol_req.plci = chan->plci; - memset(&m->msg.select_b3_protocol_req.ncpd, 0, - sizeof(m->msg.select_b3_protocol_req.ncpd)); - switch (chan->l3prot) { - case ISDN_PROTO_L3_TRANS: - m->msg.select_b3_protocol_req.protocol = 0x04; - m->msg.select_b3_protocol_req.ncpd.len = 13; - m->msg.select_b3_protocol_req.ncpd.modulo = 8; - break; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x81, 0x00); - ACTCAPI_CHKSKB; - m->msg.listen_b3_req.plci = chan->plci; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(3, 0x04, 0x00); - ACTCAPI_CHKSKB; - m->msg.disconnect_req.plci = chan->plci; - m->msg.disconnect_req.cause = 0; - ACTCAPI_QUEUE_TX; -} - -void -actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x84, 0x00); - ACTCAPI_CHKSKB; - m->msg.disconnect_b3_req.ncci = chan->ncci; - memset(&m->msg.disconnect_b3_req.ncpi, 0, - sizeof(m->msg.disconnect_b3_req.ncpi)); - m->msg.disconnect_b3_req.ncpi.len = 13; - m->msg.disconnect_b3_req.ncpi.modulo = 8; - chan->fsm_state = ACT2000_STATE_BHWAIT; - ACTCAPI_QUEUE_TX; -} - -void -actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(3, 0x02, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_resp.plci = chan->plci; - m->msg.connect_resp.rejectcause = cause; - if (cause) { - chan->fsm_state = ACT2000_STATE_NULL; - chan->plci = 0x8000; - } else - chan->fsm_state = ACT2000_STATE_IWAIT; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x03, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_resp.plci = chan->plci; - if (chan->fsm_state == ACT2000_STATE_IWAIT) - chan->fsm_state = ACT2000_STATE_IBWAIT; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR((rejectcause ? 3 : 17), 0x82, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_b3_resp.ncci = chan->ncci; - m->msg.connect_b3_resp.rejectcause = rejectcause; - if (!rejectcause) { - memset(&m->msg.connect_b3_resp.ncpi, 0, - sizeof(m->msg.connect_b3_resp.ncpi)); - m->msg.connect_b3_resp.ncpi.len = 13; - m->msg.connect_b3_resp.ncpi.modulo = 8; - chan->fsm_state = ACT2000_STATE_BWAIT; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x83, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_b3_active_resp.ncci = chan->ncci; - chan->fsm_state = ACT2000_STATE_ACTIVE; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_info_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x07, 0x03); - ACTCAPI_CHKSKB; - m->msg.info_resp.plci = chan->plci; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x84, 0x03); - ACTCAPI_CHKSKB; - m->msg.disconnect_b3_resp.ncci = chan->ncci; - chan->ncci = 0x8000; - chan->queued = 0; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x04, 0x03); - ACTCAPI_CHKSKB; - m->msg.disconnect_resp.plci = chan->plci; - chan->plci = 0x8000; - ACTCAPI_QUEUE_TX; -} - -static int -new_plci(act2000_card *card, __u16 plci) -{ - int i; - - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].plci == 0x8000) { - card->bch[i].plci = plci; - return i; - } - return -1; -} - -static int -find_plci(act2000_card *card, __u16 plci) -{ - int i; - - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].plci == plci) - return i; - return -1; -} - -static int -find_ncci(act2000_card *card, __u16 ncci) -{ - int i; - - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].ncci == ncci) - return i; - return -1; -} - -static int -find_dialing(act2000_card *card, __u16 callref) -{ - int i; - - for (i = 0; i < ACT2000_BCH; i++) - if ((card->bch[i].callref == callref) && - (card->bch[i].fsm_state == ACT2000_STATE_OCALL)) - return i; - return -1; -} - -static int -actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) { - __u16 plci; - __u16 ncci; - __u8 blocknr; - int chan; - actcapi_msg *msg = (actcapi_msg *)skb->data; - - EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, ncci); - chan = find_ncci(card, ncci); - if (chan < 0) - return 0; - if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE) - return 0; - if (card->bch[chan].plci != plci) - return 0; - blocknr = msg->msg.data_b3_ind.blocknr; - skb_pull(skb, 19); - card->interface.rcvcallb_skb(card->myid, chan, skb); - if (!(skb = alloc_skb(11, GFP_ATOMIC))) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return 1; - } - msg = (actcapi_msg *)skb_put(skb, 11); - msg->hdr.len = 11; - msg->hdr.applicationID = 1; - msg->hdr.cmd.cmd = 0x86; - msg->hdr.cmd.subcmd = 0x03; - msg->hdr.msgnum = actcapi_nextsmsg(card); - msg->msg.data_b3_resp.ncci = ncci; - msg->msg.data_b3_resp.blocknr = blocknr; - ACTCAPI_QUEUE_TX; - return 1; -} - -/* - * Walk over ackq, unlink DATA_B3_REQ from it, if - * ncci and blocknr are matching. - * Decrement queued-bytes counter. - */ -static int -handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) { - unsigned long flags; - struct sk_buff *skb; - struct sk_buff *tmp; - struct actcapi_msg *m; - int ret = 0; - - spin_lock_irqsave(&card->lock, flags); - skb = skb_peek(&card->ackq); - spin_unlock_irqrestore(&card->lock, flags); - if (!skb) { - printk(KERN_WARNING "act2000: handle_ack nothing found!\n"); - return 0; - } - tmp = skb; - while (1) { - m = (actcapi_msg *)tmp->data; - if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) && - (m->msg.data_b3_req.blocknr == blocknr)) { - /* found corresponding DATA_B3_REQ */ - skb_unlink(tmp, &card->ackq); - chan->queued -= m->msg.data_b3_req.datalen; - if (m->msg.data_b3_req.flags) - ret = m->msg.data_b3_req.datalen; - dev_kfree_skb(tmp); - if (chan->queued < 0) - chan->queued = 0; - return ret; - } - spin_lock_irqsave(&card->lock, flags); - tmp = skb_peek((struct sk_buff_head *)tmp); - spin_unlock_irqrestore(&card->lock, flags); - if ((tmp == skb) || !tmp) { - /* reached end of queue */ - printk(KERN_WARNING "act2000: handle_ack nothing found!\n"); - return 0; - } - } -} - -void -actcapi_dispatch(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, rcv_tq); - struct sk_buff *skb; - actcapi_msg *msg; - __u16 ccmd; - int chan; - int len; - act2000_chan *ctmp; - isdn_ctrl cmd; - char tmp[170]; - - while ((skb = skb_dequeue(&card->rcvq))) { - actcapi_debug_msg(skb, 0); - msg = (actcapi_msg *)skb->data; - ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd); - switch (ccmd) { - case 0x8602: - /* DATA_B3_IND */ - if (actcapi_data_b3_ind(card, skb)) - return; - break; - case 0x8601: - /* DATA_B3_CONF */ - chan = find_ncci(card, msg->msg.data_b3_conf.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) { - if (msg->msg.data_b3_conf.info != 0) - printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n", - msg->msg.data_b3_conf.info); - len = handle_ack(card, &card->bch[chan], - msg->msg.data_b3_conf.blocknr); - if (len) { - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BSENT; - cmd.arg = chan; - cmd.parm.length = len; - card->interface.statcallb(&cmd); - } - } - break; - case 0x0201: - /* CONNECT_CONF */ - chan = find_dialing(card, msg->hdr.msgnum); - if (chan >= 0) { - if (msg->msg.connect_conf.info) { - card->bch[chan].fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - card->bch[chan].fsm_state = ACT2000_STATE_OWAIT; - card->bch[chan].plci = msg->msg.connect_conf.plci; - } - } - break; - case 0x0202: - /* CONNECT_IND */ - chan = new_plci(card, msg->msg.connect_ind.plci); - if (chan < 0) { - ctmp = (act2000_chan *)tmp; - ctmp->plci = msg->msg.connect_ind.plci; - actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */ - } else { - card->bch[chan].fsm_state = ACT2000_STATE_ICALL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_ICALL; - cmd.arg = chan; - cmd.parm.setup.si1 = msg->msg.connect_ind.si1; - cmd.parm.setup.si2 = msg->msg.connect_ind.si2; - if (card->ptype == ISDN_PTYPE_EURO) - strcpy(cmd.parm.setup.eazmsn, - act2000_find_eaz(card, msg->msg.connect_ind.eaz)); - else { - cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz; - cmd.parm.setup.eazmsn[1] = 0; - } - memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone)); - memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num, - msg->msg.connect_ind.addr.len - 1); - cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp; - cmd.parm.setup.screen = 0; - if (card->interface.statcallb(&cmd) == 2) - actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */ - } - break; - case 0x0302: - /* CONNECT_ACTIVE_IND */ - chan = find_plci(card, msg->msg.connect_active_ind.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_IWAIT: - actcapi_connect_active_resp(card, &card->bch[chan]); - break; - case ACT2000_STATE_OWAIT: - actcapi_connect_active_resp(card, &card->bch[chan]); - actcapi_select_b2_protocol_req(card, &card->bch[chan]); - break; - } - break; - case 0x8202: - /* CONNECT_B3_IND */ - chan = find_plci(card, msg->msg.connect_b3_ind.plci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) { - card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci; - actcapi_connect_b3_resp(card, &card->bch[chan], 0); - } else { - ctmp = (act2000_chan *)tmp; - ctmp->ncci = msg->msg.connect_b3_ind.ncci; - actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */ - } - break; - case 0x8302: - /* CONNECT_B3_ACTIVE_IND */ - chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) { - actcapi_connect_b3_active_resp(card, &card->bch[chan]); - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BCONN; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - case 0x8402: - /* DISCONNECT_B3_IND */ - chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci); - if (chan >= 0) { - ctmp = &card->bch[chan]; - actcapi_disconnect_b3_resp(card, ctmp); - switch (ctmp->fsm_state) { - case ACT2000_STATE_ACTIVE: - ctmp->fsm_state = ACT2000_STATE_DHWAIT2; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - break; - case ACT2000_STATE_BHWAIT2: - actcapi_disconnect_req(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_DHWAIT; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - break; - } - } - break; - case 0x0402: - /* DISCONNECT_IND */ - chan = find_plci(card, msg->msg.disconnect_ind.plci); - if (chan >= 0) { - ctmp = &card->bch[chan]; - actcapi_disconnect_resp(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp = (act2000_chan *)tmp; - ctmp->plci = msg->msg.disconnect_ind.plci; - actcapi_disconnect_resp(card, ctmp); - } - break; - case 0x4001: - /* SELECT_B2_PROTOCOL_CONF */ - chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.select_b2_protocol_conf.info == 0) - actcapi_select_b3_protocol_req(card, ctmp); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - } - break; - case 0x8001: - /* SELECT_B3_PROTOCOL_CONF */ - chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.select_b3_protocol_conf.info == 0) - actcapi_listen_b3_req(card, ctmp); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - } - break; - case 0x8101: - /* LISTEN_B3_CONF */ - chan = find_plci(card, msg->msg.listen_b3_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - ctmp = &card->bch[chan]; - if (msg->msg.listen_b3_conf.info == 0) - actcapi_connect_resp(card, ctmp, 0); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.listen_b3_conf.info == 0) { - actcapi_connect_b3_req(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_OBWAIT; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DCONN; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - } - break; - case 0x8201: - /* CONNECT_B3_CONF */ - chan = find_plci(card, msg->msg.connect_b3_conf.plci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) { - ctmp = &card->bch[chan]; - if (msg->msg.connect_b3_conf.info) { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp->ncci = msg->msg.connect_b3_conf.ncci; - ctmp->fsm_state = ACT2000_STATE_BWAIT; - } - } - break; - case 0x8401: - /* DISCONNECT_B3_CONF */ - chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT)) - card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2; - break; - case 0x0702: - /* INFO_IND */ - chan = find_plci(card, msg->msg.info_ind.plci); - if (chan >= 0) - /* TODO: Eval Charging info / cause */ - actcapi_info_resp(card, &card->bch[chan]); - break; - case 0x0401: - /* LISTEN_CONF */ - case 0x0501: - /* LISTEN_CONF */ - case 0xff01: - /* MANUFACTURER_CONF */ - break; - case 0xff02: - /* MANUFACTURER_IND */ - if (msg->msg.manuf_msg == 3) { - memset(tmp, 0, sizeof(tmp)); - strncpy(tmp, - &msg->msg.manufacturer_ind_err.errstring, - msg->hdr.len - 16); - if (msg->msg.manufacturer_ind_err.errcode) - printk(KERN_WARNING "act2000: %s\n", tmp); - else { - printk(KERN_DEBUG "act2000: %s\n", tmp); - if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) || - (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) { - card->flags |= ACT2000_FLAGS_RUNNING; - cmd.command = ISDN_STAT_RUN; - cmd.driver = card->myid; - cmd.arg = 0; - actcapi_manufacturer_req_net(card); - actcapi_manufacturer_req_msn(card); - actcapi_listen_req(card); - card->interface.statcallb(&cmd); - } - } - } - break; - default: - printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd); - break; - } - dev_kfree_skb(skb); - } -} - -#ifdef DEBUG_MSG -static void -actcapi_debug_caddr(actcapi_addr *addr) -{ - char tmp[30]; - - printk(KERN_DEBUG " Alen = %d\n", addr->len); - if (addr->len > 0) - printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp); - if (addr->len > 1) { - memset(tmp, 0, 30); - memcpy(tmp, addr->num, addr->len - 1); - printk(KERN_DEBUG " Anum = '%s'\n", tmp); - } -} - -static void -actcapi_debug_ncpi(actcapi_ncpi *ncpi) -{ - printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len); - if (ncpi->len >= 2) - printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic); - if (ncpi->len >= 4) - printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic); - if (ncpi->len >= 6) - printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc); - if (ncpi->len >= 8) - printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc); - if (ncpi->len >= 10) - printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc); - if (ncpi->len >= 12) - printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc); - if (ncpi->len >= 13) - printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo); -} - -static void -actcapi_debug_dlpd(actcapi_dlpd *dlpd) -{ - printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len); - if (dlpd->len >= 2) - printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen); - if (dlpd->len >= 3) - printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa); - if (dlpd->len >= 4) - printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab); - if (dlpd->len >= 5) - printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo); - if (dlpd->len >= 6) - printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win); -} - -#ifdef DEBUG_DUMP_SKB -static void dump_skb(struct sk_buff *skb) -{ - char tmp[80]; - char *p = skb->data; - char *t = tmp; - int i; - - for (i = 0; i < skb->len; i++) { - t += sprintf(t, "%02x ", *p++ & 0xff); - if ((i & 0x0f) == 8) { - printk(KERN_DEBUG "dump: %s\n", tmp); - t = tmp; - } - } - if (i & 0x07) - printk(KERN_DEBUG "dump: %s\n", tmp); -} -#endif - -void -actcapi_debug_msg(struct sk_buff *skb, int direction) -{ - actcapi_msg *msg = (actcapi_msg *)skb->data; - char *descr; - int i; - char tmp[170]; - -#ifndef DEBUG_DATA_MSG - if (msg->hdr.cmd.cmd == 0x86) - return; -#endif - descr = "INVALID"; -#ifdef DEBUG_DUMP_SKB - dump_skb(skb); -#endif - for (i = 0; i < ARRAY_SIZE(valid_msg); i++) - if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) && - (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) { - descr = valid_msg[i].description; - break; - } - printk(KERN_DEBUG "%s %s msg\n", direction ? "Outgoing" : "Incoming", descr); - printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID); - printk(KERN_DEBUG " Len = %d\n", msg->hdr.len); - printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum); - printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd); - printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd); - switch (i) { - case 0: - /* DATA B3 IND */ - printk(KERN_DEBUG " BLOCK = 0x%02x\n", - msg->msg.data_b3_ind.blocknr); - break; - case 2: - /* CONNECT CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.connect_conf.info); - break; - case 3: - /* CONNECT IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_ind.plci); - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.connect_ind.controller); - printk(KERN_DEBUG " SI1 = %d\n", - msg->msg.connect_ind.si1); - printk(KERN_DEBUG " SI2 = %d\n", - msg->msg.connect_ind.si2); - printk(KERN_DEBUG " EAZ = '%c'\n", - msg->msg.connect_ind.eaz); - actcapi_debug_caddr(&msg->msg.connect_ind.addr); - break; - case 5: - /* CONNECT ACTIVE IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_active_ind.plci); - actcapi_debug_caddr(&msg->msg.connect_active_ind.addr); - break; - case 8: - /* LISTEN CONF */ - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.listen_conf.controller); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.listen_conf.info); - break; - case 11: - /* INFO IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.info_ind.plci); - printk(KERN_DEBUG " Imsk = 0x%04x\n", - msg->msg.info_ind.nr.mask); - if (msg->hdr.len > 12) { - int l = msg->hdr.len - 12; - int j; - char *p = tmp; - - for (j = 0; j < l; j++) - p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]); - printk(KERN_DEBUG " D = '%s'\n", tmp); - } - break; - case 14: - /* SELECT B2 PROTOCOL CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b2_protocol_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.select_b2_protocol_conf.info); - break; - case 15: - /* SELECT B3 PROTOCOL CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b3_protocol_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.select_b3_protocol_conf.info); - break; - case 16: - /* LISTEN B3 CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.listen_b3_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.listen_b3_conf.info); - break; - case 18: - /* CONNECT B3 IND */ - printk(KERN_DEBUG " NCCI = 0x%04x\n", - msg->msg.connect_b3_ind.ncci); - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_b3_ind.plci); - actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi); - break; - case 19: - /* CONNECT B3 ACTIVE IND */ - printk(KERN_DEBUG " NCCI = 0x%04x\n", - msg->msg.connect_b3_active_ind.ncci); - actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi); - break; - case 26: - /* MANUFACTURER IND */ - printk(KERN_DEBUG " Mmsg = 0x%02x\n", - msg->msg.manufacturer_ind_err.manuf_msg); - switch (msg->msg.manufacturer_ind_err.manuf_msg) { - case 3: - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.manufacturer_ind_err.controller); - printk(KERN_DEBUG " Code = 0x%08x\n", - msg->msg.manufacturer_ind_err.errcode); - memset(tmp, 0, sizeof(tmp)); - strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring, - msg->hdr.len - 16); - printk(KERN_DEBUG " Emsg = '%s'\n", tmp); - break; - } - break; - case 30: - /* LISTEN REQ */ - printk(KERN_DEBUG " Imsk = 0x%08x\n", - msg->msg.listen_req.infomask); - printk(KERN_DEBUG " Emsk = 0x%04x\n", - msg->msg.listen_req.eazmask); - printk(KERN_DEBUG " Smsk = 0x%04x\n", - msg->msg.listen_req.simask); - break; - case 35: - /* SELECT_B2_PROTOCOL_REQ */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b2_protocol_req.plci); - printk(KERN_DEBUG " prot = 0x%02x\n", - msg->msg.select_b2_protocol_req.protocol); - if (msg->hdr.len >= 11) - printk(KERN_DEBUG "No dlpd\n"); - else - actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd); - break; - case 44: - /* CONNECT RESP */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_resp.plci); - printk(KERN_DEBUG " CAUSE = 0x%02x\n", - msg->msg.connect_resp.rejectcause); - break; - case 45: - /* CONNECT ACTIVE RESP */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_active_resp.plci); - break; - } -} -#endif diff --git a/drivers/staging/i4l/act2000/capi.h b/drivers/staging/i4l/act2000/capi.h deleted file mode 100644 index 34884a5efee5..000000000000 --- a/drivers/staging/i4l/act2000/capi.h +++ /dev/null @@ -1,357 +0,0 @@ -/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef CAPI_H -#define CAPI_H - -/* Command-part of a CAPI message */ -typedef struct actcapi_msgcmd { - __u8 cmd; - __u8 subcmd; -} actcapi_msgcmd; - -/* CAPI message header */ -typedef struct actcapi_msghdr { - __u16 len; - __u16 applicationID; - actcapi_msgcmd cmd; - __u16 msgnum; -} actcapi_msghdr; - -/* CAPI message description (for debugging) */ -typedef struct actcapi_msgdsc { - actcapi_msgcmd cmd; - char *description; -} actcapi_msgdsc; - -/* CAPI Address */ -typedef struct actcapi_addr { - __u8 len; /* Length of element */ - __u8 tnp; /* Type/Numbering Plan */ - __u8 num[20]; /* Caller ID */ -} actcapi_addr; - -/* CAPI INFO element mask */ -typedef union actcapi_infonr { /* info number */ - __u16 mask; /* info-mask field */ - struct bmask { /* bit definitions */ - unsigned codes:3; /* code set */ - unsigned rsvd:5; /* reserved */ - unsigned svind:1; /* single, variable length ind. */ - unsigned wtype:7; /* W-element type */ - } bmask; -} actcapi_infonr; - -/* CAPI INFO element */ -typedef union actcapi_infoel { /* info element */ - __u8 len; /* length of info element */ - __u8 display[40]; /* display contents */ - __u8 uuinfo[40]; /* User-user info field */ - struct cause { /* Cause information */ - unsigned ext2:1; /* extension */ - unsigned cod:2; /* coding standard */ - unsigned spare:1; /* spare */ - unsigned loc:4; /* location */ - unsigned ext1:1; /* extension */ - unsigned cval:7; /* Cause value */ - } cause; - struct charge { /* Charging information */ - __u8 toc; /* type of charging info */ - __u8 unit[10]; /* charging units */ - } charge; - __u8 date[20]; /* date fields */ - __u8 stat; /* state of remote party */ -} actcapi_infoel; - -/* Message for EAZ<->MSN Mapping */ -typedef struct actcapi_msn { - __u8 eaz; - __u8 len; /* Length of MSN */ - __u8 msn[15]; -} __attribute__((packed)) actcapi_msn; - -typedef struct actcapi_dlpd { - __u8 len; /* Length of structure */ - __u16 dlen; /* Data Length */ - __u8 laa; /* Link Address A */ - __u8 lab; /* Link Address B */ - __u8 modulo; /* Modulo Mode */ - __u8 win; /* Window size */ - __u8 xid[100]; /* XID Information */ -} __attribute__((packed)) actcapi_dlpd; - -typedef struct actcapi_ncpd { - __u8 len; /* Length of structure */ - __u16 lic; - __u16 hic; - __u16 ltc; - __u16 htc; - __u16 loc; - __u16 hoc; - __u8 modulo; -} __attribute__((packed)) actcapi_ncpd; -#define actcapi_ncpi actcapi_ncpd - -/* - * Layout of NCCI field in a B3 DATA CAPI message is different from - * standard at act2000: - * - * Bit 0-4 = PLCI - * Bit 5-7 = Controller - * Bit 8-15 = NCCI - */ -#define MAKE_NCCI(plci, contr, ncci) \ - ((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8)) - -#define EVAL_NCCI(fakencci, plci, ncci) { \ - plci = fakencci & 0x1f; \ - ncci = (fakencci >> 8) & 0xff; \ - } - -/* - * Layout of PLCI field in a B3 DATA CAPI message is different from - * standard at act2000: - * - * Bit 0-4 = PLCI - * Bit 5-7 = Controller - * Bit 8-15 = reserved (must be 0) - */ - -typedef struct actcapi_msg { - actcapi_msghdr hdr; - union { - __u16 manuf_msg; - struct manufacturer_req_net { - __u16 manuf_msg; - __u16 controller; - __u8 nettype; - } manufacturer_req_net; - struct manufacturer_req_v42 { - __u16 manuf_msg; - __u16 controller; - __u32 v42control; - } manufacturer_req_v42; - struct manufacturer_conf_v42 { - __u16 manuf_msg; - __u16 controller; - } manufacturer_conf_v42; - struct manufacturer_req_err { - __u16 manuf_msg; - __u16 controller; - } manufacturer_req_err; - struct manufacturer_ind_err { - __u16 manuf_msg; - __u16 controller; - __u32 errcode; - __u8 errstring; /* actually up to 160 */ - } manufacturer_ind_err; - struct manufacturer_req_msn { - __u16 manuf_msg; - __u16 controller; - actcapi_msn msnmap; - } __attribute ((packed)) manufacturer_req_msn; - /* TODO: TraceInit-req/conf/ind/resp and - * TraceDump-req/conf/ind/resp - */ - struct connect_req { - __u8 controller; - __u8 bchan; - __u32 infomask; - __u8 si1; - __u8 si2; - __u8 eaz; - actcapi_addr addr; - } __attribute__ ((packed)) connect_req; - struct connect_conf { - __u16 plci; - __u16 info; - } connect_conf; - struct connect_ind { - __u16 plci; - __u8 controller; - __u8 si1; - __u8 si2; - __u8 eaz; - actcapi_addr addr; - } __attribute__ ((packed)) connect_ind; - struct connect_resp { - __u16 plci; - __u8 rejectcause; - } connect_resp; - struct connect_active_ind { - __u16 plci; - actcapi_addr addr; - } __attribute__ ((packed)) connect_active_ind; - struct connect_active_resp { - __u16 plci; - } connect_active_resp; - struct connect_b3_req { - __u16 plci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_req; - struct connect_b3_conf { - __u16 plci; - __u16 ncci; - __u16 info; - } connect_b3_conf; - struct connect_b3_ind { - __u16 ncci; - __u16 plci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_ind; - struct connect_b3_resp { - __u16 ncci; - __u8 rejectcause; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_resp; - struct disconnect_req { - __u16 plci; - __u8 cause; - } disconnect_req; - struct disconnect_conf { - __u16 plci; - __u16 info; - } disconnect_conf; - struct disconnect_ind { - __u16 plci; - __u16 info; - } disconnect_ind; - struct disconnect_resp { - __u16 plci; - } disconnect_resp; - struct connect_b3_active_ind { - __u16 ncci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_active_ind; - struct connect_b3_active_resp { - __u16 ncci; - } connect_b3_active_resp; - struct disconnect_b3_req { - __u16 ncci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_req; - struct disconnect_b3_conf { - __u16 ncci; - __u16 info; - } disconnect_b3_conf; - struct disconnect_b3_ind { - __u16 ncci; - __u16 info; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_ind; - struct disconnect_b3_resp { - __u16 ncci; - } disconnect_b3_resp; - struct info_ind { - __u16 plci; - actcapi_infonr nr; - actcapi_infoel el; - } __attribute__ ((packed)) info_ind; - struct info_resp { - __u16 plci; - } info_resp; - struct listen_b3_req { - __u16 plci; - } listen_b3_req; - struct listen_b3_conf { - __u16 plci; - __u16 info; - } listen_b3_conf; - struct select_b2_protocol_req { - __u16 plci; - __u8 protocol; - actcapi_dlpd dlpd; - } __attribute__ ((packed)) select_b2_protocol_req; - struct select_b2_protocol_conf { - __u16 plci; - __u16 info; - } select_b2_protocol_conf; - struct select_b3_protocol_req { - __u16 plci; - __u8 protocol; - actcapi_ncpd ncpd; - } __attribute__ ((packed)) select_b3_protocol_req; - struct select_b3_protocol_conf { - __u16 plci; - __u16 info; - } select_b3_protocol_conf; - struct listen_req { - __u8 controller; - __u32 infomask; - __u16 eazmask; - __u16 simask; - } __attribute__ ((packed)) listen_req; - struct listen_conf { - __u8 controller; - __u16 info; - } __attribute__ ((packed)) listen_conf; - struct data_b3_req { - __u16 fakencci; - __u16 datalen; - __u32 unused; - __u8 blocknr; - __u16 flags; - } __attribute ((packed)) data_b3_req; - struct data_b3_ind { - __u16 fakencci; - __u16 datalen; - __u32 unused; - __u8 blocknr; - __u16 flags; - } __attribute__ ((packed)) data_b3_ind; - struct data_b3_resp { - __u16 ncci; - __u8 blocknr; - } __attribute__ ((packed)) data_b3_resp; - struct data_b3_conf { - __u16 ncci; - __u8 blocknr; - __u16 info; - } __attribute__ ((packed)) data_b3_conf; - } msg; -} __attribute__ ((packed)) actcapi_msg; - -static inline unsigned short -actcapi_nextsmsg(act2000_card *card) -{ - unsigned long flags; - unsigned short n; - - spin_lock_irqsave(&card->mnlock, flags); - n = card->msgnum; - card->msgnum++; - card->msgnum &= 0x7fff; - spin_unlock_irqrestore(&card->mnlock, flags); - return n; -} -#define DEBUG_MSG -#undef DEBUG_DATA_MSG -#undef DEBUG_DUMP_SKB - -extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *); -extern int actcapi_listen_req(act2000_card *); -extern int actcapi_manufacturer_req_net(act2000_card *); -extern int actcapi_manufacturer_req_errh(act2000_card *); -extern int actcapi_manufacturer_req_msn(act2000_card *); -extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int); -extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *); -extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *); -extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8); -extern void actcapi_dispatch(struct work_struct *); -#ifdef DEBUG_MSG -extern void actcapi_debug_msg(struct sk_buff *skb, int); -#else -#define actcapi_debug_msg(skb, len) -#endif -#endif diff --git a/drivers/staging/i4l/act2000/module.c b/drivers/staging/i4l/act2000/module.c deleted file mode 100644 index 6aa120319e52..000000000000 --- a/drivers/staging/i4l/act2000/module.c +++ /dev/null @@ -1,816 +0,0 @@ -/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright by Fritz Elfert <fritz@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "act2000_isa.h" -#include "capi.h" -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> - -static unsigned short act2000_isa_ports[] = { - 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, - 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60, -}; - -static act2000_card *cards = (act2000_card *) NULL; - -/* Parameters to be set by insmod */ -static int act_bus; -static int act_port = -1; /* -1 = Autoprobe */ -static int act_irq = -1; -static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - -MODULE_DESCRIPTION("ISDN4Linux: Driver for IBM Active 2000 ISDN card"); -MODULE_AUTHOR("Fritz Elfert"); -MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA"); -MODULE_PARM_DESC(act_port, "Base port address of first card"); -MODULE_PARM_DESC(act_irq, "IRQ of first card"); -MODULE_PARM_DESC(act_id, "ID-String of first card"); -module_param(act_bus, int, 0); -module_param(act_port, int, 0); -module_param(act_irq, int, 0); -module_param(act_id, charp, 0); - -static int act2000_addcard(int, int, int, char *); - -static act2000_chan * -find_channel(act2000_card *card, int channel) -{ - if ((channel >= 0) && (channel < ACT2000_BCH)) - return &(card->bch[channel]); - printk(KERN_WARNING "act2000: Invalid channel %d\n", channel); - return NULL; -} - -/* - * Free MSN list - */ -static void -act2000_clear_msn(act2000_card *card) -{ - struct msn_entry *p = card->msn_list; - struct msn_entry *q; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - card->msn_list = NULL; - spin_unlock_irqrestore(&card->lock, flags); - while (p) { - q = p->next; - kfree(p); - p = q; - } -} - -/* - * Find an MSN entry in the list. - * If ia5 != 0, return IA5-encoded EAZ, else - * return a bitmask with corresponding bit set. - */ -static __u16 -act2000_find_msn(act2000_card *card, char *msn, int ia5) -{ - struct msn_entry *p = card->msn_list; - __u8 eaz = '0'; - - while (p) { - if (!strcmp(p->msn, msn)) { - eaz = p->eaz; - break; - } - p = p->next; - } - if (!ia5) - return 1 << (eaz - '0'); - else - return eaz; -} - -/* - * Find an EAZ entry in the list. - * return a string with corresponding msn. - */ -char * -act2000_find_eaz(act2000_card *card, char eaz) -{ - struct msn_entry *p = card->msn_list; - - while (p) { - if (p->eaz == eaz) - return p->msn; - p = p->next; - } - return "\0"; -} - -/* - * Add or delete an MSN to the MSN list - * - * First character of msneaz is EAZ, rest is MSN. - * If length of eazmsn is 1, delete that entry. - */ -static int -act2000_set_msn(act2000_card *card, char *eazmsn) -{ - struct msn_entry *p = card->msn_list; - struct msn_entry *q = NULL; - unsigned long flags; - int i; - - if (!strlen(eazmsn)) - return 0; - if (strlen(eazmsn) > 16) - return -EINVAL; - for (i = 0; i < strlen(eazmsn); i++) - if (!isdigit(eazmsn[i])) - return -EINVAL; - if (strlen(eazmsn) == 1) { - /* Delete a single MSN */ - while (p) { - if (p->eaz == eazmsn[0]) { - spin_lock_irqsave(&card->lock, flags); - if (q) - q->next = p->next; - else - card->msn_list = p->next; - spin_unlock_irqrestore(&card->lock, flags); - kfree(p); - printk(KERN_DEBUG - "Mapping for EAZ %c deleted\n", - eazmsn[0]); - return 0; - } - q = p; - p = p->next; - } - return 0; - } - /* Add a single MSN */ - while (p) { - /* Found in list, replace MSN */ - if (p->eaz == eazmsn[0]) { - spin_lock_irqsave(&card->lock, flags); - strcpy(p->msn, &eazmsn[1]); - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_DEBUG - "Mapping for EAZ %c changed to %s\n", - eazmsn[0], - &eazmsn[1]); - return 0; - } - p = p->next; - } - /* Not found in list, add new entry */ - p = kmalloc(sizeof(msn_entry), GFP_KERNEL); - if (!p) - return -ENOMEM; - p->eaz = eazmsn[0]; - strcpy(p->msn, &eazmsn[1]); - p->next = card->msn_list; - spin_lock_irqsave(&card->lock, flags); - card->msn_list = p; - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_DEBUG - "Mapping %c -> %s added\n", - eazmsn[0], - &eazmsn[1]); - return 0; -} - -static void -act2000_transmit(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, snd_tq); - - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_send(card); - break; - case ACT2000_BUS_PCMCIA: - case ACT2000_BUS_MCA: - default: - printk(KERN_WARNING - "act2000_transmit: Illegal bustype %d\n", card->bus); - } -} - -static void -act2000_receive(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, poll_tq); - - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_receive(card); - break; - case ACT2000_BUS_PCMCIA: - case ACT2000_BUS_MCA: - default: - printk(KERN_WARNING - "act2000_receive: Illegal bustype %d\n", card->bus); - } -} - -static void -act2000_poll(unsigned long data) -{ - act2000_card *card = (act2000_card *)data; - unsigned long flags; - - act2000_receive(&card->poll_tq); - spin_lock_irqsave(&card->lock, flags); - mod_timer(&card->ptimer, jiffies + 3); - spin_unlock_irqrestore(&card->lock, flags); -} - -static int -act2000_command(act2000_card *card, isdn_ctrl *c) -{ - ulong a; - act2000_chan *chan; - act2000_cdef cdef; - isdn_ctrl cmd; - char tmp[17]; - int ret; - unsigned long flags; - void __user *arg; - - switch (c->command) { - case ISDN_CMD_IOCTL: - memcpy(&a, c->parm.num, sizeof(ulong)); - arg = (void __user *)a; - switch (c->arg) { - case ACT2000_IOCTL_LOADBOOT: - switch (card->bus) { - case ACT2000_BUS_ISA: - ret = act2000_isa_download(card, - arg); - if (!ret) { - card->flags |= ACT2000_FLAGS_LOADED; - if (!(card->flags & ACT2000_FLAGS_IVALID)) { - card->ptimer.expires = jiffies + 3; - card->ptimer.function = act2000_poll; - card->ptimer.data = (unsigned long)card; - add_timer(&card->ptimer); - } - actcapi_manufacturer_req_errh(card); - } - break; - default: - printk(KERN_WARNING - "act2000: Illegal BUS type %d\n", - card->bus); - ret = -EIO; - } - return ret; - case ACT2000_IOCTL_SETPROTO: - card->ptype = a ? ISDN_PTYPE_EURO : ISDN_PTYPE_1TR6; - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return 0; - actcapi_manufacturer_req_net(card); - return 0; - case ACT2000_IOCTL_SETMSN: - if (copy_from_user(tmp, arg, - sizeof(tmp))) - return -EFAULT; - ret = act2000_set_msn(card, tmp); - if (ret) - return ret; - if (card->flags & ACT2000_FLAGS_RUNNING) - return actcapi_manufacturer_req_msn(card); - return 0; - case ACT2000_IOCTL_ADDCARD: - if (copy_from_user(&cdef, arg, - sizeof(cdef))) - return -EFAULT; - if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id)) - return -EIO; - return 0; - case ACT2000_IOCTL_TEST: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return 0; - default: - return -EINVAL; - } - break; - case ISDN_CMD_DIAL: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - spin_lock_irqsave(&card->lock, flags); - if (chan->fsm_state != ACT2000_STATE_NULL) { - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_WARNING "Dial on channel with state %d\n", - chan->fsm_state); - return -EBUSY; - } - if (card->ptype == ISDN_PTYPE_EURO) - tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1); - else - tmp[0] = c->parm.setup.eazmsn[0]; - chan->fsm_state = ACT2000_STATE_OCALL; - chan->callref = 0xffff; - spin_unlock_irqrestore(&card->lock, flags); - ret = actcapi_connect_req(card, chan, c->parm.setup.phone, - tmp[0], c->parm.setup.si1, - c->parm.setup.si2); - if (ret) { - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg &= 0x0f; - card->interface.statcallb(&cmd); - } - return ret; - case ISDN_CMD_ACCEPTD: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - if (chan->fsm_state == ACT2000_STATE_ICALL) - actcapi_select_b2_protocol_req(card, chan); - return 0; - case ISDN_CMD_ACCEPTB: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return 0; - case ISDN_CMD_HANGUP: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - switch (chan->fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_BSETUP: - actcapi_connect_resp(card, chan, 0x15); - break; - case ACT2000_STATE_ACTIVE: - actcapi_disconnect_b3_req(card, chan); - break; - } - return 0; - case ISDN_CMD_SETEAZ: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - if (strlen(c->parm.num)) { - if (card->ptype == ISDN_PTYPE_EURO) { - chan->eazmask = act2000_find_msn(card, c->parm.num, 0); - } - if (card->ptype == ISDN_PTYPE_1TR6) { - int i; - - chan->eazmask = 0; - for (i = 0; i < strlen(c->parm.num); i++) - if (isdigit(c->parm.num[i])) - chan->eazmask |= (1 << (c->parm.num[i] - '0')); - } - } else - chan->eazmask = 0x3ff; - actcapi_listen_req(card); - return 0; - case ISDN_CMD_CLREAZ: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->eazmask = 0; - actcapi_listen_req(card); - return 0; - case ISDN_CMD_SETL2: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->l2prot = (c->arg >> 8); - return 0; - case ISDN_CMD_SETL3: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { - printk(KERN_WARNING "L3 protocol unknown\n"); - return -1; - } - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->l3prot = (c->arg >> 8); - return 0; - } - - return -EINVAL; -} - -static int -act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb) -{ - struct sk_buff *xmit_skb; - int len; - act2000_chan *chan; - actcapi_msg *msg; - - if (!(chan = find_channel(card, channel))) - return -1; - if (chan->fsm_state != ACT2000_STATE_ACTIVE) - return -1; - len = skb->len; - if ((chan->queued + len) >= ACT2000_MAX_QUEUED) - return 0; - if (!len) - return 0; - if (skb_headroom(skb) < 19) { - printk(KERN_WARNING "act2000_sendbuf: Headroom only %d\n", - skb_headroom(skb)); - xmit_skb = alloc_skb(len + 19, GFP_ATOMIC); - if (!xmit_skb) { - printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); - return 0; - } - skb_reserve(xmit_skb, 19); - skb_copy_from_linear_data(skb, skb_put(xmit_skb, len), len); - } else { - xmit_skb = skb_clone(skb, GFP_ATOMIC); - if (!xmit_skb) { - printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); - return 0; - } - } - dev_kfree_skb(skb); - msg = (actcapi_msg *)skb_push(xmit_skb, 19); - msg->hdr.len = 19 + len; - msg->hdr.applicationID = 1; - msg->hdr.cmd.cmd = 0x86; - msg->hdr.cmd.subcmd = 0x00; - msg->hdr.msgnum = actcapi_nextsmsg(card); - msg->msg.data_b3_req.datalen = len; - msg->msg.data_b3_req.blocknr = (msg->hdr.msgnum & 0xff); - msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci); - msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */ - actcapi_debug_msg(xmit_skb, 1); - chan->queued += len; - skb_queue_tail(&card->sndq, xmit_skb); - act2000_schedule_tx(card); - return len; -} - - -/* Read the Status-replies from the Interface */ -static int -act2000_readstatus(u_char __user *buf, int len, act2000_card *card) -{ - int count; - u_char __user *p; - - for (p = buf, count = 0; count < len; p++, count++) { - if (card->status_buf_read == card->status_buf_write) - return count; - put_user(*card->status_buf_read++, p); - if (card->status_buf_read > card->status_buf_end) - card->status_buf_read = card->status_buf; - } - return count; -} - -/* - * Find card with given driverId - */ -static inline act2000_card * -act2000_findcard(int driverid) -{ - act2000_card *p = cards; - - while (p) { - if (p->myid == driverid) - return p; - p = p->next; - } - return (act2000_card *) 0; -} - -/* - * Wrapper functions for interface to linklevel - */ -static int -if_command(isdn_ctrl *c) -{ - act2000_card *card = act2000_findcard(c->driver); - - if (card) - return act2000_command(card, c); - printk(KERN_ERR - "act2000: if_command %d called with invalid driverId %d!\n", - c->command, c->driver); - return -ENODEV; -} - -static int -if_writecmd(const u_char __user *buf, int len, int id, int channel) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return len; - } - printk(KERN_ERR - "act2000: if_writecmd called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_readstatus(u_char __user *buf, int len, int id, int channel) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return act2000_readstatus(buf, len, card); - } - printk(KERN_ERR - "act2000: if_readstatus called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return act2000_sendbuf(card, channel, ack, skb); - } - printk(KERN_ERR - "act2000: if_sendbuf called with invalid driverId!\n"); - return -ENODEV; -} - - -/* - * Allocate a new card-struct, initialize it - * link it into cards-list. - */ -static void -act2000_alloccard(int bus, int port, int irq, char *id) -{ - int i; - act2000_card *card; - - if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) { - printk(KERN_WARNING - "act2000: (%s) Could not allocate card-struct.\n", id); - return; - } - spin_lock_init(&card->lock); - spin_lock_init(&card->mnlock); - skb_queue_head_init(&card->sndq); - skb_queue_head_init(&card->rcvq); - skb_queue_head_init(&card->ackq); - INIT_WORK(&card->snd_tq, act2000_transmit); - INIT_WORK(&card->rcv_tq, actcapi_dispatch); - INIT_WORK(&card->poll_tq, act2000_receive); - init_timer(&card->ptimer); - card->interface.owner = THIS_MODULE; - card->interface.channels = ACT2000_BCH; - card->interface.maxbufsize = 4000; - card->interface.command = if_command; - card->interface.writebuf_skb = if_sendbuf; - card->interface.writecmd = if_writecmd; - card->interface.readstat = if_readstatus; - card->interface.features = - ISDN_FEATURE_L2_X75I | - ISDN_FEATURE_L2_HDLC | - ISDN_FEATURE_L3_TRANS | - ISDN_FEATURE_P_UNKNOWN; - card->interface.hl_hdrlen = 20; - card->ptype = ISDN_PTYPE_EURO; - strlcpy(card->interface.id, id, sizeof(card->interface.id)); - for (i = 0; i < ACT2000_BCH; i++) { - card->bch[i].plci = 0x8000; - card->bch[i].ncci = 0x8000; - card->bch[i].l2prot = ISDN_PROTO_L2_X75I; - card->bch[i].l3prot = ISDN_PROTO_L3_TRANS; - } - card->myid = -1; - card->bus = bus; - card->port = port; - card->irq = irq; - card->next = cards; - cards = card; -} - -/* - * register card at linklevel - */ -static int -act2000_registercard(act2000_card *card) -{ - switch (card->bus) { - case ACT2000_BUS_ISA: - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: Illegal BUS type %d\n", - card->bus); - return -1; - } - if (!register_isdn(&card->interface)) { - printk(KERN_WARNING - "act2000: Unable to register %s\n", - card->interface.id); - return -1; - } - card->myid = card->interface.channels; - sprintf(card->regname, "act2000-isdn (%s)", card->interface.id); - return 0; -} - -static void -unregister_card(act2000_card *card) -{ - isdn_ctrl cmd; - - cmd.command = ISDN_STAT_UNLOAD; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_release(card); - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: Invalid BUS type %d\n", - card->bus); - break; - } -} - -static int -act2000_addcard(int bus, int port, int irq, char *id) -{ - act2000_card *p; - act2000_card *q = NULL; - int initialized; - int added = 0; - int failed = 0; - int i; - - if (!bus) - bus = ACT2000_BUS_ISA; - if (port != -1) { - /* Port defined, do fixed setup */ - act2000_alloccard(bus, port, irq, id); - } else { - /* No port defined, perform autoprobing. - * This may result in more than one card detected. - */ - switch (bus) { - case ACT2000_BUS_ISA: - for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++) - if (act2000_isa_detect(act2000_isa_ports[i])) { - printk(KERN_INFO "act2000: Detected " - "ISA card at port 0x%x\n", - act2000_isa_ports[i]); - act2000_alloccard(bus, - act2000_isa_ports[i], irq, id); - } - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: addcard: Invalid BUS type %d\n", bus); - } - } - if (!cards) - return 1; - p = cards; - while (p) { - initialized = 0; - if (!p->interface.statcallb) { - /* Not yet registered. - * Try to register and activate it. - */ - added++; - switch (p->bus) { - case ACT2000_BUS_ISA: - if (act2000_isa_detect(p->port)) { - if (act2000_registercard(p)) - break; - if (act2000_isa_config_port(p, p->port)) { - printk(KERN_WARNING - "act2000: Could not request port 0x%04x\n", - p->port); - unregister_card(p); - p->interface.statcallb = NULL; - break; - } - if (act2000_isa_config_irq(p, p->irq)) { - printk(KERN_INFO - "act2000: No IRQ available, fallback to polling\n"); - /* Fall back to polled operation */ - p->irq = 0; - } - printk(KERN_INFO - "act2000: ISA" - "-type card at port " - "0x%04x ", - p->port); - if (p->irq) - printk("irq %d\n", p->irq); - else - printk("polled\n"); - initialized = 1; - } - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: addcard: Invalid BUS type %d\n", - p->bus); - } - } else - /* Card already initialized */ - initialized = 1; - if (initialized) { - /* Init OK, next card ... */ - q = p; - p = p->next; - } else { - /* Init failed, remove card from list, free memory */ - printk(KERN_WARNING - "act2000: Initialization of %s failed\n", - p->interface.id); - if (q) { - q->next = p->next; - kfree(p); - p = q->next; - } else { - cards = p->next; - kfree(p); - p = cards; - } - failed++; - } - } - return added - failed; -} - -#define DRIVERNAME "IBM Active 2000 ISDN driver" - -static int __init act2000_init(void) -{ - printk(KERN_INFO "%s\n", DRIVERNAME); - if (!cards) - act2000_addcard(act_bus, act_port, act_irq, act_id); - if (!cards) - printk(KERN_INFO "act2000: No cards defined yet\n"); - return 0; -} - -static void __exit act2000_exit(void) -{ - act2000_card *card = cards; - act2000_card *last; - - while (card) { - unregister_card(card); - del_timer_sync(&card->ptimer); - card = card->next; - } - card = cards; - while (card) { - last = card; - card = card->next; - act2000_clear_msn(last); - kfree(last); - } - printk(KERN_INFO "%s unloaded\n", DRIVERNAME); -} - -module_init(act2000_init); -module_exit(act2000_exit); diff --git a/drivers/staging/i4l/icn/Kconfig b/drivers/staging/i4l/icn/Kconfig deleted file mode 100644 index 4534f21a1852..000000000000 --- a/drivers/staging/i4l/icn/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config ISDN_DRV_ICN - tristate "ICN 2B and 4B support" - depends on ISA - help - This enables support for two kinds of ISDN-cards made by a German - company called ICN. 2B is the standard version for a single ISDN - line with two B-channels, 4B supports two ISDN lines. For running - this card, additional firmware is necessary, which has to be - downloaded into the card using a utility which is distributed - separately. See <file:Documentation/isdn/README> and - <file:Documentation/isdn/README.icn> for more - information. diff --git a/drivers/staging/i4l/icn/Makefile b/drivers/staging/i4l/icn/Makefile deleted file mode 100644 index d9b476fcf384..000000000000 --- a/drivers/staging/i4l/icn/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# Makefile for the icn ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_ICN) += icn.o diff --git a/drivers/staging/i4l/icn/icn.c b/drivers/staging/i4l/icn/icn.c deleted file mode 100644 index 3750ba38adc5..000000000000 --- a/drivers/staging/i4l/icn/icn.c +++ /dev/null @@ -1,1696 +0,0 @@ -/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $ - * - * ISDN low-level module for the ICN active ISDN-Card. - * - * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include "icn.h" -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/sched.h> - -static int portbase = ICN_BASEADDR; -static unsigned long membase = ICN_MEMADDR; -static char *icn_id = "\0"; -static char *icn_id2 = "\0"; - -MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card"); -MODULE_AUTHOR("Fritz Elfert"); -MODULE_LICENSE("GPL"); -module_param(portbase, int, 0); -MODULE_PARM_DESC(portbase, "Port address of first card"); -module_param(membase, ulong, 0); -MODULE_PARM_DESC(membase, "Shared memory address of all cards"); -module_param(icn_id, charp, 0); -MODULE_PARM_DESC(icn_id, "ID-String of first card"); -module_param(icn_id2, charp, 0); -MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)"); - -/* - * Verbose bootcode- and protocol-downloading. - */ -#undef BOOT_DEBUG - -/* - * Verbose Shmem-Mapping. - */ -#undef MAP_DEBUG - -static char -*revision = "$Revision: 1.65.6.8 $"; - -static int icn_addcard(int, char *, char *); - -/* - * Free send-queue completely. - * Parameter: - * card = pointer to card struct - * channel = channel number - */ -static void -icn_free_queue(icn_card *card, int channel) -{ - struct sk_buff_head *queue = &card->spqueue[channel]; - struct sk_buff *skb; - - skb_queue_purge(queue); - card->xlen[channel] = 0; - card->sndcount[channel] = 0; - skb = card->xskb[channel]; - if (skb) { - card->xskb[channel] = NULL; - dev_kfree_skb(skb); - } -} - -/* Put a value into a shift-register, highest bit first. - * Parameters: - * port = port for output (bit 0 is significant) - * val = value to be output - * firstbit = Bit-Number of highest bit - * bitcount = Number of bits to output - */ -static inline void -icn_shiftout(unsigned short port, - unsigned long val, - int firstbit, - int bitcount) -{ - register u_char s; - register u_char c; - - for (s = firstbit, c = bitcount; c > 0; s--, c--) - OUTB_P((u_char)((val >> s) & 1) ? 0xff : 0, port); -} - -/* - * disable a cards shared memory - */ -static inline void -icn_disable_ram(icn_card *card) -{ - OUTB_P(0, ICN_MAPRAM); -} - -/* - * enable a cards shared memory - */ -static inline void -icn_enable_ram(icn_card *card) -{ - OUTB_P(0xff, ICN_MAPRAM); -} - -/* - * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12) - * - * must called with holding the devlock - */ -static inline void -icn_map_channel(icn_card *card, int channel) -{ -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel); -#endif - if ((channel == dev.channel) && (card == dev.mcard)) - return; - if (dev.mcard) - icn_disable_ram(dev.mcard); - icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4); /* Select Bank */ - icn_enable_ram(card); - dev.mcard = card; - dev.channel = channel; -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_map_channel done\n"); -#endif -} - -/* - * Lock a cards channel. - * Return 0 if requested card/channel is unmapped (failure). - * Return 1 on success. - * - * must called with holding the devlock - */ -static inline int -icn_lock_channel(icn_card *card, int channel) -{ - register int retval; - -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_lock_channel %d\n", channel); -#endif - if ((dev.channel == channel) && (card == dev.mcard)) { - dev.chanlock++; - retval = 1; -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel); -#endif - } else { - retval = 0; -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel); -#endif - } - return retval; -} - -/* - * Release current card/channel lock - * - * must called with holding the devlock - */ -static inline void -__icn_release_channel(void) -{ -#ifdef MAP_DEBUG - printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock); -#endif - if (dev.chanlock > 0) - dev.chanlock--; -} - -/* - * Release current card/channel lock - */ -static inline void -icn_release_channel(void) -{ - ulong flags; - - spin_lock_irqsave(&dev.devlock, flags); - __icn_release_channel(); - spin_unlock_irqrestore(&dev.devlock, flags); -} - -/* - * Try to map and lock a cards channel. - * Return 1 on success, 0 on failure. - */ -static inline int -icn_trymaplock_channel(icn_card *card, int channel) -{ - ulong flags; - -#ifdef MAP_DEBUG - printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel, - dev.chanlock); -#endif - spin_lock_irqsave(&dev.devlock, flags); - if ((!dev.chanlock) || - ((dev.channel == channel) && (dev.mcard == card))) { - dev.chanlock++; - icn_map_channel(card, channel); - spin_unlock_irqrestore(&dev.devlock, flags); -#ifdef MAP_DEBUG - printk(KERN_DEBUG "trymaplock %d OK\n", channel); -#endif - return 1; - } - spin_unlock_irqrestore(&dev.devlock, flags); -#ifdef MAP_DEBUG - printk(KERN_DEBUG "trymaplock %d FAILED\n", channel); -#endif - return 0; -} - -/* - * Release current card/channel lock, - * then map same or other channel without locking. - */ -static inline void -icn_maprelease_channel(icn_card *card, int channel) -{ - ulong flags; - -#ifdef MAP_DEBUG - printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock); -#endif - spin_lock_irqsave(&dev.devlock, flags); - if (dev.chanlock > 0) - dev.chanlock--; - if (!dev.chanlock) - icn_map_channel(card, channel); - spin_unlock_irqrestore(&dev.devlock, flags); -} - -/* Get Data from the B-Channel, assemble fragmented packets and put them - * into receive-queue. Wake up any B-Channel-reading processes. - * This routine is called via timer-callback from icn_pollbchan(). - */ - -static void -icn_pollbchan_receive(int channel, icn_card *card) -{ - int mch = channel + ((card->secondhalf) ? 2 : 0); - int eflag; - int cnt; - struct sk_buff *skb; - - if (icn_trymaplock_channel(card, mch)) { - while (rbavl) { - cnt = readb(&rbuf_l); - if ((card->rcvidx[channel] + cnt) > 4000) { - printk(KERN_WARNING - "icn: (%s) bogus packet on ch%d, dropping.\n", - CID, - channel + 1); - card->rcvidx[channel] = 0; - eflag = 0; - } else { - memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]], - &rbuf_d, cnt); - card->rcvidx[channel] += cnt; - eflag = readb(&rbuf_f); - } - rbnext; - icn_maprelease_channel(card, mch & 2); - if (!eflag) { - cnt = card->rcvidx[channel]; - if (cnt) { - skb = dev_alloc_skb(cnt); - if (!skb) { - printk(KERN_WARNING "icn: receive out of memory\n"); - break; - } - memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt); - card->rcvidx[channel] = 0; - card->interface.rcvcallb_skb(card->myid, channel, skb); - } - } - if (!icn_trymaplock_channel(card, mch)) - break; - } - icn_maprelease_channel(card, mch & 2); - } -} - -/* Send data-packet to B-Channel, split it up into fragments of - * ICN_FRAGSIZE length. If last fragment is sent out, signal - * success to upper layers via statcallb with ISDN_STAT_BSENT argument. - * This routine is called via timer-callback from icn_pollbchan() or - * directly from icn_sendbuf(). - */ - -static void -icn_pollbchan_send(int channel, icn_card *card) -{ - int mch = channel + ((card->secondhalf) ? 2 : 0); - int cnt; - unsigned long flags; - struct sk_buff *skb; - isdn_ctrl cmd; - - if (!(card->sndcount[channel] || card->xskb[channel] || - !skb_queue_empty(&card->spqueue[channel]))) - return; - if (icn_trymaplock_channel(card, mch)) { - while (sbfree && - (card->sndcount[channel] || - !skb_queue_empty(&card->spqueue[channel]) || - card->xskb[channel])) { - spin_lock_irqsave(&card->lock, flags); - if (card->xmit_lock[channel]) { - spin_unlock_irqrestore(&card->lock, flags); - break; - } - card->xmit_lock[channel]++; - spin_unlock_irqrestore(&card->lock, flags); - skb = card->xskb[channel]; - if (!skb) { - skb = skb_dequeue(&card->spqueue[channel]); - if (skb) { - /* Pop ACK-flag off skb. - * Store length to xlen. - */ - if (*(skb_pull(skb, 1))) - card->xlen[channel] = skb->len; - else - card->xlen[channel] = 0; - } - } - if (!skb) - break; - if (skb->len > ICN_FRAGSIZE) { - writeb(0xff, &sbuf_f); - cnt = ICN_FRAGSIZE; - } else { - writeb(0x0, &sbuf_f); - cnt = skb->len; - } - writeb(cnt, &sbuf_l); - memcpy_toio(&sbuf_d, skb->data, cnt); - skb_pull(skb, cnt); - sbnext; /* switch to next buffer */ - icn_maprelease_channel(card, mch & 2); - spin_lock_irqsave(&card->lock, flags); - card->sndcount[channel] -= cnt; - if (!skb->len) { - if (card->xskb[channel]) - card->xskb[channel] = NULL; - card->xmit_lock[channel] = 0; - spin_unlock_irqrestore(&card->lock, flags); - dev_kfree_skb(skb); - if (card->xlen[channel]) { - cmd.command = ISDN_STAT_BSENT; - cmd.driver = card->myid; - cmd.arg = channel; - cmd.parm.length = card->xlen[channel]; - card->interface.statcallb(&cmd); - } - } else { - card->xskb[channel] = skb; - card->xmit_lock[channel] = 0; - spin_unlock_irqrestore(&card->lock, flags); - } - if (!icn_trymaplock_channel(card, mch)) - break; - } - icn_maprelease_channel(card, mch & 2); - } -} - -/* Send/Receive Data to/from the B-Channel. - * This routine is called via timer-callback. - * It schedules itself while any B-Channel is open. - */ - -static void -icn_pollbchan(unsigned long data) -{ - icn_card *card = (icn_card *)data; - unsigned long flags; - - if (card->flags & ICN_FLAGS_B1ACTIVE) { - icn_pollbchan_receive(0, card); - icn_pollbchan_send(0, card); - } - if (card->flags & ICN_FLAGS_B2ACTIVE) { - icn_pollbchan_receive(1, card); - icn_pollbchan_send(1, card); - } - if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) { - /* schedule b-channel polling again */ - spin_lock_irqsave(&card->lock, flags); - mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD); - card->flags |= ICN_FLAGS_RBTIMER; - spin_unlock_irqrestore(&card->lock, flags); - } else - card->flags &= ~ICN_FLAGS_RBTIMER; -} - -typedef struct icn_stat { - char *statstr; - int command; - int action; -} icn_stat; -/* *INDENT-OFF* */ -static icn_stat icn_stat_table[] = { - {"BCON_", ISDN_STAT_BCONN, 1}, /* B-Channel connected */ - {"BDIS_", ISDN_STAT_BHUP, 2}, /* B-Channel disconnected */ - /* - ** add d-channel connect and disconnect support to link-level - */ - {"DCON_", ISDN_STAT_DCONN, 10}, /* D-Channel connected */ - {"DDIS_", ISDN_STAT_DHUP, 11}, /* D-Channel disconnected */ - {"DCAL_I", ISDN_STAT_ICALL, 3}, /* Incoming call dialup-line */ - {"DSCA_I", ISDN_STAT_ICALL, 3}, /* Incoming call 1TR6-SPV */ - {"FCALL", ISDN_STAT_ICALL, 4}, /* Leased line connection up */ - {"CIF", ISDN_STAT_CINF, 5}, /* Charge-info, 1TR6-type */ - {"AOC", ISDN_STAT_CINF, 6}, /* Charge-info, DSS1-type */ - {"CAU", ISDN_STAT_CAUSE, 7}, /* Cause code */ - {"TEI OK", ISDN_STAT_RUN, 0}, /* Card connected to wallplug */ - {"E_L1: ACT FAIL", ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ - {"E_L2: DATA LIN", ISDN_STAT_BHUP, 8}, /* Layer-2 data link lost */ - {"E_L1: ACTIVATION FAILED", - ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ - {NULL, 0, -1} -}; -/* *INDENT-ON* */ - - -/* - * Check Statusqueue-Pointer from isdn-cards. - * If there are new status-replies from the interface, check - * them against B-Channel-connects/disconnects and set flags accordingly. - * Wake-Up any processes, who are reading the status-device. - * If there are B-Channels open, initiate a timer-callback to - * icn_pollbchan(). - * This routine is called periodically via timer. - */ - -static void -icn_parse_status(u_char *status, int channel, icn_card *card) -{ - icn_stat *s = icn_stat_table; - int action = -1; - unsigned long flags; - isdn_ctrl cmd; - - while (s->statstr) { - if (!strncmp(status, s->statstr, strlen(s->statstr))) { - cmd.command = s->command; - action = s->action; - break; - } - s++; - } - if (action == -1) - return; - cmd.driver = card->myid; - cmd.arg = channel; - switch (action) { - case 11: - spin_lock_irqsave(&card->lock, flags); - icn_free_queue(card, channel); - card->rcvidx[channel] = 0; - - if (card->flags & - ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) { - isdn_ctrl ncmd; - - card->flags &= ~((channel) ? - ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE); - - memset(&ncmd, 0, sizeof(ncmd)); - - ncmd.driver = card->myid; - ncmd.arg = channel; - ncmd.command = ISDN_STAT_BHUP; - spin_unlock_irqrestore(&card->lock, flags); - card->interface.statcallb(&cmd); - } else - spin_unlock_irqrestore(&card->lock, flags); - break; - case 1: - spin_lock_irqsave(&card->lock, flags); - icn_free_queue(card, channel); - card->flags |= (channel) ? - ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE; - spin_unlock_irqrestore(&card->lock, flags); - break; - case 2: - spin_lock_irqsave(&card->lock, flags); - card->flags &= ~((channel) ? - ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE); - icn_free_queue(card, channel); - card->rcvidx[channel] = 0; - spin_unlock_irqrestore(&card->lock, flags); - break; - case 3: - { - char *t = status + 6; - char *s = strchr(t, ','); - - *s++ = '\0'; - strlcpy(cmd.parm.setup.phone, t, - sizeof(cmd.parm.setup.phone)); - s = strchr(t = s, ','); - *s++ = '\0'; - if (!strlen(t)) - cmd.parm.setup.si1 = 0; - else - cmd.parm.setup.si1 = - simple_strtoul(t, NULL, 10); - s = strchr(t = s, ','); - *s++ = '\0'; - if (!strlen(t)) - cmd.parm.setup.si2 = 0; - else - cmd.parm.setup.si2 = - simple_strtoul(t, NULL, 10); - strlcpy(cmd.parm.setup.eazmsn, s, - sizeof(cmd.parm.setup.eazmsn)); - } - cmd.parm.setup.plan = 0; - cmd.parm.setup.screen = 0; - break; - case 4: - sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid); - sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1); - cmd.parm.setup.si1 = 7; - cmd.parm.setup.si2 = 0; - cmd.parm.setup.plan = 0; - cmd.parm.setup.screen = 0; - break; - case 5: - strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num)); - break; - case 6: - snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d", - (int)simple_strtoul(status + 7, NULL, 16)); - break; - case 7: - status += 3; - if (strlen(status) == 4) - snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c", - status + 2, *status, *(status + 1)); - else - strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num)); - break; - case 8: - spin_lock_irqsave(&card->lock, flags); - card->flags &= ~ICN_FLAGS_B1ACTIVE; - icn_free_queue(card, 0); - card->rcvidx[0] = 0; - spin_unlock_irqrestore(&card->lock, flags); - cmd.arg = 0; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - cmd.command = ISDN_STAT_DHUP; - cmd.arg = 0; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - cmd.command = ISDN_STAT_BHUP; - spin_lock_irqsave(&card->lock, flags); - card->flags &= ~ICN_FLAGS_B2ACTIVE; - icn_free_queue(card, 1); - card->rcvidx[1] = 0; - spin_unlock_irqrestore(&card->lock, flags); - cmd.arg = 1; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - cmd.command = ISDN_STAT_DHUP; - cmd.arg = 1; - cmd.driver = card->myid; - break; - } - card->interface.statcallb(&cmd); - return; -} - -static void -icn_putmsg(icn_card *card, unsigned char c) -{ - ulong flags; - - spin_lock_irqsave(&card->lock, flags); - *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; - if (card->msg_buf_write == card->msg_buf_read) { - if (++card->msg_buf_read > card->msg_buf_end) - card->msg_buf_read = card->msg_buf; - } - if (card->msg_buf_write > card->msg_buf_end) - card->msg_buf_write = card->msg_buf; - spin_unlock_irqrestore(&card->lock, flags); -} - -static void -icn_polldchan(unsigned long data) -{ - icn_card *card = (icn_card *)data; - int mch = card->secondhalf ? 2 : 0; - int avail = 0; - int left; - u_char c; - int ch; - unsigned long flags; - int i; - u_char *p; - isdn_ctrl cmd; - - if (icn_trymaplock_channel(card, mch)) { - avail = msg_avail; - for (left = avail, i = readb(&msg_o); left > 0; i++, left--) { - c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]); - icn_putmsg(card, c); - if (c == 0xff) { - card->imsg[card->iptr] = 0; - card->iptr = 0; - if (card->imsg[0] == '0' && card->imsg[1] >= '0' && - card->imsg[1] <= '2' && card->imsg[2] == ';') { - ch = (card->imsg[1] - '0') - 1; - p = &card->imsg[3]; - icn_parse_status(p, ch, card); - } else { - p = card->imsg; - if (!strncmp(p, "DRV1.", 5)) { - u_char vstr[10]; - u_char *q = vstr; - - printk(KERN_INFO "icn: (%s) %s\n", CID, p); - if (!strncmp(p + 7, "TC", 2)) { - card->ptype = ISDN_PTYPE_1TR6; - card->interface.features |= ISDN_FEATURE_P_1TR6; - printk(KERN_INFO - "icn: (%s) 1TR6-Protocol loaded and running\n", CID); - } - if (!strncmp(p + 7, "EC", 2)) { - card->ptype = ISDN_PTYPE_EURO; - card->interface.features |= ISDN_FEATURE_P_EURO; - printk(KERN_INFO - "icn: (%s) Euro-Protocol loaded and running\n", CID); - } - p = strstr(card->imsg, "BRV") + 3; - while (*p) { - if (*p >= '0' && *p <= '9') - *q++ = *p; - p++; - } - *q = '\0'; - strcat(vstr, "000"); - vstr[3] = '\0'; - card->fw_rev = (int)simple_strtoul(vstr, NULL, 10); - continue; - } - } - } else { - card->imsg[card->iptr] = c; - if (card->iptr < 59) - card->iptr++; - } - } - writeb((readb(&msg_o) + avail) & 0xff, &msg_o); - icn_release_channel(); - } - if (avail) { - cmd.command = ISDN_STAT_STAVAIL; - cmd.driver = card->myid; - cmd.arg = avail; - card->interface.statcallb(&cmd); - } - spin_lock_irqsave(&card->lock, flags); - if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) - if (!(card->flags & ICN_FLAGS_RBTIMER)) { - /* schedule b-channel polling */ - card->flags |= ICN_FLAGS_RBTIMER; - del_timer(&card->rb_timer); - card->rb_timer.function = icn_pollbchan; - card->rb_timer.data = (unsigned long)card; - card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD; - add_timer(&card->rb_timer); - } - /* schedule again */ - mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD); - spin_unlock_irqrestore(&card->lock, flags); -} - -/* Append a packet to the transmit buffer-queue. - * Parameters: - * channel = Number of B-channel - * skb = pointer to sk_buff - * card = pointer to card-struct - * Return: - * Number of bytes transferred, -E??? on error - */ - -static int -icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card) -{ - int len = skb->len; - unsigned long flags; - struct sk_buff *nskb; - - if (len > 4000) { - printk(KERN_WARNING - "icn: Send packet too large\n"); - return -EINVAL; - } - if (len) { - if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) - return 0; - if (card->sndcount[channel] > ICN_MAX_SQUEUE) - return 0; - /* TODO test headroom or use skb->nb to flag ACK */ - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - /* Push ACK flag as one - * byte in front of data. - */ - *(skb_push(nskb, 1)) = ack ? 1 : 0; - skb_queue_tail(&card->spqueue[channel], nskb); - dev_kfree_skb(skb); - } else - len = 0; - spin_lock_irqsave(&card->lock, flags); - card->sndcount[channel] += len; - spin_unlock_irqrestore(&card->lock, flags); - } - return len; -} - -/* - * Check card's status after starting the bootstrap loader. - * On entry, the card's shared memory has already to be mapped. - * Return: - * 0 on success (Boot loader ready) - * -EIO on failure (timeout) - */ -static int -icn_check_loader(int cardnumber) -{ - int timer = 0; - - while (1) { -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Loader %d ?\n", cardnumber); -#endif - if (readb(&dev.shmem->data_control.scns) || - readb(&dev.shmem->data_control.scnr)) { - if (timer++ > 5) { - printk(KERN_WARNING - "icn: Boot-Loader %d timed out.\n", - cardnumber); - icn_release_channel(); - return -EIO; - } -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Loader %d TO?\n", cardnumber); -#endif - msleep_interruptible(ICN_BOOT_TIMEOUT1); - } else { -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Loader %d OK\n", cardnumber); -#endif - icn_release_channel(); - return 0; - } - } -} - -/* Load the boot-code into the interface-card's memory and start it. - * Always called from user-process. - * - * Parameters: - * buffer = pointer to packet - * Return: - * 0 if successfully loaded - */ - -#ifdef BOOT_DEBUG -#define SLEEP(sec) { \ - int slsec = sec; \ - printk(KERN_DEBUG "SLEEP(%d)\n", slsec); \ - while (slsec) { \ - msleep_interruptible(1000); \ - slsec--; \ - } \ - } -#else -#define SLEEP(sec) -#endif - -static int -icn_loadboot(u_char __user *buffer, icn_card *card) -{ - int ret; - u_char *codebuf; - unsigned long flags; - -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong)buffer); -#endif - codebuf = memdup_user(buffer, ICN_CODE_STAGE1); - if (IS_ERR(codebuf)) - return PTR_ERR(codebuf); - - if (!card->rvalid) { - if (!request_region(card->port, ICN_PORTLEN, card->regname)) { - printk(KERN_WARNING - "icn: (%s) ports 0x%03x-0x%03x in use.\n", - CID, - card->port, - card->port + ICN_PORTLEN); - ret = -EBUSY; - goto out_kfree; - } - card->rvalid = 1; - if (card->doubleS0) - card->other->rvalid = 1; - } - if (!dev.mvalid) { - if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) { - printk(KERN_WARNING - "icn: memory at 0x%08lx in use.\n", dev.memaddr); - ret = -EBUSY; - goto out_kfree; - } - dev.shmem = ioremap(dev.memaddr, 0x4000); - dev.mvalid = 1; - } - OUTB_P(0, ICN_RUN); /* Reset Controller */ - OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ - icn_shiftout(ICN_CFG, 0x0f, 3, 4); /* Windowsize= 16k */ - icn_shiftout(ICN_CFG, dev.memaddr, 23, 10); /* Set RAM-Addr. */ -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr); -#endif - SLEEP(1); -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Map Bank 0\n"); -#endif - spin_lock_irqsave(&dev.devlock, flags); - icn_map_channel(card, 0); /* Select Bank 0 */ - icn_lock_channel(card, 0); /* Lock Bank 0 */ - spin_unlock_irqrestore(&dev.devlock, flags); - SLEEP(1); - memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Bootloader transferred\n"); -#endif - if (card->doubleS0) { - SLEEP(1); -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Map Bank 8\n"); -#endif - spin_lock_irqsave(&dev.devlock, flags); - __icn_release_channel(); - icn_map_channel(card, 2); /* Select Bank 8 */ - icn_lock_channel(card, 2); /* Lock Bank 8 */ - spin_unlock_irqrestore(&dev.devlock, flags); - SLEEP(1); - memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Bootloader transferred\n"); -#endif - } - SLEEP(1); - OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */ - ret = icn_check_loader(card->doubleS0 ? 2 : 1); - if (ret) - goto out_kfree; - if (!card->doubleS0) { - ret = 0; - goto out_kfree; - } - /* reached only, if we have a Double-S0-Card */ -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Map Bank 0\n"); -#endif - spin_lock_irqsave(&dev.devlock, flags); - icn_map_channel(card, 0); /* Select Bank 0 */ - icn_lock_channel(card, 0); /* Lock Bank 0 */ - spin_unlock_irqrestore(&dev.devlock, flags); - SLEEP(1); - ret = (icn_check_loader(1)); - -out_kfree: - kfree(codebuf); - return ret; -} - -static int -icn_loadproto(u_char __user *buffer, icn_card *card) -{ - register u_char __user *p = buffer; - u_char codebuf[256]; - uint left = ICN_CODE_STAGE2; - uint cnt; - int timer; - unsigned long flags; - -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "icn_loadproto called\n"); -#endif - if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2)) - return -EFAULT; - timer = 0; - spin_lock_irqsave(&dev.devlock, flags); - if (card->secondhalf) { - icn_map_channel(card, 2); - icn_lock_channel(card, 2); - } else { - icn_map_channel(card, 0); - icn_lock_channel(card, 0); - } - spin_unlock_irqrestore(&dev.devlock, flags); - while (left) { - if (sbfree) { /* If there is a free buffer... */ - cnt = left; - if (cnt > 256) - cnt = 256; - if (copy_from_user(codebuf, p, cnt)) { - icn_maprelease_channel(card, 0); - return -EFAULT; - } - memcpy_toio(&sbuf_l, codebuf, cnt); /* copy data */ - sbnext; /* switch to next buffer */ - p += cnt; - left -= cnt; - timer = 0; - } else { -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "boot 2 !sbfree\n"); -#endif - if (timer++ > 5) { - icn_maprelease_channel(card, 0); - return -EIO; - } - schedule_timeout_interruptible(10); - } - } - writeb(0x20, &sbuf_n); - timer = 0; - while (1) { - if (readb(&cmd_o) || readb(&cmd_i)) { -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Proto?\n"); -#endif - if (timer++ > 5) { - printk(KERN_WARNING - "icn: (%s) Protocol timed out.\n", - CID); -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Proto TO!\n"); -#endif - icn_maprelease_channel(card, 0); - return -EIO; - } -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Proto TO?\n"); -#endif - msleep_interruptible(ICN_BOOT_TIMEOUT1); - } else { - if ((card->secondhalf) || (!card->doubleS0)) { -#ifdef BOOT_DEBUG - printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n", - card->secondhalf); -#endif - spin_lock_irqsave(&card->lock, flags); - setup_timer(&card->st_timer, icn_polldchan, - (unsigned long)card); - mod_timer(&card->st_timer, - jiffies + ICN_TIMER_DCREAD); - card->flags |= ICN_FLAGS_RUNNING; - if (card->doubleS0) { - setup_timer(&card->other->st_timer, - icn_polldchan, - (unsigned long)card->other); - mod_timer(&card->other->st_timer, - jiffies + ICN_TIMER_DCREAD); - card->other->flags |= ICN_FLAGS_RUNNING; - } - spin_unlock_irqrestore(&card->lock, flags); - } - icn_maprelease_channel(card, 0); - return 0; - } - } -} - -/* Read the Status-replies from the Interface */ -static int -icn_readstatus(u_char __user *buf, int len, icn_card *card) -{ - int count; - u_char __user *p; - - for (p = buf, count = 0; count < len; p++, count++) { - if (card->msg_buf_read == card->msg_buf_write) - return count; - if (put_user(*card->msg_buf_read++, p)) - return -EFAULT; - if (card->msg_buf_read > card->msg_buf_end) - card->msg_buf_read = card->msg_buf; - } - return count; -} - -/* Put command-strings into the command-queue of the Interface */ -static int -icn_writecmd(const u_char __user *ubuf, const u_char *kbuf, int len, - int user, icn_card *card) -{ - int mch = card->secondhalf ? 2 : 0; - int pp; - int i; - int count; - int xcount; - int ocount; - int loop; - unsigned long flags; - int lastmap_channel; - struct icn_card *lastmap_card; - u_char *p; - isdn_ctrl cmd; - u_char msg[0x100]; - - ocount = 1; - xcount = loop = 0; - while (len) { - count = cmd_free; - if (count > len) - count = len; - if (user) { - if (copy_from_user(msg, ubuf, count)) - return -EFAULT; - } else - memcpy(msg, kbuf, count); - - spin_lock_irqsave(&dev.devlock, flags); - lastmap_card = dev.mcard; - lastmap_channel = dev.channel; - icn_map_channel(card, mch); - - icn_putmsg(card, '>'); - for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp - ++) { - writeb((*p == '\n') ? 0xff : *p, - &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]); - len--; - xcount++; - icn_putmsg(card, *p); - if ((*p == '\n') && (i > 1)) { - icn_putmsg(card, '>'); - ocount++; - } - ocount++; - } - writeb((readb(&cmd_i) + count) & 0xff, &cmd_i); - if (lastmap_card) - icn_map_channel(lastmap_card, lastmap_channel); - spin_unlock_irqrestore(&dev.devlock, flags); - if (len) { - mdelay(1); - if (loop++ > 20) - break; - } else - break; - } - if (len && (!user)) - printk(KERN_WARNING "icn: writemsg incomplete!\n"); - cmd.command = ISDN_STAT_STAVAIL; - cmd.driver = card->myid; - cmd.arg = ocount; - card->interface.statcallb(&cmd); - return xcount; -} - -/* - * Delete card's pending timers, send STOP to linklevel - */ -static void -icn_stopcard(icn_card *card) -{ - unsigned long flags; - isdn_ctrl cmd; - - spin_lock_irqsave(&card->lock, flags); - if (card->flags & ICN_FLAGS_RUNNING) { - card->flags &= ~ICN_FLAGS_RUNNING; - del_timer(&card->st_timer); - del_timer(&card->rb_timer); - spin_unlock_irqrestore(&card->lock, flags); - cmd.command = ISDN_STAT_STOP; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - if (card->doubleS0) - icn_stopcard(card->other); - } else - spin_unlock_irqrestore(&card->lock, flags); -} - -static void -icn_stopallcards(void) -{ - icn_card *p = cards; - - while (p) { - icn_stopcard(p); - p = p->next; - } -} - -/* - * Unmap all cards, because some of them may be mapped accidetly during - * autoprobing of some network drivers (SMC-driver?) - */ -static void -icn_disable_cards(void) -{ - icn_card *card = cards; - - while (card) { - if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) { - printk(KERN_WARNING - "icn: (%s) ports 0x%03x-0x%03x in use.\n", - CID, - card->port, - card->port + ICN_PORTLEN); - } else { - OUTB_P(0, ICN_RUN); /* Reset Controller */ - OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ - release_region(card->port, ICN_PORTLEN); - } - card = card->next; - } -} - -static int -icn_command(isdn_ctrl *c, icn_card *card) -{ - ulong a; - ulong flags; - int i; - char cbuf[80]; - isdn_ctrl cmd; - icn_cdef cdef; - char __user *arg; - - switch (c->command) { - case ISDN_CMD_IOCTL: - memcpy(&a, c->parm.num, sizeof(ulong)); - arg = (char __user *)a; - switch (c->arg) { - case ICN_IOCTL_SETMMIO: - if (dev.memaddr != (a & 0x0ffc000)) { - if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) { - printk(KERN_WARNING - "icn: memory at 0x%08lx in use.\n", - a & 0x0ffc000); - return -EINVAL; - } - release_mem_region(a & 0x0ffc000, 0x4000); - icn_stopallcards(); - spin_lock_irqsave(&card->lock, flags); - if (dev.mvalid) { - iounmap(dev.shmem); - release_mem_region(dev.memaddr, 0x4000); - } - dev.mvalid = 0; - dev.memaddr = a & 0x0ffc000; - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_INFO - "icn: (%s) mmio set to 0x%08lx\n", - CID, - dev.memaddr); - } - break; - case ICN_IOCTL_GETMMIO: - return (long)dev.memaddr; - case ICN_IOCTL_SETPORT: - if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330 - || a == 0x340 || a == 0x350 || a == 0x360 || - a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338 - || a == 0x348 || a == 0x358 || a == 0x368) { - if (card->port != (unsigned short)a) { - if (!request_region((unsigned short)a, ICN_PORTLEN, "icn-isdn")) { - printk(KERN_WARNING - "icn: (%s) ports 0x%03x-0x%03x in use.\n", - CID, (int)a, (int)a + ICN_PORTLEN); - return -EINVAL; - } - release_region((unsigned short)a, ICN_PORTLEN); - icn_stopcard(card); - spin_lock_irqsave(&card->lock, flags); - if (card->rvalid) - release_region(card->port, ICN_PORTLEN); - card->port = (unsigned short)a; - card->rvalid = 0; - if (card->doubleS0) { - card->other->port = (unsigned short)a; - card->other->rvalid = 0; - } - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_INFO - "icn: (%s) port set to 0x%03x\n", - CID, card->port); - } - } else - return -EINVAL; - break; - case ICN_IOCTL_GETPORT: - return (int)card->port; - case ICN_IOCTL_GETDOUBLE: - return (int)card->doubleS0; - case ICN_IOCTL_DEBUGVAR: - if (copy_to_user(arg, - &card, - sizeof(ulong))) - return -EFAULT; - a += sizeof(ulong); - { - ulong l = (ulong)&dev; - if (copy_to_user(arg, - &l, - sizeof(ulong))) - return -EFAULT; - } - return 0; - case ICN_IOCTL_LOADBOOT: - if (dev.firstload) { - icn_disable_cards(); - dev.firstload = 0; - } - icn_stopcard(card); - return icn_loadboot(arg, card); - case ICN_IOCTL_LOADPROTO: - icn_stopcard(card); - i = (icn_loadproto(arg, card)); - if (i) - return i; - if (card->doubleS0) - i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other); - return i; - break; - case ICN_IOCTL_ADDCARD: - if (!dev.firstload) - return -EBUSY; - if (copy_from_user(&cdef, - arg, - sizeof(cdef))) - return -EFAULT; - return icn_addcard(cdef.port, cdef.id1, cdef.id2); - break; - case ICN_IOCTL_LEASEDCFG: - if (a) { - if (!card->leased) { - card->leased = 1; - while (card->ptype == ISDN_PTYPE_UNKNOWN) - msleep_interruptible(ICN_BOOT_TIMEOUT1); - msleep_interruptible(ICN_BOOT_TIMEOUT1); - sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n", - (a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C'); - i = icn_writecmd(NULL, cbuf, - strlen(cbuf), - 0, card); - printk(KERN_INFO - "icn: (%s) Leased-line mode enabled\n", - CID); - cmd.command = ISDN_STAT_RUN; - cmd.driver = card->myid; - cmd.arg = 0; - card->interface.statcallb(&cmd); - } - } else { - if (card->leased) { - card->leased = 0; - sprintf(cbuf, "00;FV2OFF\n"); - i = icn_writecmd(NULL, cbuf, - strlen(cbuf), - 0, card); - printk(KERN_INFO - "icn: (%s) Leased-line mode disabled\n", - CID); - cmd.command = ISDN_STAT_RUN; - cmd.driver = card->myid; - cmd.arg = 0; - card->interface.statcallb(&cmd); - } - } - return 0; - default: - return -EINVAL; - } - break; - case ISDN_CMD_DIAL: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (card->leased) - break; - if ((c->arg & 255) < ICN_BCH) { - char *p; - char dcode[4]; - - a = c->arg; - p = c->parm.setup.phone; - if (*p == 's' || *p == 'S') { - /* Dial for SPV */ - p++; - strcpy(dcode, "SCA"); - } else - /* Normal Dial */ - strcpy(dcode, "CAL"); - snprintf(cbuf, sizeof(cbuf), - "%02d;D%s_R%s,%02d,%02d,%s\n", (int)(a + 1), - dcode, p, c->parm.setup.si1, - c->parm.setup.si2, c->parm.setup.eazmsn); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_ACCEPTD: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (c->arg < ICN_BCH) { - a = c->arg + 1; - if (card->fw_rev >= 300) { - switch (card->l2_proto[a - 1]) { - case ISDN_PROTO_L2_X75I: - sprintf(cbuf, "%02d;BX75\n", (int)a); - break; - case ISDN_PROTO_L2_HDLC: - sprintf(cbuf, "%02d;BTRA\n", (int)a); - break; - } - i = icn_writecmd(NULL, cbuf, - strlen(cbuf), 0, - card); - } - sprintf(cbuf, "%02d;DCON_R\n", (int)a); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_ACCEPTB: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (c->arg < ICN_BCH) { - a = c->arg + 1; - if (card->fw_rev >= 300) - switch (card->l2_proto[a - 1]) { - case ISDN_PROTO_L2_X75I: - sprintf(cbuf, "%02d;BCON_R,BX75\n", (int)a); - break; - case ISDN_PROTO_L2_HDLC: - sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int)a); - break; - } else - sprintf(cbuf, "%02d;BCON_R\n", (int)a); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_HANGUP: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (c->arg < ICN_BCH) { - a = c->arg + 1; - sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int)a, (int)a); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_SETEAZ: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (card->leased) - break; - if (c->arg < ICN_BCH) { - a = c->arg + 1; - if (card->ptype == ISDN_PTYPE_EURO) { - sprintf(cbuf, "%02d;MS%s%s\n", (int)a, - c->parm.num[0] ? "N" : "ALL", c->parm.num); - } else - sprintf(cbuf, "%02d;EAZ%s\n", (int)a, - c->parm.num[0] ? (char *)(c->parm.num) : "0123456789"); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_CLREAZ: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if (card->leased) - break; - if (c->arg < ICN_BCH) { - a = c->arg + 1; - if (card->ptype == ISDN_PTYPE_EURO) - sprintf(cbuf, "%02d;MSNC\n", (int)a); - else - sprintf(cbuf, "%02d;EAZC\n", (int)a); - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - } - break; - case ISDN_CMD_SETL2: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - if ((c->arg & 255) < ICN_BCH) { - a = c->arg; - switch (a >> 8) { - case ISDN_PROTO_L2_X75I: - sprintf(cbuf, "%02d;BX75\n", (int)(a & 255) + 1); - break; - case ISDN_PROTO_L2_HDLC: - sprintf(cbuf, "%02d;BTRA\n", (int)(a & 255) + 1); - break; - default: - return -EINVAL; - } - i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card); - card->l2_proto[a & 255] = (a >> 8); - } - break; - case ISDN_CMD_SETL3: - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - return 0; - default: - return -EINVAL; - } - return 0; -} - -/* - * Find card with given driverId - */ -static inline icn_card * -icn_findcard(int driverid) -{ - icn_card *p = cards; - - while (p) { - if (p->myid == driverid) - return p; - p = p->next; - } - return (icn_card *)0; -} - -/* - * Wrapper functions for interface to linklevel - */ -static int -if_command(isdn_ctrl *c) -{ - icn_card *card = icn_findcard(c->driver); - - if (card) - return icn_command(c, card); - printk(KERN_ERR - "icn: if_command %d called with invalid driverId %d!\n", - c->command, c->driver); - return -ENODEV; -} - -static int -if_writecmd(const u_char __user *buf, int len, int id, int channel) -{ - icn_card *card = icn_findcard(id); - - if (card) { - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - return icn_writecmd(buf, NULL, len, 1, card); - } - printk(KERN_ERR - "icn: if_writecmd called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_readstatus(u_char __user *buf, int len, int id, int channel) -{ - icn_card *card = icn_findcard(id); - - if (card) { - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - return icn_readstatus(buf, len, card); - } - printk(KERN_ERR - "icn: if_readstatus called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) -{ - icn_card *card = icn_findcard(id); - - if (card) { - if (!(card->flags & ICN_FLAGS_RUNNING)) - return -ENODEV; - return icn_sendbuf(channel, ack, skb, card); - } - printk(KERN_ERR - "icn: if_sendbuf called with invalid driverId!\n"); - return -ENODEV; -} - -/* - * Allocate a new card-struct, initialize it - * link it into cards-list and register it at linklevel. - */ -static icn_card * -icn_initcard(int port, char *id) -{ - icn_card *card; - int i; - - card = kzalloc(sizeof(icn_card), GFP_KERNEL); - if (!card) { - printk(KERN_WARNING - "icn: (%s) Could not allocate card-struct.\n", id); - return (icn_card *)0; - } - spin_lock_init(&card->lock); - card->port = port; - card->interface.owner = THIS_MODULE; - card->interface.hl_hdrlen = 1; - card->interface.channels = ICN_BCH; - card->interface.maxbufsize = 4000; - card->interface.command = if_command; - card->interface.writebuf_skb = if_sendbuf; - card->interface.writecmd = if_writecmd; - card->interface.readstat = if_readstatus; - card->interface.features = ISDN_FEATURE_L2_X75I | - ISDN_FEATURE_L2_HDLC | - ISDN_FEATURE_L3_TRANS | - ISDN_FEATURE_P_UNKNOWN; - card->ptype = ISDN_PTYPE_UNKNOWN; - strlcpy(card->interface.id, id, sizeof(card->interface.id)); - card->msg_buf_write = card->msg_buf; - card->msg_buf_read = card->msg_buf; - card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1]; - for (i = 0; i < ICN_BCH; i++) { - card->l2_proto[i] = ISDN_PROTO_L2_X75I; - skb_queue_head_init(&card->spqueue[i]); - } - card->next = cards; - cards = card; - if (!register_isdn(&card->interface)) { - cards = cards->next; - printk(KERN_WARNING - "icn: Unable to register %s\n", id); - kfree(card); - return (icn_card *)0; - } - card->myid = card->interface.channels; - sprintf(card->regname, "icn-isdn (%s)", card->interface.id); - return card; -} - -static int -icn_addcard(int port, char *id1, char *id2) -{ - icn_card *card; - icn_card *card2; - - card = icn_initcard(port, id1); - if (!card) - return -EIO; - if (!strlen(id2)) { - printk(KERN_INFO - "icn: (%s) ICN-2B, port 0x%x added\n", - card->interface.id, port); - return 0; - } - card2 = icn_initcard(port, id2); - if (!card2) { - printk(KERN_INFO - "icn: (%s) half ICN-4B, port 0x%x added\n", id2, port); - return 0; - } - card->doubleS0 = 1; - card->secondhalf = 0; - card->other = card2; - card2->doubleS0 = 1; - card2->secondhalf = 1; - card2->other = card; - printk(KERN_INFO - "icn: (%s and %s) ICN-4B, port 0x%x added\n", - card->interface.id, card2->interface.id, port); - return 0; -} - -#ifndef MODULE -static int __init -icn_setup(char *line) -{ - char *p, *str; - int ints[3]; - static char sid[20]; - static char sid2[20]; - - str = get_options(line, 2, ints); - if (ints[0]) - portbase = ints[1]; - if (ints[0] > 1) - membase = (unsigned long)ints[2]; - if (str && *str) { - strlcpy(sid, str, sizeof(sid)); - icn_id = sid; - p = strchr(sid, ','); - if (p) { - *p++ = 0; - strcpy(sid2, p); - icn_id2 = sid2; - } - } - return 1; -} -__setup("icn=", icn_setup); -#endif /* MODULE */ - -static int __init icn_init(void) -{ - char *p; - char rev[21]; - - memset(&dev, 0, sizeof(icn_dev)); - dev.memaddr = (membase & 0x0ffc000); - dev.channel = -1; - dev.mcard = NULL; - dev.firstload = 1; - spin_lock_init(&dev.devlock); - - p = strchr(revision, ':'); - if (p) { - strncpy(rev, p + 1, 20); - rev[20] = '\0'; - p = strchr(rev, '$'); - if (p) - *p = 0; - } else - strcpy(rev, " ??? "); - printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev, - dev.memaddr); - return icn_addcard(portbase, icn_id, icn_id2); -} - -static void __exit icn_exit(void) -{ - isdn_ctrl cmd; - icn_card *card = cards; - icn_card *last, *tmpcard; - int i; - unsigned long flags; - - icn_stopallcards(); - while (card) { - cmd.command = ISDN_STAT_UNLOAD; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - spin_lock_irqsave(&card->lock, flags); - if (card->rvalid) { - OUTB_P(0, ICN_RUN); /* Reset Controller */ - OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ - if (card->secondhalf || (!card->doubleS0)) { - release_region(card->port, ICN_PORTLEN); - card->rvalid = 0; - } - for (i = 0; i < ICN_BCH; i++) - icn_free_queue(card, i); - } - tmpcard = card->next; - spin_unlock_irqrestore(&card->lock, flags); - card = tmpcard; - } - card = cards; - cards = NULL; - while (card) { - last = card; - card = card->next; - kfree(last); - } - if (dev.mvalid) { - iounmap(dev.shmem); - release_mem_region(dev.memaddr, 0x4000); - } - printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n"); -} - -module_init(icn_init); -module_exit(icn_exit); diff --git a/drivers/staging/i4l/icn/icn.h b/drivers/staging/i4l/icn/icn.h deleted file mode 100644 index 07e2e0196527..000000000000 --- a/drivers/staging/i4l/icn/icn.h +++ /dev/null @@ -1,252 +0,0 @@ -/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $ - * - * ISDN lowlevel-module for the ICN active ISDN-Card. - * - * Copyright 1994 by Fritz Elfert (fritz@isdn4linux.de) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef icn_h -#define icn_h - -#define ICN_IOCTL_SETMMIO 0 -#define ICN_IOCTL_GETMMIO 1 -#define ICN_IOCTL_SETPORT 2 -#define ICN_IOCTL_GETPORT 3 -#define ICN_IOCTL_LOADBOOT 4 -#define ICN_IOCTL_LOADPROTO 5 -#define ICN_IOCTL_LEASEDCFG 6 -#define ICN_IOCTL_GETDOUBLE 7 -#define ICN_IOCTL_DEBUGVAR 8 -#define ICN_IOCTL_ADDCARD 9 - -/* Struct for adding new cards */ -typedef struct icn_cdef { - int port; - char id1[10]; - char id2[10]; -} icn_cdef; - -#if defined(__KERNEL__) || defined(__DEBUGVAR__) - -#ifdef __KERNEL__ -/* Kernel includes */ - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/ioport.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/isdnif.h> - -#endif /* __KERNEL__ */ - -/* some useful macros for debugging */ -#ifdef ICN_DEBUG_PORT -#define OUTB_P(v, p) {pr_debug("icn: outb_p(0x%02x,0x%03x)\n", v, p); outb_p(v, p);} -#else -#define OUTB_P outb -#endif - -/* Defaults for Port-Address and shared-memory */ -#define ICN_BASEADDR 0x320 -#define ICN_PORTLEN (0x04) -#define ICN_MEMADDR 0x0d0000 - -#define ICN_FLAGS_B1ACTIVE 1 /* B-Channel-1 is open */ -#define ICN_FLAGS_B2ACTIVE 2 /* B-Channel-2 is open */ -#define ICN_FLAGS_RUNNING 4 /* Cards driver activated */ -#define ICN_FLAGS_RBTIMER 8 /* cyclic scheduling of B-Channel-poll */ - -#define ICN_BOOT_TIMEOUT1 1000 /* Delay for Boot-download (msecs) */ - -#define ICN_TIMER_BCREAD (HZ / 100) /* B-Channel poll-cycle */ -#define ICN_TIMER_DCREAD (HZ / 2) /* D-Channel poll-cycle */ - -#define ICN_CODE_STAGE1 4096 /* Size of bootcode */ -#define ICN_CODE_STAGE2 65536 /* Size of protocol-code */ - -#define ICN_MAX_SQUEUE 8000 /* Max. outstanding send-data (2* hw-buf.) */ -#define ICN_FRAGSIZE (250) /* Max. size of send-fragments */ -#define ICN_BCH 2 /* Number of supported channels per card */ - -/* type-definitions for accessing the mmap-io-areas */ - -#define SHM_DCTL_OFFSET (0) /* Offset to data-controlstructures in shm */ -#define SHM_CCTL_OFFSET (0x1d2) /* Offset to comm-controlstructures in shm */ -#define SHM_CBUF_OFFSET (0x200) /* Offset to comm-buffers in shm */ -#define SHM_DBUF_OFFSET (0x2000) /* Offset to data-buffers in shm */ - -/* - * Layout of card's data buffers - */ -typedef struct { - unsigned char length; /* Bytecount of fragment (max 250) */ - unsigned char endflag; /* 0=last frag., 0xff=frag. continued */ - unsigned char data[ICN_FRAGSIZE]; /* The data */ - /* Fill to 256 bytes */ - char unused[0x100 - ICN_FRAGSIZE - 2]; -} frag_buf; - -/* - * Layout of card's shared memory - */ -typedef union { - struct { - unsigned char scns; /* Index to free SendFrag. */ - unsigned char scnr; /* Index to active SendFrag READONLY */ - unsigned char ecns; /* Index to free RcvFrag. READONLY */ - unsigned char ecnr; /* Index to valid RcvFrag */ - char unused[6]; - unsigned short fuell1; /* Internal Buf Bytecount */ - } data_control; - struct { - char unused[SHM_CCTL_OFFSET]; - unsigned char iopc_i; /* Read-Ptr Status-Queue READONLY */ - unsigned char iopc_o; /* Write-Ptr Status-Queue */ - unsigned char pcio_i; /* Write-Ptr Command-Queue */ - unsigned char pcio_o; /* Read-Ptr Command Queue READONLY */ - } comm_control; - struct { - char unused[SHM_CBUF_OFFSET]; - unsigned char pcio_buf[0x100]; /* Ring-Buffer Command-Queue */ - unsigned char iopc_buf[0x100]; /* Ring-Buffer Status-Queue */ - } comm_buffers; - struct { - char unused[SHM_DBUF_OFFSET]; - frag_buf receive_buf[0x10]; - frag_buf send_buf[0x10]; - } data_buffers; -} icn_shmem; - -/* - * Per card driver data - */ -typedef struct icn_card { - struct icn_card *next; /* Pointer to next device struct */ - struct icn_card *other; /* Pointer to other card for ICN4B */ - unsigned short port; /* Base-port-address */ - int myid; /* Driver-Nr. assigned by linklevel */ - int rvalid; /* IO-portregion has been requested */ - int leased; /* Flag: This Adapter is connected */ - /* to a leased line */ - unsigned short flags; /* Statusflags */ - int doubleS0; /* Flag: ICN4B */ - int secondhalf; /* Flag: Second half of a doubleS0 */ - int fw_rev; /* Firmware revision loaded */ - int ptype; /* Protocol type (1TR6 or Euro) */ - struct timer_list st_timer; /* Timer for Status-Polls */ - struct timer_list rb_timer; /* Timer for B-Channel-Polls */ - u_char rcvbuf[ICN_BCH][4096]; /* B-Channel-Receive-Buffers */ - int rcvidx[ICN_BCH]; /* Index for above buffers */ - int l2_proto[ICN_BCH]; /* Current layer-2-protocol */ - isdn_if interface; /* Interface to upper layer */ - int iptr; /* Index to imsg-buffer */ - char imsg[60]; /* Internal buf for status-parsing */ - char msg_buf[2048]; /* Buffer for status-messages */ - char *msg_buf_write; /* Writepointer for statusbuffer */ - char *msg_buf_read; /* Readpointer for statusbuffer */ - char *msg_buf_end; /* Pointer to end of statusbuffer */ - int sndcount[ICN_BCH]; /* Byte-counters for B-Ch.-send */ - int xlen[ICN_BCH]; /* Byte-counters/Flags for sent-ACK */ - struct sk_buff *xskb[ICN_BCH]; /* Current transmitted skb */ - struct sk_buff_head spqueue[ICN_BCH]; /* Sendqueue */ - char regname[35]; /* Name used for request_region */ - u_char xmit_lock[ICN_BCH]; /* Semaphore for pollbchan_send()*/ - spinlock_t lock; /* protect critical operations */ -} icn_card; - -/* - * Main driver data - */ -typedef struct icn_dev { - spinlock_t devlock; /* spinlock to protect this struct */ - unsigned long memaddr; /* Address of memory mapped buffers */ - icn_shmem __iomem *shmem; /* Pointer to memory-mapped-buffers */ - int mvalid; /* IO-shmem has been requested */ - int channel; /* Currently mapped channel */ - struct icn_card *mcard; /* Currently mapped card */ - int chanlock; /* Semaphore for channel-mapping */ - int firstload; /* Flag: firmware never loaded */ -} icn_dev; - -typedef icn_dev *icn_devptr; - -#ifdef __KERNEL__ - -static icn_card *cards = (icn_card *) 0; -static u_char chan2bank[] = {0, 4, 8, 12}; /* for icn_map_channel() */ - -static icn_dev dev; - -#endif /* __KERNEL__ */ - -/* Utility-Macros */ - -/* Macros for accessing ports */ -#define ICN_CFG (card->port) -#define ICN_MAPRAM (card->port + 1) -#define ICN_RUN (card->port + 2) -#define ICN_BANK (card->port + 3) - -/* Return true, if there is a free transmit-buffer */ -#define sbfree (((readb(&dev.shmem->data_control.scns) + 1) & 0xf) != \ - readb(&dev.shmem->data_control.scnr)) - -/* Switch to next transmit-buffer */ -#define sbnext (writeb((readb(&dev.shmem->data_control.scns) + 1) & 0xf, \ - &dev.shmem->data_control.scns)) - -/* Shortcuts for transmit-buffer-access */ -#define sbuf_n dev.shmem->data_control.scns -#define sbuf_d dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].data -#define sbuf_l dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].length -#define sbuf_f dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].endflag - -/* Return true, if there is receive-data is available */ -#define rbavl (readb(&dev.shmem->data_control.ecnr) != \ - readb(&dev.shmem->data_control.ecns)) - -/* Switch to next receive-buffer */ -#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr) + 1) & 0xf, \ - &dev.shmem->data_control.ecnr)) - -/* Shortcuts for receive-buffer-access */ -#define rbuf_n dev.shmem->data_control.ecnr -#define rbuf_d dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].data -#define rbuf_l dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].length -#define rbuf_f dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].endflag - -/* Shortcuts for command-buffer-access */ -#define cmd_o (dev.shmem->comm_control.pcio_o) -#define cmd_i (dev.shmem->comm_control.pcio_i) - -/* Return free space in command-buffer */ -#define cmd_free ((readb(&cmd_i) >= readb(&cmd_o)) ? \ - 0x100 - readb(&cmd_i) + readb(&cmd_o) : \ - readb(&cmd_o) - readb(&cmd_i)) - -/* Shortcuts for message-buffer-access */ -#define msg_o (dev.shmem->comm_control.iopc_o) -#define msg_i (dev.shmem->comm_control.iopc_i) - -/* Return length of Message, if avail. */ -#define msg_avail ((readb(&msg_o) > readb(&msg_i)) ? \ - 0x100 - readb(&msg_o) + readb(&msg_i) : \ - readb(&msg_i) - readb(&msg_o)) - -#define CID (card->interface.id) - -#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */ -#endif /* icn_h */ diff --git a/drivers/staging/i4l/pcbit/Kconfig b/drivers/staging/i4l/pcbit/Kconfig deleted file mode 100644 index e9b2dd85d410..000000000000 --- a/drivers/staging/i4l/pcbit/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config ISDN_DRV_PCBIT - tristate "PCBIT-D support" - depends on ISA && (BROKEN || X86) - help - This enables support for the PCBIT ISDN-card. This card is - manufactured in Portugal by Octal. For running this card, - additional firmware is necessary, which has to be downloaded into - the card using a utility which is distributed separately. See - <file:Documentation/isdn/README> and - <file:Documentation/isdn/README.pcbit> for more information. diff --git a/drivers/staging/i4l/pcbit/Makefile b/drivers/staging/i4l/pcbit/Makefile deleted file mode 100644 index 2d026c3242e8..000000000000 --- a/drivers/staging/i4l/pcbit/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for the pcbit ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit.o - -# Multipart objects. - -pcbit-y := module.o edss1.o drv.o layer2.o capi.o callbacks.o diff --git a/drivers/staging/i4l/pcbit/callbacks.c b/drivers/staging/i4l/pcbit/callbacks.c deleted file mode 100644 index 212ab0b229d4..000000000000 --- a/drivers/staging/i4l/pcbit/callbacks.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Callbacks for the FSM - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -/* - * Fix: 19981230 - Carlos Morgado <chbm@techie.com> - * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN - * NULL pointer dereference in cb_in_1 (originally fixed in 2.0) - */ - -#include <linux/string.h> -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <linux/io.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "layer2.h" -#include "edss1.h" -#include "callbacks.h" -#include "capi.h" - -ushort last_ref_num = 1; - -/* - * send_conn_req - * - */ - -void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *cbdata) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - -#ifdef DEBUG - printk(KERN_DEBUG "Called Party Number: %s\n", - cbdata->data.setup.CalledPN); -#endif - /* - * hdr - kmalloc in capi_conn_req - * - kfree when msg has been sent - */ - - if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb, - chan->proto)) < 0) - { - printk("capi_conn_req failed\n"); - return; - } - - - refnum = last_ref_num++ & 0x7fffU; - - chan->callref = 0; - chan->layer2link = 0; - chan->snum = 0; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len); -} - -/* - * rcv CONNECT - * will go into ACTIVE state - * send CONN_ACTIVE_RESP - * send Select protocol request - */ - -void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_conn_active_resp(chan, &skb)) < 0) - { - printk("capi_conn_active_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len); - - - ictl.command = ISDN_STAT_DCONN; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); - - /* ACTIVE D-channel */ - - /* Select protocol */ - - if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) { - printk("capi_select_proto_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len); -} - - -/* - * Incoming call received - * inform user - */ - -void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *cbdata) -{ - isdn_ctrl ictl; - unsigned short refnum; - struct sk_buff *skb; - int len; - - - ictl.command = ISDN_STAT_ICALL; - ictl.driver = dev->id; - ictl.arg = chan->id; - - /* - * ictl.num >= strlen() + strlen() + 5 - */ - - if (cbdata->data.setup.CallingPN == NULL) { - printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n"); - strcpy(ictl.parm.setup.phone, "0"); - } - else { - strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN); - } - if (cbdata->data.setup.CalledPN == NULL) { - printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n"); - strcpy(ictl.parm.setup.eazmsn, "0"); - } - else { - strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN); - } - ictl.parm.setup.si1 = 7; - ictl.parm.setup.si2 = 0; - ictl.parm.setup.plan = 0; - ictl.parm.setup.screen = 0; - -#ifdef DEBUG - printk(KERN_DEBUG "statstr: %s\n", ictl.num); -#endif - - dev->dev_if->statcallb(&ictl); - - - if ((len = capi_conn_resp(chan, &skb)) < 0) { - printk(KERN_DEBUG "capi_conn_resp failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len); -} - -/* - * user has replied - * open the channel - * send CONNECT message CONNECT_ACTIVE_REQ in CAPI - */ - -void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - unsigned short refnum; - struct sk_buff *skb; - int len; - - if ((len = capi_conn_active_req(chan, &skb)) < 0) { - printk(KERN_DEBUG "capi_conn_active_req failed\n"); - return; - } - - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n"); - pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len); -} - -/* - * CONN_ACK arrived - * start b-proto selection - * - */ - -void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - unsigned short refnum; - struct sk_buff *skb; - int len; - - if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0) - { - printk("capi_select_proto_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len); - -} - - -/* - * Received disconnect ind on active state - * send disconnect resp - * send msg to user - */ -void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - isdn_ctrl ictl; - - if ((len = capi_disc_resp(chan, &skb)) < 0) { - printk("capi_disc_resp failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len); - - ictl.command = ISDN_STAT_BHUP; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} - - -/* - * User HANGUP on active/call proceeding state - * send disc.req - */ -void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0) - { - printk("capi_disc_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len); -} - -/* - * Disc confirm received send BHUP - * Problem: when the HL driver sends the disc req itself - * LL receives BHUP - */ -void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - - ictl.command = ISDN_STAT_BHUP; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} - -void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ -} - -/* - * send activate b-chan protocol - */ -void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_activate_transp_req(chan, &skb)) < 0) - { - printk("capi_conn_activate_transp_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len); -} - -/* - * Inform User that the B-channel is available - */ -void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - - ictl.command = ISDN_STAT_BCONN; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} diff --git a/drivers/staging/i4l/pcbit/callbacks.h b/drivers/staging/i4l/pcbit/callbacks.h deleted file mode 100644 index a036b4a7ffad..000000000000 --- a/drivers/staging/i4l/pcbit/callbacks.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Callbacks prototypes for FSM - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -#ifndef CALLBACKS_H -#define CALLBACKS_H - - -extern void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -#endif diff --git a/drivers/staging/i4l/pcbit/capi.c b/drivers/staging/i4l/pcbit/capi.c deleted file mode 100644 index a6c4e00dc726..000000000000 --- a/drivers/staging/i4l/pcbit/capi.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * CAPI encoder/decoder for - * Portugal Telecom CAPI 2.0 - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - * - * Not compatible with the AVM Gmbh. CAPI 2.0 - * - */ - -/* - * Documentation: - * - "Common ISDN API - Perfil Português - Versão 2.1", - * Telecom Portugal, Fev 1992. - * - "Common ISDN API - Especificação de protocolos para - * acesso aos canais B", Inesc, Jan 1994. - */ - -/* - * TODO: better decoding of Information Elements - * for debug purposes mainly - * encode our number in CallerPN and ConnectedPN - */ - -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/mm.h> - -#include <linux/skbuff.h> - -#include <linux/io.h> -#include <linux/string.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "edss1.h" -#include "capi.h" - - -/* - * Encoding of CAPI messages - * - */ - -int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto) -{ - ushort len; - - /* - * length - * AppInfoMask - 2 - * BC0 - 3 - * BC1 - 1 - * Chan - 2 - * Keypad - 1 - * CPN - 1 - * CPSA - 1 - * CalledPN - 2 + strlen - * CalledPSA - 1 - * rest... - 4 - * ---------------- - * Total 18 + strlen - */ - - len = 18 + strlen(calledPN); - - if (proto == ISDN_PROTO_L2_TRANS) - len++; - - if ((*skb = dev_alloc_skb(len)) == NULL) { - - printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n"); - return -1; - } - - /* InfoElmMask */ - *((ushort *)skb_put(*skb, 2)) = AppInfoMask; - - if (proto == ISDN_PROTO_L2_TRANS) - { - /* Bearer Capability - Mandatory*/ - *(skb_put(*skb, 1)) = 3; /* BC0.Length */ - *(skb_put(*skb, 1)) = 0x80; /* Speech */ - *(skb_put(*skb, 1)) = 0x10; /* Circuit Mode */ - *(skb_put(*skb, 1)) = 0x23; /* A-law */ - } else { - /* Bearer Capability - Mandatory*/ - *(skb_put(*skb, 1)) = 2; /* BC0.Length */ - *(skb_put(*skb, 1)) = 0x88; /* Digital Information */ - *(skb_put(*skb, 1)) = 0x90; /* BC0.Octect4 */ - } - - /* Bearer Capability - Optional*/ - *(skb_put(*skb, 1)) = 0; /* BC1.Length = 0 */ - - *(skb_put(*skb, 1)) = 1; /* ChannelID.Length = 1 */ - *(skb_put(*skb, 1)) = 0x83; /* Basic Interface - Any Channel */ - - *(skb_put(*skb, 1)) = 0; /* Keypad.Length = 0 */ - - - *(skb_put(*skb, 1)) = 0; /* CallingPN.Length = 0 */ - *(skb_put(*skb, 1)) = 0; /* CallingPSA.Length = 0 */ - - /* Called Party Number */ - *(skb_put(*skb, 1)) = strlen(calledPN) + 1; - *(skb_put(*skb, 1)) = 0x81; - memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN)); - - /* '#' */ - - *(skb_put(*skb, 1)) = 0; /* CalledPSA.Length = 0 */ - - /* LLC.Length = 0; */ - /* HLC0.Length = 0; */ - /* HLC1.Length = 0; */ - /* UTUS.Length = 0; */ - memset(skb_put(*skb, 4), 0, 4); - - return len; -} - -int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - - if ((*skb = dev_alloc_skb(5)) == NULL) { - - printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - *(skb_put(*skb, 1)) = 0x01; /* ACCEPT_CALL */ - *(skb_put(*skb, 1)) = 0; - *(skb_put(*skb, 1)) = 0; - - return 5; -} - -int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb) -{ - /* - * 8 bytes - */ - - if ((*skb = dev_alloc_skb(8)) == NULL) { - - printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - -#ifdef DEBUG - printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); -#endif - - *(skb_put(*skb, 1)) = 0; /* BC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* ConnectedPN.Length = 0 */ - *(skb_put(*skb, 1)) = 0; /* PSA.Length */ - *(skb_put(*skb, 1)) = 0; /* LLC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* HLC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */ - - return 8; -} - -int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - /* - * 2 bytes - */ - - if ((*skb = dev_alloc_skb(2)) == NULL) { - - printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - return 2; -} - - -int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, - int outgoing) -{ - - /* - * 18 bytes - */ - - if ((*skb = dev_alloc_skb(18)) == NULL) { - - printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - /* Layer2 protocol */ - - switch (chan->proto) { - case ISDN_PROTO_L2_X75I: - *(skb_put(*skb, 1)) = 0x05; /* LAPB */ - break; - case ISDN_PROTO_L2_HDLC: - *(skb_put(*skb, 1)) = 0x02; - break; - case ISDN_PROTO_L2_TRANS: - /* - * Voice (a-law) - */ - *(skb_put(*skb, 1)) = 0x06; - break; - default: -#ifdef DEBUG - printk(KERN_DEBUG "Transparent\n"); -#endif - *(skb_put(*skb, 1)) = 0x03; - break; - } - - *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42); /* Don't ask */ - *(skb_put(*skb, 1)) = 0x00; - - *((ushort *) skb_put(*skb, 2)) = MRU; - - - *(skb_put(*skb, 1)) = 0x08; /* Modulo */ - *(skb_put(*skb, 1)) = 0x07; /* Max Window */ - - *(skb_put(*skb, 1)) = 0x01; /* No Layer3 Protocol */ - - /* - * 2 - layer3 MTU [10] - * - Modulo [12] - * - Window - * - layer1 proto [14] - * - bitrate - * - sub-channel [16] - * - layer1dataformat [17] - */ - - memset(skb_put(*skb, 8), 0, 8); - - return 18; -} - - -int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb) -{ - - if ((*skb = dev_alloc_skb(7)) == NULL) { - - printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - - *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */ - *(skb_put(*skb, 1)) = 0x00; /* Transmit by default */ - - *((ushort *) skb_put(*skb, 2)) = MRU; - - *(skb_put(*skb, 1)) = 0x01; /* Enables reception*/ - - return 7; -} - -int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort data_len; - - - /* - * callref - 2 - * layer2link - 1 - * wBlockLength - 2 - * data - 4 - * sernum - 1 - */ - - data_len = skb->len; - - if (skb_headroom(skb) < 10) - { - printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb); - } - else - { - skb_push(skb, 10); - } - - *((u16 *) (skb->data)) = chan->callref; - skb->data[2] = chan->layer2link; - *((u16 *) (skb->data + 3)) = data_len; - - chan->s_refnum = (chan->s_refnum + 1) % 8; - *((u32 *) (skb->data + 5)) = chan->s_refnum; - - skb->data[9] = 0; /* HDLC frame number */ - - return 10; -} - -int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb) - -{ - if ((*skb = dev_alloc_skb(4)) == NULL) { - - printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - *(skb_put(*skb, 1)) = chan->layer2link; - *(skb_put(*skb, 1)) = chan->r_refnum; - - return (*skb)->len; -} - -int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause) -{ - - if ((*skb = dev_alloc_skb(6)) == NULL) { - - printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = callref; - - *(skb_put(*skb, 1)) = 2; /* Cause.Length = 2; */ - *(skb_put(*skb, 1)) = 0x80; - *(skb_put(*skb, 1)) = 0x80 | cause; - - /* - * Change it: we should send 'Sic transit gloria Mundi' here ;-) - */ - - *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */ - - return 6; -} - -int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - if ((*skb = dev_alloc_skb(2)) == NULL) { - - printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - return 2; -} - - -/* - * Decoding of CAPI messages - * - */ - -int capi_decode_conn_ind(struct pcbit_chan *chan, - struct sk_buff *skb, - struct callb_data *info) -{ - int CIlen, len; - - /* Call Reference [CAPI] */ - chan->callref = *((ushort *)skb->data); - skb_pull(skb, 2); - -#ifdef DEBUG - printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); -#endif - - /* Channel Identification */ - - /* Expect - Len = 1 - Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ] - */ - - CIlen = skb->data[0]; -#ifdef DEBUG - if (CIlen == 1) { - - if (((skb->data[1]) & 0xFC) == 0x48) - printk(KERN_DEBUG "decode_conn_ind: chan ok\n"); - printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03); - } - else - printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen); -#endif - skb_pull(skb, CIlen + 1); - - /* Calling Party Number */ - /* An "additional service" as far as Portugal Telecom is concerned */ - - len = skb->data[0]; - - if (len > 0) { - int count = 1; - -#ifdef DEBUG - printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]); -#endif - if ((skb->data[1] & 0x80) == 0) - count = 2; - - if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC))) - return -1; - - skb_copy_from_linear_data_offset(skb, count + 1, - info->data.setup.CallingPN, - len - count); - info->data.setup.CallingPN[len - count] = 0; - - } - else { - info->data.setup.CallingPN = NULL; - printk(KERN_DEBUG "NULL CallingPN\n"); - } - - skb_pull(skb, len + 1); - - /* Calling Party Subaddress */ - skb_pull(skb, skb->data[0] + 1); - - /* Called Party Number */ - - len = skb->data[0]; - - if (len > 0) { - int count = 1; - - if ((skb->data[1] & 0x80) == 0) - count = 2; - - if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC))) - return -1; - - skb_copy_from_linear_data_offset(skb, count + 1, - info->data.setup.CalledPN, - len - count); - info->data.setup.CalledPN[len - count] = 0; - - } - else { - info->data.setup.CalledPN = NULL; - printk(KERN_DEBUG "NULL CalledPN\n"); - } - - skb_pull(skb, len + 1); - - /* Called Party Subaddress */ - skb_pull(skb, skb->data[0] + 1); - - /* LLC */ - skb_pull(skb, skb->data[0] + 1); - - /* HLC */ - skb_pull(skb, skb->data[0] + 1); - - /* U2U */ - skb_pull(skb, skb->data[0] + 1); - - return 0; -} - -/* - * returns errcode - */ - -int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb, - int *complete) -{ - int errcode; - - chan->callref = *((ushort *)skb->data); /* Update CallReference */ - skb_pull(skb, 2); - - errcode = *((ushort *) skb->data); /* read errcode */ - skb_pull(skb, 2); - - *complete = *(skb->data); - skb_pull(skb, 1); - - /* FIX ME */ - /* This is actually a firmware bug */ - if (!*complete) - { - printk(KERN_DEBUG "complete=%02x\n", *complete); - *complete = 1; - } - - - /* Optional Bearer Capability */ - skb_pull(skb, *(skb->data) + 1); - - /* Channel Identification */ - skb_pull(skb, *(skb->data) + 1); - - /* High Layer Compatibility follows */ - skb_pull(skb, *(skb->data) + 1); - - return errcode; -} - -int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort len; -#ifdef DEBUG - char str[32]; -#endif - - /* Yet Another Bearer Capability */ - skb_pull(skb, *(skb->data) + 1); - - - /* Connected Party Number */ - len = *(skb->data); - -#ifdef DEBUG - if (len > 1 && len < 31) { - skb_copy_from_linear_data_offset(skb, 2, str, len - 1); - str[len] = 0; - printk(KERN_DEBUG "Connected Party Number: %s\n", str); - } - else - printk(KERN_DEBUG "actv_ind CPN len = %d\n", len); -#endif - - skb_pull(skb, len + 1); - - /* Connected Subaddress */ - skb_pull(skb, *(skb->data) + 1); - - /* Low Layer Capability */ - skb_pull(skb, *(skb->data) + 1); - - /* High Layer Capability */ - skb_pull(skb, *(skb->data) + 1); - - return 0; -} - -int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - /* Channel Identification - skb_pull(skb, skb->data[0] + 1); - */ - return errcode; -} - - -int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - chan->layer2link = *(skb->data); - skb_pull(skb, 1); - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - return errcode; -} - -int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - if (chan->layer2link != *(skb->data)) - printk("capi_decode_actv_trans_conf: layer2link doesn't match\n"); - - skb_pull(skb, 1); - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - return errcode; -} - -int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort len; -#ifdef DEBUG - int i; -#endif - /* Cause */ - - len = *(skb->data); - skb_pull(skb, 1); - -#ifdef DEBUG - - for (i = 0; i < len; i++) - printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3, - *(skb->data + i)); -#endif - - skb_pull(skb, len); - - return 0; -} - -#ifdef DEBUG -int capi_decode_debug_188(u_char *hdr, ushort hdrlen) -{ - char str[64]; - int len; - - len = hdr[0]; - - if (len < 64 && len == hdrlen - 1) { - memcpy(str, hdr + 1, hdrlen - 1); - str[hdrlen - 1] = 0; - printk("%s\n", str); - } - else - printk("debug message incorrect\n"); - - return 0; -} -#endif diff --git a/drivers/staging/i4l/pcbit/capi.h b/drivers/staging/i4l/pcbit/capi.h deleted file mode 100644 index 6f6f4dd0714e..000000000000 --- a/drivers/staging/i4l/pcbit/capi.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * CAPI encode/decode prototypes and defines - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -#ifndef CAPI_H -#define CAPI_H - - -#define REQ_CAUSE 0x01 -#define REQ_DISPLAY 0x04 -#define REQ_USER_TO_USER 0x08 - -#define AppInfoMask (REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER) - -/* Connection Setup */ -extern int capi_conn_req(const char *calledPN, struct sk_buff **buf, - int proto); -extern int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb, - int *complete); - -extern int capi_decode_conn_ind(struct pcbit_chan *chan, struct sk_buff *skb, - struct callb_data *info); -extern int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -extern int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb); -extern int capi_decode_conn_actv_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_decode_conn_actv_ind(struct pcbit_chan *chan, - struct sk_buff *skb); -extern int capi_conn_active_resp(struct pcbit_chan *chan, - struct sk_buff **skb); - -/* Data */ -extern int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, - int outgoing); -extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_activate_transp_req(struct pcbit_chan *chan, - struct sk_buff **skb); -extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb); -extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -/* Connection Termination */ -extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause); - -extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb); -extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -#ifdef DEBUG -extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen); -#endif - -static inline struct pcbit_chan * -capi_channel(struct pcbit_dev *dev, struct sk_buff *skb) -{ - ushort callref; - - callref = *((ushort *)skb->data); - skb_pull(skb, 2); - - if (dev->b1->callref == callref) - return dev->b1; - else if (dev->b2->callref == callref) - return dev->b2; - - return NULL; -} - -#endif diff --git a/drivers/staging/i4l/pcbit/drv.c b/drivers/staging/i4l/pcbit/drv.c deleted file mode 100644 index 89b0b5b94ce5..000000000000 --- a/drivers/staging/i4l/pcbit/drv.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * PCBIT-D interface with isdn4linux - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -/* - * Fixes: - * - * Nuno Grilo <l38486@alfa.ist.utl.pt> - * fixed msn_list NULL pointer dereference. - * - */ - -#include <linux/module.h> - - -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/skbuff.h> - -#include <linux/isdnif.h> -#include <linux/string.h> -#include <linux/io.h> -#include <linux/ioport.h> - -#include "pcbit.h" -#include "edss1.h" -#include "layer2.h" -#include "capi.h" - - -extern ushort last_ref_num; - -static int pcbit_ioctl(isdn_ctrl *ctl); - -static char *pcbit_devname[MAX_PCBIT_CARDS] = { - "pcbit0", - "pcbit1", - "pcbit2", - "pcbit3" -}; - -/* - * prototypes - */ - -static int pcbit_command(isdn_ctrl *ctl); -static int pcbit_stat(u_char __user *buf, int len, int, int); -static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb); -static int pcbit_writecmd(const u_char __user *, int, int, int); - -static int set_protocol_running(struct pcbit_dev *dev); - -static void pcbit_clear_msn(struct pcbit_dev *dev); -static void pcbit_set_msn(struct pcbit_dev *dev, char *list); -static int pcbit_check_msn(struct pcbit_dev *dev, char *msn); - - -int pcbit_init_dev(int board, int mem_base, int irq) -{ - struct pcbit_dev *dev; - isdn_if *dev_if; - - if ((dev = kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL) - { - printk("pcbit_init: couldn't malloc pcbit_dev struct\n"); - return -ENOMEM; - } - - dev_pcbit[board] = dev; - init_waitqueue_head(&dev->set_running_wq); - spin_lock_init(&dev->lock); - - if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF) { - dev->ph_mem = mem_base; - if (!request_mem_region(dev->ph_mem, 4096, "PCBIT mem")) { - printk(KERN_WARNING - "PCBIT: memory region %lx-%lx already in use\n", - dev->ph_mem, dev->ph_mem + 4096); - kfree(dev); - dev_pcbit[board] = NULL; - return -EACCES; - } - dev->sh_mem = ioremap(dev->ph_mem, 4096); - } - else - { - printk("memory address invalid"); - kfree(dev); - dev_pcbit[board] = NULL; - return -EACCES; - } - - dev->b1 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL); - if (!dev->b1) { - printk("pcbit_init: couldn't malloc pcbit_chan struct\n"); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - return -ENOMEM; - } - - dev->b2 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL); - if (!dev->b2) { - printk("pcbit_init: couldn't malloc pcbit_chan struct\n"); - kfree(dev->b1); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - return -ENOMEM; - } - - dev->b2->id = 1; - - INIT_WORK(&dev->qdelivery, pcbit_deliver); - - /* - * interrupts - */ - - if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0) - { - kfree(dev->b1); - kfree(dev->b2); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - dev_pcbit[board] = NULL; - return -EIO; - } - - dev->irq = irq; - - /* next frame to be received */ - dev->rcv_seq = 0; - dev->send_seq = 0; - dev->unack_seq = 0; - - dev->hl_hdrlen = 16; - - dev_if = kmalloc(sizeof(isdn_if), GFP_KERNEL); - - if (!dev_if) { - free_irq(irq, dev); - kfree(dev->b1); - kfree(dev->b2); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - dev_pcbit[board] = NULL; - return -EIO; - } - - dev->dev_if = dev_if; - - dev_if->owner = THIS_MODULE; - - dev_if->channels = 2; - - dev_if->features = (ISDN_FEATURE_P_EURO | ISDN_FEATURE_L3_TRANS | - ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS); - - dev_if->writebuf_skb = pcbit_xmit; - dev_if->hl_hdrlen = 16; - - dev_if->maxbufsize = MAXBUFSIZE; - dev_if->command = pcbit_command; - - dev_if->writecmd = pcbit_writecmd; - dev_if->readstat = pcbit_stat; - - - strcpy(dev_if->id, pcbit_devname[board]); - - if (!register_isdn(dev_if)) { - free_irq(irq, dev); - kfree(dev->b1); - kfree(dev->b2); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - dev_pcbit[board] = NULL; - return -EIO; - } - - dev->id = dev_if->channels; - - - dev->l2_state = L2_DOWN; - dev->free = 511; - - /* - * set_protocol_running(dev); - */ - - return 0; -} - -#ifdef MODULE -void pcbit_terminate(int board) -{ - struct pcbit_dev *dev; - - dev = dev_pcbit[board]; - - if (dev) { - /* unregister_isdn(dev->dev_if); */ - free_irq(dev->irq, dev); - pcbit_clear_msn(dev); - kfree(dev->dev_if); - if (dev->b1->fsm_timer.function) - del_timer(&dev->b1->fsm_timer); - if (dev->b2->fsm_timer.function) - del_timer(&dev->b2->fsm_timer); - kfree(dev->b1); - kfree(dev->b2); - iounmap(dev->sh_mem); - release_mem_region(dev->ph_mem, 4096); - kfree(dev); - } -} -#endif - -static int pcbit_command(isdn_ctrl *ctl) -{ - struct pcbit_dev *dev; - struct pcbit_chan *chan; - struct callb_data info; - - dev = finddev(ctl->driver); - - if (!dev) - { - printk("pcbit_command: unknown device\n"); - return -1; - } - - chan = (ctl->arg & 0x0F) ? dev->b2 : dev->b1; - - - switch (ctl->command) { - case ISDN_CMD_IOCTL: - return pcbit_ioctl(ctl); - break; - case ISDN_CMD_DIAL: - info.type = EV_USR_SETUP_REQ; - info.data.setup.CalledPN = (char *) &ctl->parm.setup.phone; - pcbit_fsm_event(dev, chan, EV_USR_SETUP_REQ, &info); - break; - case ISDN_CMD_ACCEPTD: - pcbit_fsm_event(dev, chan, EV_USR_SETUP_RESP, NULL); - break; - case ISDN_CMD_ACCEPTB: - printk("ISDN_CMD_ACCEPTB - not really needed\n"); - break; - case ISDN_CMD_HANGUP: - pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL); - break; - case ISDN_CMD_SETL2: - chan->proto = (ctl->arg >> 8); - break; - case ISDN_CMD_CLREAZ: - pcbit_clear_msn(dev); - break; - case ISDN_CMD_SETEAZ: - pcbit_set_msn(dev, ctl->parm.num); - break; - case ISDN_CMD_SETL3: - if ((ctl->arg >> 8) != ISDN_PROTO_L3_TRANS) - printk(KERN_DEBUG "L3 protocol unknown\n"); - break; - default: - printk(KERN_DEBUG "pcbit_command: unknown command\n"); - break; - } - - return 0; -} - -/* - * Another Hack :-( - * on some conditions the board stops sending TDATA_CONFs - * let's see if we can turn around the problem - */ - -#ifdef BLOCK_TIMER -static void pcbit_block_timer(unsigned long data) -{ - struct pcbit_chan *chan; - struct pcbit_dev *dev; - isdn_ctrl ictl; - - chan = (struct pcbit_chan *)data; - - dev = chan2dev(chan); - - if (dev == NULL) { - printk(KERN_DEBUG "pcbit: chan2dev failed\n"); - return; - } - - del_timer(&chan->block_timer); - chan->block_timer.function = NULL; - -#ifdef DEBUG - printk(KERN_DEBUG "pcbit_block_timer\n"); -#endif - chan->queued = 0; - ictl.driver = dev->id; - ictl.command = ISDN_STAT_BSENT; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} -#endif - -static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb) -{ - ushort hdrlen; - int refnum, len; - struct pcbit_chan *chan; - struct pcbit_dev *dev; - - dev = finddev(driver); - if (dev == NULL) - { - printk("finddev returned NULL"); - return -1; - } - - chan = chnum ? dev->b2 : dev->b1; - - - if (chan->fsm_state != ST_ACTIVE) - return -1; - - if (chan->queued >= MAX_QUEUED) - { -#ifdef DEBUG_QUEUE - printk(KERN_DEBUG - "pcbit: %d packets already in queue - write fails\n", - chan->queued); -#endif - /* - * packet stays on the head of the device queue - * since dev_start_xmit will fail - * see net/core/dev.c - */ -#ifdef BLOCK_TIMER - if (chan->block_timer.function == NULL) { - setup_timer(&chan->block_timer, &pcbit_block_timer, - (long)chan); - mod_timer(&chan->block_timer, jiffies + 1 * HZ); - } -#endif - return 0; - } - - - chan->queued++; - - len = skb->len; - - hdrlen = capi_tdata_req(chan, skb); - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_TDATA_REQ, refnum, skb, hdrlen); - - return len; -} - -static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel) -{ - struct pcbit_dev *dev; - int i, j; - const u_char *loadbuf; - u_char *ptr = NULL; - u_char *cbuf; - - int errstat; - - dev = finddev(driver); - - if (!dev) - { - printk("pcbit_writecmd: couldn't find device"); - return -ENODEV; - } - - switch (dev->l2_state) { - case L2_LWMODE: - /* check (size <= rdp_size); write buf into board */ - if (len < 0 || len > BANK4 + 1 || len > 1024) - { - printk("pcbit_writecmd: invalid length %d\n", len); - return -EINVAL; - } - - cbuf = memdup_user(buf, len); - if (IS_ERR(cbuf)) - return PTR_ERR(cbuf); - - memcpy_toio(dev->sh_mem, cbuf, len); - kfree(cbuf); - return len; - case L2_FWMODE: - /* this is the hard part */ - /* dumb board */ - /* get it into kernel space */ - if ((ptr = kmalloc(len, GFP_KERNEL)) == NULL) - return -ENOMEM; - if (copy_from_user(ptr, buf, len)) { - kfree(ptr); - return -EFAULT; - } - loadbuf = ptr; - - errstat = 0; - - for (i = 0; i < len; i++) - { - for (j = 0; j < LOAD_RETRY; j++) - if (!(readb(dev->sh_mem + dev->loadptr))) - break; - - if (j == LOAD_RETRY) - { - errstat = -ETIME; - printk("TIMEOUT i=%d\n", i); - break; - } - writeb(loadbuf[i], dev->sh_mem + dev->loadptr + 1); - writeb(0x01, dev->sh_mem + dev->loadptr); - - dev->loadptr += 2; - if (dev->loadptr > LOAD_ZONE_END) - dev->loadptr = LOAD_ZONE_START; - } - kfree(ptr); - - return errstat ? errstat : len; - default: - return -EBUSY; - } -} - -/* - * demultiplexing of messages - * - */ - -void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, - struct sk_buff *skb, - ushort hdr_len, ushort refnum) -{ - struct pcbit_chan *chan; - struct sk_buff *skb2; - unsigned short len; - struct callb_data cbdata; - int complete, err; - isdn_ctrl ictl; - - switch (msg) { - - case MSG_TDATA_IND: - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - chan->r_refnum = skb->data[7]; - skb_pull(skb, 8); - - dev->dev_if->rcvcallb_skb(dev->id, chan->id, skb); - - if (capi_tdata_resp(chan, &skb2) > 0) - pcbit_l2_write(dev, MSG_TDATA_RESP, refnum, - skb2, skb2->len); - return; - break; - case MSG_TDATA_CONF: - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - -#ifdef DEBUG - if ((*((ushort *)(skb->data + 2))) != 0) { - printk(KERN_DEBUG "TDATA_CONF error\n"); - } -#endif -#ifdef BLOCK_TIMER - if (chan->queued == MAX_QUEUED) { - del_timer(&chan->block_timer); - chan->block_timer.function = NULL; - } - -#endif - chan->queued--; - - ictl.driver = dev->id; - ictl.command = ISDN_STAT_BSENT; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); - break; - - case MSG_CONN_IND: - /* - * channel: 1st not used will do - * if both are used we're in trouble - */ - - if (!dev->b1->fsm_state) - chan = dev->b1; - else if (!dev->b2->fsm_state) - chan = dev->b2; - else { - printk(KERN_INFO - "Incoming connection: no channels available"); - - if ((len = capi_disc_req(*(ushort *)(skb->data), &skb2, CAUSE_NOCHAN)) > 0) - pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len); - break; - } - - cbdata.data.setup.CalledPN = NULL; - cbdata.data.setup.CallingPN = NULL; - - capi_decode_conn_ind(chan, skb, &cbdata); - cbdata.type = EV_NET_SETUP; - - pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL); - - if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN)) - pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata); - else - pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL); - - kfree(cbdata.data.setup.CalledPN); - kfree(cbdata.data.setup.CallingPN); - break; - - case MSG_CONN_CONF: - /* - * We should be able to find the channel by the message - * reference number. The current version of the firmware - * doesn't sent the ref number correctly. - */ -#ifdef DEBUG - printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum, - dev->b1->s_refnum, - dev->b2->s_refnum); -#endif - /* We just try to find a channel in the right state */ - - if (dev->b1->fsm_state == ST_CALL_INIT) - chan = dev->b1; - else { - if (dev->b2->s_refnum == ST_CALL_INIT) - chan = dev->b2; - else { - chan = NULL; - printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n"); - break; - } - } - if (capi_decode_conn_conf(chan, skb, &complete)) { - printk(KERN_DEBUG "conn_conf indicates error\n"); - pcbit_fsm_event(dev, chan, EV_ERROR, NULL); - } - else - if (complete) - pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL); - else - pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL); - break; - case MSG_CONN_ACTV_IND: - - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (capi_decode_conn_actv_ind(chan, skb)) { - printk("error in capi_decode_conn_actv_ind\n"); - /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */ - break; - } - chan->r_refnum = refnum; - pcbit_fsm_event(dev, chan, EV_NET_CONN, NULL); - break; - case MSG_CONN_ACTV_CONF: - - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (capi_decode_conn_actv_conf(chan, skb) == 0) - pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL); - - else - printk(KERN_DEBUG "decode_conn_actv_conf failed\n"); - break; - - case MSG_SELP_CONF: - - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (!(err = capi_decode_sel_proto_conf(chan, skb))) - pcbit_fsm_event(dev, chan, EV_NET_SELP_RESP, NULL); - else { - /* Error */ - printk("error %d - capi_decode_sel_proto_conf\n", err); - } - break; - case MSG_ACT_TRANSP_CONF: - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (!capi_decode_actv_trans_conf(chan, skb)) - pcbit_fsm_event(dev, chan, EV_NET_ACTV_RESP, NULL); - break; - - case MSG_DISC_IND: - - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (!capi_decode_disc_ind(chan, skb)) - pcbit_fsm_event(dev, chan, EV_NET_DISC, NULL); - else - printk(KERN_WARNING "capi_decode_disc_ind - error\n"); - break; - case MSG_DISC_CONF: - if (!(chan = capi_channel(dev, skb))) { - printk(KERN_WARNING - "CAPI header: unknown channel id\n"); - break; - } - - if (!capi_decode_disc_ind(chan, skb)) - pcbit_fsm_event(dev, chan, EV_NET_RELEASE, NULL); - else - printk(KERN_WARNING "capi_decode_disc_conf - error\n"); - break; - case MSG_INFO_IND: -#ifdef DEBUG - printk(KERN_DEBUG "received Info Indication - discarded\n"); -#endif - break; -#ifdef DEBUG - case MSG_DEBUG_188: - capi_decode_debug_188(skb->data, skb->len); - break; - - default: - printk(KERN_DEBUG "pcbit_l3_receive: unknown message %08lx\n", - msg); - break; -#endif - } - - kfree_skb(skb); - -} - -/* - * Single statbuf - * should be a statbuf per device - */ - -static char statbuf[STATBUF_LEN]; -static int stat_st; -static int stat_end; - -static int pcbit_stat(u_char __user *buf, int len, int driver, int channel) -{ - int stat_count; - stat_count = stat_end - stat_st; - - if (stat_count < 0) - stat_count = STATBUF_LEN - stat_st + stat_end; - - /* FIXME: should we sleep and wait for more cookies ? */ - if (len > stat_count) - len = stat_count; - - if (stat_st < stat_end) - { - if (copy_to_user(buf, statbuf + stat_st, len)) - return -EFAULT; - stat_st += len; - } - else - { - if (len > STATBUF_LEN - stat_st) - { - if (copy_to_user(buf, statbuf + stat_st, - STATBUF_LEN - stat_st)) - return -EFAULT; - if (copy_to_user(buf, statbuf, - len - (STATBUF_LEN - stat_st))) - return -EFAULT; - - stat_st = len - (STATBUF_LEN - stat_st); - } - else - { - if (copy_to_user(buf, statbuf + stat_st, len)) - return -EFAULT; - - stat_st += len; - - if (stat_st == STATBUF_LEN) - stat_st = 0; - } - } - - if (stat_st == stat_end) - stat_st = stat_end = 0; - - return len; -} - -static void pcbit_logstat(struct pcbit_dev *dev, char *str) -{ - int i; - isdn_ctrl ictl; - - for (i = stat_end; i < strlen(str); i++) - { - statbuf[i] = str[i]; - stat_end = (stat_end + 1) % STATBUF_LEN; - if (stat_end == stat_st) - stat_st = (stat_st + 1) % STATBUF_LEN; - } - - ictl.command = ISDN_STAT_STAVAIL; - ictl.driver = dev->id; - ictl.arg = strlen(str); - dev->dev_if->statcallb(&ictl); -} - -void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan, - unsigned short i, unsigned short ev, unsigned short f) -{ - char buf[256]; - - sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n", - dev->id, chan->id, - isdn_state_table[i], strisdnevent(ev), isdn_state_table[f] - ); - -#ifdef DEBUG - printk("%s", buf); -#endif - - pcbit_logstat(dev, buf); -} - -static void set_running_timeout(unsigned long ptr) -{ - struct pcbit_dev *dev; - -#ifdef DEBUG - printk(KERN_DEBUG "set_running_timeout\n"); -#endif - dev = (struct pcbit_dev *) ptr; - - dev->l2_state = L2_DOWN; - wake_up_interruptible(&dev->set_running_wq); -} - -static int set_protocol_running(struct pcbit_dev *dev) -{ - isdn_ctrl ctl; - - setup_timer(&dev->set_running_timer, &set_running_timeout, (ulong)dev); - - /* kick it */ - - dev->l2_state = L2_STARTING; - - writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), - dev->sh_mem + BANK4); - - mod_timer(&dev->set_running_timer, jiffies + SET_RUN_TIMEOUT); - - wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING || - dev->l2_state == L2_DOWN); - - del_timer(&dev->set_running_timer); - - if (dev->l2_state == L2_RUNNING) - { - printk(KERN_DEBUG "pcbit: running\n"); - - dev->unack_seq = dev->send_seq; - - dev->writeptr = dev->sh_mem; - dev->readptr = dev->sh_mem + BANK2; - - /* tell the good news to the upper layer */ - ctl.driver = dev->id; - ctl.command = ISDN_STAT_RUN; - - dev->dev_if->statcallb(&ctl); - } - else - { - printk(KERN_DEBUG "pcbit: initialization failed\n"); - printk(KERN_DEBUG "pcbit: firmware not loaded\n"); - -#ifdef DEBUG - printk(KERN_DEBUG "Bank3 = %02x\n", - readb(dev->sh_mem + BANK3)); -#endif - writeb(0x40, dev->sh_mem + BANK4); - - /* warn the upper layer */ - ctl.driver = dev->id; - ctl.command = ISDN_STAT_STOP; - - dev->dev_if->statcallb(&ctl); - - return -EL2HLT; /* Level 2 halted */ - } - - return 0; -} - -static int pcbit_ioctl(isdn_ctrl *ctl) -{ - struct pcbit_dev *dev; - struct pcbit_ioctl *cmd; - - dev = finddev(ctl->driver); - - if (!dev) - { - printk(KERN_DEBUG "pcbit_ioctl: unknown device\n"); - return -ENODEV; - } - - cmd = (struct pcbit_ioctl *) ctl->parm.num; - - switch (ctl->arg) { - case PCBIT_IOCTL_GETSTAT: - cmd->info.l2_status = dev->l2_state; - break; - - case PCBIT_IOCTL_STRLOAD: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - - dev->unack_seq = dev->send_seq = dev->rcv_seq = 0; - - dev->writeptr = dev->sh_mem; - dev->readptr = dev->sh_mem + BANK2; - - dev->l2_state = L2_LOADING; - break; - - case PCBIT_IOCTL_LWMODE: - if (dev->l2_state != L2_LOADING) - return -EINVAL; - - dev->l2_state = L2_LWMODE; - break; - - case PCBIT_IOCTL_FWMODE: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - dev->loadptr = LOAD_ZONE_START; - dev->l2_state = L2_FWMODE; - - break; - case PCBIT_IOCTL_ENDLOAD: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - dev->l2_state = L2_DOWN; - break; - - case PCBIT_IOCTL_SETBYTE: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - - /* check addr */ - if (cmd->info.rdp_byte.addr > BANK4) - return -EFAULT; - - writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr); - break; - case PCBIT_IOCTL_GETBYTE: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - - /* check addr */ - - if (cmd->info.rdp_byte.addr > BANK4) - { - printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr); - return -EFAULT; - } - - cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr); - break; - case PCBIT_IOCTL_RUNNING: - if (dev->l2_state == L2_RUNNING) - return -EBUSY; - return set_protocol_running(dev); - break; - case PCBIT_IOCTL_WATCH188: - if (dev->l2_state != L2_LOADING) - return -EINVAL; - pcbit_l2_write(dev, MSG_WATCH188, 0x0001, NULL, 0); - break; - case PCBIT_IOCTL_PING188: - if (dev->l2_state != L2_LOADING) - return -EINVAL; - pcbit_l2_write(dev, MSG_PING188_REQ, 0x0001, NULL, 0); - break; - case PCBIT_IOCTL_APION: - if (dev->l2_state != L2_LOADING) - return -EINVAL; - pcbit_l2_write(dev, MSG_API_ON, 0x0001, NULL, 0); - break; - case PCBIT_IOCTL_STOP: - dev->l2_state = L2_DOWN; - writeb(0x40, dev->sh_mem + BANK4); - dev->rcv_seq = 0; - dev->send_seq = 0; - dev->unack_seq = 0; - break; - default: - printk("error: unknown ioctl\n"); - break; - } - return 0; -} - -/* - * MSN list handling - * - * if null reject all calls - * if first entry has null MSN accept all calls - */ - -static void pcbit_clear_msn(struct pcbit_dev *dev) -{ - struct msn_entry *ptr, *back; - - for (ptr = dev->msn_list; ptr;) - { - back = ptr->next; - kfree(ptr); - ptr = back; - } - - dev->msn_list = NULL; -} - -static void pcbit_set_msn(struct pcbit_dev *dev, char *list) -{ - struct msn_entry *ptr; - struct msn_entry *back = NULL; - char *cp, *sp; - int len; - - if (strlen(list) == 0) { - ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC); - if (!ptr) { - printk(KERN_WARNING "kmalloc failed\n"); - return; - } - - ptr->msn = NULL; - - ptr->next = dev->msn_list; - dev->msn_list = ptr; - - return; - } - - if (dev->msn_list) - for (back = dev->msn_list; back->next; back = back->next); - - sp = list; - - do { - cp = strchr(sp, ','); - if (cp) - len = cp - sp; - else - len = strlen(sp); - - ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC); - - if (!ptr) { - printk(KERN_WARNING "kmalloc failed\n"); - return; - } - ptr->next = NULL; - - ptr->msn = kmalloc(len + 1, GFP_ATOMIC); - if (!ptr->msn) { - printk(KERN_WARNING "kmalloc failed\n"); - kfree(ptr); - return; - } - - memcpy(ptr->msn, sp, len); - ptr->msn[len] = 0; - -#ifdef DEBUG - printk(KERN_DEBUG "msn: %s\n", ptr->msn); -#endif - if (dev->msn_list == NULL) - dev->msn_list = ptr; - else - back->next = ptr; - back = ptr; - sp += len; - } while (cp); -} - -/* - * check if we do signal or reject an incoming call - */ -static int pcbit_check_msn(struct pcbit_dev *dev, char *msn) -{ - struct msn_entry *ptr; - - for (ptr = dev->msn_list; ptr; ptr = ptr->next) { - - if (ptr->msn == NULL) - return 1; - - if (strcmp(ptr->msn, msn) == 0) - return 1; - } - - return 0; -} diff --git a/drivers/staging/i4l/pcbit/edss1.c b/drivers/staging/i4l/pcbit/edss1.c deleted file mode 100644 index 5980d1b5da95..000000000000 --- a/drivers/staging/i4l/pcbit/edss1.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * DSS.1 Finite State Machine - * base: ITU-T Rec Q.931 - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -/* - * TODO: complete the FSM - * move state/event descriptions to a user space logger - */ - -#include <linux/string.h> -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <linux/timer.h> -#include <linux/io.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "edss1.h" -#include "layer2.h" -#include "callbacks.h" - - -const char * const isdn_state_table[] = { - "Closed", - "Call initiated", - "Overlap sending", - "Outgoing call proceeding", - "NOT DEFINED", - "Call delivered", - "Call present", - "Call received", - "Connect request", - "Incoming call proceeding", - "Active", - "Disconnect request", - "Disconnect indication", - "NOT DEFINED", - "NOT DEFINED", - "Suspend request", - "NOT DEFINED", - "Resume request", - "NOT DEFINED", - "Release Request", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "Overlap receiving", - "Select protocol on B-Channel", - "Activate B-channel protocol" -}; - -#ifdef DEBUG_ERRS -static -struct CauseValue { - byte nr; - char *descr; -} cvlist[] = { - {0x01, "Unallocated (unassigned) number"}, - {0x02, "No route to specified transit network"}, - {0x03, "No route to destination"}, - {0x04, "Send special information tone"}, - {0x05, "Misdialled trunk prefix"}, - {0x06, "Channel unacceptable"}, - {0x07, "Channel awarded and being delivered in an established channel"}, - {0x08, "Preemption"}, - {0x09, "Preemption - circuit reserved for reuse"}, - {0x10, "Normal call clearing"}, - {0x11, "User busy"}, - {0x12, "No user responding"}, - {0x13, "No answer from user (user alerted)"}, - {0x14, "Subscriber absent"}, - {0x15, "Call rejected"}, - {0x16, "Number changed"}, - {0x1a, "non-selected user clearing"}, - {0x1b, "Destination out of order"}, - {0x1c, "Invalid number format (address incomplete)"}, - {0x1d, "Facility rejected"}, - {0x1e, "Response to Status enquiry"}, - {0x1f, "Normal, unspecified"}, - {0x22, "No circuit/channel available"}, - {0x26, "Network out of order"}, - {0x27, "Permanent frame mode connection out-of-service"}, - {0x28, "Permanent frame mode connection operational"}, - {0x29, "Temporary failure"}, - {0x2a, "Switching equipment congestion"}, - {0x2b, "Access information discarded"}, - {0x2c, "Requested circuit/channel not available"}, - {0x2e, "Precedence call blocked"}, - {0x2f, "Resource unavailable, unspecified"}, - {0x31, "Quality of service unavailable"}, - {0x32, "Requested facility not subscribed"}, - {0x35, "Outgoing calls barred within CUG"}, - {0x37, "Incoming calls barred within CUG"}, - {0x39, "Bearer capability not authorized"}, - {0x3a, "Bearer capability not presently available"}, - {0x3e, "Inconsistency in designated outgoing access information and subscriber class"}, - {0x3f, "Service or option not available, unspecified"}, - {0x41, "Bearer capability not implemented"}, - {0x42, "Channel type not implemented"}, - {0x43, "Requested facility not implemented"}, - {0x44, "Only restricted digital information bearer capability is available"}, - {0x4f, "Service or option not implemented"}, - {0x51, "Invalid call reference value"}, - {0x52, "Identified channel does not exist"}, - {0x53, "A suspended call exists, but this call identity does not"}, - {0x54, "Call identity in use"}, - {0x55, "No call suspended"}, - {0x56, "Call having the requested call identity has been cleared"}, - {0x57, "User not member of CUG"}, - {0x58, "Incompatible destination"}, - {0x5a, "Non-existent CUG"}, - {0x5b, "Invalid transit network selection"}, - {0x5f, "Invalid message, unspecified"}, - {0x60, "Mandatory information element is missing"}, - {0x61, "Message type non-existent or not implemented"}, - {0x62, "Message not compatible with call state or message type non-existent or not implemented"}, - {0x63, "Information element/parameter non-existent or not implemented"}, - {0x64, "Invalid information element contents"}, - {0x65, "Message not compatible with call state"}, - {0x66, "Recovery on timer expiry"}, - {0x67, "Parameter non-existent or not implemented - passed on"}, - {0x6e, "Message with unrecognized parameter discarded"}, - {0x6f, "Protocol error, unspecified"}, - {0x7f, "Interworking, unspecified"} -}; - -#endif - -static struct isdn_event_desc { - unsigned short ev; - char *desc; -} isdn_event_table[] = { - {EV_USR_SETUP_REQ, "CC->L3: Setup Request"}, - {EV_USR_SETUP_RESP, "CC->L3: Setup Response"}, - {EV_USR_PROCED_REQ, "CC->L3: Proceeding Request"}, - {EV_USR_RELEASE_REQ, "CC->L3: Release Request"}, - - {EV_NET_SETUP, "NET->TE: setup "}, - {EV_NET_CALL_PROC, "NET->TE: call proceeding"}, - {EV_NET_SETUP_ACK, "NET->TE: setup acknowledge (more info needed)"}, - {EV_NET_CONN, "NET->TE: connect"}, - {EV_NET_CONN_ACK, "NET->TE: connect acknowledge"}, - {EV_NET_DISC, "NET->TE: disconnect indication"}, - {EV_NET_RELEASE, "NET->TE: release"}, - {EV_NET_RELEASE_COMP, "NET->TE: release complete"}, - {EV_NET_SELP_RESP, "Board: Select B-channel protocol ack"}, - {EV_NET_ACTV_RESP, "Board: Activate B-channel protocol ack"}, - {EV_TIMER, "Timeout"}, - {0, "NULL"} -}; - -char *strisdnevent(ushort ev) -{ - struct isdn_event_desc *entry; - - for (entry = isdn_event_table; entry->ev; entry++) - if (entry->ev == ev) - break; - - return entry->desc; -} - -/* - * Euro ISDN finite state machine - */ - -static struct fsm_timer_entry fsm_timers[] = { - {ST_CALL_PROC, 10}, - {ST_DISC_REQ, 2}, - {ST_ACTIVE_SELP, 5}, - {ST_ACTIVE_ACTV, 5}, - {ST_INCM_PROC, 10}, - {ST_CONN_REQ, 2}, - {0xff, 0} -}; - -static struct fsm_entry fsm_table[] = { -/* Connect Phase */ - /* Outgoing */ - {ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1}, - - {ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone}, - {ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL}, - {ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2}, - - {ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2}, - {ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - /* Incoming */ - {ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL}, - - {ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1}, - {ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2}, - {ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3}, - - /* Active */ - {ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - {ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3}, - - /* Disconnect */ - - {ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3}, - - /* protocol selection */ - {ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1}, - {ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open}, - {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - /* Timers */ - {ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3}, - {ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2}, - - {0xff, 0, 0, NULL} -}; - - -static void pcbit_fsm_timer(unsigned long data) -{ - struct pcbit_dev *dev; - struct pcbit_chan *chan; - - chan = (struct pcbit_chan *) data; - - del_timer(&chan->fsm_timer); - chan->fsm_timer.function = NULL; - - dev = chan2dev(chan); - - if (!dev) { - printk(KERN_WARNING "pcbit: timer for unknown device\n"); - return; - } - - pcbit_fsm_event(dev, chan, EV_TIMER, NULL); -} - - -void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan, - unsigned short event, struct callb_data *data) -{ - struct fsm_entry *action; - struct fsm_timer_entry *tentry; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - for (action = fsm_table; action->init != 0xff; action++) - if (action->init == chan->fsm_state && action->event == event) - break; - - if (action->init == 0xff) { - - spin_unlock_irqrestore(&dev->lock, flags); - printk(KERN_DEBUG "fsm error: event %x on state %x\n", - event, chan->fsm_state); - return; - } - - if (chan->fsm_timer.function) { - del_timer(&chan->fsm_timer); - chan->fsm_timer.function = NULL; - } - - chan->fsm_state = action->final; - - pcbit_state_change(dev, chan, action->init, event, action->final); - - for (tentry = fsm_timers; tentry->init != 0xff; tentry++) - if (tentry->init == chan->fsm_state) - break; - - if (tentry->init != 0xff) { - setup_timer(&chan->fsm_timer, &pcbit_fsm_timer, (ulong)chan); - mod_timer(&chan->fsm_timer, jiffies + tentry->timeout * HZ); - } - - spin_unlock_irqrestore(&dev->lock, flags); - - if (action->callb) - action->callb(dev, chan, data); - -} diff --git a/drivers/staging/i4l/pcbit/edss1.h b/drivers/staging/i4l/pcbit/edss1.h deleted file mode 100644 index 2f6b3a8edfba..000000000000 --- a/drivers/staging/i4l/pcbit/edss1.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * DSS.1 module definitions - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -#ifndef EDSS1_H -#define EDSS1_H - -/* ISDN states */ - -#define ST_NULL 0 -#define ST_CALL_INIT 1 /* Call initiated */ -#define ST_OVER_SEND 2 /* Overlap sending - Requests More Info 4 call */ -#define ST_CALL_PROC 3 /* Call Proceeding */ -#define ST_CALL_DELV 4 -#define ST_CALL_PRES 6 /* Call Present - Received CONN.IND */ -#define ST_CALL_RECV 7 /* Alerting sent */ -#define ST_CONN_REQ 8 /* Answered - waiting 4 CONN.CONF */ -#define ST_INCM_PROC 9 -#define ST_ACTIVE 10 -#define ST_DISC_REQ 11 -#define ST_DISC_IND 12 -#define ST_SUSP_REQ 15 -#define ST_RESM_REQ 17 -#define ST_RELS_REQ 19 -#define ST_OVER_RECV 25 - -#define ST_ACTIVE_SELP 26 /* Select protocol on B-Channel */ -#define ST_ACTIVE_ACTV 27 /* Activate B-channel protocol */ - -#define MAX_STATE ST_ACTIVE_ACTV - -#define EV_NULL 0 -#define EV_USR_SETUP_REQ 1 -#define EV_USR_SETUP_RESP 2 -#define EV_USR_PROCED_REQ 3 -#define EV_USR_RELEASE_REQ 4 -#define EV_USR_REJECT_REQ 4 - -#define EV_NET_SETUP 16 -#define EV_NET_CALL_PROC 17 -#define EV_NET_SETUP_ACK 18 -#define EV_NET_CONN 19 -#define EV_NET_CONN_ACK 20 - -#define EV_NET_SELP_RESP 21 -#define EV_NET_ACTV_RESP 22 - -#define EV_NET_DISC 23 -#define EV_NET_RELEASE 24 -#define EV_NET_RELEASE_COMP 25 - -#define EV_TIMER 26 -#define EV_ERROR 32 - -/* - * Cause values - * only the ones we use - */ - -#define CAUSE_NORMAL 0x10U -#define CAUSE_NOCHAN 0x22U - -struct callb_data { - unsigned short type; - union { - struct ConnInfo { - char *CalledPN; - char *CallingPN; - } setup; - unsigned short cause; - } data; -}; - -struct fsm_entry { - unsigned short init; - unsigned short final; - unsigned short event; - void (*callb)(struct pcbit_dev *, struct pcbit_chan *, struct callb_data*); -}; - -struct fsm_timer_entry { - unsigned short init; - unsigned long timeout; /* in seconds */ -}; - -extern const char * const isdn_state_table[]; - -void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, - unsigned short event, struct callb_data *); -char *strisdnevent(ushort ev); - -#endif diff --git a/drivers/staging/i4l/pcbit/layer2.c b/drivers/staging/i4l/pcbit/layer2.c deleted file mode 100644 index 0592bf6ee9c9..000000000000 --- a/drivers/staging/i4l/pcbit/layer2.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * PCBIT-D low-layer interface - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -/* - * 19991203 - Fernando Carvalho - takion@superbofh.org - * Hacked to compile with egcs and run with current version of isdn modules - */ - -/* - * Based on documentation provided by Inesc: - * - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93 - */ - -/* - * TODO: better handling of errors - * re-write/remove debug printks - */ - -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/workqueue.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <linux/isdnif.h> - -#include <linux/io.h> - - -#include "pcbit.h" -#include "layer2.h" -#include "edss1.h" - -#undef DEBUG_FRAG - - -/* - * Prototypes - */ - -static void pcbit_transmit(struct pcbit_dev *dev); - -static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack); - -static void pcbit_l2_error(struct pcbit_dev *dev); -static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info); -static void pcbit_l2_err_recover(unsigned long data); - -static void pcbit_firmware_bug(struct pcbit_dev *dev); - -static __inline__ void -pcbit_sched_delivery(struct pcbit_dev *dev) -{ - schedule_work(&dev->qdelivery); -} - - -/* - * Called from layer3 - */ - -int -pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum, - struct sk_buff *skb, unsigned short hdr_len) -{ - struct frame_buf *frame, - *ptr; - unsigned long flags; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) { - dev_kfree_skb(skb); - return -1; - } - if ((frame = kmalloc(sizeof(struct frame_buf), - GFP_ATOMIC)) == NULL) { - dev_kfree_skb(skb); - return -1; - } - frame->msg = msg; - frame->refnum = refnum; - frame->copied = 0; - frame->hdr_len = hdr_len; - - if (skb) - frame->dt_len = skb->len - hdr_len; - else - frame->dt_len = 0; - - frame->skb = skb; - - frame->next = NULL; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->write_queue == NULL) { - dev->write_queue = frame; - spin_unlock_irqrestore(&dev->lock, flags); - pcbit_transmit(dev); - } else { - for (ptr = dev->write_queue; ptr->next; ptr = ptr->next); - ptr->next = frame; - - spin_unlock_irqrestore(&dev->lock, flags); - } - return 0; -} - -static __inline__ void -pcbit_tx_update(struct pcbit_dev *dev, ushort len) -{ - u_char info; - - dev->send_seq = (dev->send_seq + 1) % 8; - - dev->fsize[dev->send_seq] = len; - info = 0; - info |= dev->rcv_seq << 3; - info |= dev->send_seq; - - writeb(info, dev->sh_mem + BANK4); - -} - -/* - * called by interrupt service routine or by write_2 - */ - -static void -pcbit_transmit(struct pcbit_dev *dev) -{ - struct frame_buf *frame = NULL; - unsigned char unacked; - int flen; /* fragment frame length including all headers */ - int free; - int count, - cp_len; - unsigned long flags; - unsigned short tt; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) - return; - - unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->free > 16 && dev->write_queue && unacked < 7) { - - if (!dev->w_busy) - dev->w_busy = 1; - else { - spin_unlock_irqrestore(&dev->lock, flags); - return; - } - - - frame = dev->write_queue; - free = dev->free; - - spin_unlock_irqrestore(&dev->lock, flags); - - if (frame->copied == 0) { - - /* Type 0 frame */ - - ulong msg; - - if (frame->skb) - flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len; - else - flen = FRAME_HDR_LEN + PREHDR_LEN; - - if (flen > free) - flen = free; - - msg = frame->msg; - - /* - * Board level 2 header - */ - - pcbit_writew(dev, flen - FRAME_HDR_LEN); - - pcbit_writeb(dev, GET_MSG_CPU(msg)); - - pcbit_writeb(dev, GET_MSG_PROC(msg)); - - /* TH */ - pcbit_writew(dev, frame->hdr_len + PREHDR_LEN); - - /* TD */ - pcbit_writew(dev, frame->dt_len); - - - /* - * Board level 3 fixed-header - */ - - /* LEN = TH */ - pcbit_writew(dev, frame->hdr_len + PREHDR_LEN); - - /* XX */ - pcbit_writew(dev, 0); - - /* C + S */ - pcbit_writeb(dev, GET_MSG_CMD(msg)); - pcbit_writeb(dev, GET_MSG_SCMD(msg)); - - /* NUM */ - pcbit_writew(dev, frame->refnum); - - count = FRAME_HDR_LEN + PREHDR_LEN; - } else { - /* Type 1 frame */ - - flen = 2 + (frame->skb->len - frame->copied); - - if (flen > free) - flen = free; - - /* TT */ - tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */ - pcbit_writew(dev, tt); - - count = 2; - } - - if (frame->skb) { - cp_len = frame->skb->len - frame->copied; - if (cp_len > flen - count) - cp_len = flen - count; - - memcpy_topcbit(dev, frame->skb->data + frame->copied, - cp_len); - frame->copied += cp_len; - } - /* bookkeeping */ - dev->free -= flen; - pcbit_tx_update(dev, flen); - - spin_lock_irqsave(&dev->lock, flags); - - if (frame->skb == NULL || frame->copied == frame->skb->len) { - - dev->write_queue = frame->next; - - if (frame->skb != NULL) { - /* free frame */ - dev_kfree_skb(frame->skb); - } - kfree(frame); - } - dev->w_busy = 0; - spin_unlock_irqrestore(&dev->lock, flags); - } else { - spin_unlock_irqrestore(&dev->lock, flags); -#ifdef DEBUG - printk(KERN_DEBUG "unacked %d free %d write_queue %s\n", - unacked, dev->free, dev->write_queue ? "not empty" : - "empty"); -#endif - } -} - - -/* - * deliver a queued frame to the upper layer - */ - -void -pcbit_deliver(struct work_struct *work) -{ - struct frame_buf *frame; - unsigned long flags, msg; - struct pcbit_dev *dev = - container_of(work, struct pcbit_dev, qdelivery); - - spin_lock_irqsave(&dev->lock, flags); - - while ((frame = dev->read_queue)) { - dev->read_queue = frame->next; - spin_unlock_irqrestore(&dev->lock, flags); - - msg = 0; - SET_MSG_CPU(msg, 0); - SET_MSG_PROC(msg, 0); - SET_MSG_CMD(msg, frame->skb->data[2]); - SET_MSG_SCMD(msg, frame->skb->data[3]); - - frame->refnum = *((ushort *)frame->skb->data + 4); - frame->msg = *((ulong *)&msg); - - skb_pull(frame->skb, 6); - - pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len, - frame->refnum); - - kfree(frame); - - spin_lock_irqsave(&dev->lock, flags); - } - - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* - * Reads BANK 2 & Reassembles - */ - -static void -pcbit_receive(struct pcbit_dev *dev) -{ - unsigned short tt; - u_char cpu, - proc; - struct frame_buf *frame = NULL; - unsigned long flags; - u_char type1; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) - return; - - tt = pcbit_readw(dev); - - if ((tt & 0x7fffU) > 511) { - printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n", - tt); - pcbit_l2_error(dev); - return; - } - if (!(tt & 0x8000U)) { /* Type 0 */ - type1 = 0; - - if (dev->read_frame) { - printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n"); - /* discard previous queued frame */ - kfree_skb(dev->read_frame->skb); - kfree(dev->read_frame); - dev->read_frame = NULL; - } - frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC); - - if (frame == NULL) { - printk(KERN_WARNING "kmalloc failed\n"); - return; - } - - cpu = pcbit_readb(dev); - proc = pcbit_readb(dev); - - - if (cpu != 0x06 && cpu != 0x02) { - printk(KERN_DEBUG "pcbit: invalid cpu value\n"); - kfree(frame); - pcbit_l2_error(dev); - return; - } - /* - * we discard cpu & proc on receiving - * but we read it to update the pointer - */ - - frame->hdr_len = pcbit_readw(dev); - frame->dt_len = pcbit_readw(dev); - - /* - * 0 sized packet - * I don't know if they are an error or not... - * But they are very frequent - * Not documented - */ - - if (frame->hdr_len == 0) { - kfree(frame); -#ifdef DEBUG - printk(KERN_DEBUG "0 sized frame\n"); -#endif - pcbit_firmware_bug(dev); - return; - } - /* sanity check the length values */ - if (frame->hdr_len > 1024 || frame->dt_len > 2048) { -#ifdef DEBUG - printk(KERN_DEBUG "length problem: "); - printk(KERN_DEBUG "TH=%04x TD=%04x\n", - frame->hdr_len, - frame->dt_len); -#endif - pcbit_l2_error(dev); - kfree(frame); - return; - } - /* minimum frame read */ - - frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len + - ((frame->hdr_len + 15) & ~15)); - - if (!frame->skb) { - printk(KERN_DEBUG "pcbit_receive: out of memory\n"); - kfree(frame); - return; - } - /* 16 byte alignment for IP */ - if (frame->dt_len) - skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15); - - } else { - /* Type 1 */ - type1 = 1; - tt &= 0x7fffU; - - if (!(frame = dev->read_frame)) { - printk("Type 1 frame and no frame queued\n"); - /* usually after an error: toss frame */ - dev->readptr += tt; - if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN) - dev->readptr -= BANKLEN; - return; - - } - } - - memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt); - - frame->copied += tt; - spin_lock_irqsave(&dev->lock, flags); - if (frame->copied == frame->hdr_len + frame->dt_len) { - - if (type1) { - dev->read_frame = NULL; - } - if (dev->read_queue) { - struct frame_buf *ptr; - for (ptr = dev->read_queue; ptr->next; ptr = ptr->next); - ptr->next = frame; - } else - dev->read_queue = frame; - - } else { - dev->read_frame = frame; - } - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* - * The board sends 0 sized frames - * They are TDATA_CONFs that get messed up somehow - * gotta send a fake acknowledgment to the upper layer somehow - */ - -static __inline__ void -pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan) -{ - isdn_ctrl ictl; - - if (chan->queued) { - chan->queued--; - - ictl.driver = dev->id; - ictl.command = ISDN_STAT_BSENT; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); - } -} - -static void -pcbit_firmware_bug(struct pcbit_dev *dev) -{ - struct pcbit_chan *chan; - - chan = dev->b1; - - if (chan->fsm_state == ST_ACTIVE) { - pcbit_fake_conf(dev, chan); - } - chan = dev->b2; - - if (chan->fsm_state == ST_ACTIVE) { - pcbit_fake_conf(dev, chan); - } -} - -irqreturn_t -pcbit_irq_handler(int interrupt, void *devptr) -{ - struct pcbit_dev *dev; - u_char info, - ack_seq, - read_seq; - - dev = (struct pcbit_dev *) devptr; - - if (!dev) { - printk(KERN_WARNING "pcbit_irq_handler: wrong device\n"); - return IRQ_NONE; - } - if (dev->interrupt) { - printk(KERN_DEBUG "pcbit: reentering interrupt handler\n"); - return IRQ_HANDLED; - } - dev->interrupt = 1; - - info = readb(dev->sh_mem + BANK3); - - if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) { - pcbit_l2_active_conf(dev, info); - dev->interrupt = 0; - return IRQ_HANDLED; - } - if (info & 0x40U) { /* E bit set */ -#ifdef DEBUG - printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n"); -#endif - pcbit_l2_error(dev); - dev->interrupt = 0; - return IRQ_HANDLED; - } - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) { - dev->interrupt = 0; - return IRQ_HANDLED; - } - ack_seq = (info >> 3) & 0x07U; - read_seq = (info & 0x07U); - - dev->interrupt = 0; - - if (read_seq != dev->rcv_seq) { - while (read_seq != dev->rcv_seq) { - pcbit_receive(dev); - dev->rcv_seq = (dev->rcv_seq + 1) % 8; - } - pcbit_sched_delivery(dev); - } - if (ack_seq != dev->unack_seq) { - pcbit_recv_ack(dev, ack_seq); - } - info = dev->rcv_seq << 3; - info |= dev->send_seq; - - writeb(info, dev->sh_mem + BANK4); - return IRQ_HANDLED; -} - - -static void -pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info) -{ - u_char state; - - state = dev->l2_state; - -#ifdef DEBUG - printk(KERN_DEBUG "layer2_active_confirm\n"); -#endif - - - if (info & 0x80U) { - dev->rcv_seq = info & 0x07U; - dev->l2_state = L2_RUNNING; - } else - dev->l2_state = L2_DOWN; - - if (state == L2_STARTING) - wake_up_interruptible(&dev->set_running_wq); - - if (state == L2_ERROR && dev->l2_state == L2_RUNNING) { - pcbit_transmit(dev); - } -} - -static void -pcbit_l2_err_recover(unsigned long data) -{ - - struct pcbit_dev *dev; - struct frame_buf *frame; - - dev = (struct pcbit_dev *) data; - - del_timer(&dev->error_recover_timer); - if (dev->w_busy || dev->r_busy) { - init_timer(&dev->error_recover_timer); - dev->error_recover_timer.expires = jiffies + ERRTIME; - add_timer(&dev->error_recover_timer); - return; - } - dev->w_busy = dev->r_busy = 1; - - if (dev->read_frame) { - kfree_skb(dev->read_frame->skb); - kfree(dev->read_frame); - dev->read_frame = NULL; - } - if (dev->write_queue) { - frame = dev->write_queue; -#ifdef FREE_ON_ERROR - dev->write_queue = dev->write_queue->next; - - if (frame->skb) { - dev_kfree_skb(frame->skb); - } - kfree(frame); -#else - frame->copied = 0; -#endif - } - dev->rcv_seq = dev->send_seq = dev->unack_seq = 0; - dev->free = 511; - dev->l2_state = L2_ERROR; - - /* this is an hack... */ - pcbit_firmware_bug(dev); - - dev->writeptr = dev->sh_mem; - dev->readptr = dev->sh_mem + BANK2; - - writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), - dev->sh_mem + BANK4); - dev->w_busy = dev->r_busy = 0; - -} - -static void -pcbit_l2_error(struct pcbit_dev *dev) -{ - if (dev->l2_state == L2_RUNNING) { - - printk(KERN_INFO "pcbit: layer 2 error\n"); - -#ifdef DEBUG - log_state(dev); -#endif - - dev->l2_state = L2_DOWN; - - setup_timer(&dev->error_recover_timer, &pcbit_l2_err_recover, - (ulong)dev); - mod_timer(&dev->error_recover_timer, jiffies + ERRTIME); - } -} - -/* - * Description: - * if board acks frames - * update dev->free - * call pcbit_transmit to write possible queued frames - */ - -static void -pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack) -{ - int i, - count; - int unacked; - - unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07; - - /* dev->unack_seq < ack <= dev->send_seq; */ - - if (unacked) { - - if (dev->send_seq > dev->unack_seq) { - if (ack <= dev->unack_seq || ack > dev->send_seq) { - printk(KERN_DEBUG - "layer 2 ack unacceptable - dev %d", - dev->id); - - pcbit_l2_error(dev); - } else if (ack > dev->send_seq && ack <= dev->unack_seq) { - printk(KERN_DEBUG - "layer 2 ack unacceptable - dev %d", - dev->id); - pcbit_l2_error(dev); - } - } - /* ack is acceptable */ - - - i = dev->unack_seq; - - do { - dev->unack_seq = i = (i + 1) % 8; - dev->free += dev->fsize[i]; - } while (i != ack); - - count = 0; - while (count < 7 && dev->write_queue) { - u8 lsend_seq = dev->send_seq; - - pcbit_transmit(dev); - - if (dev->send_seq == lsend_seq) - break; - count++; - } - } else - printk(KERN_DEBUG "recv_ack: unacked = 0\n"); -} diff --git a/drivers/staging/i4l/pcbit/layer2.h b/drivers/staging/i4l/pcbit/layer2.h deleted file mode 100644 index 6b9063e388cd..000000000000 --- a/drivers/staging/i4l/pcbit/layer2.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * PCBIT-D low-layer interface definitions - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -/* - * 19991203 - Fernando Carvalho - takion@superbofh.org - * Hacked to compile with egcs and run with current version of isdn modules - */ - -#ifndef LAYER2_H -#define LAYER2_H - -#include <linux/interrupt.h> - -#include <asm/byteorder.h> - -#define BANK1 0x0000U /* PC -> Board */ -#define BANK2 0x01ffU /* Board -> PC */ -#define BANK3 0x03feU /* Att Board */ -#define BANK4 0x03ffU /* Att PC */ - -#define BANKLEN 0x01FFU - -#define LOAD_ZONE_START 0x03f8U -#define LOAD_ZONE_END 0x03fdU - -#define LOAD_RETRY 18000000 - - - -/* TAM - XX - C - S - NUM */ -#define PREHDR_LEN 8 -/* TT - M - I - TH - TD */ -#define FRAME_HDR_LEN 8 - -#define MSG_CONN_REQ 0x08000100 -#define MSG_CONN_CONF 0x00000101 -#define MSG_CONN_IND 0x00000102 -#define MSG_CONN_RESP 0x08000103 - -#define MSG_CONN_ACTV_REQ 0x08000300 -#define MSG_CONN_ACTV_CONF 0x00000301 -#define MSG_CONN_ACTV_IND 0x00000302 -#define MSG_CONN_ACTV_RESP 0x08000303 - -#define MSG_DISC_REQ 0x08000400 -#define MSG_DISC_CONF 0x00000401 -#define MSG_DISC_IND 0x00000402 -#define MSG_DISC_RESP 0x08000403 - -#define MSG_TDATA_REQ 0x0908E200 -#define MSG_TDATA_CONF 0x0000E201 -#define MSG_TDATA_IND 0x0000E202 -#define MSG_TDATA_RESP 0x0908E203 - -#define MSG_SELP_REQ 0x09004000 -#define MSG_SELP_CONF 0x00004001 - -#define MSG_ACT_TRANSP_REQ 0x0908E000 -#define MSG_ACT_TRANSP_CONF 0x0000E001 - -#define MSG_STPROT_REQ 0x09004100 -#define MSG_STPROT_CONF 0x00004101 - -#define MSG_PING188_REQ 0x09030500 -#define MSG_PING188_CONF 0x000005bc - -#define MSG_WATCH188 0x09030400 - -#define MSG_API_ON 0x08020102 -#define MSG_POOL_PCBIT 0x08020400 -#define MSG_POOL_PCBIT_CONF 0x00000401 - -#define MSG_INFO_IND 0x00002602 -#define MSG_INFO_RESP 0x08002603 - -#define MSG_DEBUG_188 0x0000ff00 - -/* - - long 4 3 2 1 - Intel 1 2 3 4 -*/ - -#ifdef __LITTLE_ENDIAN -#define SET_MSG_SCMD(msg, ch) (msg = (msg & 0xffffff00) | (((ch) & 0xff))) -#define SET_MSG_CMD(msg, ch) (msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8)) -#define SET_MSG_PROC(msg, ch) (msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16)) -#define SET_MSG_CPU(msg, ch) (msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24)) - -#define GET_MSG_SCMD(msg) ((msg) & 0xFF) -#define GET_MSG_CMD(msg) ((msg) >> 8 & 0xFF) -#define GET_MSG_PROC(msg) ((msg) >> 16 & 0xFF) -#define GET_MSG_CPU(msg) ((msg) >> 24) - -#else -#error "Non-Intel CPU" -#endif - -#define MAX_QUEUED 7 - -#define SCHED_READ 0x01 -#define SCHED_WRITE 0x02 - -#define SET_RUN_TIMEOUT (2 * HZ) /* 2 seconds */ - -struct frame_buf { - ulong msg; - unsigned int refnum; - unsigned int dt_len; - unsigned int hdr_len; - struct sk_buff *skb; - unsigned int copied; - struct frame_buf *next; -}; - -extern int pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum, - struct sk_buff *skb, unsigned short hdr_len); - -extern irqreturn_t pcbit_irq_handler(int interrupt, void *); - -extern struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS]; - -#ifdef DEBUG -static __inline__ void log_state(struct pcbit_dev *dev) { - printk(KERN_DEBUG "writeptr = %ld\n", - (ulong) (dev->writeptr - dev->sh_mem)); - printk(KERN_DEBUG "readptr = %ld\n", - (ulong) (dev->readptr - (dev->sh_mem + BANK2))); - printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n", - dev->rcv_seq, dev->send_seq, dev->unack_seq); -} -#endif - -static __inline__ struct pcbit_dev *chan2dev(struct pcbit_chan *chan) -{ - struct pcbit_dev *dev; - int i; - - - for (i = 0; i < MAX_PCBIT_CARDS; i++) - if ((dev = dev_pcbit[i])) - if (dev->b1 == chan || dev->b2 == chan) - return dev; - return NULL; - -} - -static __inline__ struct pcbit_dev *finddev(int id) -{ - struct pcbit_dev *dev; - int i; - - for (i = 0; i < MAX_PCBIT_CARDS; i++) - if ((dev = dev_pcbit[i])) - if (dev->id == id) - return dev; - return NULL; -} - - -/* - * Support routines for reading and writing in the board - */ - -static __inline__ void pcbit_writeb(struct pcbit_dev *dev, unsigned char dt) -{ - writeb(dt, dev->writeptr++); - if (dev->writeptr == dev->sh_mem + BANKLEN) - dev->writeptr = dev->sh_mem; -} - -static __inline__ void pcbit_writew(struct pcbit_dev *dev, unsigned short dt) -{ - int dist; - - dist = BANKLEN - (dev->writeptr - dev->sh_mem); - switch (dist) { - case 2: - writew(dt, dev->writeptr); - dev->writeptr = dev->sh_mem; - break; - case 1: - writeb((u_char) (dt & 0x00ffU), dev->writeptr); - dev->writeptr = dev->sh_mem; - writeb((u_char) (dt >> 8), dev->writeptr++); - break; - default: - writew(dt, dev->writeptr); - dev->writeptr += 2; - break; - }; -} - -static __inline__ void memcpy_topcbit(struct pcbit_dev *dev, u_char *data, - int len) -{ - int diff; - - diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem)); - - if (diff > 0) - { - memcpy_toio(dev->writeptr, data, len - diff); - memcpy_toio(dev->sh_mem, data + (len - diff), diff); - dev->writeptr = dev->sh_mem + diff; - } - else - { - memcpy_toio(dev->writeptr, data, len); - - dev->writeptr += len; - if (diff == 0) - dev->writeptr = dev->sh_mem; - } -} - -static __inline__ unsigned char pcbit_readb(struct pcbit_dev *dev) -{ - unsigned char val; - - val = readb(dev->readptr++); - if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN) - dev->readptr = dev->sh_mem + BANK2; - - return val; -} - -static __inline__ unsigned short pcbit_readw(struct pcbit_dev *dev) -{ - int dist; - unsigned short val; - - dist = BANKLEN - (dev->readptr - (dev->sh_mem + BANK2)); - switch (dist) { - case 2: - val = readw(dev->readptr); - dev->readptr = dev->sh_mem + BANK2; - break; - case 1: - val = readb(dev->readptr); - dev->readptr = dev->sh_mem + BANK2; - val = (readb(dev->readptr++) << 8) | val; - break; - default: - val = readw(dev->readptr); - dev->readptr += 2; - break; - }; - return val; -} - -static __inline__ void memcpy_frompcbit(struct pcbit_dev *dev, u_char *data, int len) -{ - int diff; - - diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2))); - if (diff > 0) - { - memcpy_fromio(data, dev->readptr, len - diff); - memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff); - dev->readptr = dev->sh_mem + BANK2 + diff; - } - else - { - memcpy_fromio(data, dev->readptr, len); - dev->readptr += len; - if (diff == 0) - dev->readptr = dev->sh_mem + BANK2; - } -} - - -#endif diff --git a/drivers/staging/i4l/pcbit/module.c b/drivers/staging/i4l/pcbit/module.c deleted file mode 100644 index 0a59bd0b8210..000000000000 --- a/drivers/staging/i4l/pcbit/module.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * PCBIT-D module support - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> - -#include <linux/isdnif.h> -#include "pcbit.h" - -MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card"); -MODULE_AUTHOR("Pedro Roque Marques"); -MODULE_LICENSE("GPL"); - -static int mem[MAX_PCBIT_CARDS]; -static int irq[MAX_PCBIT_CARDS]; - -module_param_array(mem, int, NULL, 0); -module_param_array(irq, int, NULL, 0); - -static int num_boards; -struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS]; - -static int __init pcbit_init(void) -{ - int board; - - num_boards = 0; - - printk(KERN_NOTICE - "PCBIT-D device driver v 0.5-fjpc0 19991204 - " - "Copyright (C) 1996 Universidade de Lisboa\n"); - - if (mem[0] || irq[0]) - { - for (board = 0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++) - { - if (!mem[board]) - mem[board] = 0xD0000; - if (!irq[board]) - irq[board] = 5; - - if (pcbit_init_dev(board, mem[board], irq[board]) == 0) - num_boards++; - - else - { - printk(KERN_WARNING - "pcbit_init failed for dev %d", - board + 1); - return -EIO; - } - } - } - - /* Hardcoded default settings detection */ - - if (!num_boards) - { - printk(KERN_INFO - "Trying to detect board using default settings\n"); - if (pcbit_init_dev(0, 0xD0000, 5) == 0) - num_boards++; - else - return -EIO; - } - return 0; -} - -static void __exit pcbit_exit(void) -{ -#ifdef MODULE - int board; - - for (board = 0; board < num_boards; board++) - pcbit_terminate(board); - printk(KERN_NOTICE - "PCBIT-D module unloaded\n"); -#endif -} - -#ifndef MODULE -#define MAX_PARA (MAX_PCBIT_CARDS * 2) -static int __init pcbit_setup(char *line) -{ - int i, j, argc; - char *str; - int ints[MAX_PARA + 1]; - - str = get_options(line, MAX_PARA, ints); - argc = ints[0]; - i = 0; - j = 1; - - while (argc && (i < MAX_PCBIT_CARDS)) { - - if (argc) { - mem[i] = ints[j]; - j++; argc--; - } - - if (argc) { - irq[i] = ints[j]; - j++; argc--; - } - - i++; - } - return (1); -} -__setup("pcbit=", pcbit_setup); -#endif - -module_init(pcbit_init); -module_exit(pcbit_exit); diff --git a/drivers/staging/i4l/pcbit/pcbit.h b/drivers/staging/i4l/pcbit/pcbit.h deleted file mode 100644 index 0a5a99440a80..000000000000 --- a/drivers/staging/i4l/pcbit/pcbit.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * PCBIT-D device driver definitions - * - * Copyright (C) 1996 Universidade de Lisboa - * - * Written by Pedro Roque Marques (roque@di.fc.ul.pt) - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - */ - -#ifndef PCBIT_H -#define PCBIT_H - -#include <linux/workqueue.h> - -#define MAX_PCBIT_CARDS 4 - - -#define BLOCK_TIMER - -#ifdef __KERNEL__ - -struct pcbit_chan { - unsigned short id; - unsigned short callref; /* Call Reference */ - unsigned char proto; /* layer2protocol */ - unsigned char queued; /* unacked data messages */ - unsigned char layer2link; /* used in TData */ - unsigned char snum; /* used in TData */ - unsigned short s_refnum; - unsigned short r_refnum; - unsigned short fsm_state; - struct timer_list fsm_timer; -#ifdef BLOCK_TIMER - struct timer_list block_timer; -#endif -}; - -struct msn_entry { - char *msn; - struct msn_entry *next; -}; - -struct pcbit_dev { - /* board */ - - volatile unsigned char __iomem *sh_mem; /* RDP address */ - unsigned long ph_mem; - unsigned int irq; - unsigned int id; - unsigned int interrupt; /* set during interrupt - processing */ - spinlock_t lock; - /* isdn4linux */ - - struct msn_entry *msn_list; /* ISDN address list */ - - isdn_if *dev_if; - - ushort ll_hdrlen; - ushort hl_hdrlen; - - /* link layer */ - unsigned char l2_state; - - struct frame_buf *read_queue; - struct frame_buf *read_frame; - struct frame_buf *write_queue; - - /* Protocol start */ - wait_queue_head_t set_running_wq; - struct timer_list set_running_timer; - - struct timer_list error_recover_timer; - - struct work_struct qdelivery; - - u_char w_busy; - u_char r_busy; - - volatile unsigned char __iomem *readptr; - volatile unsigned char __iomem *writeptr; - - ushort loadptr; - - unsigned short fsize[8]; /* sent layer2 frames size */ - - unsigned char send_seq; - unsigned char rcv_seq; - unsigned char unack_seq; - - unsigned short free; - - /* channels */ - - struct pcbit_chan *b1; - struct pcbit_chan *b2; -}; - -#define STATS_TIMER (10 * HZ) -#define ERRTIME (HZ / 10) - -/* MRU */ -#define MAXBUFSIZE 1534 -#define MRU MAXBUFSIZE - -#define STATBUF_LEN 2048 -/* - * - */ - -#endif /* __KERNEL__ */ - -/* isdn_ctrl only allows a long sized argument */ - -struct pcbit_ioctl { - union { - struct byte_op { - ushort addr; - ushort value; - } rdp_byte; - unsigned long l2_status; - } info; -}; - - - -#define PCBIT_IOCTL_GETSTAT 0x01 /* layer2 status */ -#define PCBIT_IOCTL_LWMODE 0x02 /* linear write mode */ -#define PCBIT_IOCTL_STRLOAD 0x03 /* start load mode */ -#define PCBIT_IOCTL_ENDLOAD 0x04 /* end load mode */ -#define PCBIT_IOCTL_SETBYTE 0x05 /* set byte */ -#define PCBIT_IOCTL_GETBYTE 0x06 /* get byte */ -#define PCBIT_IOCTL_RUNNING 0x07 /* set protocol running */ -#define PCBIT_IOCTL_WATCH188 0x08 /* set watch 188 */ -#define PCBIT_IOCTL_PING188 0x09 /* ping 188 */ -#define PCBIT_IOCTL_FWMODE 0x0A /* firmware write mode */ -#define PCBIT_IOCTL_STOP 0x0B /* stop protocol */ -#define PCBIT_IOCTL_APION 0x0C /* issue API_ON */ - -#ifndef __KERNEL__ - -#define PCBIT_GETSTAT (PCBIT_IOCTL_GETSTAT + IIOCDRVCTL) -#define PCBIT_LWMODE (PCBIT_IOCTL_LWMODE + IIOCDRVCTL) -#define PCBIT_STRLOAD (PCBIT_IOCTL_STRLOAD + IIOCDRVCTL) -#define PCBIT_ENDLOAD (PCBIT_IOCTL_ENDLOAD + IIOCDRVCTL) -#define PCBIT_SETBYTE (PCBIT_IOCTL_SETBYTE + IIOCDRVCTL) -#define PCBIT_GETBYTE (PCBIT_IOCTL_GETBYTE + IIOCDRVCTL) -#define PCBIT_RUNNING (PCBIT_IOCTL_RUNNING + IIOCDRVCTL) -#define PCBIT_WATCH188 (PCBIT_IOCTL_WATCH188 + IIOCDRVCTL) -#define PCBIT_PING188 (PCBIT_IOCTL_PING188 + IIOCDRVCTL) -#define PCBIT_FWMODE (PCBIT_IOCTL_FWMODE + IIOCDRVCTL) -#define PCBIT_STOP (PCBIT_IOCTL_STOP + IIOCDRVCTL) -#define PCBIT_APION (PCBIT_IOCTL_APION + IIOCDRVCTL) - -#define MAXSUPERLINE 3000 - -#endif - -#define L2_DOWN 0 -#define L2_LOADING 1 -#define L2_LWMODE 2 -#define L2_FWMODE 3 -#define L2_STARTING 4 -#define L2_RUNNING 5 -#define L2_ERROR 6 - -void pcbit_deliver(struct work_struct *work); -int pcbit_init_dev(int board, int mem_base, int irq); -void pcbit_terminate(int board); -void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, struct sk_buff *skb, - ushort hdr_len, ushort refnum); -void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan, - unsigned short i, unsigned short ev, unsigned short f); - -#endif diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 6f3f8ff2a066..7963d4a83f84 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -1,5 +1,5 @@ /* - * ADIS16201 Programmable Digital Vibration Sensor driver + * ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer * * Copyright 2010 Analog Devices Inc. * @@ -243,6 +243,6 @@ static struct spi_driver adis16201_driver = { module_spi_driver(adis16201_driver); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16201 Programmable Digital Vibration Sensor driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16201"); diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index c70671778bae..bd8119a23339 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -1,7 +1,7 @@ /* - * ADIS16203 Programmable Digital Vibration Sensor driver + * ADIS16203 Programmable 360 Degrees Inclinometer * - * Copyright 2030 Analog Devices Inc. + * Copyright 2010 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -211,6 +211,6 @@ static struct spi_driver adis16203_driver = { module_spi_driver(adis16203_driver); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable Digital Vibration Sensor driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16203"); diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 8dbad58628a1..a599e19303d3 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -1,5 +1,5 @@ /* - * ADIS16209 Programmable Digital Vibration Sensor driver + * ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer * * Copyright 2010 Analog Devices Inc. * @@ -243,6 +243,6 @@ static struct spi_driver adis16209_driver = { module_spi_driver(adis16209_driver); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16209"); diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/staging/iio/adc/ad7606.c index 453190864b2f..9dbfa64b1e53 100644 --- a/drivers/staging/iio/adc/ad7606.c +++ b/drivers/staging/iio/adc/ad7606.c @@ -26,6 +26,11 @@ #include "ad7606.h" +/* Scales are computed as 2.5/2**16 and 5/2**16 respectively */ +static const unsigned int scale_avail[2][2] = { + {0, 38147}, {0, 76294} +}; + static int ad7606_reset(struct ad7606_state *st) { if (st->gpio_reset) { @@ -151,9 +156,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, *val = (short)ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = st->range * 2; - *val2 = st->chip_info->channels[0].scan_type.realbits; - return IIO_VAL_FRACTIONAL_LOG2; + *val = scale_avail[st->range][0]; + *val2 = scale_avail[st->range][1]; + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *val = st->oversampling; return IIO_VAL_INT; @@ -161,42 +166,22 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, return -EINVAL; } -static ssize_t ad7606_show_range(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - return sprintf(buf, "%u\n", st->range); -} - -static ssize_t ad7606_store_range(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t in_voltage_scale_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7606_state *st = iio_priv(indio_dev); - unsigned long lval; - int ret; - - ret = kstrtoul(buf, 10, &lval); - if (ret) - return ret; + int i, len = 0; - if (!(lval == 5000 || lval == 10000)) - return -EINVAL; + for (i = 0; i < ARRAY_SIZE(scale_avail); i++) + len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", + scale_avail[i][0], scale_avail[i][1]); - mutex_lock(&indio_dev->mlock); - gpiod_set_value(st->gpio_range, lval == 10000); - st->range = lval; - mutex_unlock(&indio_dev->mlock); + buf[len - 1] = '\n'; - return count; + return len; } -static IIO_DEVICE_ATTR(in_voltage_range, S_IRUGO | S_IWUSR, - ad7606_show_range, ad7606_store_range, 0); -static IIO_CONST_ATTR(in_voltage_range_available, "5000 10000"); +static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); static int ad7606_oversampling_get_index(unsigned int val) { @@ -218,9 +203,23 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, { struct ad7606_state *st = iio_priv(indio_dev); int values[3]; - int ret; + int ret, i; switch (mask) { + case IIO_CHAN_INFO_SCALE: + ret = -EINVAL; + mutex_lock(&indio_dev->mlock); + for (i = 0; i < ARRAY_SIZE(scale_avail); i++) + if (val2 == scale_avail[i][1]) { + gpiod_set_value(st->gpio_range, i); + st->range = i; + + ret = 0; + break; + } + mutex_unlock(&indio_dev->mlock); + + return ret; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: if (val2) return -EINVAL; @@ -247,8 +246,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, static IIO_CONST_ATTR(oversampling_ratio_available, "1 2 4 8 16 32 64"); static struct attribute *ad7606_attributes_os_and_range[] = { - &iio_dev_attr_in_voltage_range.dev_attr.attr, - &iio_const_attr_in_voltage_range_available.dev_attr.attr, + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, &iio_const_attr_oversampling_ratio_available.dev_attr.attr, NULL, }; @@ -267,8 +265,7 @@ static const struct attribute_group ad7606_attribute_group_os = { }; static struct attribute *ad7606_attributes_range[] = { - &iio_dev_attr_in_voltage_range.dev_attr.attr, - &iio_const_attr_in_voltage_range_available.dev_attr.attr, + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, NULL, }; @@ -397,6 +394,7 @@ static const struct iio_info ad7606_info_os = { static const struct iio_info ad7606_info_range = { .driver_module = THIS_MODULE, .read_raw = &ad7606_read_raw, + .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_range, }; @@ -417,7 +415,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->dev = dev; st->bops = bops; st->base_address = base_address; - st->range = 5000; + /* tied to logic low, analog input range is +/- 5V */ + st->range = 0; st->oversampling = 1; INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); @@ -525,7 +524,7 @@ static int ad7606_resume(struct device *dev) struct ad7606_state *st = iio_priv(indio_dev); if (st->gpio_standby) { - gpiod_set_value(st->gpio_range, st->range == 10000); + gpiod_set_value(st->gpio_range, st->range); gpiod_set_value(st->gpio_standby, 1); ad7606_reset(st); } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 72551f827382..17d280581e24 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -139,7 +139,7 @@ static ssize_t ad7816_store_mode(struct device *dev, return len; } -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, +static IIO_DEVICE_ATTR(mode, 0644, ad7816_show_mode, ad7816_store_mode, 0); @@ -151,7 +151,7 @@ static ssize_t ad7816_show_available_modes(struct device *dev, return sprintf(buf, "full\npower-save\n"); } -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, +static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes, NULL, 0); static ssize_t ad7816_show_channel(struct device *dev, @@ -197,7 +197,7 @@ static ssize_t ad7816_store_channel(struct device *dev, return len; } -static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR, +static IIO_DEVICE_ATTR(channel, 0644, ad7816_show_channel, ad7816_store_channel, 0); @@ -228,7 +228,7 @@ static ssize_t ad7816_show_value(struct device *dev, return sprintf(buf, "%u\n", data); } -static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0); +static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0); static struct attribute *ad7816_attributes[] = { &iio_dev_attr_available_modes.dev_attr.attr, @@ -319,7 +319,7 @@ static inline ssize_t ad7816_set_oti(struct device *dev, return len; } -static IIO_DEVICE_ATTR(oti, S_IRUGO | S_IWUSR, +static IIO_DEVICE_ATTR(oti, 0644, ad7816_show_oti, ad7816_set_oti, 0); static struct attribute *ad7816_event_attributes[] = { diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 0ccf192b9a03..f66dd3ebbab1 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -93,7 +93,7 @@ static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) */ static int adt7316_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct adt7316_bus bus = { .client = client, diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index a7d90c8bac5e..6054c7298fce 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -661,8 +661,9 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev, chip->dac_bits = 12; else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) chip->dac_bits = 10; - } else + } else { config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); + } ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); if (ret) diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index 6998c3ddfb6a..ca72af3e9d4b 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -274,7 +274,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev, error_ret: mutex_unlock(&chip->state_lock); - return 0; + return ret; } static int ad7150_read_event_value(struct iio_dev *indio_dev, @@ -414,7 +414,7 @@ error_ret: #define AD7150_TIMEOUT(chan, type, dir, ev_type, ev_dir) \ IIO_DEVICE_ATTR(in_capacitance##chan##_##type##_##dir##_timeout, \ - S_IRUGO | S_IWUSR, \ + 0644, \ &ad7150_show_timeout, \ &ad7150_store_timeout, \ IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, \ @@ -610,27 +610,27 @@ static int ad7150_probe(struct i2c_client *client, if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, - &ad7150_event_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, - "ad7150_irq1", - indio_dev); + NULL, + &ad7150_event_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "ad7150_irq1", + indio_dev); if (ret) return ret; } if (client->dev.platform_data) { ret = devm_request_threaded_irq(&client->dev, *(unsigned int *) - client->dev.platform_data, - NULL, - &ad7150_event_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, - "ad7150_irq2", - indio_dev); + client->dev.platform_data, + NULL, + &ad7150_event_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "ad7150_irq2", + indio_dev); if (ret) return ret; } diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 944789843938..5e96352fa4ac 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -23,8 +23,8 @@ #include <linux/iio/kfifo_buf.h> /* AD5933/AD5934 Registers */ -#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 2 bytes */ -#define AD5933_REG_CONTROL_LB 0x81 /* R/W, 2 bytes */ +#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 1 byte */ +#define AD5933_REG_CONTROL_LB 0x81 /* R/W, 1 byte */ #define AD5933_REG_FREQ_START 0x82 /* R/W, 3 bytes */ #define AD5933_REG_FREQ_INC 0x85 /* R/W, 3 bytes */ #define AD5933_REG_INC_NUM 0x88 /* R/W, 2 bytes, 9 bit */ diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index aa413e5878b9..6bb6d37cc7d1 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -26,39 +26,42 @@ #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/pm_runtime.h> -#define ISL29028_CONV_TIME_MS 100 +#define ISL29028_CONV_TIME_MS 100 -#define ISL29028_REG_CONFIGURE 0x01 +#define ISL29028_REG_CONFIGURE 0x01 -#define ISL29028_CONF_ALS_IR_MODE_ALS 0 -#define ISL29028_CONF_ALS_IR_MODE_IR BIT(0) -#define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0) +#define ISL29028_CONF_ALS_IR_MODE_ALS 0 +#define ISL29028_CONF_ALS_IR_MODE_IR BIT(0) +#define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0) -#define ISL29028_CONF_ALS_RANGE_LOW_LUX 0 +#define ISL29028_CONF_ALS_RANGE_LOW_LUX 0 #define ISL29028_CONF_ALS_RANGE_HIGH_LUX BIT(1) -#define ISL29028_CONF_ALS_RANGE_MASK BIT(1) +#define ISL29028_CONF_ALS_RANGE_MASK BIT(1) -#define ISL29028_CONF_ALS_DIS 0 -#define ISL29028_CONF_ALS_EN BIT(2) -#define ISL29028_CONF_ALS_EN_MASK BIT(2) +#define ISL29028_CONF_ALS_DIS 0 +#define ISL29028_CONF_ALS_EN BIT(2) +#define ISL29028_CONF_ALS_EN_MASK BIT(2) -#define ISL29028_CONF_PROX_SLP_SH 4 -#define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH) +#define ISL29028_CONF_PROX_SLP_SH 4 +#define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH) -#define ISL29028_CONF_PROX_EN BIT(7) -#define ISL29028_CONF_PROX_EN_MASK BIT(7) +#define ISL29028_CONF_PROX_EN BIT(7) +#define ISL29028_CONF_PROX_EN_MASK BIT(7) -#define ISL29028_REG_INTERRUPT 0x02 +#define ISL29028_REG_INTERRUPT 0x02 -#define ISL29028_REG_PROX_DATA 0x08 -#define ISL29028_REG_ALSIR_L 0x09 -#define ISL29028_REG_ALSIR_U 0x0A +#define ISL29028_REG_PROX_DATA 0x08 +#define ISL29028_REG_ALSIR_L 0x09 +#define ISL29028_REG_ALSIR_U 0x0A -#define ISL29028_REG_TEST1_MODE 0x0E -#define ISL29028_REG_TEST2_MODE 0x0F +#define ISL29028_REG_TEST1_MODE 0x0E +#define ISL29028_REG_TEST2_MODE 0x0F -#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1) +#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1) + +#define ISL29028_POWER_OFF_DELAY_MS 2000 enum isl29028_als_ir_mode { ISL29028_MODE_NONE = 0, @@ -67,62 +70,93 @@ enum isl29028_als_ir_mode { }; struct isl29028_chip { - struct mutex lock; - struct regmap *regmap; - - unsigned int prox_sampling; - bool enable_prox; - - int lux_scale; + struct mutex lock; + struct regmap *regmap; + unsigned int prox_sampling; + bool enable_prox; + int lux_scale; enum isl29028_als_ir_mode als_ir_mode; }; static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, unsigned int sampling) { + struct device *dev = regmap_get_device(chip->regmap); static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0}; - int sel; unsigned int period = DIV_ROUND_UP(1000, sampling); + int sel, ret; for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) { if (period >= prox_period[sel]) break; } - return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, - ISL29028_CONF_PROX_SLP_MASK, - sel << ISL29028_CONF_PROX_SLP_SH); + + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + ISL29028_CONF_PROX_SLP_MASK, + sel << ISL29028_CONF_PROX_SLP_SH); + + if (ret < 0) { + dev_err(dev, "%s(): Error %d setting the proximity sampling\n", + __func__, ret); + return ret; + } + + chip->prox_sampling = sampling; + + return ret; } -static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable) +static int isl29028_enable_proximity(struct isl29028_chip *chip) { int ret; - int val = 0; - if (enable) - val = ISL29028_CONF_PROX_EN; + ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); + if (ret < 0) + return ret; + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, - ISL29028_CONF_PROX_EN_MASK, val); + ISL29028_CONF_PROX_EN_MASK, + ISL29028_CONF_PROX_EN); if (ret < 0) return ret; /* Wait for conversion to be complete for first sample */ mdelay(DIV_ROUND_UP(1000, chip->prox_sampling)); + return 0; } static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale) { + struct device *dev = regmap_get_device(chip->regmap); int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX : ISL29028_CONF_ALS_RANGE_LOW_LUX; + int ret; - return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, - ISL29028_CONF_ALS_RANGE_MASK, val); + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + ISL29028_CONF_ALS_RANGE_MASK, val); + if (ret < 0) { + dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__, + ret); + return ret; + } + + chip->lux_scale = lux_scale; + + return ret; } static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, enum isl29028_als_ir_mode mode) { - int ret = 0; + int ret; + + if (chip->als_ir_mode == mode) + return 0; + + ret = isl29028_set_als_scale(chip, chip->lux_scale); + if (ret < 0) + return ret; switch (mode) { case ISL29028_MODE_ALS: @@ -136,16 +170,15 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, ISL29028_CONF_ALS_RANGE_MASK, ISL29028_CONF_ALS_RANGE_HIGH_LUX); break; - case ISL29028_MODE_IR: ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, ISL29028_CONF_ALS_IR_MODE_MASK, ISL29028_CONF_ALS_IR_MODE_IR); break; - case ISL29028_MODE_NONE: return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, - ISL29028_CONF_ALS_EN_MASK, ISL29028_CONF_ALS_DIS); + ISL29028_CONF_ALS_EN_MASK, + ISL29028_CONF_ALS_DIS); } if (ret < 0) @@ -160,6 +193,9 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, /* Need to wait for conversion time if ALS/IR mode enabled */ mdelay(ISL29028_CONV_TIME_MS); + + chip->als_ir_mode = mode; + return 0; } @@ -173,18 +209,21 @@ static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb); if (ret < 0) { dev_err(dev, - "Error in reading register ALSIR_L err %d\n", ret); + "%s(): Error %d reading register ALSIR_L\n", + __func__, ret); return ret; } ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb); if (ret < 0) { dev_err(dev, - "Error in reading register ALSIR_U err %d\n", ret); + "%s(): Error %d reading register ALSIR_U\n", + __func__, ret); return ret; } *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF); + return 0; } @@ -194,27 +233,24 @@ static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox) unsigned int data; int ret; + if (!chip->enable_prox) { + ret = isl29028_enable_proximity(chip); + if (ret < 0) + return ret; + + chip->enable_prox = true; + } + ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data); if (ret < 0) { - dev_err(dev, "Error in reading register %d, error %d\n", - ISL29028_REG_PROX_DATA, ret); + dev_err(dev, "%s(): Error %d reading register PROX_DATA\n", + __func__, ret); return ret; } - *prox = data; - return 0; -} -static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data) -{ - int ret; + *prox = data; - if (!chip->enable_prox) { - ret = isl29028_enable_proximity(chip, true); - if (ret < 0) - return ret; - chip->enable_prox = true; - } - return isl29028_read_proxim(chip, prox_data); + return 0; } static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) @@ -223,14 +259,11 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) int ret; int als_ir_data; - if (chip->als_ir_mode != ISL29028_MODE_ALS) { - ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS); - if (ret < 0) { - dev_err(dev, - "Error in enabling ALS mode err %d\n", ret); - return ret; - } - chip->als_ir_mode = ISL29028_MODE_ALS; + ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS); + if (ret < 0) { + dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__, + ret); + return ret; } ret = isl29028_read_als_ir(chip, &als_ir_data); @@ -248,6 +281,7 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) als_ir_data = (als_ir_data * 49) / 100; *als_data = als_ir_data; + return 0; } @@ -256,18 +290,33 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data) struct device *dev = regmap_get_device(chip->regmap); int ret; - if (chip->als_ir_mode != ISL29028_MODE_IR) { - ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR); - if (ret < 0) { - dev_err(dev, - "Error in enabling IR mode err %d\n", ret); - return ret; - } - chip->als_ir_mode = ISL29028_MODE_IR; + ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR); + if (ret < 0) { + dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__, + ret); + return ret; } + return isl29028_read_als_ir(chip, ir_data); } +static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on) +{ + struct device *dev = regmap_get_device(chip->regmap); + int ret; + + if (on) { + ret = pm_runtime_get_sync(dev); + if (ret < 0) + pm_runtime_put_noidle(dev); + } else { + pm_runtime_mark_last_busy(dev); + ret = pm_runtime_put_autosuspend(dev); + } + + return ret; +} + /* Channel IO */ static int isl29028_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -275,58 +324,65 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, { struct isl29028_chip *chip = iio_priv(indio_dev); struct device *dev = regmap_get_device(chip->regmap); - int ret = -EINVAL; + int ret; + + ret = isl29028_set_pm_runtime_busy(chip, true); + if (ret < 0) + return ret; mutex_lock(&chip->lock); + + ret = -EINVAL; switch (chan->type) { case IIO_PROXIMITY: if (mask != IIO_CHAN_INFO_SAMP_FREQ) { dev_err(dev, - "proximity: mask value 0x%08lx not supported\n", - mask); + "%s(): proximity: Mask value 0x%08lx is not supported\n", + __func__, mask); break; } + if (val < 1 || val > 100) { dev_err(dev, - "Samp_freq %d is not in range[1:100]\n", val); + "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n", + __func__, val); break; } + ret = isl29028_set_proxim_sampling(chip, val); - if (ret < 0) { - dev_err(dev, - "Setting proximity samp_freq fail, err %d\n", - ret); - break; - } - chip->prox_sampling = val; break; - case IIO_LIGHT: if (mask != IIO_CHAN_INFO_SCALE) { dev_err(dev, - "light: mask value 0x%08lx not supported\n", - mask); + "%s(): light: Mask value 0x%08lx is not supported\n", + __func__, mask); break; } - if ((val != 125) && (val != 2000)) { + + if (val != 125 && val != 2000) { dev_err(dev, - "lux scale %d is invalid [125, 2000]\n", val); + "%s(): light: Lux scale %d is not in the set {125, 2000}\n", + __func__, val); break; } + ret = isl29028_set_als_scale(chip, val); - if (ret < 0) { - dev_err(dev, - "Setting lux scale fail with error %d\n", ret); - break; - } - chip->lux_scale = val; break; - default: - dev_err(dev, "Unsupported channel type\n"); + dev_err(dev, "%s(): Unsupported channel type %x\n", + __func__, chan->type); break; } + mutex_unlock(&chip->lock); + + if (ret < 0) + return ret; + + ret = isl29028_set_pm_runtime_busy(chip, false); + if (ret < 0) + return ret; + return ret; } @@ -336,9 +392,15 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, { struct isl29028_chip *chip = iio_priv(indio_dev); struct device *dev = regmap_get_device(chip->regmap); - int ret = -EINVAL; + int ret, pm_ret; + + ret = isl29028_set_pm_runtime_busy(chip, true); + if (ret < 0) + return ret; mutex_lock(&chip->lock); + + ret = -EINVAL; switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: @@ -350,35 +412,50 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, ret = isl29028_ir_get(chip, val); break; case IIO_PROXIMITY: - ret = isl29028_proxim_get(chip, val); + ret = isl29028_read_proxim(chip, val); break; default: break; } + if (ret < 0) break; + ret = IIO_VAL_INT; break; - case IIO_CHAN_INFO_SAMP_FREQ: if (chan->type != IIO_PROXIMITY) break; + *val = chip->prox_sampling; ret = IIO_VAL_INT; break; - case IIO_CHAN_INFO_SCALE: if (chan->type != IIO_LIGHT) break; *val = chip->lux_scale; ret = IIO_VAL_INT; break; - default: - dev_err(dev, "mask value 0x%08lx not supported\n", mask); + dev_err(dev, "%s(): mask value 0x%08lx is not supported\n", + __func__, mask); break; } + mutex_unlock(&chip->lock); + + if (ret < 0) + return ret; + + /** + * Preserve the ret variable if the call to + * isl29028_set_pm_runtime_busy() is successful so the reading + * (if applicable) is returned to user space. + */ + pm_ret = isl29028_set_pm_runtime_busy(chip, false); + if (pm_ret < 0) + return pm_ret; + return ret; } @@ -386,7 +463,6 @@ static IIO_CONST_ATTR(in_proximity_sampling_frequency_available, "1 3 5 10 13 20 83 100"); static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000"); -#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) #define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) static struct attribute *isl29028_attributes[] = { ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available), @@ -420,45 +496,19 @@ static const struct iio_info isl29028_info = { .write_raw = isl29028_write_raw, }; -static int isl29028_chip_init(struct isl29028_chip *chip) +static int isl29028_clear_configure_reg(struct isl29028_chip *chip) { struct device *dev = regmap_get_device(chip->regmap); int ret; - chip->enable_prox = false; - chip->prox_sampling = 20; - chip->lux_scale = 2000; - chip->als_ir_mode = ISL29028_MODE_NONE; - - ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); - if (ret < 0) { - dev_err(dev, "%s(): write to reg %d failed, err = %d\n", - __func__, ISL29028_REG_TEST1_MODE, ret); - return ret; - } - ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); - if (ret < 0) { - dev_err(dev, "%s(): write to reg %d failed, err = %d\n", - __func__, ISL29028_REG_TEST2_MODE, ret); - return ret; - } - ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0); - if (ret < 0) { - dev_err(dev, "%s(): write to reg %d failed, err = %d\n", - __func__, ISL29028_REG_CONFIGURE, ret); - return ret; - } + if (ret < 0) + dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n", + __func__, ret); - ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); - if (ret < 0) { - dev_err(dev, "setting the proximity, err = %d\n", ret); - return ret; - } + chip->als_ir_mode = ISL29028_MODE_NONE; + chip->enable_prox = false; - ret = isl29028_set_als_scale(chip, chip->lux_scale); - if (ret < 0) - dev_err(dev, "setting als scale failed, err = %d\n", ret); return ret; } @@ -492,10 +542,8 @@ static int isl29028_probe(struct i2c_client *client, int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); - if (!indio_dev) { - dev_err(&client->dev, "iio allocation fails\n"); + if (!indio_dev) return -ENOMEM; - } chip = iio_priv(indio_dev); @@ -505,33 +553,102 @@ static int isl29028_probe(struct i2c_client *client, chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); - dev_err(&client->dev, "regmap initialization failed: %d\n", - ret); + dev_err(&client->dev, "%s: Error %d initializing regmap\n", + __func__, ret); return ret; } - ret = isl29028_chip_init(chip); + chip->enable_prox = false; + chip->prox_sampling = 20; + chip->lux_scale = 2000; + + ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); if (ret < 0) { - dev_err(&client->dev, "chip initialization failed: %d\n", ret); + dev_err(&client->dev, + "%s(): Error %d writing to TEST1_MODE register\n", + __func__, ret); return ret; } + ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); + if (ret < 0) { + dev_err(&client->dev, + "%s(): Error %d writing to TEST2_MODE register\n", + __func__, ret); + return ret; + } + + ret = isl29028_clear_configure_reg(chip); + if (ret < 0) + return ret; + indio_dev->info = &isl29028_info; indio_dev->channels = isl29028_channels; indio_dev->num_channels = ARRAY_SIZE(isl29028_channels); indio_dev->name = id->name; indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, + ISL29028_POWER_OFF_DELAY_MS); + pm_runtime_use_autosuspend(&client->dev); + ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); if (ret < 0) { dev_err(&client->dev, - "iio registration fails with error %d\n", - ret); + "%s(): iio registration failed with error %d\n", + __func__, ret); return ret; } + return 0; } +static int isl29028_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct isl29028_chip *chip = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); + + return isl29028_clear_configure_reg(chip); +} + +static int __maybe_unused isl29028_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct isl29028_chip *chip = iio_priv(indio_dev); + int ret; + + mutex_lock(&chip->lock); + + ret = isl29028_clear_configure_reg(chip); + + mutex_unlock(&chip->lock); + + return ret; +} + +static int __maybe_unused isl29028_resume(struct device *dev) +{ + /** + * The specific component (ALS/IR or proximity) will enable itself as + * needed the next time that the user requests a reading. This is done + * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity(). + */ + return 0; +} + +static const struct dev_pm_ops isl29028_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(isl29028_suspend, isl29028_resume) + SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL) +}; + static const struct i2c_device_id isl29028_id[] = { {"isl29028", 0}, {} @@ -548,9 +665,11 @@ MODULE_DEVICE_TABLE(of, isl29028_of_match); static struct i2c_driver isl29028_driver = { .driver = { .name = "isl29028", + .pm = &isl29028_pm_ops, .of_match_table = isl29028_of_match, }, .probe = isl29028_probe, + .remove = isl29028_remove, .id_table = isl29028_id, }; diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 4b5f05fdadcd..671dc9971610 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -377,7 +377,7 @@ static int ade7753_initial_setup(struct iio_dev *indio_dev) } ade7753_reset(dev); - msleep(ADE7753_STARTUP_DELAY); + usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h index a9d93cc1c414..bfe749156bce 100644 --- a/drivers/staging/iio/meter/ade7753.h +++ b/drivers/staging/iio/meter/ade7753.h @@ -49,7 +49,7 @@ #define ADE7753_MAX_TX 4 #define ADE7753_MAX_RX 4 -#define ADE7753_STARTUP_DELAY 1 +#define ADE7753_STARTUP_DELAY 1000 #define ADE7753_SPI_SLOW (u32)(300 * 1000) #define ADE7753_SPI_BURST (u32)(1000 * 1000) diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 17309591ca57..024463a11c47 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -389,7 +389,7 @@ static int ade7754_initial_setup(struct iio_dev *indio_dev) } ade7754_reset(dev); - msleep(ADE7754_STARTUP_DELAY); + usleep_range(ADE7754_STARTUP_DELAY, ADE7754_STARTUP_DELAY + 100); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h index e42ffc387a14..28f71c2cde0c 100644 --- a/drivers/staging/iio/meter/ade7754.h +++ b/drivers/staging/iio/meter/ade7754.h @@ -67,7 +67,7 @@ #define ADE7754_MAX_TX 4 #define ADE7754_MAX_RX 4 -#define ADE7754_STARTUP_DELAY 1 +#define ADE7754_STARTUP_DELAY 1000 #define ADE7754_SPI_SLOW (u32)(300 * 1000) #define ADE7754_SPI_BURST (u32)(1000 * 1000) diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index 1d04ec9524c8..6ae78d8aa24f 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -89,7 +89,7 @@ #define ADE7758_MAX_TX 8 #define ADE7758_MAX_RX 4 -#define ADE7758_STARTUP_DELAY 1 +#define ADE7758_STARTUP_DELAY 1000 #define AD7758_NUM_WAVSEL 5 #define AD7758_NUM_PHSEL 3 diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 3af8f77b8e41..99c89e606c8d 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -459,7 +459,7 @@ static int ade7758_initial_setup(struct iio_dev *indio_dev) } ade7758_reset(dev); - msleep(ADE7758_STARTUP_DELAY); + usleep_range(ADE7758_STARTUP_DELAY, ADE7758_STARTUP_DELAY + 100); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 57c213dfadcc..6d7444d6e880 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -13,6 +13,7 @@ #include <asm/unaligned.h> #include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> #include <linux/iio/trigger_consumer.h> #include "ade7758.h" diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 80144d40d9ca..944ee3401029 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -338,7 +338,7 @@ static int ade7759_initial_setup(struct iio_dev *indio_dev) } ade7759_reset(dev); - msleep(ADE7759_STARTUP_DELAY); + usleep_range(ADE7759_STARTUP_DELAY, ADE7759_STARTUP_DELAY + 100); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h index f9ff1f8e7372..f0716d2fdf8e 100644 --- a/drivers/staging/iio/meter/ade7759.h +++ b/drivers/staging/iio/meter/ade7759.h @@ -30,7 +30,7 @@ #define ADE7759_MAX_TX 6 #define ADE7759_MAX_RX 6 -#define ADE7759_STARTUP_DELAY 1 +#define ADE7759_STARTUP_DELAY 1000 #define ADE7759_SPI_SLOW (u32)(300 * 1000) #define ADE7759_SPI_BURST (u32)(1000 * 1000) diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 24edbc39ab4e..e8007f0c5186 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -444,7 +444,7 @@ static int ade7854_initial_setup(struct iio_dev *indio_dev) } ade7854_reset(dev); - msleep(ADE7854_STARTUP_DELAY); + usleep_range(ADE7854_STARTUP_DELAY, ADE7854_STARTUP_DELAY + 100); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h index 52f4195cf6f4..dbd97def9cd8 100644 --- a/drivers/staging/iio/meter/ade7854.h +++ b/drivers/staging/iio/meter/ade7854.h @@ -136,7 +136,7 @@ #define ADE7854_MAX_TX 7 #define ADE7854_MAX_RX 7 -#define ADE7854_STARTUP_DELAY 1 +#define ADE7854_STARTUP_DELAY 1000 #define ADE7854_SPI_SLOW (u32)(300 * 1000) #define ADE7854_SPI_BURST (u32)(1000 * 1000) diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 38dca69a06eb..4e0b4eedb53d 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -133,7 +133,7 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, return sprintf(buf, "%lu\n", val); } -static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show, +static DEVICE_ATTR(frequency, 0644, iio_bfin_tmr_frequency_show, iio_bfin_tmr_frequency_store); static struct attribute *iio_bfin_tmr_trigger_attrs[] = { @@ -260,7 +260,7 @@ out_free_irq: out1: iio_trigger_unregister(st->trig); out: - iio_trigger_put(st->trig); + iio_trigger_free(st->trig); return ret; } @@ -273,7 +273,7 @@ static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev) peripheral_free(st->t->pin); free_irq(st->irq, st); iio_trigger_unregister(st->trig); - iio_trigger_put(st->trig); + iio_trigger_free(st->trig); return 0; } diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index a604c83c957e..6f9f746a3a61 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -884,7 +884,6 @@ static void ks7010_card_init(struct ks_wlan_private *priv) if (priv->mac_address_valid && priv->version_size) priv->dev_state = DEVICE_STATE_PREINIT; - hostif_sme_enqueue(priv, SME_GET_EEPROM_CKSUM); /* load initial wireless parameter */ diff --git a/drivers/staging/ks7010/ks7010_sdio.h b/drivers/staging/ks7010/ks7010_sdio.h index 0f5fd848e23d..d7e1523a222f 100644 --- a/drivers/staging/ks7010/ks7010_sdio.h +++ b/drivers/staging/ks7010/ks7010_sdio.h @@ -81,11 +81,11 @@ /* AHB Data Window 0x010000-0x01FFFF */ #define DATA_WINDOW 0x010000 -#define WINDOW_SIZE 64*1024 +#define WINDOW_SIZE (64 * 1024) #define KS7010_IRAM_ADDRESS 0x06000000 -/* +/* * struct define */ struct hw_info_t { @@ -142,6 +142,7 @@ struct rx_device { unsigned int qtail; /* rx buffer queue last pointer */ spinlock_t rx_dev_lock; }; + #define ROM_FILE "ks7010sd.rom" #endif /* _KS7010_SDIO_H */ diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c index c7652c35be19..da7c42ef05f5 100644 --- a/drivers/staging/ks7010/ks_hostif.c +++ b/drivers/staging/ks7010/ks_hostif.c @@ -727,7 +727,6 @@ void hostif_power_mngmt_confirm(struct ks_wlan_private *priv) } else { priv->dev_state = DEVICE_STATE_READY; } - } static @@ -853,7 +852,6 @@ void hostif_scan_indication(struct ks_wlan_private *priv) DPRINTK(4, " count over :: scan_ind_count=%d\n", priv->scan_ind_count); } - } static @@ -900,7 +898,6 @@ void hostif_ps_adhoc_set_confirm(struct ks_wlan_private *priv) DPRINTK(3, "\n"); priv->infra_status = 0; /* infrastructure mode cancel */ hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM); - } static @@ -1102,7 +1099,7 @@ void hostif_event_check(struct ks_wlan_private *priv) priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE; } -#define CHECK_ALINE(size) (size%4 ? (size+(4-(size%4))):size) +#define CHECK_ALINE(size) (size % 4 ? (size + (4 - (size % 4))) : size) int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet) { @@ -1916,7 +1913,6 @@ void hostif_sme_set_wep(struct ks_wlan_private *priv, int type) sizeof(val), MIB_VALUE_TYPE_BOOL, &val); break; } - } struct wpa_suite_t { @@ -2103,7 +2099,6 @@ void hostif_sme_set_rsn(struct ks_wlan_private *priv, int type) hostif_mib_set_request(priv, LOCAL_RSN_MODE, sizeof(rsn_mode), MIB_VALUE_TYPE_OSTRING, &rsn_mode); break; - } } @@ -2211,13 +2206,11 @@ void hostif_sme_mode_setup(struct ks_wlan_private *priv) default: break; } - } static void hostif_sme_multicast_set(struct ks_wlan_private *priv) { - struct net_device *dev = priv->net_dev; int mc_count; struct netdev_hw_addr *ha; @@ -2267,7 +2260,6 @@ void hostif_sme_multicast_set(struct ks_wlan_private *priv) } spin_unlock(&priv->multicast_spin); - } static @@ -2311,7 +2303,6 @@ void hostif_sme_powermgt_set(struct ks_wlan_private *priv) break; } hostif_power_mngmt_request(priv, mode, wake_up, receiveDTIMs); - } static @@ -2328,7 +2319,6 @@ void hostif_sme_sleep_set(struct ks_wlan_private *priv) default: break; } - } static @@ -2639,7 +2629,6 @@ void hostif_sme_enqueue(struct ks_wlan_private *priv, unsigned short event) } tasklet_schedule(&priv->sme_task); - } int hostif_init(struct ks_wlan_private *priv) diff --git a/drivers/staging/ks7010/ks_hostif.h b/drivers/staging/ks7010/ks_hostif.h index 743f31ead56e..30c49b699d62 100644 --- a/drivers/staging/ks7010/ks_hostif.h +++ b/drivers/staging/ks7010/ks_hostif.h @@ -553,34 +553,34 @@ struct hostif_mic_failure_confirm_t { #define TX_RATE_FIXED 5 /* 11b rate */ -#define TX_RATE_1M (uint8_t)(10/5) /* 11b 11g basic rate */ -#define TX_RATE_2M (uint8_t)(20/5) /* 11b 11g basic rate */ -#define TX_RATE_5M (uint8_t)(55/5) /* 11g basic rate */ -#define TX_RATE_11M (uint8_t)(110/5) /* 11g basic rate */ +#define TX_RATE_1M (uint8_t)(10 / 5) /* 11b 11g basic rate */ +#define TX_RATE_2M (uint8_t)(20 / 5) /* 11b 11g basic rate */ +#define TX_RATE_5M (uint8_t)(55 / 5) /* 11g basic rate */ +#define TX_RATE_11M (uint8_t)(110 / 5) /* 11g basic rate */ /* 11g rate */ -#define TX_RATE_6M (uint8_t)(60/5) /* 11g basic rate */ -#define TX_RATE_12M (uint8_t)(120/5) /* 11g basic rate */ -#define TX_RATE_24M (uint8_t)(240/5) /* 11g basic rate */ -#define TX_RATE_9M (uint8_t)(90/5) -#define TX_RATE_18M (uint8_t)(180/5) -#define TX_RATE_36M (uint8_t)(360/5) -#define TX_RATE_48M (uint8_t)(480/5) -#define TX_RATE_54M (uint8_t)(540/5) +#define TX_RATE_6M (uint8_t)(60 / 5) /* 11g basic rate */ +#define TX_RATE_12M (uint8_t)(120 / 5) /* 11g basic rate */ +#define TX_RATE_24M (uint8_t)(240 / 5) /* 11g basic rate */ +#define TX_RATE_9M (uint8_t)(90 / 5) +#define TX_RATE_18M (uint8_t)(180 / 5) +#define TX_RATE_36M (uint8_t)(360 / 5) +#define TX_RATE_48M (uint8_t)(480 / 5) +#define TX_RATE_54M (uint8_t)(540 / 5) -#define IS_11B_RATE(A) (((A&RATE_MASK)==TX_RATE_1M)||((A&RATE_MASK)==TX_RATE_2M)||\ - ((A&RATE_MASK)==TX_RATE_5M)||((A&RATE_MASK)==TX_RATE_11M)) +#define IS_11B_RATE(A) (((A & RATE_MASK) == TX_RATE_1M ) || ((A & RATE_MASK) == TX_RATE_2M) || \ + ((A & RATE_MASK) == TX_RATE_5M) || ((A & RATE_MASK) == TX_RATE_11M)) -#define IS_OFDM_RATE(A) (((A&RATE_MASK)==TX_RATE_6M)||((A&RATE_MASK)==TX_RATE_12M)||\ - ((A&RATE_MASK)==TX_RATE_24M)||((A&RATE_MASK)==TX_RATE_9M)||\ - ((A&RATE_MASK)==TX_RATE_18M)||((A&RATE_MASK)==TX_RATE_36M)||\ - ((A&RATE_MASK)==TX_RATE_48M)||((A&RATE_MASK)==TX_RATE_54M)) +#define IS_OFDM_RATE(A) (((A & RATE_MASK) == TX_RATE_6M) || ((A & RATE_MASK) == TX_RATE_12M) || \ + ((A & RATE_MASK) == TX_RATE_24M) || ((A & RATE_MASK) == TX_RATE_9M) || \ + ((A & RATE_MASK) == TX_RATE_18M) || ((A & RATE_MASK) == TX_RATE_36M) || \ + ((A & RATE_MASK) == TX_RATE_48M) || ((A & RATE_MASK) == TX_RATE_54M)) -#define IS_11BG_RATE(A) (IS_11B_RATE(A)||IS_OFDM_RATE(A)) +#define IS_11BG_RATE(A) (IS_11B_RATE(A) || IS_OFDM_RATE(A)) -#define IS_OFDM_EXT_RATE(A) (((A&RATE_MASK)==TX_RATE_9M)||((A&RATE_MASK)==TX_RATE_18M)||\ - ((A&RATE_MASK)==TX_RATE_36M)||((A&RATE_MASK)==TX_RATE_48M)||\ - ((A&RATE_MASK)==TX_RATE_54M)) +#define IS_OFDM_EXT_RATE(A) (((A & RATE_MASK) == TX_RATE_9M) || ((A & RATE_MASK) == TX_RATE_18M) || \ + ((A & RATE_MASK) == TX_RATE_36M) || ((A & RATE_MASK) == TX_RATE_48M) || \ + ((A & RATE_MASK) == TX_RATE_54M)) enum { CONNECT_STATUS = 0, @@ -602,16 +602,16 @@ enum { /* macro function */ #define HIF_EVENT_MASK 0xE800 -#define IS_HIF_IND(_EVENT) ((_EVENT&HIF_EVENT_MASK)==0xE800 && \ - ((_EVENT&~HIF_EVENT_MASK)==0x0001 || \ - (_EVENT&~HIF_EVENT_MASK)==0x0006 || \ - (_EVENT&~HIF_EVENT_MASK)==0x000C || \ - (_EVENT&~HIF_EVENT_MASK)==0x0011 || \ - (_EVENT&~HIF_EVENT_MASK)==0x0012)) - -#define IS_HIF_CONF(_EVENT) ((_EVENT&HIF_EVENT_MASK)==0xE800 && \ - (_EVENT&~HIF_EVENT_MASK)>0x0000 && \ - (_EVENT&~HIF_EVENT_MASK)<0x0012 && \ +#define IS_HIF_IND(_EVENT) ((_EVENT & HIF_EVENT_MASK) == 0xE800 && \ + ((_EVENT & ~HIF_EVENT_MASK) == 0x0001 || \ + (_EVENT & ~HIF_EVENT_MASK) == 0x0006 || \ + (_EVENT & ~HIF_EVENT_MASK) == 0x000C || \ + (_EVENT & ~HIF_EVENT_MASK) == 0x0011 || \ + (_EVENT & ~HIF_EVENT_MASK) == 0x0012)) + +#define IS_HIF_CONF(_EVENT) ((_EVENT & HIF_EVENT_MASK) == 0xE800 && \ + (_EVENT & ~HIF_EVENT_MASK) > 0x0000 && \ + (_EVENT & ~HIF_EVENT_MASK) < 0x0012 && \ !IS_HIF_IND(_EVENT) ) #ifdef __KERNEL__ diff --git a/drivers/staging/ks7010/ks_wlan.h b/drivers/staging/ks7010/ks_wlan.h index 279e9b06fc4b..9ab80e1f123e 100644 --- a/drivers/staging/ks7010/ks_wlan.h +++ b/drivers/staging/ks7010/ks_wlan.h @@ -36,7 +36,7 @@ #ifdef KS_WLAN_DEBUG #define DPRINTK(n, fmt, args...) \ - if (KS_WLAN_DEBUG>(n)) printk(KERN_NOTICE "%s: "fmt, __FUNCTION__, ## args) + if (KS_WLAN_DEBUG > (n)) printk(KERN_NOTICE "%s: "fmt, __FUNCTION__, ## args) #else #define DPRINTK(n, fmt, args...) #endif @@ -94,7 +94,7 @@ enum { #define SME_WEP_VAL2 (1<<6) #define SME_WEP_VAL3 (1<<7) #define SME_WEP_VAL4 (1<<8) -#define SME_WEP_VAL_MASK (SME_WEP_VAL1|SME_WEP_VAL2|SME_WEP_VAL3|SME_WEP_VAL4) +#define SME_WEP_VAL_MASK (SME_WEP_VAL1 | SME_WEP_VAL2 | SME_WEP_VAL3 | SME_WEP_VAL4) #define SME_RSN (1<<9) #define SME_RSN_MULTICAST (1<<10) #define SME_RSN_UNICAST (1<<11) @@ -363,6 +363,7 @@ struct wpa_key_t { u8 tx_mic_key[MIC_KEY_SIZE]; u8 rx_mic_key[MIC_KEY_SIZE]; }; + #define WPA_KEY_INDEX_MAX 4 #define WPA_RX_SEQ_LEN 6 @@ -408,7 +409,6 @@ struct wps_status_t { #endif /* WPS */ struct ks_wlan_private { - struct hw_info_t ks_wlan_hw; /* hardware information */ struct net_device *net_dev; diff --git a/drivers/staging/ks7010/ks_wlan_ioctl.h b/drivers/staging/ks7010/ks_wlan_ioctl.h index 84554b6bb239..8e62b10effd6 100644 --- a/drivers/staging/ks7010/ks_wlan_ioctl.h +++ b/drivers/staging/ks7010/ks_wlan_ioctl.h @@ -15,43 +15,43 @@ #include <linux/wireless.h> /* The low order bit identify a SET (0) or a GET (1) ioctl. */ -/* SIOCIWFIRSTPRIV+0 */ -/* former KS_WLAN_GET_DRIVER_VERSION SIOCIWFIRSTPRIV+1 */ -/* SIOCIWFIRSTPRIV+2 */ -#define KS_WLAN_GET_FIRM_VERSION SIOCIWFIRSTPRIV+3 +/* SIOCIWFIRSTPRIV + 0 */ +/* former KS_WLAN_GET_DRIVER_VERSION SIOCIWFIRSTPRIV + 1 */ +/* SIOCIWFIRSTPRIV + 2 */ +#define KS_WLAN_GET_FIRM_VERSION SIOCIWFIRSTPRIV + 3 #ifdef WPS -#define KS_WLAN_SET_WPS_ENABLE SIOCIWFIRSTPRIV+4 -#define KS_WLAN_GET_WPS_ENABLE SIOCIWFIRSTPRIV+5 -#define KS_WLAN_SET_WPS_PROBE_REQ SIOCIWFIRSTPRIV+6 +#define KS_WLAN_SET_WPS_ENABLE SIOCIWFIRSTPRIV + 4 +#define KS_WLAN_GET_WPS_ENABLE SIOCIWFIRSTPRIV + 5 +#define KS_WLAN_SET_WPS_PROBE_REQ SIOCIWFIRSTPRIV + 6 #endif -#define KS_WLAN_GET_EEPROM_CKSUM SIOCIWFIRSTPRIV+7 -#define KS_WLAN_SET_PREAMBLE SIOCIWFIRSTPRIV+8 -#define KS_WLAN_GET_PREAMBLE SIOCIWFIRSTPRIV+9 -#define KS_WLAN_SET_POWER_SAVE SIOCIWFIRSTPRIV+10 -#define KS_WLAN_GET_POWER_SAVE SIOCIWFIRSTPRIV+11 -#define KS_WLAN_SET_SCAN_TYPE SIOCIWFIRSTPRIV+12 -#define KS_WLAN_GET_SCAN_TYPE SIOCIWFIRSTPRIV+13 -#define KS_WLAN_SET_RX_GAIN SIOCIWFIRSTPRIV+14 -#define KS_WLAN_GET_RX_GAIN SIOCIWFIRSTPRIV+15 -#define KS_WLAN_HOSTT SIOCIWFIRSTPRIV+16 /* unused */ -//#define KS_WLAN_SET_REGION SIOCIWFIRSTPRIV+17 -#define KS_WLAN_SET_BEACON_LOST SIOCIWFIRSTPRIV+18 -#define KS_WLAN_GET_BEACON_LOST SIOCIWFIRSTPRIV+19 +#define KS_WLAN_GET_EEPROM_CKSUM SIOCIWFIRSTPRIV + 7 +#define KS_WLAN_SET_PREAMBLE SIOCIWFIRSTPRIV + 8 +#define KS_WLAN_GET_PREAMBLE SIOCIWFIRSTPRIV + 9 +#define KS_WLAN_SET_POWER_SAVE SIOCIWFIRSTPRIV + 10 +#define KS_WLAN_GET_POWER_SAVE SIOCIWFIRSTPRIV + 11 +#define KS_WLAN_SET_SCAN_TYPE SIOCIWFIRSTPRIV + 12 +#define KS_WLAN_GET_SCAN_TYPE SIOCIWFIRSTPRIV + 13 +#define KS_WLAN_SET_RX_GAIN SIOCIWFIRSTPRIV + 14 +#define KS_WLAN_GET_RX_GAIN SIOCIWFIRSTPRIV + 15 +#define KS_WLAN_HOSTT SIOCIWFIRSTPRIV + 16 /* unused */ +//#define KS_WLAN_SET_REGION SIOCIWFIRSTPRIV + 17 +#define KS_WLAN_SET_BEACON_LOST SIOCIWFIRSTPRIV + 18 +#define KS_WLAN_GET_BEACON_LOST SIOCIWFIRSTPRIV + 19 -#define KS_WLAN_SET_TX_GAIN SIOCIWFIRSTPRIV+20 -#define KS_WLAN_GET_TX_GAIN SIOCIWFIRSTPRIV+21 +#define KS_WLAN_SET_TX_GAIN SIOCIWFIRSTPRIV + 20 +#define KS_WLAN_GET_TX_GAIN SIOCIWFIRSTPRIV + 21 /* for KS7010 */ -#define KS_WLAN_SET_PHY_TYPE SIOCIWFIRSTPRIV+22 -#define KS_WLAN_GET_PHY_TYPE SIOCIWFIRSTPRIV+23 -#define KS_WLAN_SET_CTS_MODE SIOCIWFIRSTPRIV+24 -#define KS_WLAN_GET_CTS_MODE SIOCIWFIRSTPRIV+25 -/* SIOCIWFIRSTPRIV+26 */ -/* SIOCIWFIRSTPRIV+27 */ -#define KS_WLAN_SET_SLEEP_MODE SIOCIWFIRSTPRIV+28 /* sleep mode */ -#define KS_WLAN_GET_SLEEP_MODE SIOCIWFIRSTPRIV+29 /* sleep mode */ -/* SIOCIWFIRSTPRIV+30 */ -/* SIOCIWFIRSTPRIV+31 */ +#define KS_WLAN_SET_PHY_TYPE SIOCIWFIRSTPRIV + 22 +#define KS_WLAN_GET_PHY_TYPE SIOCIWFIRSTPRIV + 23 +#define KS_WLAN_SET_CTS_MODE SIOCIWFIRSTPRIV + 24 +#define KS_WLAN_GET_CTS_MODE SIOCIWFIRSTPRIV + 25 +/* SIOCIWFIRSTPRIV + 26 */ +/* SIOCIWFIRSTPRIV + 27 */ +#define KS_WLAN_SET_SLEEP_MODE SIOCIWFIRSTPRIV + 28 /* sleep mode */ +#define KS_WLAN_GET_SLEEP_MODE SIOCIWFIRSTPRIV + 29 /* sleep mode */ +/* SIOCIWFIRSTPRIV + 30 */ +/* SIOCIWFIRSTPRIV + 31 */ #ifdef __KERNEL__ diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index e5d04adaeb1a..121e1530fdba 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -285,7 +285,6 @@ static int ks_wlan_set_essid(struct net_device *dev, if (priv->sleep_mode == SLP_SLEEP) return -EPERM; - /* for SLEEP MODE */ /* Check if we asked for `any' */ if (dwrq->flags == 0) { @@ -342,7 +341,6 @@ static int ks_wlan_get_essid(struct net_device *dev, if (priv->sleep_mode == SLP_SLEEP) return -EPERM; - /* for SLEEP MODE */ /* Note : if dwrq->flags != 0, we should * get the relevant SSID from the SSID list... */ @@ -2095,7 +2093,6 @@ static int ks_wlan_set_pmksa(struct net_device *dev, static struct iw_statistics *ks_get_wireless_stats(struct net_device *dev) { - struct ks_wlan_private *priv = (struct ks_wlan_private *)netdev_priv(dev); struct iw_statistics *wstats = &priv->wstats; @@ -2264,7 +2261,6 @@ static int ks_wlan_set_preamble(struct net_device *dev, priv->need_commit |= SME_MODE_SET; return -EINPROGRESS; /* Call commit handler */ - } /*------------------------------------------------------------------*/ @@ -2455,7 +2451,7 @@ static int ks_wlan_data_read(struct net_device *dev, #if 0 /*------------------------------------------------------------------*/ /* Private handler : get wep string */ -#define WEP_ASCII_BUFF_SIZE (17+64*4+1) +#define WEP_ASCII_BUFF_SIZE (17 + 64 * 4 + 1) static int ks_wlan_get_wep_ascii(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) @@ -2933,7 +2929,6 @@ static int ks_wlan_get_eeprom_cksum(struct net_device *dev, static void print_hif_event(struct net_device *dev, int event) { - switch (event) { case HIF_DATA_REQ: netdev_info(dev, "HIF_DATA_REQ\n"); @@ -3353,7 +3348,6 @@ void send_packet_complete(void *arg1, void *arg2) dev_kfree_skb(packet); packet = NULL; } - } /* Set or clear the multicast filter for this adaptor. @@ -3388,7 +3382,6 @@ int ks_wlan_open(struct net_device *dev) static int ks_wlan_close(struct net_device *dev) { - netif_stop_queue(dev); DPRINTK(4, "%s: Shutting down ethercard, status was 0x%4.4x.\n", @@ -3399,9 +3392,10 @@ int ks_wlan_close(struct net_device *dev) /* Operational parameters that usually are not changed. */ /* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (3*HZ) -static const unsigned char dummy_addr[] = - { 0x00, 0x0b, 0xe3, 0x00, 0x00, 0x00 }; +#define TX_TIMEOUT (3 * HZ) +static const unsigned char dummy_addr[] = { + 0x00, 0x0b, 0xe3, 0x00, 0x00, 0x00 +}; static const struct net_device_ops ks_wlan_netdev_ops = { .ndo_start_xmit = ks_wlan_start_xmit, diff --git a/drivers/staging/ks7010/michael_mic.c b/drivers/staging/ks7010/michael_mic.c index 2f535c08e172..f6e70fa2a12f 100644 --- a/drivers/staging/ks7010/michael_mic.c +++ b/drivers/staging/ks7010/michael_mic.c @@ -14,11 +14,11 @@ #include "michael_mic.h" // Rotation functions on 32 bit values -#define ROL32(A, n) (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) -#define ROR32(A, n) ROL32((A), 32-(n)) +#define ROL32(A, n) (((A) << (n)) | (((A) >> (32 - (n))) & ((1UL << (n)) - 1))) +#define ROR32(A, n) ROL32((A), 32 - (n)) // Convert from Byte[] to UInt32 in a portable way -#define getUInt32(A, B) ((uint32_t)(A[B+0] << 0) \ - + (A[B+1] << 8) + (A[B+2] << 16) + (A[B+3] << 24)) +#define getUInt32(A, B) ((uint32_t)(A[B + 0] << 0) \ + + (A[B + 1] << 8) + (A[B + 2] << 16) + (A[B + 3] << 24)) // Convert from UInt32 to Byte[] in a portable way #define putUInt32(A, B, C) \ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index 8f34c5ddc63e..3f773a4a344b 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -53,16 +53,56 @@ enum cfs_crypto_hash_alg { }; static struct cfs_crypto_hash_type hash_types[] = { - [CFS_HASH_ALG_NULL] = { "null", 0, 0 }, - [CFS_HASH_ALG_ADLER32] = { "adler32", 1, 4 }, - [CFS_HASH_ALG_CRC32] = { "crc32", ~0, 4 }, - [CFS_HASH_ALG_CRC32C] = { "crc32c", ~0, 4 }, - [CFS_HASH_ALG_MD5] = { "md5", 0, 16 }, - [CFS_HASH_ALG_SHA1] = { "sha1", 0, 20 }, - [CFS_HASH_ALG_SHA256] = { "sha256", 0, 32 }, - [CFS_HASH_ALG_SHA384] = { "sha384", 0, 48 }, - [CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 }, - [CFS_HASH_ALG_MAX] = { NULL, 0, 64 }, + [CFS_HASH_ALG_NULL] = { + .cht_name = "null", + .cht_key = 0, + .cht_size = 0 + }, + [CFS_HASH_ALG_ADLER32] = { + .cht_name = "adler32", + .cht_key = 1, + .cht_size = 4 + }, + [CFS_HASH_ALG_CRC32] = { + .cht_name = "crc32", + .cht_key = ~0, + .cht_size = 4 + }, + [CFS_HASH_ALG_CRC32C] = { + .cht_name = "crc32c", + .cht_key = ~0, + .cht_size = 4 + }, + [CFS_HASH_ALG_MD5] = { + .cht_name = "md5", + .cht_key = 0, + .cht_size = 16 + }, + [CFS_HASH_ALG_SHA1] = { + .cht_name = "sha1", + .cht_key = 0, + .cht_size = 20 + }, + [CFS_HASH_ALG_SHA256] = { + .cht_name = "sha256", + .cht_key = 0, + .cht_size = 32 + }, + [CFS_HASH_ALG_SHA384] = { + .cht_name = "sha384", + .cht_key = 0, + .cht_size = 48 + }, + [CFS_HASH_ALG_SHA512] = { + .cht_name = "sha512", + .cht_key = 0, + .cht_size = 64 + }, + [CFS_HASH_ALG_MAX] = { + .cht_name = NULL, + .cht_key = 0, + .cht_size = 64 + }, }; /* Maximum size of hash_types[].cht_size */ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index aab15d8112a4..2dae85798ec1 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -277,22 +277,6 @@ do { \ #define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr))) #define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr))) -/** Compile-time assertion. - * - * Check an invariant described by a constant expression at compile time by - * forcing a compiler error if it does not hold. \a cond must be a constant - * expression as defined by the ISO C Standard: - * - * 6.8.4.2 The switch statement - * .... - * [#3] The expression of each case label shall be an integer - * constant expression and no two of the case constant - * expressions in the same switch statement shall have the same - * value after conversion... - * - */ -#define CLASSERT(cond) do {switch (42) {case (cond): case 0: break; } } while (0) - /* max value for numeric network address */ #define MAX_NUMERIC_VALUE 0xffffffff diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h index e8695e4a39d1..fa0808d2953b 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h @@ -125,10 +125,6 @@ do { \ #include <linux/capability.h> -/* long integer with size equal to pointer */ -typedef unsigned long ulong_ptr_t; -typedef long long_ptr_t; - #ifndef WITH_WATCHDOG #define WITH_WATCHDOG #endif diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index a59c5e99cbd3..3d19402ba728 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -78,7 +78,7 @@ static inline int lnet_is_route_alive(lnet_route_t *route) return route->lr_downis == 0; } -static inline int lnet_is_wire_handle_none(lnet_handle_wire_t *wh) +static inline int lnet_is_wire_handle_none(struct lnet_handle_wire *wh) { return (wh->wh_interface_cookie == LNET_WIRE_HANDLE_COOKIE_NONE && wh->wh_object_cookie == LNET_WIRE_HANDLE_COOKIE_NONE); @@ -323,7 +323,7 @@ lnet_handle2md(lnet_handle_md_t *handle) } static inline lnet_libmd_t * -lnet_wire_handle2md(lnet_handle_wire_t *wh) +lnet_wire_handle2md(struct lnet_handle_wire *wh) { /* ALWAYS called with resource lock held */ lnet_libhandle_t *lh; @@ -552,7 +552,7 @@ int lnet_portals_create(void); void lnet_portals_destroy(void); /* message functions */ -int lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, +int lnet_parse(lnet_ni_t *ni, struct lnet_hdr *hdr, lnet_nid_t fromnid, void *private, int rdma_req); int lnet_parse_local(lnet_ni_t *ni, lnet_msg_t *msg); int lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg); @@ -579,7 +579,7 @@ void lnet_msg_containers_destroy(void); int lnet_msg_containers_create(void); char *lnet_msgtyp2str(int type); -void lnet_print_hdr(lnet_hdr_t *hdr); +void lnet_print_hdr(struct lnet_hdr *hdr); int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold); /** \addtogroup lnet_fault_simulation @{ */ @@ -588,7 +588,7 @@ int lnet_fault_ctl(int cmd, struct libcfs_ioctl_data *data); int lnet_fault_init(void); void lnet_fault_fini(void); -bool lnet_drop_rule_match(lnet_hdr_t *hdr); +bool lnet_drop_rule_match(struct lnet_hdr *hdr); int lnet_delay_rule_add(struct lnet_fault_attr *attr); int lnet_delay_rule_del(lnet_nid_t src, lnet_nid_t dst, bool shutdown); @@ -596,7 +596,7 @@ int lnet_delay_rule_list(int pos, struct lnet_fault_attr *attr, struct lnet_fault_stat *stat); void lnet_delay_rule_reset(void); void lnet_delay_rule_check(void); -bool lnet_delay_rule_match_locked(lnet_hdr_t *hdr, struct lnet_msg *msg); +bool lnet_delay_rule_match_locked(struct lnet_hdr *hdr, struct lnet_msg *msg); /** @} lnet_fault_simulation */ @@ -664,7 +664,7 @@ int lnet_peer_buffer_credits(lnet_ni_t *ni); int lnet_router_checker_start(void); void lnet_router_checker_stop(void); void lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net); -void lnet_swap_pinginfo(lnet_ping_info_t *info); +void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index b84a5bb9186c..9850398bf29a 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -105,7 +105,7 @@ typedef struct lnet_msg { lnet_kiov_t *msg_kiov; lnet_event_t msg_ev; - lnet_hdr_t msg_hdr; + struct lnet_hdr msg_hdr; } lnet_msg_t; typedef struct lnet_libhandle { @@ -270,7 +270,7 @@ typedef struct lnet_ni { struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */ int **ni_refs; /* percpt reference count */ time64_t ni_last_alive;/* when I was last alive */ - lnet_ni_status_t *ni_status; /* my health status */ + struct lnet_ni_status *ni_status; /* my health status */ /* per NI LND tunables */ struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; /* equivalent interfaces to use */ @@ -295,13 +295,13 @@ typedef struct lnet_ni { /* router checker data, per router */ #define LNET_MAX_RTR_NIS 16 -#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS]) +#define LNET_PINGINFO_SIZE offsetof(struct lnet_ping_info, pi_ni[LNET_MAX_RTR_NIS]) typedef struct { /* chain on the_lnet.ln_zombie_rcd or ln_deathrow_rcd */ struct list_head rcd_list; lnet_handle_md_t rcd_mdh; /* ping buffer MD */ struct lnet_peer *rcd_gateway; /* reference to gateway */ - lnet_ping_info_t *rcd_pinginfo; /* ping buffer */ + struct lnet_ping_info *rcd_pinginfo; /* ping buffer */ } lnet_rc_data_t; typedef struct lnet_peer { @@ -599,7 +599,7 @@ typedef struct { lnet_handle_md_t ln_ping_target_md; lnet_handle_eq_t ln_ping_target_eq; - lnet_ping_info_t *ln_ping_info; + struct lnet_ping_info *ln_ping_info; /* router checker startup/shutdown state */ int ln_rc_state; diff --git a/drivers/staging/lustre/include/linux/lnet/lnetst.h b/drivers/staging/lustre/include/linux/lnet/lnetst.h index 8a84888635ff..c81c246ef221 100644 --- a/drivers/staging/lustre/include/linux/lnet/lnetst.h +++ b/drivers/staging/lustre/include/linux/lnet/lnetst.h @@ -68,16 +68,16 @@ #define LSTIO_BATCH_QUERY 0xC27 /* query batch status */ #define LSTIO_STAT_QUERY 0xC30 /* get stats */ -typedef struct { +struct lst_sid { lnet_nid_t ses_nid; /* nid of console node */ __u64 ses_stamp; /* time stamp */ -} lst_sid_t; /*** session id */ +}; /*** session id */ -extern lst_sid_t LST_INVALID_SID; +extern struct lst_sid LST_INVALID_SID; -typedef struct { +struct lst_bid { __u64 bat_id; /* unique id in session */ -} lst_bid_t; /*** batch id (group of tests) */ +}; /*** batch id (group of tests) */ /* Status of test node */ #define LST_NODE_ACTIVE 0x1 /* node in this session */ @@ -85,59 +85,59 @@ typedef struct { #define LST_NODE_DOWN 0x4 /* node is down */ #define LST_NODE_UNKNOWN 0x8 /* node not in session */ -typedef struct { +struct lstcon_node_ent { lnet_process_id_t nde_id; /* id of node */ int nde_state; /* state of node */ -} lstcon_node_ent_t; /*** node entry, for list_group command */ +}; /*** node entry, for list_group command */ -typedef struct { +struct lstcon_ndlist_ent { int nle_nnode; /* # of nodes */ int nle_nactive; /* # of active nodes */ int nle_nbusy; /* # of busy nodes */ int nle_ndown; /* # of down nodes */ int nle_nunknown; /* # of unknown nodes */ -} lstcon_ndlist_ent_t; /*** node_list entry, for list_batch command */ +}; /*** node_list entry, for list_batch command */ -typedef struct { +struct lstcon_test_ent { int tse_type; /* test type */ int tse_loop; /* loop count */ int tse_concur; /* concurrency of test */ -} lstcon_test_ent_t; /*** test summary entry, for +}; /*** test summary entry, for *** list_batch command */ -typedef struct { +struct lstcon_batch_ent { int bae_state; /* batch status */ int bae_timeout; /* batch timeout */ int bae_ntest; /* # of tests in the batch */ -} lstcon_batch_ent_t; /*** batch summary entry, for +}; /*** batch summary entry, for *** list_batch command */ -typedef struct { - lstcon_ndlist_ent_t tbe_cli_nle; /* client (group) node_list +struct lstcon_test_batch_ent { + struct lstcon_ndlist_ent tbe_cli_nle; /* client (group) node_list * entry */ - lstcon_ndlist_ent_t tbe_srv_nle; /* server (group) node_list + struct lstcon_ndlist_ent tbe_srv_nle; /* server (group) node_list * entry */ union { - lstcon_test_ent_t tbe_test; /* test entry */ - lstcon_batch_ent_t tbe_batch; /* batch entry */ + struct lstcon_test_ent tbe_test; /* test entry */ + struct lstcon_batch_ent tbe_batch;/* batch entry */ } u; -} lstcon_test_batch_ent_t; /*** test/batch verbose information entry, +}; /*** test/batch verbose information entry, *** for list_batch command */ -typedef struct { +struct lstcon_rpc_ent { struct list_head rpe_link; /* link chain */ lnet_process_id_t rpe_peer; /* peer's id */ struct timeval rpe_stamp; /* time stamp of RPC */ int rpe_state; /* peer's state */ int rpe_rpc_errno; /* RPC errno */ - lst_sid_t rpe_sid; /* peer's session id */ + struct lst_sid rpe_sid; /* peer's session id */ int rpe_fwk_errno; /* framework errno */ int rpe_priv[4]; /* private data */ char rpe_payload[0]; /* private reply payload */ -} lstcon_rpc_ent_t; +}; -typedef struct { +struct lstcon_trans_stat { int trs_rpc_stat[4]; /* RPCs stat (0: total 1: failed 2: finished @@ -146,125 +146,125 @@ typedef struct { int trs_fwk_stat[8]; /* framework stat */ int trs_fwk_errno; /* errno of the first remote error */ void *trs_fwk_private; /* private framework stat */ -} lstcon_trans_stat_t; +}; static inline int -lstcon_rpc_stat_total(lstcon_trans_stat_t *stat, int inc) +lstcon_rpc_stat_total(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_rpc_stat[0] : stat->trs_rpc_stat[0]; } static inline int -lstcon_rpc_stat_success(lstcon_trans_stat_t *stat, int inc) +lstcon_rpc_stat_success(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_rpc_stat[1] : stat->trs_rpc_stat[1]; } static inline int -lstcon_rpc_stat_failure(lstcon_trans_stat_t *stat, int inc) +lstcon_rpc_stat_failure(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_rpc_stat[2] : stat->trs_rpc_stat[2]; } static inline int -lstcon_sesop_stat_success(lstcon_trans_stat_t *stat, int inc) +lstcon_sesop_stat_success(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0]; } static inline int -lstcon_sesop_stat_failure(lstcon_trans_stat_t *stat, int inc) +lstcon_sesop_stat_failure(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1]; } static inline int -lstcon_sesqry_stat_active(lstcon_trans_stat_t *stat, int inc) +lstcon_sesqry_stat_active(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0]; } static inline int -lstcon_sesqry_stat_busy(lstcon_trans_stat_t *stat, int inc) +lstcon_sesqry_stat_busy(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1]; } static inline int -lstcon_sesqry_stat_unknown(lstcon_trans_stat_t *stat, int inc) +lstcon_sesqry_stat_unknown(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2]; } static inline int -lstcon_tsbop_stat_success(lstcon_trans_stat_t *stat, int inc) +lstcon_tsbop_stat_success(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0]; } static inline int -lstcon_tsbop_stat_failure(lstcon_trans_stat_t *stat, int inc) +lstcon_tsbop_stat_failure(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1]; } static inline int -lstcon_tsbqry_stat_idle(lstcon_trans_stat_t *stat, int inc) +lstcon_tsbqry_stat_idle(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0]; } static inline int -lstcon_tsbqry_stat_run(lstcon_trans_stat_t *stat, int inc) +lstcon_tsbqry_stat_run(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1]; } static inline int -lstcon_tsbqry_stat_failure(lstcon_trans_stat_t *stat, int inc) +lstcon_tsbqry_stat_failure(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2]; } static inline int -lstcon_statqry_stat_success(lstcon_trans_stat_t *stat, int inc) +lstcon_statqry_stat_success(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0]; } static inline int -lstcon_statqry_stat_failure(lstcon_trans_stat_t *stat, int inc) +lstcon_statqry_stat_failure(struct lstcon_trans_stat *stat, int inc) { return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1]; } /* create a session */ -typedef struct { +struct lstio_session_new_args { int lstio_ses_key; /* IN: local key */ int lstio_ses_timeout; /* IN: session timeout */ int lstio_ses_force; /* IN: force create ? */ /** IN: session features */ unsigned int lstio_ses_feats; - lst_sid_t __user *lstio_ses_idp; /* OUT: session id */ + struct lst_sid __user *lstio_ses_idp; /* OUT: session id */ int lstio_ses_nmlen; /* IN: name length */ char __user *lstio_ses_namep; /* IN: session name */ -} lstio_session_new_args_t; +}; /* query current session */ -typedef struct { - lst_sid_t __user *lstio_ses_idp; /* OUT: session id */ +struct lstio_session_info_args { + struct lst_sid __user *lstio_ses_idp; /* OUT: session id */ int __user *lstio_ses_keyp; /* OUT: local key */ /** OUT: session features */ unsigned int __user *lstio_ses_featp; - lstcon_ndlist_ent_t __user *lstio_ses_ndinfo; /* OUT: */ + struct lstcon_ndlist_ent __user *lstio_ses_ndinfo;/* OUT: */ int lstio_ses_nmlen; /* IN: name length */ char __user *lstio_ses_namep; /* OUT: session name */ -} lstio_session_info_args_t; +}; /* delete a session */ -typedef struct { +struct lstio_session_end_args { int lstio_ses_key; /* IN: session key */ -} lstio_session_end_args_t; +}; #define LST_OPC_SESSION 1 #define LST_OPC_GROUP 2 @@ -272,7 +272,7 @@ typedef struct { #define LST_OPC_BATCHCLI 4 #define LST_OPC_BATCHSRV 5 -typedef struct { +struct lstio_debug_args { int lstio_dbg_key; /* IN: session key */ int lstio_dbg_type; /* IN: debug session|batch| @@ -291,26 +291,26 @@ typedef struct { nodes */ struct list_head __user *lstio_dbg_resultp; /* OUT: list head of result buffer */ -} lstio_debug_args_t; +}; -typedef struct { +struct lstio_group_add_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_nmlen; /* IN: name length */ char __user *lstio_grp_namep; /* IN: group name */ -} lstio_group_add_args_t; +}; -typedef struct { +struct lstio_group_del_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_nmlen; /* IN: name length */ char __user *lstio_grp_namep; /* IN: group name */ -} lstio_group_del_args_t; +}; #define LST_GROUP_CLEAN 1 /* remove inactive nodes in the group */ #define LST_GROUP_REFRESH 2 /* refresh inactive nodes * in the group */ #define LST_GROUP_RMND 3 /* delete nodes from the group */ -typedef struct { +struct lstio_group_update_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_opc; /* IN: OPC */ int lstio_grp_args; /* IN: arguments */ @@ -320,9 +320,9 @@ typedef struct { lnet_process_id_t __user *lstio_grp_idsp; /* IN: array of nodes */ struct list_head __user *lstio_grp_resultp; /* OUT: list head of result buffer */ -} lstio_group_update_args_t; +}; -typedef struct { +struct lstio_group_nodes_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_nmlen; /* IN: name length */ char __user *lstio_grp_namep; /* IN: group name */ @@ -332,41 +332,41 @@ typedef struct { lnet_process_id_t __user *lstio_grp_idsp; /* IN: nodes */ struct list_head __user *lstio_grp_resultp; /* OUT: list head of result buffer */ -} lstio_group_nodes_args_t; +}; -typedef struct { +struct lstio_group_list_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_idx; /* IN: group idx */ int lstio_grp_nmlen; /* IN: name len */ char __user *lstio_grp_namep; /* OUT: name */ -} lstio_group_list_args_t; +}; -typedef struct { +struct lstio_group_info_args { int lstio_grp_key; /* IN: session key */ int lstio_grp_nmlen; /* IN: name len */ char __user *lstio_grp_namep; /* IN: name */ - lstcon_ndlist_ent_t __user *lstio_grp_entp; /* OUT: description of - group */ + struct lstcon_ndlist_ent __user *lstio_grp_entp;/* OUT: description of + group */ int __user *lstio_grp_idxp; /* IN/OUT: node index */ int __user *lstio_grp_ndentp; /* IN/OUT: # of nodent */ - lstcon_node_ent_t __user *lstio_grp_dentsp; /* OUT: nodent array */ -} lstio_group_info_args_t; + struct lstcon_node_ent __user *lstio_grp_dentsp;/* OUT: nodent array */ +}; #define LST_DEFAULT_BATCH "batch" /* default batch name */ -typedef struct { +struct lstio_batch_add_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_nmlen; /* IN: name length */ char __user *lstio_bat_namep; /* IN: batch name */ -} lstio_batch_add_args_t; +}; -typedef struct { +struct lstio_batch_del_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_nmlen; /* IN: name length */ char __user *lstio_bat_namep; /* IN: batch name */ -} lstio_batch_del_args_t; +}; -typedef struct { +struct lstio_batch_run_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_timeout; /* IN: timeout for the batch */ @@ -374,9 +374,9 @@ typedef struct { char __user *lstio_bat_namep; /* IN: batch name */ struct list_head __user *lstio_bat_resultp; /* OUT: list head of result buffer */ -} lstio_batch_run_args_t; +}; -typedef struct { +struct lstio_batch_stop_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_force; /* IN: abort unfinished test RPC */ @@ -384,9 +384,9 @@ typedef struct { char __user *lstio_bat_namep; /* IN: batch name */ struct list_head __user *lstio_bat_resultp; /* OUT: list head of result buffer */ -} lstio_batch_stop_args_t; +}; -typedef struct { +struct lstio_batch_query_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_testidx; /* IN: test index */ int lstio_bat_client; /* IN: we testing @@ -397,31 +397,31 @@ typedef struct { char __user *lstio_bat_namep; /* IN: batch name */ struct list_head __user *lstio_bat_resultp; /* OUT: list head of result buffer */ -} lstio_batch_query_args_t; +}; -typedef struct { +struct lstio_batch_list_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_idx; /* IN: index */ int lstio_bat_nmlen; /* IN: name length */ char __user *lstio_bat_namep; /* IN: batch name */ -} lstio_batch_list_args_t; +}; -typedef struct { +struct lstio_batch_info_args { int lstio_bat_key; /* IN: session key */ int lstio_bat_nmlen; /* IN: name length */ char __user *lstio_bat_namep; /* IN: name */ int lstio_bat_server; /* IN: query server or not */ int lstio_bat_testidx; /* IN: test index */ - lstcon_test_batch_ent_t __user *lstio_bat_entp; /* OUT: batch ent */ + struct lstcon_test_batch_ent __user *lstio_bat_entp;/* OUT: batch ent */ int __user *lstio_bat_idxp; /* IN/OUT: index of node */ int __user *lstio_bat_ndentp; /* IN/OUT: # of nodent */ - lstcon_node_ent_t __user *lstio_bat_dentsp; /* array of nodent */ -} lstio_batch_info_args_t; + struct lstcon_node_ent __user *lstio_bat_dentsp;/* array of nodent */ +}; /* add stat in session */ -typedef struct { +struct lstio_stat_args { int lstio_sta_key; /* IN: session key */ int lstio_sta_timeout; /* IN: timeout for stat request */ @@ -432,17 +432,17 @@ typedef struct { lnet_process_id_t __user *lstio_sta_idsp; /* IN: pid */ struct list_head __user *lstio_sta_resultp; /* OUT: list head of result buffer */ -} lstio_stat_args_t; +}; -typedef enum { +enum lst_test_type { LST_TEST_BULK = 1, LST_TEST_PING = 2 -} lst_test_type_t; +}; /* create a test in a batch */ #define LST_MAX_CONCUR 1024 /* Max concurrency of test */ -typedef struct { +struct lstio_test_args { int lstio_tes_key; /* IN: session key */ int lstio_tes_bat_nmlen; /* IN: batch name len */ char __user *lstio_tes_bat_name; /* IN: batch name */ @@ -472,36 +472,36 @@ typedef struct { value */ struct list_head __user *lstio_tes_resultp;/* OUT: list head of result buffer */ -} lstio_test_args_t; +}; -typedef enum { +enum lst_brw_type { LST_BRW_READ = 1, LST_BRW_WRITE = 2 -} lst_brw_type_t; +}; -typedef enum { +enum lst_brw_flags { LST_BRW_CHECK_NONE = 1, LST_BRW_CHECK_SIMPLE = 2, LST_BRW_CHECK_FULL = 3 -} lst_brw_flags_t; +}; -typedef struct { +struct lst_test_bulk_param { int blk_opc; /* bulk operation code */ int blk_size; /* size (bytes) */ int blk_time; /* time of running the test*/ int blk_flags; /* reserved flags */ int blk_cli_off; /* bulk offset on client */ int blk_srv_off; /* reserved: bulk offset on server */ -} lst_test_bulk_param_t; +}; -typedef struct { +struct lst_test_ping_param { int png_size; /* size of ping message */ int png_time; /* time */ int png_loop; /* loop */ int png_flags; /* reserved flags */ -} lst_test_ping_param_t; +}; -typedef struct { +struct srpc_counters { __u32 errors; __u32 rpcs_sent; __u32 rpcs_rcvd; @@ -509,15 +509,15 @@ typedef struct { __u32 rpcs_expired; __u64 bulk_get; __u64 bulk_put; -} WIRE_ATTR srpc_counters_t; +} WIRE_ATTR; -typedef struct { +struct sfw_counters { /** milliseconds since current session started */ __u32 running_ms; __u32 active_batches; __u32 zombie_sessions; __u32 brw_errors; __u32 ping_errors; -} WIRE_ATTR sfw_counters_t; +} WIRE_ATTR; #endif diff --git a/drivers/staging/lustre/include/linux/lnet/socklnd.h b/drivers/staging/lustre/include/linux/lnet/socklnd.h index bc32403f4a08..acf20ce6f403 100644 --- a/drivers/staging/lustre/include/linux/lnet/socklnd.h +++ b/drivers/staging/lustre/include/linux/lnet/socklnd.h @@ -60,7 +60,7 @@ typedef struct { } WIRE_ATTR ksock_hello_msg_t; typedef struct { - lnet_hdr_t ksnm_hdr; /* lnet hdr */ + struct lnet_hdr ksnm_hdr; /* lnet hdr */ /* * ksnm_payload is removed because of winnt compiler's limitation: @@ -80,15 +80,6 @@ typedef struct { } WIRE_ATTR ksm_u; } WIRE_ATTR ksock_msg_t; -static inline void -socklnd_init_msg(ksock_msg_t *msg, int type) -{ - msg->ksm_csum = 0; - msg->ksm_type = type; - msg->ksm_zc_cookies[0] = 0; - msg->ksm_zc_cookies[1] = 0; -} - #define KSOCK_MSG_NOOP 0xC0 /* ksm_u empty */ #define KSOCK_MSG_LNET 0xC1 /* lnet msg */ diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h index 8ca1e9d0cfe2..1c8de72e6d6b 100644 --- a/drivers/staging/lustre/include/linux/lnet/types.h +++ b/drivers/staging/lustre/include/linux/lnet/types.h @@ -115,11 +115,11 @@ static inline __u32 LNET_MKNET(__u32 type, __u32 num) #define WIRE_ATTR __packed /* Packed version of lnet_process_id_t to transfer via network */ -typedef struct { +struct lnet_process_id_packed { /* node id / process id */ lnet_nid_t nid; lnet_pid_t pid; -} WIRE_ATTR lnet_process_id_packed_t; +} WIRE_ATTR; /* * The wire handle's interface cookie only matches one network interface in @@ -127,10 +127,10 @@ typedef struct { * reboots). The object cookie only matches one object on that interface * during that object's lifetime (i.e. no cookie re-use). */ -typedef struct { +struct lnet_handle_wire { __u64 wh_interface_cookie; __u64 wh_object_cookie; -} WIRE_ATTR lnet_handle_wire_t; +} WIRE_ATTR; typedef enum { LNET_MSG_ACK = 0, @@ -146,38 +146,38 @@ typedef enum { * wire structs MUST be fixed size and the smaller types are placed at the * end. */ -typedef struct lnet_ack { - lnet_handle_wire_t dst_wmd; +struct lnet_ack { + struct lnet_handle_wire dst_wmd; __u64 match_bits; __u32 mlength; -} WIRE_ATTR lnet_ack_t; +} WIRE_ATTR; -typedef struct lnet_put { - lnet_handle_wire_t ack_wmd; +struct lnet_put { + struct lnet_handle_wire ack_wmd; __u64 match_bits; __u64 hdr_data; __u32 ptl_index; __u32 offset; -} WIRE_ATTR lnet_put_t; +} WIRE_ATTR; -typedef struct lnet_get { - lnet_handle_wire_t return_wmd; +struct lnet_get { + struct lnet_handle_wire return_wmd; __u64 match_bits; __u32 ptl_index; __u32 src_offset; __u32 sink_length; -} WIRE_ATTR lnet_get_t; +} WIRE_ATTR; -typedef struct lnet_reply { - lnet_handle_wire_t dst_wmd; -} WIRE_ATTR lnet_reply_t; +struct lnet_reply { + struct lnet_handle_wire dst_wmd; +} WIRE_ATTR; -typedef struct lnet_hello { +struct lnet_hello { __u64 incarnation; __u32 type; -} WIRE_ATTR lnet_hello_t; +} WIRE_ATTR; -typedef struct { +struct lnet_hdr { lnet_nid_t dest_nid; lnet_nid_t src_nid; lnet_pid_t dest_pid; @@ -186,13 +186,13 @@ typedef struct { __u32 payload_length; /* payload data to follow */ /*<------__u64 aligned------->*/ union { - lnet_ack_t ack; - lnet_put_t put; - lnet_get_t get; - lnet_reply_t reply; - lnet_hello_t hello; + struct lnet_ack ack; + struct lnet_put put; + struct lnet_get get; + struct lnet_reply reply; + struct lnet_hello hello; } msg; -} WIRE_ATTR lnet_hdr_t; +} WIRE_ATTR; /* * A HELLO message contains a magic number and protocol version @@ -202,13 +202,13 @@ typedef struct { * This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is * running the same protocol and to find out its NID. These LNDs should * exchange HELLO messages when a connection is first established. Individual - * LNDs can put whatever else they fancy in lnet_hdr_t::msg. + * LNDs can put whatever else they fancy in struct lnet_hdr::msg. */ -typedef struct { +struct lnet_magicversion { __u32 magic; /* LNET_PROTO_TCP_MAGIC */ __u16 version_major; /* increment on incompatible change */ __u16 version_minor; /* increment on compatible change */ -} WIRE_ATTR lnet_magicversion_t; +} WIRE_ATTR; /* PROTO MAGIC for LNDs */ #define LNET_PROTO_IB_MAGIC 0x0be91b91 @@ -228,27 +228,27 @@ typedef struct { #define LNET_PROTO_TCP_VERSION_MINOR 0 /* Acceptor connection request */ -typedef struct { +struct lnet_acceptor_connreq { __u32 acr_magic; /* PTL_ACCEPTOR_PROTO_MAGIC */ __u32 acr_version; /* protocol version */ __u64 acr_nid; /* target NID */ -} WIRE_ATTR lnet_acceptor_connreq_t; +} WIRE_ATTR; #define LNET_PROTO_ACCEPTOR_VERSION 1 -typedef struct { +struct lnet_ni_status { lnet_nid_t ns_nid; __u32 ns_status; __u32 ns_unused; -} WIRE_ATTR lnet_ni_status_t; +} WIRE_ATTR; -typedef struct { +struct lnet_ping_info { __u32 pi_magic; __u32 pi_features; lnet_pid_t pi_pid; __u32 pi_nnis; - lnet_ni_status_t pi_ni[0]; -} WIRE_ATTR lnet_ping_info_t; + struct lnet_ni_status pi_ni[0]; +} WIRE_ATTR; typedef struct lnet_counters { __u32 msgs_alloc; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 7f761b327166..b1e8508f9fc7 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -258,8 +258,8 @@ int kiblnd_unpack_msg(struct kib_msg *msg, int nob) if (flip) { /* leave magic unflipped as a clue to peer endianness */ msg->ibm_version = version; - CLASSERT(sizeof(msg->ibm_type) == 1); - CLASSERT(sizeof(msg->ibm_credits) == 1); + BUILD_BUG_ON(sizeof(msg->ibm_type) != 1); + BUILD_BUG_ON(sizeof(msg->ibm_credits) != 1); msg->ibm_nob = msg_nob; __swab64s(&msg->ibm_srcnid); __swab64s(&msg->ibm_srcstamp); @@ -1247,10 +1247,10 @@ static void kiblnd_map_tx_pool(struct kib_tx_pool *tpo) dev = net->ibn_dev; /* pre-mapped messages are not bigger than 1 page */ - CLASSERT(IBLND_MSG_SIZE <= PAGE_SIZE); + BUILD_BUG_ON(IBLND_MSG_SIZE > PAGE_SIZE); /* No fancy arithmetic when we do the buffer calculations */ - CLASSERT(!(PAGE_SIZE % IBLND_MSG_SIZE)); + BUILD_BUG_ON(PAGE_SIZE % IBLND_MSG_SIZE); tpo->tpo_hdev = kiblnd_current_hdev(dev); @@ -2943,7 +2943,7 @@ static int kiblnd_startup(lnet_ni_t *ni) if (ni->ni_interfaces[0]) { /* Use the IPoIB interface specified in 'networks=' */ - CLASSERT(LNET_MAX_INTERFACES > 1); + BUILD_BUG_ON(LNET_MAX_INTERFACES <= 1); if (ni->ni_interfaces[1]) { CERROR("Multiple interfaces not supported\n"); goto failed; @@ -3020,11 +3020,11 @@ static void __exit ko2iblnd_exit(void) static int __init ko2iblnd_init(void) { - CLASSERT(sizeof(struct kib_msg) <= IBLND_MSG_SIZE); - CLASSERT(offsetof(struct kib_msg, + BUILD_BUG_ON(sizeof(struct kib_msg) > IBLND_MSG_SIZE); + BUILD_BUG_ON(!offsetof(struct kib_msg, ibm_u.get.ibgm_rd.rd_frags[IBLND_MAX_RDMA_FRAGS]) <= IBLND_MSG_SIZE); - CLASSERT(offsetof(struct kib_msg, + BUILD_BUG_ON(!offsetof(struct kib_msg, ibm_u.putack.ibpam_rd.rd_frags[IBLND_MAX_RDMA_FRAGS]) <= IBLND_MSG_SIZE); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 14576977200f..2cb429830681 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -364,7 +364,7 @@ struct kib_connparams { } WIRE_ATTR; struct kib_immediate_msg { - lnet_hdr_t ibim_hdr; /* portals header */ + struct lnet_hdr ibim_hdr; /* portals header */ char ibim_payload[0]; /* piggy-backed payload */ } WIRE_ATTR; @@ -380,7 +380,7 @@ struct kib_rdma_desc { } WIRE_ATTR; struct kib_putreq_msg { - lnet_hdr_t ibprm_hdr; /* portals header */ + struct lnet_hdr ibprm_hdr; /* portals header */ __u64 ibprm_cookie; /* opaque completion cookie */ } WIRE_ATTR; @@ -391,7 +391,7 @@ struct kib_putack_msg { } WIRE_ATTR; struct kib_get_msg { - lnet_hdr_t ibgm_hdr; /* portals header */ + struct lnet_hdr ibgm_hdr; /* portals header */ __u64 ibgm_cookie; /* opaque completion cookie */ struct kib_rdma_desc ibgm_rd; /* rdma descriptor */ } WIRE_ATTR; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index c7917abf9944..e2f3f7294260 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1490,7 +1490,7 @@ kiblnd_launch_tx(lnet_ni_t *ni, struct kib_tx *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; + struct lnet_hdr *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; @@ -3546,7 +3546,7 @@ kiblnd_scheduler(void *arg) rc = cfs_cpt_bind(lnet_cpt_table(), sched->ibs_cpt); if (rc) { - CWARN("Failed to bind on CPT %d, please verify whether all CPUs are healthy and reload modules if necessary, otherwise your system might under risk of low performance\n", + CWARN("Unable to bind on CPU partition %d, please verify whether all CPUs are healthy and reload modules if necessary, otherwise your system might under risk of low performance\n", sched->ibs_cpt); } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index b74cf635faee..f25de3d7f6e8 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -1108,12 +1108,12 @@ ksocknal_create_conn(lnet_ni_t *ni, struct ksock_route *route, write_unlock_bh(global_lock); if (!conn->ksnc_proto) { - conn->ksnc_proto = &ksocknal_protocol_v3x; + conn->ksnc_proto = &ksocknal_protocol_v3x; #if SOCKNAL_VERSION_DEBUG - if (*ksocknal_tunables.ksnd_protocol == 2) - conn->ksnc_proto = &ksocknal_protocol_v2x; - else if (*ksocknal_tunables.ksnd_protocol == 1) - conn->ksnc_proto = &ksocknal_protocol_v1x; + if (*ksocknal_tunables.ksnd_protocol == 2) + conn->ksnc_proto = &ksocknal_protocol_v2x; + else if (*ksocknal_tunables.ksnd_protocol == 1) + conn->ksnc_proto = &ksocknal_protocol_v1x; #endif } @@ -2507,7 +2507,7 @@ ksocknal_base_startup(void) snprintf(name, sizeof(name), "socknal_cd%02d", i); rc = ksocknal_thread_start(ksocknal_connd, - (void *)((ulong_ptr_t)i), name); + (void *)((uintptr_t)i), name); if (rc) { spin_lock_bh(&ksocknal_data.ksnd_connd_lock); ksocknal_data.ksnd_connd_starting--; @@ -2904,8 +2904,8 @@ static int __init ksocklnd_init(void) int rc; /* check ksnr_connected/connecting field large enough */ - CLASSERT(SOCKLND_CONN_NTYPES <= 4); - CLASSERT(SOCKLND_CONN_ACK == SOCKLND_CONN_BULK_IN); + BUILD_BUG_ON(SOCKLND_CONN_NTYPES > 4); + BUILD_BUG_ON(SOCKLND_CONN_ACK != SOCKLND_CONN_BULK_IN); /* initialize the_ksocklnd */ the_ksocklnd.lnd_type = SOCKLND; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index 842c45393b38..9e86563b8c70 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -373,7 +373,7 @@ struct ksock_conn { * V2.x message takes the * whole struct * V1.x message is a bare - * lnet_hdr_t, it's stored in + * struct lnet_hdr, it's stored in * ksnc_msg.ksm_u.lnetmsg */ /* WRITER */ diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 972f6094be75..4c9f92725a44 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -80,7 +80,9 @@ ksocknal_alloc_tx_noop(__u64 cookie, int nonblk) tx->tx_niov = 1; tx->tx_nonblk = nonblk; - socklnd_init_msg(&tx->tx_msg, KSOCK_MSG_NOOP); + tx->tx_msg.ksm_csum = 0; + tx->tx_msg.ksm_type = KSOCK_MSG_NOOP; + tx->tx_msg.ksm_zc_cookies[0] = 0; tx->tx_msg.ksm_zc_cookies[1] = cookie; return tx; @@ -1004,7 +1006,10 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) tx->tx_zc_capable = 1; } - socklnd_init_msg(&tx->tx_msg, KSOCK_MSG_LNET); + tx->tx_msg.ksm_csum = 0; + tx->tx_msg.ksm_type = KSOCK_MSG_LNET; + tx->tx_msg.ksm_zc_cookies[0] = 0; + tx->tx_msg.ksm_zc_cookies[1] = 0; /* The first fragment will be set later in pro_pack */ rc = ksocknal_launch_packet(ni, tx, target); @@ -1073,14 +1078,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip) break; case KSOCK_PROTO_V1: - /* Receiving bare lnet_hdr_t */ + /* Receiving bare struct lnet_hdr */ conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER; - conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t); - conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t); + conn->ksnc_rx_nob_wanted = sizeof(struct lnet_hdr); + conn->ksnc_rx_nob_left = sizeof(struct lnet_hdr); 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(struct lnet_hdr); break; default: @@ -1126,7 +1131,7 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip) static int ksocknal_process_receive(struct ksock_conn *conn) { - lnet_hdr_t *lhdr; + struct lnet_hdr *lhdr; lnet_process_id_t *id; int rc; @@ -1414,8 +1419,8 @@ int ksocknal_scheduler(void *arg) rc = cfs_cpt_bind(lnet_cpt_table(), info->ksi_cpt); if (rc) { - CERROR("Can't set CPT affinity to %d: %d\n", - info->ksi_cpt, rc); + CWARN("Can't set CPU partition affinity to %d: %d\n", + info->ksi_cpt, rc); } spin_lock_bh(&sched->kss_lock); @@ -1656,9 +1661,9 @@ 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; + struct lnet_magicversion *hmv = (struct lnet_magicversion *)hello; - CLASSERT(sizeof(lnet_magicversion_t) == + BUILD_BUG_ON(sizeof(struct lnet_magicversion) != offsetof(ksock_hello_msg_t, kshm_src_nid)); if (hmv->version_major == cpu_to_le16(KSOCK_PROTO_V1_MAJOR) && @@ -2456,6 +2461,7 @@ ksocknal_check_peer_timeouts(int idx) list_for_each_entry(peer, peers, ksnp_list) { unsigned long deadline = 0; + struct ksock_tx *tx_stale; int resid = 0; int n = 0; @@ -2503,6 +2509,7 @@ ksocknal_check_peer_timeouts(int idx) if (list_empty(&peer->ksnp_zc_req_list)) continue; + tx_stale = NULL; spin_lock(&peer->ksnp_lock); list_for_each_entry(tx, &peer->ksnp_zc_req_list, tx_zc_list) { if (!cfs_time_aftereq(cfs_time_current(), @@ -2511,26 +2518,26 @@ ksocknal_check_peer_timeouts(int idx) /* ignore the TX if connection is being closed */ if (tx->tx_conn->ksnc_closing) continue; + if (!tx_stale) + tx_stale = tx; n++; } - if (!n) { + if (!tx_stale) { spin_unlock(&peer->ksnp_lock); continue; } - tx = list_entry(peer->ksnp_zc_req_list.next, - struct ksock_tx, tx_zc_list); - deadline = tx->tx_deadline; - resid = tx->tx_resid; - conn = tx->tx_conn; + deadline = tx_stale->tx_deadline; + resid = tx_stale->tx_resid; + conn = tx_stale->tx_conn; ksocknal_conn_addref(conn); spin_unlock(&peer->ksnp_lock); read_unlock(&ksocknal_data.ksnd_global_lock); CERROR("Total %d stale ZC_REQs for peer %s detected; the oldest(%p) timed out %ld secs ago, resid: %d, wmem: %d\n", - n, libcfs_nid2str(peer->ksnp_id.nid), tx, + n, libcfs_nid2str(peer->ksnp_id.nid), tx_stale, cfs_duration_sec(cfs_time_current() - deadline), resid, conn->ksnc_sock->sk->sk_wmem_queued); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index 8f0ff6ca1f39..d367e74d46c2 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -291,7 +291,7 @@ ksocknal_match_tx(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk) } else { nob = tx->tx_lnetmsg->msg_len + ((conn->ksnc_proto == &ksocknal_protocol_v1x) ? - sizeof(lnet_hdr_t) : sizeof(ksock_msg_t)); + sizeof(struct lnet_hdr) : sizeof(ksock_msg_t)); } /* default checking for typed connection */ @@ -459,23 +459,23 @@ static int ksocknal_send_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello) { struct socket *sock = conn->ksnc_sock; - lnet_hdr_t *hdr; - lnet_magicversion_t *hmv; + struct lnet_hdr *hdr; + struct lnet_magicversion *hmv; int rc; int i; - CLASSERT(sizeof(lnet_magicversion_t) == offsetof(lnet_hdr_t, src_nid)); + BUILD_BUG_ON(sizeof(struct lnet_magicversion) != offsetof(struct lnet_hdr, src_nid)); LIBCFS_ALLOC(hdr, sizeof(*hdr)); if (!hdr) { - CERROR("Can't allocate lnet_hdr_t\n"); + CERROR("Can't allocate struct lnet_hdr\n"); return -ENOMEM; } - hmv = (lnet_magicversion_t *)&hdr->dest_nid; + hmv = (struct lnet_magicversion *)&hdr->dest_nid; /* - * Re-organize V2.x message header to V1.x (lnet_hdr_t) + * Re-organize V2.x message header to V1.x (struct lnet_hdr) * header and send out */ hmv->magic = cpu_to_le32(LNET_PROTO_TCP_MAGIC); @@ -577,18 +577,18 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello, int timeout) { struct socket *sock = conn->ksnc_sock; - lnet_hdr_t *hdr; + struct lnet_hdr *hdr; int rc; int i; LIBCFS_ALLOC(hdr, sizeof(*hdr)); if (!hdr) { - CERROR("Can't allocate lnet_hdr_t\n"); + CERROR("Can't allocate struct lnet_hdr\n"); return -ENOMEM; } rc = lnet_sock_read(sock, &hdr->src_nid, - sizeof(*hdr) - offsetof(lnet_hdr_t, src_nid), + sizeof(*hdr) - offsetof(struct lnet_hdr, src_nid), timeout); if (rc) { CERROR("Error %d reading rest of HELLO hdr from %pI4h\n", @@ -723,10 +723,10 @@ ksocknal_pack_msg_v1(struct ksock_tx *tx) LASSERT(tx->tx_lnetmsg); tx->tx_iov[0].iov_base = &tx->tx_lnetmsg->msg_hdr; - tx->tx_iov[0].iov_len = sizeof(lnet_hdr_t); + tx->tx_iov[0].iov_len = sizeof(struct lnet_hdr); - tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t); - tx->tx_resid = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t); + tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(struct lnet_hdr); + tx->tx_resid = tx->tx_lnetmsg->msg_len + sizeof(struct lnet_hdr); } static void diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c index a38db2322225..3408041355e3 100644 --- a/drivers/staging/lustre/lnet/libcfs/debug.c +++ b/drivers/staging/lustre/lnet/libcfs/debug.c @@ -343,7 +343,7 @@ void libcfs_debug_dumplog_internal(void *arg) last_dump_time = current_time; snprintf(debug_file_name, sizeof(debug_file_name) - 1, "%s.%lld.%ld", libcfs_debug_file_path_arr, - (s64)current_time, (long_ptr_t)arg); + (s64)current_time, (long)arg); pr_alert("LustreError: dumping log to %s\n", debug_file_name); cfs_tracefile_dump_all_pages(debug_file_name); libcfs_run_debug_log_upcall(debug_file_name); diff --git a/drivers/staging/lustre/lnet/libcfs/hash.c b/drivers/staging/lustre/lnet/libcfs/hash.c index c93c59d8fe6c..5c2ce2ee6fd9 100644 --- a/drivers/staging/lustre/lnet/libcfs/hash.c +++ b/drivers/staging/lustre/lnet/libcfs/hash.c @@ -1000,7 +1000,7 @@ cfs_hash_create(char *name, unsigned int cur_bits, unsigned int max_bits, struct cfs_hash *hs; int len; - CLASSERT(CFS_HASH_THETA_BITS < 15); + BUILD_BUG_ON(CFS_HASH_THETA_BITS >= 15); LASSERT(name); LASSERT(ops->hs_key); diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c index 427e2198bb9e..4d35a371216c 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c @@ -59,7 +59,7 @@ MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions"); * * NB: If user specified cpu_pattern, cpu_npartitions will be ignored */ -static char *cpu_pattern = ""; +static char *cpu_pattern = "N"; module_param(cpu_pattern, charp, 0444); MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern"); @@ -1050,7 +1050,15 @@ cfs_cpu_init(void) ret = -EINVAL; if (*cpu_pattern) { - cfs_cpt_table = cfs_cpt_table_create_pattern(cpu_pattern); + char *cpu_pattern_dup = kstrdup(cpu_pattern, GFP_KERNEL); + + if (!cpu_pattern_dup) { + CERROR("Failed to duplicate cpu_pattern\n"); + goto failed; + } + + cfs_cpt_table = cfs_cpt_table_create_pattern(cpu_pattern_dup); + kfree(cpu_pattern_dup); if (!cfs_cpt_table) { CERROR("Failed to create cptab from pattern %s\n", cpu_pattern); @@ -1074,8 +1082,9 @@ cfs_cpu_init(void) } spin_unlock(&cpt_data.cpt_lock); - LCONSOLE(0, "HW CPU cores: %d, npartitions: %d\n", - num_online_cpus(), cfs_cpt_number(cfs_cpt_table)); + LCONSOLE(0, "HW nodes: %d, HW CPU cores: %d, npartitions: %d\n", + num_online_nodes(), num_online_cpus(), + cfs_cpt_number(cfs_cpt_table)); return 0; failed: diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 3f5d58babc2f..075826bd3a2a 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -122,7 +122,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, const struct libcfs_ioctl_hdr __user *uhdr) { struct libcfs_ioctl_hdr hdr; - int err = 0; + int err; if (copy_from_user(&hdr, uhdr, sizeof(hdr))) return -EFAULT; @@ -150,9 +150,20 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return -ENOMEM; if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { - LIBCFS_FREE(*hdr_pp, hdr.ioc_len); err = -EFAULT; + goto free; } + + if ((*hdr_pp)->ioc_version != hdr.ioc_version || + (*hdr_pp)->ioc_len != hdr.ioc_len) { + err = -EINVAL; + goto free; + } + + return 0; + +free: + LIBCFS_FREE(*hdr_pp, hdr.ioc_len); return err; } diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 161e04226521..c388550c2d10 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -488,10 +488,10 @@ static const struct file_operations lnet_debugfs_file_operations_wo = { static const struct file_operations *lnet_debugfs_fops_select(umode_t mode) { - if (!(mode & S_IWUGO)) + if (!(mode & 0222)) return &lnet_debugfs_file_operations_ro; - if (!(mode & S_IRUGO)) + if (!(mode & 0444)) return &lnet_debugfs_file_operations_wo; return &lnet_debugfs_file_operations_rw; diff --git a/drivers/staging/lustre/lnet/libcfs/workitem.c b/drivers/staging/lustre/lnet/libcfs/workitem.c index d0512da6bcde..dbc2a9b8dff8 100644 --- a/drivers/staging/lustre/lnet/libcfs/workitem.c +++ b/drivers/staging/lustre/lnet/libcfs/workitem.c @@ -209,7 +209,7 @@ static int cfs_wi_scheduler(void *arg) /* CPT affinity scheduler? */ if (sched->ws_cptab) if (cfs_cpt_bind(sched->ws_cptab, sched->ws_cpt)) - CWARN("Failed to bind %s on CPT %d\n", + CWARN("Unable to bind %s on CPU partition %d\n", sched->ws_name, sched->ws_cpt); spin_lock(&cfs_wi_data.wi_glock); diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 8c50c99d82d5..69bbd594b9bd 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -143,13 +143,13 @@ int 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 lnet_acceptor_connreq cr; struct socket *sock; int rc; int port; int fatal; - CLASSERT(sizeof(cr) <= 16); /* not too big to be on the stack */ + BUILD_BUG_ON(sizeof(cr) > 16); /* too big to be on the stack */ for (port = LNET_ACCEPTOR_MAX_RESERVED_PORT; port >= LNET_ACCEPTOR_MIN_RESERVED_PORT; @@ -164,7 +164,7 @@ lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, continue; } - CLASSERT(LNET_PROTO_ACCEPTOR_VERSION == 1); + BUILD_BUG_ON(LNET_PROTO_ACCEPTOR_VERSION != 1); cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC; cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION; @@ -206,7 +206,7 @@ EXPORT_SYMBOL(lnet_connect); static int lnet_accept(struct socket *sock, __u32 magic) { - lnet_acceptor_connreq_t cr; + struct lnet_acceptor_connreq cr; __u32 peer_ip; int peer_port; int rc; @@ -284,7 +284,7 @@ lnet_accept(struct socket *sock, __u32 magic) rc = lnet_sock_read(sock, &cr.acr_nid, sizeof(cr) - - offsetof(lnet_acceptor_connreq_t, acr_nid), + offsetof(struct lnet_acceptor_connreq, acr_nid), accept_timeout); if (rc) { CERROR("Error %d reading connection request from %pI4h\n", @@ -330,7 +330,7 @@ lnet_acceptor(void *arg) __u32 magic; __u32 peer_ip; int peer_port; - int secure = (int)((long_ptr_t)arg); + int secure = (int)((long)arg); LASSERT(!lnet_acceptor_state.pta_sock); @@ -459,7 +459,7 @@ lnet_acceptor_start(void) if (!lnet_count_acceptor_nis()) /* not required */ return 0; - task = kthread_run(lnet_acceptor, (void *)(ulong_ptr_t)secure, + task = kthread_run(lnet_acceptor, (void *)(uintptr_t)secure, "acceptor_%03ld", secure); if (IS_ERR(task)) { rc2 = PTR_ERR(task); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index b2ba10d59f84..08b38ef67784 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -180,89 +180,89 @@ static void lnet_assert_wire_constants(void) */ /* Constants... */ - CLASSERT(LNET_PROTO_TCP_MAGIC == 0xeebc0ded); - CLASSERT(LNET_PROTO_TCP_VERSION_MAJOR == 1); - CLASSERT(LNET_PROTO_TCP_VERSION_MINOR == 0); - CLASSERT(LNET_MSG_ACK == 0); - CLASSERT(LNET_MSG_PUT == 1); - CLASSERT(LNET_MSG_GET == 2); - CLASSERT(LNET_MSG_REPLY == 3); - CLASSERT(LNET_MSG_HELLO == 4); + BUILD_BUG_ON(LNET_PROTO_TCP_MAGIC != 0xeebc0ded); + BUILD_BUG_ON(LNET_PROTO_TCP_VERSION_MAJOR != 1); + BUILD_BUG_ON(LNET_PROTO_TCP_VERSION_MINOR != 0); + BUILD_BUG_ON(LNET_MSG_ACK != 0); + BUILD_BUG_ON(LNET_MSG_PUT != 1); + BUILD_BUG_ON(LNET_MSG_GET != 2); + BUILD_BUG_ON(LNET_MSG_REPLY != 3); + BUILD_BUG_ON(LNET_MSG_HELLO != 4); /* Checks for struct ptl_handle_wire_t */ - CLASSERT((int)sizeof(lnet_handle_wire_t) == 16); - CLASSERT((int)offsetof(lnet_handle_wire_t, wh_interface_cookie) == 0); - CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_interface_cookie) == 8); - CLASSERT((int)offsetof(lnet_handle_wire_t, wh_object_cookie) == 8); - CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_object_cookie) == 8); - - /* Checks for struct lnet_magicversion_t */ - CLASSERT((int)sizeof(lnet_magicversion_t) == 8); - CLASSERT((int)offsetof(lnet_magicversion_t, magic) == 0); - CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->magic) == 4); - CLASSERT((int)offsetof(lnet_magicversion_t, version_major) == 4); - CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_major) == 2); - CLASSERT((int)offsetof(lnet_magicversion_t, version_minor) == 6); - CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_minor) == 2); - - /* Checks for struct lnet_hdr_t */ - CLASSERT((int)sizeof(lnet_hdr_t) == 72); - CLASSERT((int)offsetof(lnet_hdr_t, dest_nid) == 0); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_nid) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, src_nid) == 8); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_nid) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, dest_pid) == 16); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_pid) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, src_pid) == 20); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_pid) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, type) == 24); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->type) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, payload_length) == 28); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->payload_length) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, msg) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg) == 40); + BUILD_BUG_ON((int)sizeof(struct lnet_handle_wire) != 16); + BUILD_BUG_ON((int)offsetof(struct lnet_handle_wire, wh_interface_cookie) != 0); + BUILD_BUG_ON((int)sizeof(((struct lnet_handle_wire *)0)->wh_interface_cookie) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_handle_wire, wh_object_cookie) != 8); + BUILD_BUG_ON((int)sizeof(((struct lnet_handle_wire *)0)->wh_object_cookie) != 8); + + /* Checks for struct struct lnet_magicversion */ + BUILD_BUG_ON((int)sizeof(struct lnet_magicversion) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, magic) != 0); + BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->magic) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, version_major) != 4); + BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->version_major) != 2); + BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, version_minor) != 6); + BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->version_minor) != 2); + + /* Checks for struct struct lnet_hdr */ + BUILD_BUG_ON((int)sizeof(struct lnet_hdr) != 72); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, dest_nid) != 0); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->dest_nid) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, src_nid) != 8); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->src_nid) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, dest_pid) != 16); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->dest_pid) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, src_pid) != 20); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->src_pid) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, type) != 24); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->type) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, payload_length) != 28); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->payload_length) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg) != 40); /* Ack */ - CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.dst_wmd) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.dst_wmd) == 16); - CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.match_bits) == 48); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.match_bits) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.mlength) == 56); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.mlength) == 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.dst_wmd) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.dst_wmd) != 16); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.match_bits) != 48); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.match_bits) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.mlength) != 56); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.mlength) != 4); /* Put */ - CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ack_wmd) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ack_wmd) == 16); - CLASSERT((int)offsetof(lnet_hdr_t, msg.put.match_bits) == 48); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.match_bits) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, msg.put.hdr_data) == 56); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.hdr_data) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ptl_index) == 64); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ptl_index) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, msg.put.offset) == 68); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.offset) == 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.ack_wmd) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.ack_wmd) != 16); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.match_bits) != 48); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.match_bits) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.hdr_data) != 56); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.hdr_data) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.ptl_index) != 64); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.ptl_index) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.offset) != 68); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.offset) != 4); /* Get */ - CLASSERT((int)offsetof(lnet_hdr_t, msg.get.return_wmd) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.return_wmd) == 16); - CLASSERT((int)offsetof(lnet_hdr_t, msg.get.match_bits) == 48); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.match_bits) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, msg.get.ptl_index) == 56); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.ptl_index) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, msg.get.src_offset) == 60); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.src_offset) == 4); - CLASSERT((int)offsetof(lnet_hdr_t, msg.get.sink_length) == 64); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.sink_length) == 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.return_wmd) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.return_wmd) != 16); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.match_bits) != 48); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.match_bits) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.ptl_index) != 56); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.ptl_index) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.src_offset) != 60); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.src_offset) != 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.sink_length) != 64); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.sink_length) != 4); /* Reply */ - CLASSERT((int)offsetof(lnet_hdr_t, msg.reply.dst_wmd) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.reply.dst_wmd) == 16); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.reply.dst_wmd) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.reply.dst_wmd) != 16); /* Hello */ - CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.incarnation) == 32); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.incarnation) == 8); - CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.type) == 40); - CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.hello.incarnation) != 32); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.hello.incarnation) != 8); + BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.hello.type) != 40); + BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.hello.type) != 4); } static lnd_t * @@ -822,13 +822,13 @@ lnet_count_acceptor_nis(void) return count; } -static lnet_ping_info_t * +static struct lnet_ping_info * lnet_ping_info_create(int num_ni) { - lnet_ping_info_t *ping_info; + struct lnet_ping_info *ping_info; unsigned int infosz; - infosz = offsetof(lnet_ping_info_t, pi_ni[num_ni]); + infosz = offsetof(struct lnet_ping_info, pi_ni[num_ni]); LIBCFS_ALLOC(ping_info, infosz); if (!ping_info) { CERROR("Can't allocate ping info[%d]\n", num_ni); @@ -860,10 +860,10 @@ lnet_get_ni_count(void) } static inline void -lnet_ping_info_free(lnet_ping_info_t *pinfo) +lnet_ping_info_free(struct lnet_ping_info *pinfo) { LIBCFS_FREE(pinfo, - offsetof(lnet_ping_info_t, + offsetof(struct lnet_ping_info, pi_ni[pinfo->pi_nnis])); } @@ -889,14 +889,14 @@ lnet_ping_info_destroy(void) static void lnet_ping_event_handler(lnet_event_t *event) { - lnet_ping_info_t *pinfo = event->md.user_ptr; + struct lnet_ping_info *pinfo = event->md.user_ptr; if (event->unlinked) pinfo->pi_features = LNET_PING_FEAT_INVAL; } static int -lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle, +lnet_ping_info_setup(struct lnet_ping_info **ppinfo, lnet_handle_md_t *md_handle, int ni_count, bool set_eq) { lnet_process_id_t id = {LNET_NID_ANY, LNET_PID_ANY}; @@ -930,7 +930,7 @@ lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle, /* initialize md content */ md.start = *ppinfo; - md.length = offsetof(lnet_ping_info_t, + md.length = offsetof(struct lnet_ping_info, pi_ni[(*ppinfo)->pi_nnis]); md.threshold = LNET_MD_THRESH_INF; md.max_size = 0; @@ -961,7 +961,7 @@ failed_0: } static void -lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle) +lnet_ping_md_unlink(struct lnet_ping_info *pinfo, lnet_handle_md_t *md_handle) { sigset_t blocked = cfs_block_allsigs(); @@ -979,9 +979,9 @@ lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle) } static void -lnet_ping_info_install_locked(lnet_ping_info_t *ping_info) +lnet_ping_info_install_locked(struct lnet_ping_info *ping_info) { - lnet_ni_status_t *ns; + struct lnet_ni_status *ns; lnet_ni_t *ni; int i = 0; @@ -1003,9 +1003,9 @@ lnet_ping_info_install_locked(lnet_ping_info_t *ping_info) } static void -lnet_ping_target_update(lnet_ping_info_t *pinfo, lnet_handle_md_t md_handle) +lnet_ping_target_update(struct lnet_ping_info *pinfo, lnet_handle_md_t md_handle) { - lnet_ping_info_t *old_pinfo = NULL; + struct lnet_ping_info *old_pinfo = NULL; lnet_handle_md_t old_md; /* switch the NIs to point to the new ping info created */ @@ -1496,7 +1496,7 @@ LNetNIInit(lnet_pid_t requested_pid) int im_a_router = 0; int rc; int ni_count; - lnet_ping_info_t *pinfo; + struct lnet_ping_info *pinfo; lnet_handle_md_t md_handle; struct list_head net_head; @@ -1754,7 +1754,7 @@ int lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) { char *nets = conf->cfg_config_u.cfg_net.net_intf; - lnet_ping_info_t *pinfo; + struct lnet_ping_info *pinfo; lnet_handle_md_t md_handle; struct lnet_ni *ni; struct list_head net_head; @@ -1834,7 +1834,7 @@ int lnet_dyn_del_ni(__u32 net) { lnet_ni_t *ni; - lnet_ping_info_t *pinfo; + struct lnet_ping_info *pinfo; lnet_handle_md_t md_handle; int rc; @@ -2147,7 +2147,7 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms, int replied = 0; const int a_long_time = 60000; /* mS */ int infosz; - lnet_ping_info_t *info; + struct lnet_ping_info *info; lnet_process_id_t tmpid; int i; int nob; @@ -2155,7 +2155,7 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms, int rc2; sigset_t blocked; - infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]); + infosz = offsetof(struct lnet_ping_info, pi_ni[n_ids]); if (n_ids <= 0 || id.nid == LNET_NID_ANY || @@ -2283,18 +2283,18 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms, goto out_1; } - if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) { + if (nob < offsetof(struct lnet_ping_info, pi_ni[0])) { CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id), - nob, (int)offsetof(lnet_ping_info_t, pi_ni[0])); + nob, (int)offsetof(struct lnet_ping_info, pi_ni[0])); goto out_1; } if (info->pi_nnis < n_ids) n_ids = info->pi_nnis; - if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) { + if (nob < offsetof(struct lnet_ping_info, pi_ni[n_ids])) { CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id), - nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids])); + nob, (int)offsetof(struct lnet_ping_info, pi_ni[n_ids])); goto out_1; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index f3dd6e42f4d4..6b0be6c23fff 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -641,7 +641,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) !list_empty(&lp->lp_txq)); msg->msg_peertxcredit = 1; - lp->lp_txqnob += msg->msg_len + sizeof(lnet_hdr_t); + lp->lp_txqnob += msg->msg_len + sizeof(struct lnet_hdr); lp->lp_txcredits--; if (lp->lp_txcredits < lp->lp_mintxcredits) @@ -811,7 +811,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg) LASSERT((txpeer->lp_txcredits < 0) == !list_empty(&txpeer->lp_txq)); - txpeer->lp_txqnob -= msg->msg_len + sizeof(lnet_hdr_t); + txpeer->lp_txqnob -= msg->msg_len + sizeof(struct lnet_hdr); LASSERT(txpeer->lp_txqnob >= 0); txpeer->lp_txcredits++; @@ -1245,7 +1245,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; + struct lnet_hdr *hdr = &msg->msg_hdr; if (msg->msg_wanted) lnet_setpayloadbuffer(msg); @@ -1266,7 +1266,7 @@ 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_hdr *hdr = &msg->msg_hdr; struct lnet_match_info info; bool ready_delay; int rc; @@ -1325,8 +1325,8 @@ 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; + struct lnet_hdr *hdr = &msg->msg_hdr; + struct lnet_handle_wire reply_wmd; int rc; /* Convert get fields to host byte order */ @@ -1389,7 +1389,7 @@ 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; + struct lnet_hdr *hdr = &msg->msg_hdr; lnet_process_id_t src = {0}; lnet_libmd_t *md; int rlength; @@ -1453,7 +1453,7 @@ 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; + struct lnet_hdr *hdr = &msg->msg_hdr; lnet_process_id_t src = {0}; lnet_libmd_t *md; int cpt; @@ -1576,7 +1576,7 @@ lnet_msgtyp2str(int type) } void -lnet_print_hdr(lnet_hdr_t *hdr) +lnet_print_hdr(struct lnet_hdr *hdr) { lnet_process_id_t src = {0}; lnet_process_id_t dst = {0}; @@ -1634,7 +1634,7 @@ lnet_print_hdr(lnet_hdr_t *hdr) } int -lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, +lnet_parse(lnet_ni_t *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, void *private, int rdma_req) { int rc = 0; diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index 0897e588bd54..7ee164e67fbe 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -56,7 +56,7 @@ 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; + struct lnet_hdr *hdr = &msg->msg_hdr; lnet_event_t *ev = &msg->msg_ev; LASSERT(!msg->msg_routing); @@ -361,7 +361,7 @@ lnet_msg_detach_md(lnet_msg_t *msg, int status) static int lnet_complete_msg_locked(lnet_msg_t *msg, int cpt) { - lnet_handle_wire_t ack_wmd; + struct lnet_handle_wire ack_wmd; int rc; int status = msg->msg_ev.status; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 3947e8b711c0..fa515af2ac1d 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -680,7 +680,7 @@ lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md, again: list_for_each_entry_safe(msg, tmp, head, msg_list) { struct lnet_match_info info; - lnet_hdr_t *hdr; + struct lnet_hdr *hdr; int rc; LASSERT(msg->msg_rx_delayed || head == &ptl->ptl_msg_stealing); diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index 4e6dd5149b4f..b7b87ecefcdf 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-socket.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c @@ -97,7 +97,7 @@ lnet_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask) return -EINVAL; } - CLASSERT(sizeof(ifr.ifr_name) >= IFNAMSIZ); + BUILD_BUG_ON(sizeof(ifr.ifr_name) < IFNAMSIZ); if (strlen(name) > sizeof(ifr.ifr_name) - 1) return -E2BIG; @@ -393,8 +393,10 @@ lnet_sock_create(struct socket **sockp, int *fatal, __u32 local_ip, memset(&locaddr, 0, sizeof(locaddr)); locaddr.sin_family = AF_INET; locaddr.sin_port = htons(local_port); - locaddr.sin_addr.s_addr = !local_ip ? - INADDR_ANY : htonl(local_ip); + if (!local_ip) + locaddr.sin_addr.s_addr = htonl(INADDR_ANY); + else + locaddr.sin_addr.s_addr = htonl(local_ip); rc = kernel_bind(sock, (struct sockaddr *)&locaddr, sizeof(locaddr)); diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c index e4aceb71c4ec..18183cbb9859 100644 --- a/drivers/staging/lustre/lnet/lnet/net_fault.c +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c @@ -349,7 +349,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, * Check if message from \a src to \a dst can match any existed drop rule */ bool -lnet_drop_rule_match(lnet_hdr_t *hdr) +lnet_drop_rule_match(struct lnet_hdr *hdr) { struct lnet_drop_rule *rule; lnet_nid_t src = le64_to_cpu(hdr->src_nid); @@ -530,7 +530,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, * will be delayed if there is a match. */ bool -lnet_delay_rule_match_locked(lnet_hdr_t *hdr, struct lnet_msg *msg) +lnet_delay_rule_match_locked(struct lnet_hdr *hdr, struct lnet_msg *msg) { struct lnet_delay_rule *rule; lnet_nid_t src = le64_to_cpu(hdr->src_nid); @@ -997,10 +997,10 @@ lnet_fault_ctl(int opc, struct libcfs_ioctl_data *data) int lnet_fault_init(void) { - CLASSERT(LNET_PUT_BIT == 1 << LNET_MSG_PUT); - CLASSERT(LNET_ACK_BIT == 1 << LNET_MSG_ACK); - CLASSERT(LNET_GET_BIT == 1 << LNET_MSG_GET); - CLASSERT(LNET_REPLY_BIT == 1 << LNET_MSG_REPLY); + BUILD_BUG_ON(LNET_PUT_BIT != 1 << LNET_MSG_PUT); + BUILD_BUG_ON(LNET_ACK_BIT != 1 << LNET_MSG_ACK); + BUILD_BUG_ON(LNET_GET_BIT != 1 << LNET_MSG_GET); + BUILD_BUG_ON(LNET_REPLY_BIT != 1 << LNET_MSG_REPLY); mutex_init(&delay_dd.dd_mutex); spin_lock_init(&delay_dd.dd_lock); diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 8afa0abf15cd..cf22525d7129 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -621,10 +621,10 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, } void -lnet_swap_pinginfo(lnet_ping_info_t *info) +lnet_swap_pinginfo(struct lnet_ping_info *info) { int i; - lnet_ni_status_t *stat; + struct lnet_ni_status *stat; __swab32s(&info->pi_magic); __swab32s(&info->pi_features); @@ -644,7 +644,7 @@ 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_ping_info *info = rcd->rcd_pinginfo; struct lnet_peer *gw = rcd->rcd_gateway; lnet_route_t *rte; @@ -683,7 +683,7 @@ lnet_parse_rc_info(lnet_rc_data_t *rcd) } for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) { - lnet_ni_status_t *stat = &info->pi_ni[i]; + struct lnet_ni_status *stat = &info->pi_ni[i]; lnet_nid_t nid = stat->ns_nid; if (nid == LNET_NID_ANY) { @@ -902,7 +902,7 @@ 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; + struct lnet_ping_info *pi; lnet_md_t md; int rc; int i; diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 65f65a3fc901..a19e1405e3ea 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -139,7 +139,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, int ver; int off; - CLASSERT(sizeof(loff_t) >= 4); + BUILD_BUG_ON(sizeof(loff_t) < 4); off = LNET_PROC_HOFF_GET(*ppos); ver = LNET_PROC_VER_GET(*ppos); @@ -404,7 +404,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int rc = 0; int len; - CLASSERT(LNET_PROC_HASH_BITS >= LNET_PEER_HASH_BITS); + BUILD_BUG_ON(LNET_PROC_HASH_BITS < LNET_PEER_HASH_BITS); LASSERT(!write); if (!*lenp) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 67b460f41d6e..b9ac34ecbd53 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -136,7 +136,7 @@ brw_client_init(struct sfw_test_instance *tsi) return 0; } -int brw_inject_one_error(void) +static int brw_inject_one_error(void) { struct timespec64 ts; diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index 94383023c1be..6ca7192b03b7 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -42,7 +42,7 @@ #include "console.h" static int -lst_session_new_ioctl(lstio_session_new_args_t *args) +lst_session_new_ioctl(struct lstio_session_new_args *args) { char *name; int rc; @@ -78,7 +78,7 @@ lst_session_new_ioctl(lstio_session_new_args_t *args) } static int -lst_session_end_ioctl(lstio_session_end_args_t *args) +lst_session_end_ioctl(struct lstio_session_end_args *args) { if (args->lstio_ses_key != console_session.ses_key) return -EACCES; @@ -87,7 +87,7 @@ lst_session_end_ioctl(lstio_session_end_args_t *args) } static int -lst_session_info_ioctl(lstio_session_info_args_t *args) +lst_session_info_ioctl(struct lstio_session_info_args *args) { /* no checking of key */ @@ -109,7 +109,7 @@ lst_session_info_ioctl(lstio_session_info_args_t *args) } static int -lst_debug_ioctl(lstio_debug_args_t *args) +lst_debug_ioctl(struct lstio_debug_args *args) { char *name = NULL; int client = 1; @@ -190,7 +190,7 @@ out: } static int -lst_group_add_ioctl(lstio_group_add_args_t *args) +lst_group_add_ioctl(struct lstio_group_add_args *args) { char *name; int rc; @@ -223,7 +223,7 @@ lst_group_add_ioctl(lstio_group_add_args_t *args) } static int -lst_group_del_ioctl(lstio_group_del_args_t *args) +lst_group_del_ioctl(struct lstio_group_del_args *args) { int rc; char *name; @@ -256,7 +256,7 @@ lst_group_del_ioctl(lstio_group_del_args_t *args) } static int -lst_group_update_ioctl(lstio_group_update_args_t *args) +lst_group_update_ioctl(struct lstio_group_update_args *args) { int rc; char *name; @@ -313,7 +313,7 @@ lst_group_update_ioctl(lstio_group_update_args_t *args) } static int -lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) +lst_nodes_add_ioctl(struct lstio_group_nodes_args *args) { unsigned int feats; int rc; @@ -358,7 +358,7 @@ lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) } static int -lst_group_list_ioctl(lstio_group_list_args_t *args) +lst_group_list_ioctl(struct lstio_group_list_args *args) { if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -375,7 +375,7 @@ lst_group_list_ioctl(lstio_group_list_args_t *args) } static int -lst_group_info_ioctl(lstio_group_info_args_t *args) +lst_group_info_ioctl(struct lstio_group_info_args *args) { char *name; int ndent; @@ -438,7 +438,7 @@ lst_group_info_ioctl(lstio_group_info_args_t *args) } static int -lst_batch_add_ioctl(lstio_batch_add_args_t *args) +lst_batch_add_ioctl(struct lstio_batch_add_args *args) { int rc; char *name; @@ -471,7 +471,7 @@ lst_batch_add_ioctl(lstio_batch_add_args_t *args) } static int -lst_batch_run_ioctl(lstio_batch_run_args_t *args) +lst_batch_run_ioctl(struct lstio_batch_run_args *args) { int rc; char *name; @@ -505,7 +505,7 @@ lst_batch_run_ioctl(lstio_batch_run_args_t *args) } static int -lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) +lst_batch_stop_ioctl(struct lstio_batch_stop_args *args) { int rc; char *name; @@ -540,7 +540,7 @@ lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) } static int -lst_batch_query_ioctl(lstio_batch_query_args_t *args) +lst_batch_query_ioctl(struct lstio_batch_query_args *args) { char *name; int rc; @@ -581,7 +581,7 @@ lst_batch_query_ioctl(lstio_batch_query_args_t *args) } static int -lst_batch_list_ioctl(lstio_batch_list_args_t *args) +lst_batch_list_ioctl(struct lstio_batch_list_args *args) { if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -598,7 +598,7 @@ lst_batch_list_ioctl(lstio_batch_list_args_t *args) } static int -lst_batch_info_ioctl(lstio_batch_info_args_t *args) +lst_batch_info_ioctl(struct lstio_batch_info_args *args) { char *name; int rc; @@ -662,7 +662,7 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args) } static int -lst_stat_query_ioctl(lstio_stat_args_t *args) +lst_stat_query_ioctl(struct lstio_stat_args *args) { int rc; char *name = NULL; @@ -707,7 +707,7 @@ lst_stat_query_ioctl(lstio_stat_args_t *args) return rc; } -static int lst_test_add_ioctl(lstio_test_args_t *args) +static int lst_test_add_ioctl(struct lstio_test_args *args) { char *batch_name; char *src_name = NULL; @@ -851,69 +851,69 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr) goto out; } - memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t)); + memset(&console_session.ses_trans_stat, 0, sizeof(struct lstcon_trans_stat)); switch (opc) { case LSTIO_SESSION_NEW: - rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf); + rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf); break; case LSTIO_SESSION_END: - rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf); + rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf); break; case LSTIO_SESSION_INFO: - rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf); + rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf); break; case LSTIO_DEBUG: - rc = lst_debug_ioctl((lstio_debug_args_t *)buf); + rc = lst_debug_ioctl((struct lstio_debug_args *)buf); break; case LSTIO_GROUP_ADD: - rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf); + rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf); break; case LSTIO_GROUP_DEL: - rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf); + rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf); break; case LSTIO_GROUP_UPDATE: - rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf); + rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf); break; case LSTIO_NODES_ADD: - rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf); + rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf); break; case LSTIO_GROUP_LIST: - rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf); + rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf); break; case LSTIO_GROUP_INFO: - rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf); + rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf); break; case LSTIO_BATCH_ADD: - rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf); + rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf); break; case LSTIO_BATCH_START: - rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf); + rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf); break; case LSTIO_BATCH_STOP: - rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf); + rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf); break; case LSTIO_BATCH_QUERY: - rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf); + rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf); break; case LSTIO_BATCH_LIST: - rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf); + rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf); break; case LSTIO_BATCH_INFO: - rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf); + rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf); break; case LSTIO_TEST_ADD: - rc = lst_test_add_ioctl((lstio_test_args_t *)buf); + rc = lst_test_add_ioctl((struct lstio_test_args *)buf); break; case LSTIO_STAT_QUERY: - rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf); + rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf); break; default: rc = -EINVAL; } if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat, - sizeof(lstcon_trans_stat_t))) + sizeof(struct lstcon_trans_stat))) rc = -EFAULT; out: mutex_unlock(&console_session.ses_mutex); diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 994422c62487..c6a683bda75e 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -43,7 +43,7 @@ #include "console.h" void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *, - struct lstcon_node *, lstcon_trans_stat_t *); + struct lstcon_node *, struct lstcon_trans_stat *); static void lstcon_rpc_done(struct srpc_client_rpc *rpc) @@ -420,7 +420,7 @@ lstcon_rpc_get_reply(struct lstcon_rpc *crpc, struct srpc_msg **msgpp) } void -lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans, lstcon_trans_stat_t *stat) +lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans, struct lstcon_trans_stat *stat) { struct lstcon_rpc *crpc; struct srpc_msg *rep; @@ -469,7 +469,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, { struct list_head tmp; struct list_head __user *next; - lstcon_rpc_ent_t *ent; + struct lstcon_rpc_ent *ent; struct srpc_generic_reply *rep; struct lstcon_rpc *crpc; struct srpc_msg *msg; @@ -492,7 +492,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, next = tmp.next; - ent = list_entry(next, lstcon_rpc_ent_t, rpe_link); + ent = list_entry(next, struct lstcon_rpc_ent, rpe_link); LASSERT(crpc->crp_stamp); @@ -519,7 +519,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, /* RPC is done */ rep = (struct srpc_generic_reply *)&msg->msg_body.reply; - if (copy_to_user(&ent->rpe_sid, &rep->sid, sizeof(lst_sid_t)) || + if (copy_to_user(&ent->rpe_sid, &rep->sid, sizeof(rep->sid)) || copy_to_user(&ent->rpe_fwk_errno, &rep->status, sizeof(rep->status))) return -EFAULT; @@ -698,17 +698,17 @@ lstcon_statrpc_prep(struct lstcon_node *nd, unsigned int feats, return 0; } -static lnet_process_id_packed_t * +static struct lnet_process_id_packed * lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov) { - lnet_process_id_packed_t *pid; + struct lnet_process_id_packed *pid; int i; i = idx / SFW_ID_PER_PAGE; LASSERT(i < nkiov); - pid = (lnet_process_id_packed_t *)page_address(kiov[i].bv_page); + pid = (struct lnet_process_id_packed *)page_address(kiov[i].bv_page); return &pid[idx % SFW_ID_PER_PAGE]; } @@ -717,7 +717,7 @@ static int lstcon_dstnodes_prep(struct lstcon_group *grp, int idx, int dist, int span, int nkiov, lnet_kiov_t *kiov) { - lnet_process_id_packed_t *pid; + struct lnet_process_id_packed *pid; struct lstcon_ndlink *ndl; struct lstcon_node *nd; int start; @@ -768,7 +768,7 @@ lstcon_dstnodes_prep(struct lstcon_group *grp, int idx, } static int -lstcon_pingrpc_prep(lst_test_ping_param_t *param, struct srpc_test_reqst *req) +lstcon_pingrpc_prep(struct lst_test_ping_param *param, struct srpc_test_reqst *req) { struct test_ping_req *prq = &req->tsr_u.ping; @@ -779,7 +779,7 @@ lstcon_pingrpc_prep(lst_test_ping_param_t *param, struct srpc_test_reqst *req) } static int -lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, +lstcon_bulkrpc_v0_prep(struct lst_test_bulk_param *param, struct srpc_test_reqst *req) { struct test_bulk_req *brq = &req->tsr_u.bulk_v0; @@ -793,7 +793,7 @@ lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, } static int -lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, bool is_client, +lstcon_bulkrpc_v1_prep(struct lst_test_bulk_param *param, bool is_client, struct srpc_test_reqst *req) { struct test_bulk_req_v1 *brq = &req->tsr_u.bulk_v1; @@ -823,7 +823,7 @@ lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned int feats, npg = sfw_id_pages(test->tes_span); nob = !(feats & LST_FEAT_BULK_LEN) ? npg * PAGE_SIZE : - sizeof(lnet_process_id_packed_t) * test->tes_span; + sizeof(struct lnet_process_id_packed) * test->tes_span; } rc = lstcon_rpc_prep(nd, SRPC_SERVICE_TEST, feats, npg, nob, crpc); @@ -891,17 +891,17 @@ lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned int feats, switch (test->tes_type) { case LST_TEST_PING: trq->tsr_service = SRPC_SERVICE_PING; - rc = lstcon_pingrpc_prep((lst_test_ping_param_t *) + rc = lstcon_pingrpc_prep((struct lst_test_ping_param *) &test->tes_param[0], trq); break; case LST_TEST_BULK: trq->tsr_service = SRPC_SERVICE_BRW; if (!(feats & LST_FEAT_BULK_LEN)) { - rc = lstcon_bulkrpc_v0_prep((lst_test_bulk_param_t *) + rc = lstcon_bulkrpc_v0_prep((struct lst_test_bulk_param *) &test->tes_param[0], trq); } else { - rc = lstcon_bulkrpc_v1_prep((lst_test_bulk_param_t *) + rc = lstcon_bulkrpc_v1_prep((struct lst_test_bulk_param *) &test->tes_param[0], trq->tsr_is_client, trq); } @@ -964,7 +964,7 @@ lstcon_sesnew_stat_reply(struct lstcon_rpc_trans *trans, void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *trans, struct srpc_msg *msg, - struct lstcon_node *nd, lstcon_trans_stat_t *stat) + struct lstcon_node *nd, struct lstcon_trans_stat *stat) { struct srpc_rmsn_reply *rmsn_rep; struct srpc_debug_reply *dbg_rep; @@ -1320,7 +1320,7 @@ lstcon_rpc_pinger_stop(void) lstcon_rpc_trans_stat(console_session.ses_ping, lstcon_trans_stat()); lstcon_rpc_trans_destroy(console_session.ses_ping); - memset(lstcon_trans_stat(), 0, sizeof(lstcon_trans_stat_t)); + memset(lstcon_trans_stat(), 0, sizeof(struct lstcon_trans_stat)); console_session.ses_ping = NULL; } diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h index e629e87c461c..7141d2c902a5 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.h +++ b/drivers/staging/lustre/lnet/selftest/conrpc.h @@ -103,7 +103,7 @@ struct lstcon_rpc_trans { typedef int (*lstcon_rpc_cond_func_t)(int, struct lstcon_node *, void *); typedef int (*lstcon_rpc_readent_func_t)(int, struct srpc_msg *, - lstcon_rpc_ent_t __user *); + struct lstcon_rpc_ent __user *); int lstcon_sesrpc_prep(struct lstcon_node *nd, int transop, unsigned int version, struct lstcon_rpc **crpc); @@ -125,7 +125,7 @@ int lstcon_rpc_trans_ndlist(struct list_head *ndlist, void *arg, lstcon_rpc_cond_func_t condition, struct lstcon_rpc_trans **transpp); void lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans, - lstcon_trans_stat_t *stat); + struct lstcon_trans_stat *stat); int lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, struct list_head __user *head_up, lstcon_rpc_readent_func_t readent); diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 1456d2395cc9..4e7e5c862c64 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -368,7 +368,7 @@ lstcon_sesrpc_condition(int transop, struct lstcon_node *nd, void *arg) static int lstcon_sesrpc_readent(int transop, struct srpc_msg *msg, - lstcon_rpc_ent_t __user *ent_up) + struct lstcon_rpc_ent __user *ent_up) { struct srpc_debug_reply *rep; @@ -741,7 +741,7 @@ lstcon_group_list(int index, int len, char __user *name_up) static int lstcon_nodes_getent(struct list_head *head, int *index_p, - int *count_p, lstcon_node_ent_t __user *dents_up) + int *count_p, struct lstcon_node_ent __user *dents_up) { struct lstcon_ndlink *ndl; struct lstcon_node *nd; @@ -780,11 +780,11 @@ lstcon_nodes_getent(struct list_head *head, int *index_p, } int -lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p, +lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gents_p, int *index_p, int *count_p, - lstcon_node_ent_t __user *dents_up) + struct lstcon_node_ent __user *dents_up) { - lstcon_ndlist_ent_t *gentp; + struct lstcon_ndlist_ent *gentp; struct lstcon_group *grp; struct lstcon_ndlink *ndl; int rc; @@ -805,7 +805,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p, } /* non-verbose query */ - LIBCFS_ALLOC(gentp, sizeof(lstcon_ndlist_ent_t)); + LIBCFS_ALLOC(gentp, sizeof(struct lstcon_ndlist_ent)); if (!gentp) { CERROR("Can't allocate ndlist_ent\n"); lstcon_group_decref(grp); @@ -817,9 +817,9 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p, LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp); rc = copy_to_user(gents_p, gentp, - sizeof(lstcon_ndlist_ent_t)) ? -EFAULT : 0; + sizeof(struct lstcon_ndlist_ent)) ? -EFAULT : 0; - LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t)); + LIBCFS_FREE(gentp, sizeof(struct lstcon_ndlist_ent)); lstcon_group_decref(grp); @@ -926,11 +926,11 @@ lstcon_batch_list(int index, int len, char __user *name_up) } int -lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up, +lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up, int server, int testidx, int *index_p, int *ndent_p, - lstcon_node_ent_t __user *dents_up) + struct lstcon_node_ent __user *dents_up) { - lstcon_test_batch_ent_t *entp; + struct lstcon_test_batch_ent *entp; struct list_head *clilst; struct list_head *srvlst; struct lstcon_test *test = NULL; @@ -969,7 +969,7 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up, } /* non-verbose query */ - LIBCFS_ALLOC(entp, sizeof(lstcon_test_batch_ent_t)); + LIBCFS_ALLOC(entp, sizeof(struct lstcon_test_batch_ent)); if (!entp) return -ENOMEM; @@ -989,9 +989,9 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up, LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_srv_nle); rc = copy_to_user(ent_up, entp, - sizeof(lstcon_test_batch_ent_t)) ? -EFAULT : 0; + sizeof(struct lstcon_test_batch_ent)) ? -EFAULT : 0; - LIBCFS_FREE(entp, sizeof(lstcon_test_batch_ent_t)); + LIBCFS_FREE(entp, sizeof(struct lstcon_test_batch_ent)); return rc; } @@ -1385,7 +1385,7 @@ lstcon_test_find(struct lstcon_batch *batch, int idx, static int lstcon_tsbrpc_readent(int transop, struct srpc_msg *msg, - lstcon_rpc_ent_t __user *ent_up) + struct lstcon_rpc_ent __user *ent_up) { struct srpc_batch_reply *rep = &msg->msg_body.bat_reply; @@ -1464,18 +1464,18 @@ lstcon_test_batch_query(char *name, int testidx, int client, static int lstcon_statrpc_readent(int transop, struct srpc_msg *msg, - lstcon_rpc_ent_t __user *ent_up) + struct lstcon_rpc_ent __user *ent_up) { struct srpc_stat_reply *rep = &msg->msg_body.stat_reply; - sfw_counters_t __user *sfwk_stat; - srpc_counters_t __user *srpc_stat; + struct sfw_counters __user *sfwk_stat; + struct srpc_counters __user *srpc_stat; lnet_counters_t __user *lnet_stat; if (rep->str_status) return 0; - sfwk_stat = (sfw_counters_t __user *)&ent_up->rpe_payload[0]; - srpc_stat = (srpc_counters_t __user *)(sfwk_stat + 1); + sfwk_stat = (struct sfw_counters __user *)&ent_up->rpe_payload[0]; + srpc_stat = (struct srpc_counters __user *)(sfwk_stat + 1); lnet_stat = (lnet_counters_t __user *)(srpc_stat + 1); if (copy_to_user(sfwk_stat, &rep->str_fw, sizeof(*sfwk_stat)) || @@ -1688,14 +1688,14 @@ lstcon_nodes_debug(int timeout, } int -lstcon_session_match(lst_sid_t sid) +lstcon_session_match(struct lst_sid sid) { return (console_session.ses_id.ses_nid == sid.ses_nid && console_session.ses_id.ses_stamp == sid.ses_stamp) ? 1 : 0; } static void -lstcon_new_session_id(lst_sid_t *sid) +lstcon_new_session_id(struct lst_sid *sid) { lnet_process_id_t id; @@ -1708,7 +1708,7 @@ lstcon_new_session_id(lst_sid_t *sid) int lstcon_session_new(char *name, int key, unsigned int feats, - int timeout, int force, lst_sid_t __user *sid_up) + int timeout, int force, struct lst_sid __user *sid_up) { int rc = 0; int i; @@ -1767,7 +1767,7 @@ lstcon_session_new(char *name, int key, unsigned int feats, } if (!copy_to_user(sid_up, &console_session.ses_id, - sizeof(lst_sid_t))) + sizeof(struct lst_sid))) return rc; lstcon_session_end(); @@ -1776,12 +1776,12 @@ lstcon_session_new(char *name, int key, unsigned int feats, } int -lstcon_session_info(lst_sid_t __user *sid_up, int __user *key_up, +lstcon_session_info(struct lst_sid __user *sid_up, int __user *key_up, unsigned __user *featp, - lstcon_ndlist_ent_t __user *ndinfo_up, + struct lstcon_ndlist_ent __user *ndinfo_up, char __user *name_up, int len) { - lstcon_ndlist_ent_t *entp; + struct lstcon_ndlist_ent *entp; struct lstcon_ndlink *ndl; int rc = 0; @@ -1796,7 +1796,7 @@ lstcon_session_info(lst_sid_t __user *sid_up, int __user *key_up, LST_NODE_STATE_COUNTER(ndl->ndl_node, entp); if (copy_to_user(sid_up, &console_session.ses_id, - sizeof(lst_sid_t)) || + sizeof(*sid_up)) || copy_to_user(key_up, &console_session.ses_key, sizeof(*key_up)) || copy_to_user(featp, &console_session.ses_features, diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h index 5dc1de48a10e..05b4b7013d2e 100644 --- a/drivers/staging/lustre/lnet/selftest/console.h +++ b/drivers/staging/lustre/lnet/selftest/console.h @@ -81,7 +81,7 @@ struct lstcon_group { #define LST_BATCH_RUNNING 0xB1 /* running batch */ struct lstcon_tsb_hdr { - lst_bid_t tsb_id; /* batch ID */ + struct lst_bid tsb_id; /* batch ID */ int tsb_index; /* test index */ }; @@ -140,7 +140,7 @@ struct lstcon_test { struct lstcon_session { struct mutex ses_mutex; /* only 1 thread in session */ - lst_sid_t ses_id; /* global session id */ + struct lst_sid ses_id; /* global session id */ int ses_key; /* local session key */ int ses_state; /* state of session */ int ses_timeout; /* timeout in seconds */ @@ -158,7 +158,7 @@ struct lstcon_session { char ses_name[LST_NAME_SIZE];/* session name */ struct lstcon_rpc_trans *ses_ping; /* session pinger */ struct stt_timer ses_ping_timer; /* timer for pinger */ - lstcon_trans_stat_t ses_trans_stat; /* transaction stats */ + struct lstcon_trans_stat 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 */ @@ -173,7 +173,7 @@ struct lstcon_session { extern struct lstcon_session console_session; -static inline lstcon_trans_stat_t * +static inline struct lstcon_trans_stat * lstcon_trans_stat(void) { return &console_session.ses_trans_stat; @@ -190,11 +190,11 @@ lstcon_id2hash(lnet_process_id_t id, struct list_head *hash) int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr); int lstcon_console_init(void); int lstcon_console_fini(void); -int lstcon_session_match(lst_sid_t sid); +int lstcon_session_match(struct lst_sid sid); int lstcon_session_new(char *name, int key, unsigned int version, - int timeout, int flags, lst_sid_t __user *sid_up); -int lstcon_session_info(lst_sid_t __user *sid_up, int __user *key, - unsigned __user *verp, lstcon_ndlist_ent_t __user *entp, + int timeout, int flags, struct lst_sid __user *sid_up); +int lstcon_session_info(struct lst_sid __user *sid_up, int __user *key, + unsigned __user *verp, struct lstcon_ndlist_ent __user *entp, char __user *name_up, int len); int lstcon_session_end(void); int lstcon_session_debug(int timeout, struct list_head __user *result_up); @@ -213,9 +213,9 @@ int lstcon_nodes_add(char *name, int nnd, lnet_process_id_t __user *nds_up, unsigned int *featp, struct list_head __user *result_up); int lstcon_nodes_remove(char *name, int nnd, lnet_process_id_t __user *nds_up, struct list_head __user *result_up); -int lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gent_up, +int lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gent_up, int *index_p, int *ndent_p, - lstcon_node_ent_t __user *ndents_up); + struct lstcon_node_ent __user *ndents_up); int lstcon_group_list(int idx, int len, char __user *name_up); int lstcon_batch_add(char *name); int lstcon_batch_run(char *name, int timeout, @@ -227,9 +227,9 @@ int lstcon_test_batch_query(char *name, int testidx, struct list_head __user *result_up); int lstcon_batch_del(char *name); int lstcon_batch_list(int idx, int namelen, char __user *name_up); -int lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up, +int lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up, int server, int testidx, int *index_p, - int *ndent_p, lstcon_node_ent_t __user *dents_up); + int *ndent_p, struct lstcon_node_ent __user *dents_up); int lstcon_group_stat(char *grp_name, int timeout, struct list_head __user *result_up); int lstcon_nodes_stat(int count, lnet_process_id_t __user *ids_up, diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 48dcc330dc9b..9dd4e1a70329 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -39,7 +39,7 @@ #include "selftest.h" -lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1}; +struct lst_sid LST_INVALID_SID = {LNET_NID_ANY, -1}; static int session_timeout = 100; module_param(session_timeout, int, 0444); @@ -254,7 +254,7 @@ sfw_session_expired(void *data) } static inline void -sfw_init_session(struct sfw_session *sn, lst_sid_t sid, +sfw_init_session(struct sfw_session *sn, struct lst_sid sid, unsigned int features, const char *name) { struct stt_timer *timer = &sn->sn_timer; @@ -316,7 +316,7 @@ sfw_client_rpc_fini(struct srpc_client_rpc *rpc) } static struct sfw_batch * -sfw_find_batch(lst_bid_t bid) +sfw_find_batch(struct lst_bid bid) { struct sfw_session *sn = sfw_data.fw_session; struct sfw_batch *bat; @@ -332,7 +332,7 @@ sfw_find_batch(lst_bid_t bid) } static struct sfw_batch * -sfw_bid2batch(lst_bid_t bid) +sfw_bid2batch(struct lst_bid bid) { struct sfw_session *sn = sfw_data.fw_session; struct sfw_batch *bat; @@ -361,7 +361,7 @@ static int sfw_get_stats(struct srpc_stat_reqst *request, struct srpc_stat_reply *reply) { struct sfw_session *sn = sfw_data.fw_session; - sfw_counters_t *cnt = &reply->str_fw; + struct sfw_counters *cnt = &reply->str_fw; struct sfw_batch *bat; reply->str_sid = !sn ? LST_INVALID_SID : sn->sn_id; @@ -777,14 +777,14 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc) LASSERT(bk); LASSERT(bk->bk_niov * SFW_ID_PER_PAGE >= (unsigned int)ndest); LASSERT((unsigned int)bk->bk_len >= - sizeof(lnet_process_id_packed_t) * ndest); + sizeof(struct lnet_process_id_packed) * ndest); sfw_unpack_addtest_req(msg); memcpy(&tsi->tsi_u, &req->tsr_u, sizeof(tsi->tsi_u)); for (i = 0; i < ndest; i++) { - lnet_process_id_packed_t *dests; - lnet_process_id_packed_t id; + struct lnet_process_id_packed *dests; + struct lnet_process_id_packed id; int j; dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].bv_page); @@ -1164,7 +1164,7 @@ sfw_add_test(struct srpc_server_rpc *rpc) len = npg * PAGE_SIZE; } else { - len = sizeof(lnet_process_id_packed_t) * + len = sizeof(struct lnet_process_id_packed) * request->tsr_ndest; } diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 71485f992297..b5d556fa48ab 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -112,7 +112,8 @@ lnet_selftest_init(void) rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i, nthrs, &lst_sched_test[i]); if (rc) { - CERROR("Failed to create CPT affinity WI scheduler %d for LST\n", i); + CWARN("Failed to create CPU partition affinity WI scheduler %d for LST\n", + i); goto error; } } diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index ce9de8c9be57..92cd4113cf75 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -55,7 +55,7 @@ static struct smoketest_rpc { struct srpc_service *rpc_services[SRPC_SERVICE_MAX_ID + 1]; lnet_handle_eq_t rpc_lnet_eq; /* _the_ LNet event queue */ enum srpc_state rpc_state; - srpc_counters_t rpc_counters; + struct srpc_counters rpc_counters; __u64 rpc_matchbits; /* matchbits counter */ } srpc_data; @@ -69,14 +69,14 @@ srpc_serv_portal(int svc_id) /* forward ref's */ int srpc_handle_rpc(struct swi_workitem *wi); -void srpc_get_counters(srpc_counters_t *cnt) +void srpc_get_counters(struct srpc_counters *cnt) { spin_lock(&srpc_data.rpc_glock); *cnt = srpc_data.rpc_counters; spin_unlock(&srpc_data.rpc_glock); } -void srpc_set_counters(const srpc_counters_t *cnt) +void srpc_set_counters(const struct srpc_counters *cnt) { spin_lock(&srpc_data.rpc_glock); srpc_data.rpc_counters = *cnt; diff --git a/drivers/staging/lustre/lnet/selftest/rpc.h b/drivers/staging/lustre/lnet/selftest/rpc.h index f353a634cc8e..418c9c96abe6 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.h +++ b/drivers/staging/lustre/lnet/selftest/rpc.h @@ -75,43 +75,43 @@ struct srpc_generic_reqst { struct srpc_generic_reply { __u32 status; - lst_sid_t sid; + struct lst_sid sid; } WIRE_ATTR; /* FRAMEWORK RPCs */ struct srpc_mksn_reqst { __u64 mksn_rpyid; /* reply buffer matchbits */ - lst_sid_t mksn_sid; /* session id */ + struct lst_sid mksn_sid; /* session id */ __u32 mksn_force; /* use brute force */ char mksn_name[LST_NAME_SIZE]; } WIRE_ATTR; /* make session request */ struct srpc_mksn_reply { __u32 mksn_status; /* session status */ - lst_sid_t mksn_sid; /* session id */ + struct lst_sid mksn_sid; /* session id */ __u32 mksn_timeout; /* session timeout */ char mksn_name[LST_NAME_SIZE]; } WIRE_ATTR; /* make session reply */ struct srpc_rmsn_reqst { __u64 rmsn_rpyid; /* reply buffer matchbits */ - lst_sid_t rmsn_sid; /* session id */ + struct lst_sid rmsn_sid; /* session id */ } WIRE_ATTR; /* remove session request */ struct srpc_rmsn_reply { __u32 rmsn_status; - lst_sid_t rmsn_sid; /* session id */ + struct lst_sid rmsn_sid; /* session id */ } WIRE_ATTR; /* remove session reply */ struct srpc_join_reqst { __u64 join_rpyid; /* reply buffer matchbits */ - lst_sid_t join_sid; /* session id to join */ + struct lst_sid join_sid; /* session id to join */ char join_group[LST_NAME_SIZE]; /* group name */ } WIRE_ATTR; struct srpc_join_reply { __u32 join_status; /* returned status */ - lst_sid_t join_sid; /* session id */ + struct lst_sid join_sid; /* session id */ __u32 join_timeout; /* # seconds' inactivity to * expire */ @@ -120,13 +120,13 @@ struct srpc_join_reply { struct srpc_debug_reqst { __u64 dbg_rpyid; /* reply buffer matchbits */ - lst_sid_t dbg_sid; /* session id */ + struct lst_sid dbg_sid; /* session id */ __u32 dbg_flags; /* bitmap of debug */ } WIRE_ATTR; struct srpc_debug_reply { __u32 dbg_status; /* returned code */ - lst_sid_t dbg_sid; /* session id */ + struct lst_sid 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 */ @@ -138,8 +138,8 @@ struct srpc_debug_reply { struct srpc_batch_reqst { __u64 bar_rpyid; /* reply buffer matchbits */ - lst_sid_t bar_sid; /* session id */ - lst_bid_t bar_bid; /* batch id */ + struct lst_sid bar_sid; /* session id */ + struct lst_bid bar_bid; /* batch id */ __u32 bar_opc; /* create/start/stop batch */ __u32 bar_testidx; /* index of test */ __u32 bar_arg; /* parameters */ @@ -147,22 +147,22 @@ struct srpc_batch_reqst { struct srpc_batch_reply { __u32 bar_status; /* status of request */ - lst_sid_t bar_sid; /* session id */ + struct lst_sid bar_sid; /* session id */ __u32 bar_active; /* # of active tests in batch/test */ __u32 bar_time; /* remained time */ } WIRE_ATTR; struct srpc_stat_reqst { __u64 str_rpyid; /* reply buffer matchbits */ - lst_sid_t str_sid; /* session id */ + struct lst_sid str_sid; /* session id */ __u32 str_type; /* type of stat */ } WIRE_ATTR; struct srpc_stat_reply { __u32 str_status; - lst_sid_t str_sid; - sfw_counters_t str_fw; - srpc_counters_t str_rpc; + struct lst_sid str_sid; + struct sfw_counters str_fw; + struct srpc_counters str_rpc; lnet_counters_t str_lnet; } WIRE_ATTR; @@ -187,8 +187,8 @@ struct test_ping_req { struct srpc_test_reqst { __u64 tsr_rpyid; /* reply buffer matchbits */ __u64 tsr_bulkid; /* bulk buffer matchbits */ - lst_sid_t tsr_sid; /* session id */ - lst_bid_t tsr_bid; /* batch id */ + struct lst_sid tsr_sid; /* session id */ + struct lst_bid tsr_bid; /* batch id */ __u32 tsr_service; /* test type: bulk|ping|... */ __u32 tsr_loop; /* test client loop count or * # server buffers needed @@ -207,7 +207,7 @@ struct srpc_test_reqst { struct srpc_test_reply { __u32 tsr_status; /* returned code */ - lst_sid_t tsr_sid; + struct lst_sid tsr_sid; } WIRE_ATTR; /* TEST RPCs */ diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index c8833a016b6d..f25948087ee0 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -322,7 +322,7 @@ struct srpc_service { struct sfw_session { struct list_head sn_list; /* chain on fw_zombie_sessions */ - lst_sid_t sn_id; /* unique identifier */ + struct lst_sid sn_id; /* unique identifier */ unsigned int sn_timeout; /* # seconds' inactivity to expire */ int sn_timer_active; unsigned int sn_features; @@ -340,7 +340,7 @@ struct sfw_session { struct sfw_batch { struct list_head bat_list; /* chain on sn_batches */ - lst_bid_t bat_id; /* batch id */ + struct lst_bid bat_id; /* batch id */ int bat_error; /* error code of batch */ struct sfw_session *bat_session; /* batch's session */ atomic_t bat_nactive; /* # of active tests */ @@ -396,7 +396,7 @@ struct sfw_test_instance { * pages are not used */ #define SFW_MAX_CONCUR LST_MAX_CONCUR -#define SFW_ID_PER_PAGE (PAGE_SIZE / sizeof(lnet_process_id_packed_t)) +#define SFW_ID_PER_PAGE (PAGE_SIZE / sizeof(struct lnet_process_id_packed)) #define SFW_MAX_NDESTS (LNET_MAX_IOV * SFW_ID_PER_PAGE) #define sfw_id_pages(n) (((n) + SFW_ID_PER_PAGE - 1) / SFW_ID_PER_PAGE) @@ -453,8 +453,8 @@ void srpc_abort_service(struct srpc_service *sv); int srpc_finish_service(struct srpc_service *sv); int srpc_service_add_buffers(struct srpc_service *sv, int nbuffer); void srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer); -void srpc_get_counters(srpc_counters_t *cnt); -void srpc_set_counters(const srpc_counters_t *cnt); +void srpc_get_counters(struct srpc_counters *cnt); +void srpc_set_counters(const struct srpc_counters *cnt); extern struct cfs_wi_sched *lst_sched_serial; extern struct cfs_wi_sched **lst_sched_test; diff --git a/drivers/staging/lustre/lustre/fid/fid_lib.c b/drivers/staging/lustre/lustre/fid/fid_lib.c index 4e49cb356d64..9eb405905d1a 100644 --- a/drivers/staging/lustre/lustre/fid/fid_lib.c +++ b/drivers/staging/lustre/lustre/fid/fid_lib.c @@ -60,14 +60,13 @@ * FID_SEQ_START + 2 is for .lustre directory and its objects */ const struct lu_seq_range LUSTRE_SEQ_SPACE_RANGE = { - FID_SEQ_NORMAL, - (__u64)~0ULL + .lsr_start = FID_SEQ_NORMAL, + .lsr_end = (__u64)~0ULL, }; /* Zero range, used for init and other purposes. */ const struct lu_seq_range LUSTRE_SEQ_ZERO_RANGE = { - 0, - 0 + .lsr_start = 0, }; /* Lustre Big Fs Lock fid. */ diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c index 97d4849c7199..3eed83808545 100644 --- a/drivers/staging/lustre/lustre/fid/lproc_fid.c +++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c @@ -203,9 +203,13 @@ LPROC_SEQ_FOPS_RO(ldebugfs_fid_server); LPROC_SEQ_FOPS_RO(ldebugfs_fid_fid); 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 }, + { .name = "space", + .fops = &ldebugfs_fid_space_fops }, + { .name = "width", + .fops = &ldebugfs_fid_width_fops }, + { .name = "server", + .fops = &ldebugfs_fid_server_fops }, + { .name = "fid", + .fops = &ldebugfs_fid_fid_fops }, { NULL } }; diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index dc685610c4c4..e4c0c440f01b 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -284,12 +284,6 @@ struct cl_layout { size_t cl_size; /** Layout generation. */ u32 cl_layout_gen; - /** - * True if this is a released file. - * Temporarily added for released file truncate in ll_setattr_raw(). - * It will be removed later. -Jinshan - */ - bool cl_is_released; }; /** @@ -1458,8 +1452,10 @@ struct cl_read_ahead { * cra_end is included. */ pgoff_t cra_end; + /* optimal RPC size for this read, by pages */ + unsigned long cra_rpc_size; /* - * Release routine. If readahead holds resources underneath, this + * Release callback. If readahead holds resources underneath, this * function should be called to release it. */ void (*cra_release)(const struct lu_env *env, void *cbdata); @@ -2311,7 +2307,7 @@ struct cl_io *cl_io_top(struct cl_io *io); do { \ typeof(foo_io) __foo_io = (foo_io); \ \ - CLASSERT(offsetof(typeof(*__foo_io), base) == 0); \ + BUILD_BUG_ON(offsetof(typeof(*__foo_io), base) != 0); \ memset(&__foo_io->base + 1, 0, \ sizeof(*__foo_io) - sizeof(__foo_io->base)); \ } while (0) diff --git a/drivers/staging/lustre/lustre/include/interval_tree.h b/drivers/staging/lustre/lustre/include/interval_tree.h index 5d387d372547..0d4f92ec8334 100644 --- a/drivers/staging/lustre/lustre/include/interval_tree.h +++ b/drivers/staging/lustre/lustre/include/interval_tree.h @@ -36,7 +36,9 @@ #ifndef _INTERVAL_H__ #define _INTERVAL_H__ -#include "../../include/linux/libcfs/libcfs.h" /* LASSERT. */ +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/types.h> struct interval_node { struct interval_node *in_left; @@ -73,13 +75,15 @@ static inline __u64 interval_high(struct interval_node *node) return node->in_extent.end; } -static inline void interval_set(struct interval_node *node, - __u64 start, __u64 end) +static inline int interval_set(struct interval_node *node, + __u64 start, __u64 end) { - LASSERT(start <= end); + if (start > end) + return -ERANGE; node->in_extent.start = start; node->in_extent.end = end; node->in_max_high = end; + return 0; } /* diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index 260643ee0d48..7a4f412a85a3 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -34,6 +34,7 @@ #define __LUSTRE_LU_OBJECT_H #include <stdarg.h> +#include <linux/percpu_counter.h> #include "../../include/linux/libcfs/libcfs.h" #include "lustre/lustre_idl.h" #include "lu_ref.h" @@ -580,7 +581,6 @@ enum { LU_SS_CACHE_RACE, LU_SS_CACHE_DEATH_RACE, LU_SS_LRU_PURGED, - LU_SS_LRU_LEN, /* # of objects in lsb_lru lists */ LU_SS_LAST_STAT }; @@ -635,6 +635,10 @@ struct lu_site { * XXX: a hack! fld has to find md_site via site, remove when possible */ struct seq_server_site *ld_seq_site; + /** + * Number of objects in lsb_lru_lists - used for shrinking + */ + struct percpu_counter ls_lru_len_counter; }; static inline struct lu_site_bkt_data * @@ -708,8 +712,14 @@ static inline int lu_object_is_dying(const struct lu_object_header *h) void lu_object_put(const struct lu_env *env, struct lu_object *o); void lu_object_unhash(const struct lu_env *env, struct lu_object *o); +int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s, int nr, + bool canblock); -int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr); +static inline int lu_site_purge(const struct lu_env *env, struct lu_site *s, + int nr) +{ + return lu_site_purge_objects(env, s, nr, true); +} void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie, lu_printer_t printer); @@ -1120,7 +1130,7 @@ struct lu_context_key { { \ type *value; \ \ - CLASSERT(PAGE_SIZE >= sizeof(*value)); \ + BUILD_BUG_ON(PAGE_SIZE < sizeof(*value)); \ \ value = kzalloc(sizeof(*value), GFP_NOFS); \ if (!value) \ @@ -1326,5 +1336,8 @@ void lu_buf_realloc(struct lu_buf *buf, size_t size); int lu_buf_check_and_grow(struct lu_buf *buf, size_t len); struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len); +extern __u32 lu_context_tags_default; +extern __u32 lu_session_tags_default; + /** @} lu */ #endif /* __LUSTRE_LU_OBJECT_H */ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 65ce503ad595..b0eb80d70c23 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -3130,52 +3130,6 @@ struct obdo { #define o_cksum o_nlink #define o_grant_used o_data_version -static inline void lustre_set_wire_obdo(const struct obd_connect_data *ocd, - struct obdo *wobdo, - const struct obdo *lobdo) -{ - *wobdo = *lobdo; - wobdo->o_flags &= ~OBD_FL_LOCAL_MASK; - if (!ocd) - return; - - if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) && - fid_seq_is_echo(ostid_seq(&lobdo->o_oi))) { - /* Currently OBD_FL_OSTID will only be used when 2.4 echo - * client communicate with pre-2.4 server - */ - wobdo->o_oi.oi.oi_id = fid_oid(&lobdo->o_oi.oi_fid); - wobdo->o_oi.oi.oi_seq = fid_seq(&lobdo->o_oi.oi_fid); - } -} - -static inline void lustre_get_wire_obdo(const struct obd_connect_data *ocd, - struct obdo *lobdo, - const struct obdo *wobdo) -{ - __u32 local_flags = 0; - - if (lobdo->o_valid & OBD_MD_FLFLAGS) - local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK; - - *lobdo = *wobdo; - if (local_flags != 0) { - lobdo->o_valid |= OBD_MD_FLFLAGS; - lobdo->o_flags &= ~OBD_FL_LOCAL_MASK; - lobdo->o_flags |= local_flags; - } - if (!ocd) - return; - - if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) && - fid_seq_is_echo(wobdo->o_oi.oi.oi_seq)) { - /* see above */ - lobdo->o_oi.oi_fid.f_seq = wobdo->o_oi.oi.oi_seq; - lobdo->o_oi.oi_fid.f_oid = wobdo->o_oi.oi.oi_id; - lobdo->o_oi.oi_fid.f_ver = 0; - } -} - /* request structure for OST's */ struct ost_body { struct obdo oa; diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index 3301ad652db1..21aec0ca9ad3 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h @@ -1209,23 +1209,21 @@ struct hsm_action_item { * \retval buffer */ static inline char *hai_dump_data_field(struct hsm_action_item *hai, - char *buffer, int len) + char *buffer, size_t len) { - int i, sz, data_len; + int i, data_len; char *ptr; ptr = buffer; - sz = len; data_len = hai->hai_len - sizeof(*hai); - for (i = 0 ; (i < data_len) && (sz > 0) ; i++) { - int cnt; - - cnt = snprintf(ptr, sz, "%.2X", - (unsigned char)hai->hai_data[i]); - ptr += cnt; - sz -= cnt; + for (i = 0; (i < data_len) && (len > 2); i++) { + snprintf(ptr, 3, "%02X", (unsigned char)hai->hai_data[i]); + ptr += 2; + len -= 2; } + *ptr = '\0'; + return buffer; } diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 411eb0dc7f38..1b48df0d4862 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -315,8 +315,8 @@ struct ptlrpc_client { union ptlrpc_async_args { /** * Scratchpad for passing args to completion interpreter. Users - * cast to the struct of their choosing, and CLASSERT that this is - * big enough. For _tons_ of context, kmalloc a struct and store + * cast to the struct of their choosing, and BUILD_BUG_ON oversized + * arguments. For _tons_ of context, kmalloc a struct and store * a pointer to it here. The pointer_arg ensures this struct is at * least big enough for that. */ @@ -1661,10 +1661,6 @@ struct ptlrpcd_ctl { */ char pc_name[16]; /** - * Environment for request interpreters to run in. - */ - struct lu_env pc_env; - /** * CPT the thread is bound on. */ int pc_cpt; diff --git a/drivers/staging/lustre/lustre/include/lustre_obdo.h b/drivers/staging/lustre/lustre/include/lustre_obdo.h new file mode 100644 index 000000000000..1e12f8c0f157 --- /dev/null +++ b/drivers/staging/lustre/lustre/include/lustre_obdo.h @@ -0,0 +1,54 @@ +/* + * 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.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, 2014, Intel Corporation. + * + * Copyright 2015 Cray Inc, all rights reserved. + * Author: Ben Evans. + * + * Define obdo associated functions + * obdo: OBject Device o... + */ + +#ifndef _LUSTRE_OBDO_H_ +#define _LUSTRE_OBDO_H_ + +#include "lustre/lustre_idl.h" + +/** + * Create an obdo to send over the wire + */ +void lustre_set_wire_obdo(const struct obd_connect_data *ocd, + struct obdo *wobdo, + const struct obdo *lobdo); + +/** + * Create a local obdo from a wire based odbo + */ +void lustre_get_wire_obdo(const struct obd_connect_data *ocd, + struct obdo *lobdo, + const struct obdo *wobdo); + +#endif diff --git a/drivers/staging/lustre/lustre/include/lustre_req_layout.h b/drivers/staging/lustre/lustre/include/lustre_req_layout.h index fbcd39572cd0..cd62ccd53e2c 100644 --- a/drivers/staging/lustre/lustre/include/lustre_req_layout.h +++ b/drivers/staging/lustre/lustre/include/lustre_req_layout.h @@ -39,6 +39,8 @@ #ifndef _LUSTRE_REQ_LAYOUT_H__ #define _LUSTRE_REQ_LAYOUT_H__ +#include <linux/types.h> + /** \defgroup req_layout req_layout * * @{ @@ -66,11 +68,6 @@ struct req_capsule { __u32 rc_area[RCL_NR][REQ_MAX_FIELD_NR]; }; -#if !defined(__REQ_LAYOUT_USER__) - -/* struct ptlrpc_request, lustre_msg* */ -#include "lustre_net.h" - void req_capsule_init(struct req_capsule *pill, struct ptlrpc_request *req, enum req_location location); void req_capsule_fini(struct req_capsule *pill); @@ -120,9 +117,6 @@ void req_capsule_shrink(struct req_capsule *pill, int req_layout_init(void); void req_layout_fini(void); -/* __REQ_LAYOUT_USER__ */ -#endif - extern struct req_format RQF_OBD_PING; extern struct req_format RQF_OBD_SET_INFO; extern struct req_format RQF_SEC_CTX; diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 0f48e9c3d9e3..4ce85064f9d0 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -43,6 +43,7 @@ #include "lustre_fld.h" #include "lustre_handles.h" #include "lustre_intent.h" +#include "cl_object.h" #define MAX_OBD_DEVICES 8192 @@ -76,6 +77,8 @@ static inline void loi_init(struct lov_oinfo *loi) struct lov_stripe_md; struct obd_info; +int lov_read_and_clear_async_rc(struct cl_object *clob); + typedef int (*obd_enqueue_update_f)(void *cookie, int rc); /* obd info for a particular level (lov, osc). */ @@ -284,6 +287,8 @@ struct client_obd { * the transaction has NOT yet committed. */ atomic_long_t cl_unstable_count; + /** Link to osc_shrinker_list */ + struct list_head cl_shrink_list; /* number of in flight destroy rpcs is limited to max_rpcs_in_flight */ atomic_t cl_destroy_in_flight; @@ -398,18 +403,10 @@ struct lmv_tgt_desc { unsigned long ltd_active:1; /* target up for requests */ }; -enum placement_policy { - PLACEMENT_CHAR_POLICY = 0, - PLACEMENT_NID_POLICY = 1, - PLACEMENT_INVAL_POLICY = 2, - PLACEMENT_MAX_POLICY -}; - struct lmv_obd { int refcount; struct lu_client_fld lmv_fld; spinlock_t lmv_lock; - enum placement_policy lmv_placement; struct lmv_desc desc; struct obd_uuid cluuid; struct obd_export *exp; @@ -478,16 +475,12 @@ struct niobuf_local { * Events signalled through obd_notify() upcall-chain. */ enum obd_notify_event { - /* target added */ - OBD_NOTIFY_CREATE, /* Device connect start */ OBD_NOTIFY_CONNECT, /* Device activated */ OBD_NOTIFY_ACTIVE, /* Device deactivated */ OBD_NOTIFY_INACTIVE, - /* Device disconnected */ - OBD_NOTIFY_DISCON, /* Connect data for import were changed */ OBD_NOTIFY_OCD, /* Sync request */ @@ -758,6 +751,7 @@ struct md_enqueue_info { struct lookup_intent mi_it; struct lustre_handle mi_lockh; struct inode *mi_dir; + struct ldlm_enqueue_info mi_einfo; int (*mi_cb)(struct ptlrpc_request *req, struct md_enqueue_info *minfo, int rc); void *mi_cbdata; @@ -889,7 +883,7 @@ struct obd_client_handle { struct md_open_data *och_mod; struct lustre_handle och_lease_handle; /* open lock for lease */ __u32 och_magic; - int och_flags; + fmode_t och_flags; }; #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed @@ -975,8 +969,7 @@ struct md_ops { struct lu_fid *fid); int (*intent_getattr_async)(struct obd_export *, - struct md_enqueue_info *, - struct ldlm_enqueue_info *); + struct md_enqueue_info *); int (*revalidate_lock)(struct obd_export *, struct lookup_intent *, struct lu_fid *, __u64 *bits); diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 7ec25202cd22..083a6ff56a05 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -1444,14 +1444,13 @@ static inline int md_init_ea_size(struct obd_export *exp, u32 easize, } static inline int md_intent_getattr_async(struct obd_export *exp, - struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo) + struct md_enqueue_info *minfo) { int rc; EXP_CHECK_MD_OP(exp, intent_getattr_async); EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async); - rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo, einfo); + rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); return rc; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c index 32b73ee62639..08f97e2117ed 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c @@ -162,7 +162,7 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, struct interval_node *found, **root; struct ldlm_interval *node; struct ldlm_extent *extent; - int idx; + int idx, rc; LASSERT(lock->l_granted_mode == lock->l_req_mode); @@ -176,7 +176,8 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, /* node extent initialize */ extent = &lock->l_policy_data.l_extent; - interval_set(&node->li_node, extent->start, extent->end); + rc = interval_set(&node->li_node, extent->start, extent->end); + LASSERT(!rc); root = &res->lr_itree[idx].lit_root; found = interval_insert(&node->li_node, root); @@ -243,7 +244,6 @@ void ldlm_extent_unlink_lock(struct ldlm_lock *lock) void ldlm_extent_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy, union ldlm_policy_data *lpolicy) { - memset(lpolicy, 0, sizeof(*lpolicy)); lpolicy->l_extent.start = wpolicy->l_extent.start; lpolicy->l_extent.end = wpolicy->l_extent.end; lpolicy->l_extent.gid = wpolicy->l_extent.gid; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c index 722160784f83..b7f28b39c7b3 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c @@ -143,7 +143,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int added = (mode == LCK_NL); int overlaps = 0; int splitted = 0; - const struct ldlm_callback_suite null_cbs = { NULL }; + const struct ldlm_callback_suite null_cbs = { }; CDEBUG(D_DLMTRACE, "flags %#llx owner %llu pid %u mode %u start %llu end %llu\n", @@ -615,7 +615,6 @@ EXPORT_SYMBOL(ldlm_flock_completion_ast); void ldlm_flock_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy, union ldlm_policy_data *lpolicy) { - memset(lpolicy, 0, sizeof(*lpolicy)); lpolicy->l_flock.start = wpolicy->l_flock.lfw_start; lpolicy->l_flock.end = wpolicy->l_flock.lfw_end; lpolicy->l_flock.pid = wpolicy->l_flock.lfw_pid; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c index 8e1709dc073c..ae37c3686b1b 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c @@ -57,7 +57,6 @@ void ldlm_ibits_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy, union ldlm_policy_data *lpolicy) { - memset(lpolicy, 0, sizeof(*lpolicy)); lpolicy->l_inodebits.bits = wpolicy->l_inodebits.bits; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index 9be01426c955..3663c5cdb051 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -336,6 +336,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) INIT_LIST_HEAD(&cli->cl_lru_list); spin_lock_init(&cli->cl_lru_list_lock); atomic_long_set(&cli->cl_unstable_count, 0); + INIT_LIST_HEAD(&cli->cl_shrink_list); init_waitqueue_head(&cli->cl_destroy_waitq); atomic_set(&cli->cl_destroy_in_flight, 0); @@ -350,13 +351,11 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) cli->cl_supp_cksum_types = OBD_CKSUM_CRC32; atomic_set(&cli->cl_resends, OSC_DEFAULT_RESENDS); - /* This value may be reduced at connect time in - * ptlrpc_connect_interpret() . We initialize it to only - * 1MB until we know what the performance looks like. - * In the future this should likely be increased. LU-1431 + /* + * Set it to possible maximum size. It may be reduced by ocd_brw_size + * from OFD after connecting. */ - cli->cl_max_pages_per_rpc = min_t(int, PTLRPC_MAX_BRW_PAGES, - LNET_MTU >> PAGE_SHIFT); + cli->cl_max_pages_per_rpc = PTLRPC_MAX_BRW_PAGES; /* * set cl_chunkbits default value to PAGE_CACHE_SHIFT, @@ -524,6 +523,8 @@ int client_connect_import(const struct lu_env *env, rc = ptlrpc_connect_import(imp); if (rc != 0) { + if (data && is_mdc) + data->ocd_connect_flags &= ~OBD_CONNECT_MULTIMODRPCS; LASSERT(imp->imp_state == LUSTRE_IMP_DISCON); goto out_ldlm; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index a4a291acb659..5a94265fe60b 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -533,6 +533,13 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, if (!lock) return NULL; + if (lock->l_export && lock->l_export->exp_failed) { + CDEBUG(D_INFO, "lock export failed: lock %p, exp %p\n", + lock, lock->l_export); + LDLM_LOCK_PUT(lock); + return NULL; + } + /* It's unlikely but possible that someone marked the lock as * destroyed after we did handle2object on it */ @@ -1131,8 +1138,7 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) if (!data->lmd_unref && LDLM_HAVE_MASK(lock, GONE)) return INTERVAL_ITER_CONT; - if ((data->lmd_flags & LDLM_FL_LOCAL_ONLY) && - !ldlm_is_local(lock)) + if (!equi(data->lmd_flags & LDLM_FL_LOCAL_ONLY, ldlm_is_local(lock))) return INTERVAL_ITER_CONT; if (data->lmd_flags & LDLM_FL_TEST_LOCK) { @@ -1148,7 +1154,7 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) return INTERVAL_ITER_STOP; } -static unsigned int itree_overlap_cb(struct interval_node *in, void *args) +static enum interval_iter itree_overlap_cb(struct interval_node *in, void *args) { struct ldlm_interval *node = to_ldlm_interval(in); struct lock_match_data *data = args; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index c1f8693f94a5..ebfda368b057 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1972,7 +1972,7 @@ static int replay_one_lock(struct obd_import *imp, struct ldlm_lock *lock) LDLM_DEBUG(lock, "replaying lock:"); atomic_inc(&req->rq_import->imp_replay_inflight); - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); aa->lock_handle = body->lock_handle[0]; req->rq_interpret_reply = (ptlrpc_interpterer_t)replay_lock_interpret; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index b22f5bae7201..d16f5e95ef0b 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -1368,7 +1368,7 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res) struct ldlm_lock *lock; unsigned int granted = 0; - CLASSERT(RES_NAME_SIZE == 4); + BUILD_BUG_ON(RES_NAME_SIZE != 4); if (!((libcfs_debug | D_ERROR) & level)) return; diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 65bf0c401b44..966f580e26fb 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -247,17 +247,14 @@ static int ll_revalidate_dentry(struct dentry *dentry, return 1; /* - * if open&create is set, talk to MDS to make sure file is created if - * necessary, because we can't do this in ->open() later since that's - * called on an inode. return 0 here to let lookup to handle this. + * VFS warns us that this is the second go around and previous + * operation failed (most likely open|creat), so this time + * we better talk to the server via the lookup path by name, + * not by fid. */ - if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == - (LOOKUP_OPEN | LOOKUP_CREATE)) + if (lookup_flags & LOOKUP_REVAL) return 0; - if (lookup_flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE)) - return 1; - if (!dentry_may_statahead(dir, dentry)) return 1; diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index ea5d247a3f70..13b35922a4ca 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -432,7 +432,7 @@ static int ll_dir_setdirstripe(struct inode *parent, struct lmv_user_md *lump, if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent))) mode &= ~current_umask(); - mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; + mode = (mode & (0777 | S_ISVTX)) | S_IFDIR; op_data = ll_prep_md_op_data(NULL, parent, NULL, dirname, strlen(dirname), mode, LUSTRE_OPC_MKDIR, lump); @@ -521,12 +521,15 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, rc = md_setattr(sbi->ll_md_exp, op_data, lump, lum_size, &req); ll_finish_md_op_data(op_data); ptlrpc_req_finished(req); - if (rc) { - if (rc != -EPERM && rc != -EACCES) - CERROR("mdc_setattr fails: rc = %d\n", rc); - } + if (rc) + return rc; - /* In the following we use the fact that LOV_USER_MAGIC_V1 and +#if OBD_OCD_VERSION(2, 13, 53, 0) > LUSTRE_VERSION_CODE + /* + * 2.9 server has stored filesystem default stripe in ROOT xattr, + * and it's stored into system config for backward compatibility. + * + * In the following we use the fact that LOV_USER_MAGIC_V1 and * LOV_USER_MAGIC_V3 have the same initial fields so we do not * need to make the distinction between the 2 versions */ @@ -567,6 +570,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, end: kfree(param); } +#endif return rc; } diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index f634c11216e6..10adfcdd7035 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -122,26 +122,25 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, enum mds_op_bias bias, void *data) { - struct obd_export *exp = ll_i2mdexp(inode); + const struct ll_inode_info *lli = ll_i2info(inode); struct md_op_data *op_data; struct ptlrpc_request *req = NULL; - struct obd_device *obd = class_exp2obd(exp); int rc; - if (!obd) { - /* - * XXX: in case of LMV, is this correct to access - * ->exp_handle? - */ - CERROR("Invalid MDC connection handle %#llx\n", - ll_i2mdexp(inode)->exp_handle.h_cookie); + if (!class_exp2obd(md_exp)) { + CERROR("%s: invalid MDC connection handle closing " DFID "\n", + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(&lli->lli_fid)); rc = 0; goto out; } op_data = kzalloc(sizeof(*op_data), GFP_NOFS); + /* + * We leak openhandle and request here on error, but not much to be + * done in OOM case since app won't retry close on error either. + */ if (!op_data) { - /* XXX We leak openhandle and request here. */ rc = -ENOMEM; goto out; } @@ -170,10 +169,9 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, } rc = md_close(md_exp, op_data, och->och_mod, &req); - if (rc) { - CERROR("%s: inode "DFID" mdc close failed: rc = %d\n", - ll_i2mdexp(inode)->exp_obd->obd_name, - PFID(ll_inode2fid(inode)), rc); + if (rc && rc != -EINTR) { + CERROR("%s: inode " DFID " mdc close failed: rc = %d\n", + md_exp->exp_obd->obd_name, PFID(&lli->lli_fid), rc); } if (op_data->op_bias & (MDS_HSM_RELEASE | MDS_CLOSE_LAYOUT_SWAP) && @@ -192,8 +190,7 @@ out: och->och_fh.cookie = DEAD_HANDLE_MAGIC; kfree(och); - if (req) /* This is close request */ - ptlrpc_req_finished(req); + ptlrpc_req_finished(req); return rc; } @@ -420,6 +417,17 @@ out: ptlrpc_req_finished(req); ll_intent_drop_lock(itp); + /* + * We did open by fid, but by the time we got to the server, + * the object disappeared. If this is a create, we cannot really + * tell the userspace that the file it was trying to create + * does not exist. Instead let's return -ESTALE, and the VFS will + * retry the create with LOOKUP_REVAL that we are going to catch + * in ll_revalidate_dentry() and use lookup then. + */ + if (rc == -ENOENT && itp->it_op & IT_CREAT) + rc = -ESTALE; + return rc; } @@ -1016,7 +1024,7 @@ static bool file_is_noatime(const struct file *file) return false; } -void ll_io_init(struct cl_io *io, const struct file *file, int write) +static void ll_io_init(struct cl_io *io, const struct file *file, int write) { struct inode *inode = file_inode(file); @@ -1821,7 +1829,7 @@ free: return rc; } -static int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss) +int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss) { struct md_op_data *op_data; int rc; @@ -1883,7 +1891,7 @@ static int ll_hsm_import(struct inode *inode, struct file *file, goto free_hss; } - attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + attr->ia_mode = hui->hui_mode & 0777; attr->ia_mode |= S_IFREG; attr->ia_uid = make_kuid(&init_user_ns, hui->hui_uid); attr->ia_gid = make_kgid(&init_user_ns, hui->hui_gid); @@ -2618,18 +2626,18 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx, ll_get_fsname(parent->i_sb, NULL, 0), name, PFID(&op_data->op_fid3)); rc = -EINVAL; - goto out_free; + goto out_unlock; } rc = ll_get_mdt_idx_by_fid(ll_i2sbi(parent), &op_data->op_fid3); if (rc < 0) - goto out_free; + goto out_unlock; if (rc == mdtidx) { CDEBUG(D_INFO, "%s:"DFID" is already on MDT%d.\n", name, PFID(&op_data->op_fid3), mdtidx); rc = 0; - goto out_free; + goto out_unlock; } again: if (S_ISREG(child_inode->i_mode)) { @@ -2637,13 +2645,13 @@ again: if (IS_ERR(och)) { rc = PTR_ERR(och); och = NULL; - goto out_free; + goto out_unlock; } rc = ll_data_version(child_inode, &data_version, LL_DV_WR_FLUSH); if (rc) - goto out_free; + goto out_close; op_data->op_handle = och->och_fh; op_data->op_data = och->och_mod; @@ -2656,40 +2664,45 @@ again: op_data->op_cli_flags = CLI_MIGRATE; rc = md_rename(ll_i2sbi(parent)->ll_md_exp, op_data, name, namelen, name, namelen, &request); - if (!rc) + if (!rc) { + LASSERT(request); ll_update_times(request, parent); - body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); - if (!body) { - rc = -EPROTO; - goto out_free; + body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); + LASSERT(body); + + /* + * If the server does release layout lock, then we cleanup + * the client och here, otherwise release it in out_close: + */ + if (och && body->mbo_valid & OBD_MD_CLOSE_INTENT_EXECED) { + obd_mod_put(och->och_mod); + md_clear_open_replay_data(ll_i2sbi(parent)->ll_md_exp, + och); + och->och_fh.cookie = DEAD_HANDLE_MAGIC; + kfree(och); + och = NULL; + } } - /* - * If the server does release layout lock, then we cleanup - * the client och here, otherwise release it in out_free: - */ - if (och && body->mbo_valid & OBD_MD_CLOSE_INTENT_EXECED) { - obd_mod_put(och->och_mod); - md_clear_open_replay_data(ll_i2sbi(parent)->ll_md_exp, och); - och->och_fh.cookie = DEAD_HANDLE_MAGIC; - kfree(och); - och = NULL; + if (request) { + ptlrpc_req_finished(request); + request = NULL; } - ptlrpc_req_finished(request); /* Try again if the file layout has changed. */ if (rc == -EAGAIN && S_ISREG(child_inode->i_mode)) goto again; -out_free: - if (child_inode) { - if (och) /* close the file */ - ll_lease_close(och, child_inode, NULL); - clear_nlink(child_inode); - inode_unlock(child_inode); - iput(child_inode); - } +out_close: + if (och) /* close the file */ + ll_lease_close(och, child_inode, NULL); + if (!rc) + clear_nlink(child_inode); +out_unlock: + inode_unlock(child_inode); + iput(child_inode); +out_free: ll_finish_md_op_data(op_data); return rc; } diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index dd1cfd8f5213..f1036f477a51 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -94,6 +94,7 @@ int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr, io = vvp_env_thread_io(env); io->ci_obj = obj; + io->ci_verify_layout = 1; io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime); io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime); @@ -120,13 +121,7 @@ again: cl_io_fini(env, io); if (unlikely(io->ci_need_restart)) goto again; - /* HSM import case: file is released, cannot be restored - * no need to fail except if restore registration failed - * with -ENODATA - */ - if (result == -ENODATA && io->ci_restore_needed && - io->ci_result != -ENODATA) - result = 0; + cl_env_put(env, &refcheck); return result; } diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index f48660ed350f..f0c132e2cf92 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -33,6 +33,7 @@ * future). * */ +#define DEBUG_SUBSYSTEM S_LLITE #include "../include/obd_class.h" #include "../include/obd_support.h" #include "../include/obd.h" @@ -132,7 +133,6 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, io = vvp_env_thread_io(env); io->ci_obj = obj; - io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc != 0) { diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 065a9a7e120a..ecdfd0c29b7f 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -281,10 +281,8 @@ static inline struct ll_inode_info *ll_i2info(struct inode *inode) return container_of(inode, struct ll_inode_info, lli_vfs_inode); } -/* default to about 40meg of readahead on a given system. That much tied - * up in 512k readahead requests serviced at 40ms each is about 1GB/s. - */ -#define SBI_DEFAULT_READAHEAD_MAX (40UL << (20 - PAGE_SHIFT)) +/* default to about 64M of readahead on a given system. */ +#define SBI_DEFAULT_READAHEAD_MAX (64UL << (20 - PAGE_SHIFT)) /* default to read-ahead full files smaller than 2MB on the second read */ #define SBI_DEFAULT_READAHEAD_WHOLE_MAX (2UL << (20 - PAGE_SHIFT)) @@ -321,6 +319,9 @@ struct ll_ra_info { struct ra_io_arg { unsigned long ria_start; /* start offset of read-ahead*/ unsigned long ria_end; /* end offset of read-ahead*/ + unsigned long ria_reserved; /* reserved pages for read-ahead */ + unsigned long ria_end_min; /* minimum end to cover current read */ + bool ria_eof; /* reach end of file */ /* If stride read pattern is detected, ria_stoff means where * stride read is started. Note: for normal read-ahead, the * value here is meaningless, and also it will not be accessed @@ -505,6 +506,7 @@ struct ll_sb_info { */ /* root squash */ struct root_squash_info ll_squash; + struct path ll_mnt; __kernel_fsid_t ll_fsid; struct kobject ll_kobj; /* sysfs object */ @@ -551,6 +553,11 @@ struct ll_readahead_state { */ unsigned long ras_window_start, ras_window_len; /* + * Optimal RPC size. It decides how many pages will be sent + * for each read-ahead. + */ + unsigned long ras_rpc_size; + /* * Where next read-ahead should start at. This lies within read-ahead * window. Read-ahead window is read in pieces rather than at once * because: 1. lustre limits total number of pages under read-ahead by @@ -766,6 +773,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode); int ll_fid2path(struct inode *inode, void __user *arg); int ll_data_version(struct inode *inode, __u64 *data_version, int flags); int ll_hsm_release(struct inode *inode); +int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss); /* llite/dcache.c */ diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 25f5aed97f63..b229cbc7bb33 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -103,6 +103,7 @@ static struct ll_sb_info *ll_init_sbi(struct super_block *sb) sbi->ll_flags |= LL_SBI_CHECKSUM; sbi->ll_flags |= LL_SBI_LRU_RESIZE; + sbi->ll_flags |= LL_SBI_LAZYSTATFS; for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) { spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. @@ -303,6 +304,7 @@ 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_mnt.mnt = current->fs->root.mnt; if ((sbi->ll_flags & LL_SBI_USER_XATTR) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { @@ -1402,7 +1404,11 @@ static int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data) * cache is not cleared yet. */ op_data->op_attr.ia_valid &= ~(TIMES_SET_FLAGS | ATTR_SIZE); + if (S_ISREG(inode->i_mode)) + inode_lock(inode); rc = simple_setattr(dentry, &op_data->op_attr); + if (S_ISREG(inode->i_mode)) + inode_unlock(inode); op_data->op_attr.ia_valid = ia_valid; rc = ll_update_inode(inode, &md); @@ -1431,7 +1437,6 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) struct inode *inode = d_inode(dentry); struct ll_inode_info *lli = ll_i2info(inode); struct md_op_data *op_data = NULL; - bool file_is_released = false; int rc = 0; CDEBUG(D_VFSTRACE, "%s: setattr inode "DFID"(%p) from %llu to %llu, valid %x, hsm_import %d\n", @@ -1486,76 +1491,35 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime), (s64)ktime_get_real_seconds()); - /* We always do an MDS RPC, even if we're only changing the size; - * only the MDS knows whether truncate() should fail with -ETXTBUSY - */ - - op_data = kzalloc(sizeof(*op_data), GFP_NOFS); - if (!op_data) - return -ENOMEM; - - if (!S_ISDIR(inode->i_mode)) + if (S_ISREG(inode->i_mode)) inode_unlock(inode); - /* truncate on a released file must failed with -ENODATA, - * so size must not be set on MDS for released file - * but other attributes must be set + /* + * We always do an MDS RPC, even if we're only changing the size; + * only the MDS knows whether truncate() should fail with -ETXTBUSY */ - if (S_ISREG(inode->i_mode)) { - struct cl_layout cl = { - .cl_is_released = false, - }; - struct lu_env *env; - int refcheck; - __u32 gen; + op_data = kzalloc(sizeof(*op_data), GFP_NOFS); + if (!op_data) { + rc = -ENOMEM; + goto out; + } - rc = ll_layout_refresh(inode, &gen); - if (rc < 0) - goto out; + op_data->op_attr = *attr; + if (!hsm_import && attr->ia_valid & ATTR_SIZE) { /* - * XXX: the only place we need to know the layout type, - * this will be removed by a later patch. -Jinshan + * If we are changing file size, file content is + * modified, flag it. */ - env = cl_env_get(&refcheck); - if (IS_ERR(env)) { - rc = PTR_ERR(env); - goto out; - } - - rc = cl_object_layout_get(env, lli->lli_clob, &cl); - cl_env_put(env, &refcheck); - if (rc < 0) - goto out; - - file_is_released = cl.cl_is_released; - - if (!hsm_import && attr->ia_valid & ATTR_SIZE) { - if (file_is_released) { - rc = ll_layout_restore(inode, 0, attr->ia_size); - if (rc < 0) - goto out; - - file_is_released = false; - ll_layout_refresh(inode, &gen); - } - - /* - * If we are changing file size, file content is - * modified, flag it. - */ - attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE; - op_data->op_bias |= MDS_DATA_MODIFIED; - } + attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE; + op_data->op_bias |= MDS_DATA_MODIFIED; } - memcpy(&op_data->op_attr, attr, sizeof(*attr)); - rc = ll_md_setattr(dentry, op_data); if (rc) goto out; - if (!S_ISREG(inode->i_mode) || file_is_released) { + if (!S_ISREG(inode->i_mode) || hsm_import) { rc = 0; goto out; } @@ -1572,11 +1536,40 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) */ rc = cl_setattr_ost(ll_i2info(inode)->lli_clob, attr, 0); } + + /* + * If the file was restored, it needs to set dirty flag. + * + * We've already sent MDS_DATA_MODIFIED flag in + * ll_md_setattr() for truncate. However, the MDT refuses to + * set the HS_DIRTY flag on released files, so we have to set + * it again if the file has been restored. Please check how + * LLIF_DATA_MODIFIED is set in vvp_io_setattr_fini(). + * + * Please notice that if the file is not released, the previous + * MDS_DATA_MODIFIED has taken effect and usually + * LLIF_DATA_MODIFIED is not set(see vvp_io_setattr_fini()). + * This way we can save an RPC for common open + trunc + * operation. + */ + if (test_and_clear_bit(LLIF_DATA_MODIFIED, &lli->lli_flags)) { + struct hsm_state_set hss = { + .hss_valid = HSS_SETMASK, + .hss_setmask = HS_DIRTY, + }; + int rc2; + + rc2 = ll_hsm_state_set(inode, &hss); + if (rc2 < 0) + CERROR(DFID "HSM set dirty failed: rc2 = %d\n", + PFID(ll_inode2fid(inode)), rc2); + } + out: if (op_data) ll_finish_md_op_data(op_data); - if (!S_ISDIR(inode->i_mode)) { + if (S_ISREG(inode->i_mode)) { inode_lock(inode); if ((attr->ia_valid & ATTR_SIZE) && !hsm_import) inode_dio_wait(inode); @@ -1599,7 +1592,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr) if (((attr->ia_valid & (ATTR_MODE | ATTR_FORCE | ATTR_SIZE)) == (ATTR_SIZE | ATTR_MODE)) && (((mode & S_ISUID) && !(attr->ia_mode & S_ISUID)) || - (((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) && + (((mode & (S_ISGID | 0010)) == (S_ISGID | 0010)) && !(attr->ia_mode & S_ISGID)))) attr->ia_valid |= ATTR_FORCE; @@ -1610,7 +1603,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr) attr->ia_valid |= ATTR_KILL_SUID; if ((attr->ia_valid & ATTR_MODE) && - ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) && + ((mode & (S_ISGID | 0010)) == (S_ISGID | 0010)) && !(attr->ia_mode & S_ISGID) && !(attr->ia_valid & ATTR_KILL_SGID)) attr->ia_valid |= ATTR_KILL_SGID; @@ -1998,6 +1991,8 @@ void ll_umount_begin(struct super_block *sb) struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_device *obd; struct obd_ioctl_data *ioc_data; + wait_queue_head_t waitq; + struct l_wait_info lwi; CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb, sb->s_count, atomic_read(&sb->s_active)); @@ -2030,9 +2025,14 @@ void ll_umount_begin(struct super_block *sb) } /* Really, we'd like to wait until there are no requests outstanding, - * and then continue. For now, we just invalidate the requests, - * schedule() and sleep one second if needed, and hope. + * and then continue. For now, we just periodically checking for vfs + * to decrement mnt_cnt and hope to finish it within 10sec. */ + init_waitqueue_head(&waitq); + lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(10), + cfs_time_seconds(1), NULL, NULL); + l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), &lwi); + schedule(); } diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 03682c10fc9e..f3ee584157e0 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -924,27 +924,29 @@ static ssize_t ll_unstable_stats_seq_write(struct file *file, } LPROC_SEQ_FOPS(ll_unstable_stats); -static ssize_t root_squash_show(struct kobject *kobj, struct attribute *attr, - char *buf) +static int ll_root_squash_seq_show(struct seq_file *m, void *v) { - struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, - ll_kobj); + struct super_block *sb = m->private; + struct ll_sb_info *sbi = ll_s2sbi(sb); struct root_squash_info *squash = &sbi->ll_squash; - return sprintf(buf, "%u:%u\n", squash->rsi_uid, squash->rsi_gid); + seq_printf(m, "%u:%u\n", squash->rsi_uid, squash->rsi_gid); + return 0; } -static ssize_t root_squash_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) +static ssize_t ll_root_squash_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { - struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, - ll_kobj); + struct seq_file *m = file->private_data; + struct super_block *sb = m->private; + struct ll_sb_info *sbi = ll_s2sbi(sb); struct root_squash_info *squash = &sbi->ll_squash; return lprocfs_wr_root_squash(buffer, count, squash, - ll_get_fsname(sbi->ll_sb, NULL, 0)); + ll_get_fsname(sb, NULL, 0)); } -LUSTRE_RW_ATTR(root_squash); +LPROC_SEQ_FOPS(ll_root_squash); static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v) { @@ -997,6 +999,8 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "statahead_stats", &ll_statahead_stats_fops, NULL, 0 }, { "unstable_stats", &ll_unstable_stats_fops, NULL }, { "sbi_flags", &ll_sbi_flags_fops, NULL, 0 }, + { .name = "root_squash", + .fops = &ll_root_squash_fops }, { .name = "nosquash_nids", .fops = &ll_nosquash_nids_fops }, { NULL } @@ -1027,7 +1031,6 @@ static struct attribute *llite_attrs[] = { &lustre_attr_max_easize.attr, &lustre_attr_default_easize.attr, &lustre_attr_xattr_cache.attr, - &lustre_attr_root_squash.attr, NULL, }; diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index a8f4e7fb0a46..fc176540bb95 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -994,11 +994,6 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, return rc; } -/* ll_unlink() doesn't update the inode with the new link count. - * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there - * is any lock existing. They will recycle dentries and inodes based upon locks - * too. b=20433 - */ static int ll_unlink(struct inode *dir, struct dentry *dchild) { struct ptlrpc_request *request = NULL; @@ -1041,7 +1036,7 @@ static int ll_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) mode &= ~current_umask(); - mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; + mode = (mode & (0777 | S_ISVTX)) | S_IFDIR; err = ll_new_node(dir, dentry, NULL, mode, 0, LUSTRE_OPC_MKDIR); if (!err) @@ -1089,7 +1084,7 @@ static int ll_symlink(struct inode *dir, struct dentry *dentry, CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir="DFID"(%p),target=%.*s\n", dentry, PFID(ll_inode2fid(dir)), dir, 3000, oldname); - err = ll_new_node(dir, dentry, oldname, S_IFLNK | S_IRWXUGO, + err = ll_new_node(dir, dentry, oldname, S_IFLNK | 0777, 0, LUSTRE_OPC_SYMLINK); if (!err) diff --git a/drivers/staging/lustre/lustre/llite/range_lock.c b/drivers/staging/lustre/lustre/llite/range_lock.c index 94c818f1478b..14148a097476 100644 --- a/drivers/staging/lustre/lustre/llite/range_lock.c +++ b/drivers/staging/lustre/lustre/llite/range_lock.c @@ -61,17 +61,23 @@ void range_lock_tree_init(struct range_lock_tree *tree) * Pre: Caller should have allocated the range lock node. * Post: The range lock node is meant to cover [start, end] region */ -void range_lock_init(struct range_lock *lock, __u64 start, __u64 end) +int range_lock_init(struct range_lock *lock, __u64 start, __u64 end) { + int rc; + memset(&lock->rl_node, 0, sizeof(lock->rl_node)); if (end != LUSTRE_EOF) end >>= PAGE_SHIFT; - interval_set(&lock->rl_node, start >> PAGE_SHIFT, end); + rc = interval_set(&lock->rl_node, start >> PAGE_SHIFT, end); + if (rc) + return rc; + INIT_LIST_HEAD(&lock->rl_next_lock); lock->rl_task = NULL; lock->rl_lock_count = 0; lock->rl_blocking_ranges = 0; lock->rl_sequence = 0; + return rc; } static inline struct range_lock *next_lock(struct range_lock *lock) diff --git a/drivers/staging/lustre/lustre/llite/range_lock.h b/drivers/staging/lustre/lustre/llite/range_lock.h index c6d04a6f99fd..779091ccec4e 100644 --- a/drivers/staging/lustre/lustre/llite/range_lock.h +++ b/drivers/staging/lustre/lustre/llite/range_lock.h @@ -76,7 +76,7 @@ struct range_lock_tree { }; void range_lock_tree_init(struct range_lock_tree *tree); -void range_lock_init(struct range_lock *lock, __u64 start, __u64 end); +int range_lock_init(struct range_lock *lock, __u64 start, __u64 end); int range_lock(struct range_lock_tree *tree, struct range_lock *lock); void range_unlock(struct range_lock_tree *tree, struct range_lock *lock); #endif diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index f10e092979fe..50d027e0cfab 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -92,25 +92,6 @@ static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, goto out; } - /* If the non-strided (ria_pages == 0) readahead window - * (ria_start + ret) has grown across an RPC boundary, then trim - * readahead size by the amount beyond the RPC so it ends on an - * RPC boundary. If the readahead window is already ending on - * an RPC boundary (beyond_rpc == 0), or smaller than a full - * RPC (beyond_rpc < ret) the readahead size is unchanged. - * The (beyond_rpc != 0) check is skipped since the conditional - * branch is more expensive than subtracting zero from the result. - * - * Strided read is left unaligned to avoid small fragments beyond - * the RPC boundary from needing an extra read RPC. - */ - if (ria->ria_pages == 0) { - long beyond_rpc = (ria->ria_start + ret) % PTLRPC_MAX_BRW_PAGES; - - if (/* beyond_rpc != 0 && */ beyond_rpc < ret) - ret -= beyond_rpc; - } - if (atomic_add_return(ret, &ra->ra_cur_pages) > ra->ra_max_pages) { atomic_sub(ret, &ra->ra_cur_pages); ret = 0; @@ -147,11 +128,12 @@ void ll_ra_stats_inc(struct inode *inode, enum ra_stat which) #define RAS_CDEBUG(ras) \ CDEBUG(D_READA, \ - "lrp %lu cr %lu cp %lu ws %lu wl %lu nra %lu r %lu ri %lu" \ - "csr %lu sf %lu sp %lu sl %lu\n", \ + "lrp %lu cr %lu cp %lu ws %lu wl %lu nra %lu rpc %lu " \ + "r %lu ri %lu csr %lu sf %lu sp %lu sl %lu\n", \ ras->ras_last_readpage, ras->ras_consecutive_requests, \ ras->ras_consecutive_pages, ras->ras_window_start, \ ras->ras_window_len, ras->ras_next_readahead, \ + ras->ras_rpc_size, \ ras->ras_requests, ras->ras_request_index, \ ras->ras_consecutive_stride_requests, ras->ras_stride_offset, \ ras->ras_stride_pages, ras->ras_stride_length) @@ -261,20 +243,6 @@ out: ria->ria_start, ria->ria_end, ria->ria_stoff, ria->ria_length,\ ria->ria_pages) -/* Limit this to the blocksize instead of PTLRPC_BRW_MAX_SIZE, since we don't - * know what the actual RPC size is. If this needs to change, it makes more - * sense to tune the i_blkbits value for the file based on the OSTs it is - * striped over, rather than having a constant value for all files here. - */ - -/* RAS_INCREASE_STEP should be (1UL << (inode->i_blkbits - PAGE_SHIFT)). - * Temporarily set RAS_INCREASE_STEP to 1MB. After 4MB RPC is enabled - * by default, this should be adjusted corresponding with max_read_ahead_mb - * and max_read_ahead_per_file_mb otherwise the readahead budget can be used - * up quickly which will affect read performance significantly. See LU-2816 - */ -#define RAS_INCREASE_STEP(inode) (ONE_MB_BRW_SIZE >> PAGE_SHIFT) - static inline int stride_io_mode(struct ll_readahead_state *ras) { return ras->ras_consecutive_stride_requests > 1; @@ -345,6 +313,17 @@ static int ria_page_count(struct ra_io_arg *ria) length); } +static unsigned long ras_align(struct ll_readahead_state *ras, + unsigned long index, + unsigned long *remainder) +{ + unsigned long rem = index % ras->ras_rpc_size; + + if (remainder) + *remainder = rem; + return index - rem; +} + /*Check whether the index is in the defined ra-window */ static int ras_inside_ra_window(unsigned long idx, struct ra_io_arg *ria) { @@ -358,42 +337,63 @@ static int ras_inside_ra_window(unsigned long idx, struct ra_io_arg *ria) ria->ria_length < ria->ria_pages); } -static int ll_read_ahead_pages(const struct lu_env *env, - struct cl_io *io, struct cl_page_list *queue, - struct ra_io_arg *ria, - unsigned long *reserved_pages, - pgoff_t *ra_end) +static unsigned long +ll_read_ahead_pages(const struct lu_env *env, struct cl_io *io, + struct cl_page_list *queue, struct ll_readahead_state *ras, + struct ra_io_arg *ria) { struct cl_read_ahead ra = { 0 }; - int rc, count = 0; + unsigned long ra_end = 0; bool stride_ria; pgoff_t page_idx; + int rc; LASSERT(ria); RIA_DEBUG(ria); stride_ria = ria->ria_length > ria->ria_pages && ria->ria_pages > 0; for (page_idx = ria->ria_start; - page_idx <= ria->ria_end && *reserved_pages > 0; page_idx++) { + page_idx <= ria->ria_end && ria->ria_reserved > 0; page_idx++) { if (ras_inside_ra_window(page_idx, ria)) { if (!ra.cra_end || ra.cra_end < page_idx) { + unsigned long end; + cl_read_ahead_release(env, &ra); rc = cl_io_read_ahead(env, io, page_idx, &ra); if (rc < 0) break; + CDEBUG(D_READA, "idx: %lu, ra: %lu, rpc: %lu\n", + page_idx, ra.cra_end, ra.cra_rpc_size); LASSERTF(ra.cra_end >= page_idx, "object: %p, indcies %lu / %lu\n", io->ci_obj, ra.cra_end, page_idx); + /* + * update read ahead RPC size. + * NB: it's racy but doesn't matter + */ + if (ras->ras_rpc_size > ra.cra_rpc_size && + ra.cra_rpc_size > 0) + ras->ras_rpc_size = ra.cra_rpc_size; + /* trim it to align with optimal RPC size */ + end = ras_align(ras, ria->ria_end + 1, NULL); + if (end > 0 && !ria->ria_eof) + ria->ria_end = end - 1; + if (ria->ria_end < ria->ria_end_min) + ria->ria_end = ria->ria_end_min; + if (ria->ria_end > ra.cra_end) + ria->ria_end = ra.cra_end; } - /* If the page is inside the read-ahead window*/ + /* If the page is inside the read-ahead window */ rc = ll_read_ahead_page(env, io, queue, page_idx); - if (!rc) { - (*reserved_pages)--; - count++; - } + if (rc < 0) + break; + + ra_end = page_idx; + if (!rc) + ria->ria_reserved--; } else if (stride_ria) { /* If it is not in the read-ahead window, and it is * read-ahead mode, then check whether it should skip @@ -420,8 +420,7 @@ static int ll_read_ahead_pages(const struct lu_env *env, } cl_read_ahead_release(env, &ra); - *ra_end = page_idx; - return count; + return ra_end; } static int ll_readahead(const struct lu_env *env, struct cl_io *io, @@ -431,7 +430,7 @@ static int ll_readahead(const struct lu_env *env, struct cl_io *io, struct vvp_io *vio = vvp_env_io(env); struct ll_thread_info *lti = ll_env_info(env); struct cl_attr *attr = vvp_env_thread_attr(env); - unsigned long len, mlen = 0, reserved; + unsigned long len, mlen = 0; pgoff_t ra_end, start = 0, end = 0; struct inode *inode; struct ra_io_arg *ria = <i->lti_ria; @@ -478,29 +477,15 @@ static int ll_readahead(const struct lu_env *env, struct cl_io *io, end < vio->vui_ra_start + vio->vui_ra_count - 1) end = vio->vui_ra_start + vio->vui_ra_count - 1; - if (end != 0) { - unsigned long rpc_boundary; - /* - * Align RA window to an optimal boundary. - * - * XXX This would be better to align to cl_max_pages_per_rpc - * instead of PTLRPC_MAX_BRW_PAGES, because the RPC size may - * be aligned to the RAID stripe size in the future and that - * is more important than the RPC size. - */ - /* Note: we only trim the RPC, instead of extending the RPC - * to the boundary, so to avoid reading too much pages during - * random reading. - */ - rpc_boundary = (end + 1) & (~(PTLRPC_MAX_BRW_PAGES - 1)); - if (rpc_boundary > 0) - rpc_boundary--; - - if (rpc_boundary > start) - end = rpc_boundary; + if (end) { + unsigned long end_index; /* Truncate RA window to end of file */ - end = min(end, (unsigned long)((kms - 1) >> PAGE_SHIFT)); + end_index = (unsigned long)((kms - 1) >> PAGE_SHIFT); + if (end_index <= end) { + end = end_index; + ria->ria_eof = true; + } ras->ras_next_readahead = max(end, end + 1); RAS_CDEBUG(ras); @@ -535,28 +520,31 @@ static int ll_readahead(const struct lu_env *env, struct cl_io *io, /* at least to extend the readahead window to cover current read */ if (!hit && vio->vui_ra_valid && vio->vui_ra_start + vio->vui_ra_count > ria->ria_start) { + unsigned long remainder; + /* to the end of current read window. */ mlen = vio->vui_ra_start + vio->vui_ra_count - ria->ria_start; /* trim to RPC boundary */ - start = ria->ria_start & (PTLRPC_MAX_BRW_PAGES - 1); - mlen = min(mlen, PTLRPC_MAX_BRW_PAGES - start); + ras_align(ras, ria->ria_start, &remainder); + mlen = min(mlen, ras->ras_rpc_size - remainder); + ria->ria_end_min = ria->ria_start + mlen; } - reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len, mlen); - if (reserved < len) + ria->ria_reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len, mlen); + if (ria->ria_reserved < len) ll_ra_stats_inc(inode, RA_STAT_MAX_IN_FLIGHT); CDEBUG(D_READA, "reserved pages %lu/%lu/%lu, ra_cur %d, ra_max %lu\n", - reserved, len, mlen, + ria->ria_reserved, len, mlen, atomic_read(&ll_i2sbi(inode)->ll_ra_info.ra_cur_pages), ll_i2sbi(inode)->ll_ra_info.ra_max_pages); - ret = ll_read_ahead_pages(env, io, queue, ria, &reserved, &ra_end); + ra_end = ll_read_ahead_pages(env, io, queue, ras, ria); - if (reserved != 0) - ll_ra_count_put(ll_i2sbi(inode), reserved); + if (ria->ria_reserved) + ll_ra_count_put(ll_i2sbi(inode), ria->ria_reserved); - if (ra_end == end + 1 && ra_end == (kms >> PAGE_SHIFT)) + if (ra_end == end && ra_end == (kms >> PAGE_SHIFT)) ll_ra_stats_inc(inode, RA_STAT_EOF); /* if we didn't get to the end of the region we reserved from @@ -568,13 +556,13 @@ static int ll_readahead(const struct lu_env *env, struct cl_io *io, CDEBUG(D_READA, "ra_end = %lu end = %lu stride end = %lu pages = %d\n", ra_end, end, ria->ria_end, ret); - if (ra_end != end + 1) { + if (ra_end > 0 && ra_end != end) { ll_ra_stats_inc(inode, RA_STAT_FAILED_REACH_END); spin_lock(&ras->ras_lock); - if (ra_end < ras->ras_next_readahead && + if (ra_end <= ras->ras_next_readahead && index_in_window(ra_end, ras->ras_window_start, 0, ras->ras_window_len)) { - ras->ras_next_readahead = ra_end; + ras->ras_next_readahead = ra_end + 1; RAS_CDEBUG(ras); } spin_unlock(&ras->ras_lock); @@ -586,7 +574,7 @@ static int ll_readahead(const struct lu_env *env, struct cl_io *io, static void ras_set_start(struct inode *inode, struct ll_readahead_state *ras, unsigned long index) { - ras->ras_window_start = index & (~(RAS_INCREASE_STEP(inode) - 1)); + ras->ras_window_start = ras_align(ras, index, NULL); } /* called with the ras_lock held or from places where it doesn't matter */ @@ -615,6 +603,7 @@ static void ras_stride_reset(struct ll_readahead_state *ras) void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras) { spin_lock_init(&ras->ras_lock); + ras->ras_rpc_size = PTLRPC_MAX_BRW_PAGES; ras_reset(inode, ras, 0); ras->ras_requests = 0; } @@ -719,12 +708,15 @@ static void ras_increase_window(struct inode *inode, * but current clio architecture does not support retrieve such * information from lower layer. FIXME later */ - if (stride_io_mode(ras)) - ras_stride_increase_window(ras, ra, RAS_INCREASE_STEP(inode)); - else - ras->ras_window_len = min(ras->ras_window_len + - RAS_INCREASE_STEP(inode), - ra->ra_max_pages_per_file); + if (stride_io_mode(ras)) { + ras_stride_increase_window(ras, ra, ras->ras_rpc_size); + } else { + unsigned long wlen; + + wlen = min(ras->ras_window_len + ras->ras_rpc_size, + ra->ra_max_pages_per_file); + ras->ras_window_len = ras_align(ras, wlen, NULL); + } } static void ras_update(struct ll_sb_info *sbi, struct inode *inode, @@ -737,6 +729,10 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, spin_lock(&ras->ras_lock); + if (!hit) + CDEBUG(D_READA, DFID " pages at %lu miss.\n", + PFID(ll_inode2fid(inode)), index); + ll_ra_stats_inc_sbi(sbi, hit ? RA_STAT_HIT : RA_STAT_MISS); /* reset the read-ahead window in two cases. First when the app seeks @@ -852,6 +848,8 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, * instead of ras_window_start, which is RPC aligned */ ras->ras_next_readahead = max(index, ras->ras_next_readahead); + ras->ras_window_start = max(ras->ras_stride_offset, + ras->ras_window_start); } else { if (ras->ras_next_readahead < ras->ras_window_start) ras->ras_next_readahead = ras->ras_window_start; @@ -881,7 +879,7 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, */ ras->ras_next_readahead = max(index, ras->ras_next_readahead); ras->ras_stride_offset = index; - ras->ras_window_len = RAS_INCREASE_STEP(inode); + ras->ras_window_start = max(index, ras->ras_window_start); } /* The initial ras_window_len is set to the request size. To avoid @@ -1098,38 +1096,39 @@ static int ll_io_read_page(const struct lu_env *env, struct cl_io *io, struct cl_2queue *queue = &io->ci_queue; struct ll_sb_info *sbi = ll_i2sbi(inode); struct vvp_page *vpg; + bool uptodate; int rc = 0; vpg = cl2vvp_page(cl_object_page_slice(page->cp_obj, page)); + uptodate = vpg->vpg_defer_uptodate; + if (sbi->ll_ra_info.ra_max_pages_per_file > 0 && sbi->ll_ra_info.ra_max_pages > 0) { struct vvp_io *vio = vvp_env_io(env); enum ras_update_flags flags = 0; - if (vpg->vpg_defer_uptodate) + if (uptodate) flags |= LL_RAS_HIT; if (!vio->vui_ra_valid) flags |= LL_RAS_MMAP; ras_update(sbi, inode, ras, vvp_index(vpg), flags); } - if (vpg->vpg_defer_uptodate) { + cl_2queue_init(queue); + if (uptodate) { vpg->vpg_ra_used = 1; cl_page_export(env, page, 1); + cl_page_disown(env, io, page); + } else { + cl_page_list_add(&queue->c2_qin, page); } - cl_2queue_init(queue); - /* - * Add page into the queue even when it is marked uptodate above. - * this will unlock it automatically as part of cl_page_list_disown(). - */ - cl_page_list_add(&queue->c2_qin, page); if (sbi->ll_ra_info.ra_max_pages_per_file > 0 && sbi->ll_ra_info.ra_max_pages > 0) { int rc2; rc2 = ll_readahead(env, io, &queue->c2_qin, ras, - vpg->vpg_defer_uptodate); + uptodate); CDEBUG(D_READA, DFID "%d pages read ahead at %lu\n", PFID(ll_inode2fid(inode)), rc2, vvp_index(vpg)); } diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 21e06e5b514e..d89e79599199 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -345,6 +345,10 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter) ssize_t tot_bytes = 0, result = 0; long size = MAX_DIO_SIZE; + /* Check EOF by ourselves */ + if (iov_iter_rw(iter) == READ && file_offset >= i_size_read(inode)) + return 0; + /* FIXME: io smaller than PAGE_SIZE is broken on ia64 ??? */ if ((file_offset & ~PAGE_MASK) || (count & ~PAGE_MASK)) return -EINVAL; diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index f1ee17f9ec0d..fb7c315b33cb 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -79,6 +79,8 @@ struct sa_entry { struct inode *se_inode; /* entry name */ struct qstr se_qstr; + /* entry fid */ + struct lu_fid se_fid; }; static unsigned int sai_generation; @@ -169,7 +171,7 @@ static inline int is_omitted_entry(struct ll_statahead_info *sai, __u64 index) /* allocate sa_entry and hash it to allow scanner process to find it */ static struct sa_entry * sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index, - const char *name, int len) + const char *name, int len, const struct lu_fid *fid) { struct ll_inode_info *lli; struct sa_entry *entry; @@ -194,6 +196,7 @@ sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index, entry->se_qstr.hash = full_name_hash(parent, name, len); entry->se_qstr.len = len; entry->se_qstr.name = dname; + entry->se_fid = *fid; lli = ll_i2info(sai->sai_dentry->d_inode); spin_lock(&lli->lli_sa_lock); @@ -566,24 +569,8 @@ static void sa_instantiate(struct ll_statahead_info *sai, } child = entry->se_inode; - if (!child) { - /* - * lookup. - */ - LASSERT(fid_is_zero(&minfo->mi_data.op_fid2)); - - /* XXX: No fid in reply, this is probably cross-ref case. - * SA can't handle it yet. - */ - if (body->mbo_valid & OBD_MD_MDS) { - rc = -EAGAIN; - goto out; - } - } else { - /* - * revalidate. - */ - /* unlinked and re-created with the same name */ + if (child) { + /* revalidate; unlinked and re-created with the same name */ if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->mbo_fid1))) { entry->se_inode = NULL; iput(child); @@ -720,50 +707,42 @@ static int ll_statahead_interpret(struct ptlrpc_request *req, } /* finish async stat RPC arguments */ -static void sa_fini_data(struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo) +static void sa_fini_data(struct md_enqueue_info *minfo) { - LASSERT(minfo && einfo); iput(minfo->mi_dir); kfree(minfo); - kfree(einfo); } /** * prepare arguments for async stat RPC. */ -static int sa_prep_data(struct inode *dir, struct inode *child, - struct sa_entry *entry, struct md_enqueue_info **pmi, - struct ldlm_enqueue_info **pei) +static struct md_enqueue_info * +sa_prep_data(struct inode *dir, struct inode *child, struct sa_entry *entry) { - const struct qstr *qstr = &entry->se_qstr; struct md_enqueue_info *minfo; struct ldlm_enqueue_info *einfo; struct md_op_data *op_data; - einfo = kzalloc(sizeof(*einfo), GFP_NOFS); - if (!einfo) - return -ENOMEM; - minfo = kzalloc(sizeof(*minfo), GFP_NOFS); - if (!minfo) { - kfree(einfo); - return -ENOMEM; - } + if (!minfo) + return ERR_PTR(-ENOMEM); - op_data = ll_prep_md_op_data(&minfo->mi_data, dir, child, qstr->name, - qstr->len, 0, LUSTRE_OPC_ANY, NULL); + op_data = ll_prep_md_op_data(&minfo->mi_data, dir, child, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) { - kfree(einfo); kfree(minfo); - return PTR_ERR(op_data); + return (struct md_enqueue_info *)op_data; } + if (!child) + op_data->op_fid2 = entry->se_fid; + minfo->mi_it.it_op = IT_GETATTR; minfo->mi_dir = igrab(dir); minfo->mi_cb = ll_statahead_interpret; minfo->mi_cbdata = entry; + einfo = &minfo->mi_einfo; einfo->ei_type = LDLM_IBITS; einfo->ei_mode = it_to_lock_mode(&minfo->mi_it); einfo->ei_cb_bl = ll_md_blocking_ast; @@ -771,26 +750,22 @@ static int sa_prep_data(struct inode *dir, struct inode *child, einfo->ei_cb_gl = NULL; einfo->ei_cbdata = NULL; - *pmi = minfo; - *pei = einfo; - - return 0; + return minfo; } /* async stat for file not found in dcache */ static int sa_lookup(struct inode *dir, struct sa_entry *entry) { struct md_enqueue_info *minfo; - struct ldlm_enqueue_info *einfo; int rc; - rc = sa_prep_data(dir, NULL, entry, &minfo, &einfo); - if (rc) - return rc; + minfo = sa_prep_data(dir, NULL, entry); + if (IS_ERR(minfo)) + return PTR_ERR(minfo); - rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo); + rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo); if (rc) - sa_fini_data(minfo, einfo); + sa_fini_data(minfo); return rc; } @@ -809,7 +784,6 @@ static int sa_revalidate(struct inode *dir, struct sa_entry *entry, struct lookup_intent it = { .it_op = IT_GETATTR, .it_lock_handle = 0 }; struct md_enqueue_info *minfo; - struct ldlm_enqueue_info *einfo; int rc; if (unlikely(!inode)) @@ -827,25 +801,26 @@ static int sa_revalidate(struct inode *dir, struct sa_entry *entry, return 1; } - rc = sa_prep_data(dir, inode, entry, &minfo, &einfo); - if (rc) { + minfo = sa_prep_data(dir, inode, entry); + if (IS_ERR(minfo)) { entry->se_inode = NULL; iput(inode); - return rc; + return PTR_ERR(minfo); } - rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo); + rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo); if (rc) { entry->se_inode = NULL; iput(inode); - sa_fini_data(minfo, einfo); + sa_fini_data(minfo); } return rc; } /* async stat for file with @name */ -static void sa_statahead(struct dentry *parent, const char *name, int len) +static void sa_statahead(struct dentry *parent, const char *name, int len, + const struct lu_fid *fid) { struct inode *dir = d_inode(parent); struct ll_inode_info *lli = ll_i2info(dir); @@ -854,7 +829,7 @@ static void sa_statahead(struct dentry *parent, const char *name, int len) struct sa_entry *entry; int rc; - entry = sa_alloc(parent, sai, sai->sai_index, name, len); + entry = sa_alloc(parent, sai, sai->sai_index, name, len, fid); if (IS_ERR(entry)) return; @@ -1043,6 +1018,7 @@ static int ll_statahead_thread(void *arg) for (ent = lu_dirent_start(dp); ent && thread_is_running(sa_thread) && !sa_low_hit(sai); ent = lu_dirent_next(ent)) { + struct lu_fid fid; __u64 hash; int namelen; char *name; @@ -1088,6 +1064,8 @@ static int ll_statahead_thread(void *arg) if (unlikely(++first == 1)) continue; + fid_le_to_cpu(&fid, &ent->lde_fid); + /* wait for spare statahead window */ do { l_wait_event(sa_thread->t_ctl_waitq, @@ -1117,7 +1095,7 @@ static int ll_statahead_thread(void *arg) } while (sa_sent_full(sai) && thread_is_running(sa_thread)); - sa_statahead(parent, name, namelen); + sa_statahead(parent, name, namelen, &fid); } pos = le64_to_cpu(dp->ldp_hash_end); diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 106cd00910a7..4759802e062d 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -88,7 +88,7 @@ static int __init lustre_init(void) struct timespec64 ts; int i, rc, seed[2]; - CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1); + BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) != LUSTRE_VOLATILE_HDR_LEN + 1); /* print an address of _any_ initialized kernel symbol from this * module, to allow debugging with gdb that doesn't support data diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 12c129f7e4ad..3669ea77ee93 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -391,7 +391,7 @@ struct vvp_pgcache_id { static void vvp_pgcache_id_unpack(loff_t pos, struct vvp_pgcache_id *id) { - CLASSERT(sizeof(pos) == sizeof(__u64)); + BUILD_BUG_ON(sizeof(pos) != sizeof(__u64)); id->vpi_index = pos & 0xffffffff; id->vpi_depth = (pos >> PGC_DEPTH_SHIFT) & 0xf; diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index c60d0414ac25..f40fd7f115d1 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -301,8 +301,6 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) # define CLOBINVRNT(env, clob, expr) \ ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr))) -int lov_read_and_clear_async_rc(struct cl_object *clob); - int vvp_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io); int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 697cbfbe9374..3e9cf710501b 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -288,7 +288,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) io->ci_ignore_layout, io->ci_verify_layout, vio->vui_layout_gen, io->ci_restore_needed); - if (io->ci_restore_needed == 1) { + if (io->ci_restore_needed) { int rc; /* file was detected release, we need to restore it @@ -657,7 +657,15 @@ static void vvp_io_setattr_end(const struct lu_env *env, static void vvp_io_setattr_fini(const struct lu_env *env, const struct cl_io_slice *ios) { + bool restore_needed = ios->cis_io->ci_restore_needed; + struct inode *inode = vvp_object_inode(ios->cis_obj); + vvp_io_fini(env, ios); + + if (restore_needed && !ios->cis_io->ci_restore_needed) { + /* restore finished, set data modified flag for HSM */ + set_bit(LLIF_DATA_MODIFIED, &(ll_i2info(inode))->lli_flags); + } } static int vvp_io_read_start(const struct lu_env *env, @@ -1340,13 +1348,6 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, io->ci_lockreq = CILR_MANDATORY; } - /* ignore layout change for generic CIT_MISC but not for glimpse. - * io context for glimpse must set ci_verify_layout to true, - * see cl_glimpse_size0() for details. - */ - if (io->ci_type == CIT_MISC && !io->ci_verify_layout) - io->ci_ignore_layout = 1; - /* Enqueue layout lock and get layout version. We need to do this * even for operations requiring to open file, such as read and write, * because it might not grant layout lock in IT_OPEN. diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 23d66308ff20..687c0c79d621 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -227,7 +227,8 @@ static int vvp_page_prep_write(const struct lu_env *env, * This takes inode as a separate argument, because inode on which error is to * be set can be different from \a vmpage inode in case of direct-io. */ -static void vvp_vmpage_error(struct inode *inode, struct page *vmpage, int ioret) +static void vvp_vmpage_error(struct inode *inode, struct page *vmpage, + int ioret) { struct vvp_object *obj = cl_inode2vvp(inode); diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 7a848ebc57c1..421cc04ecf1e 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -132,6 +132,15 @@ ll_xattr_set_common(const struct xattr_handler *handler, (!strcmp(name, "ima") || !strcmp(name, "evm"))) return -EOPNOTSUPP; + /* + * In user.* namespace, only regular files and directories can have + * extended attributes. + */ + if (handler->flags == XATTR_USER_T) { + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) + return -EPERM; + } + sprintf(fullname, "%s%s\n", handler->prefix, name); rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid, fullname, pv, size, 0, flags, diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c index b1071cf5a70c..aa42066678e0 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c @@ -220,21 +220,7 @@ int lmv_revalidate_slaves(struct obd_export *exp, /* refresh slave from server */ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); - LASSERT(body); - - if (unlikely(body->mbo_nlink < 2)) { - /* - * If this is bad stripe, most likely due - * to the race between close(unlink) and - * getattr, let's return -EONENT, so llite - * will revalidate the dentry see - * ll_inode_revalidate_fini() - */ - CDEBUG(D_INODE, "%s: nlink %d < 2 corrupt stripe %d "DFID":" DFID"\n", - obd->obd_name, body->mbo_nlink, i, - PFID(&lsm->lsm_md_oinfo[i].lmo_fid), - PFID(&lsm->lsm_md_oinfo[0].lmo_fid)); - + if (!body) { if (it.it_lock_mode && lockh) { ldlm_lock_decref(lockh, it.it_lock_mode); it.it_lock_mode = 0; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index f124f6c05ea4..271e18966f50 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -173,14 +173,7 @@ static int lmv_notify(struct obd_device *obd, struct obd_device *watched, */ obd->obd_self_export->exp_connect_data = *conn_data; } -#if 0 - else if (ev == OBD_NOTIFY_DISCON) { - /* - * For disconnect event, flush fld cache for failout MDS case. - */ - fld_client_flush(&lmv->lmv_fld); - } -#endif + /* * Pass the notification up the chain. */ @@ -736,16 +729,18 @@ static int lmv_hsm_req_count(struct lmv_obd *lmv, /* count how many requests must be sent to the given target */ for (i = 0; i < hur->hur_request.hr_itemcount; i++) { curr_tgt = lmv_find_target(lmv, &hur->hur_user_item[i].hui_fid); + if (IS_ERR(curr_tgt)) + return PTR_ERR(curr_tgt); if (obd_uuid_equals(&curr_tgt->ltd_uuid, &tgt_mds->ltd_uuid)) nr++; } return nr; } -static void lmv_hsm_req_build(struct lmv_obd *lmv, - struct hsm_user_request *hur_in, - const struct lmv_tgt_desc *tgt_mds, - struct hsm_user_request *hur_out) +static int lmv_hsm_req_build(struct lmv_obd *lmv, + struct hsm_user_request *hur_in, + const struct lmv_tgt_desc *tgt_mds, + struct hsm_user_request *hur_out) { int i, nr_out; struct lmv_tgt_desc *curr_tgt; @@ -756,6 +751,8 @@ static void lmv_hsm_req_build(struct lmv_obd *lmv, for (i = 0; i < hur_in->hur_request.hr_itemcount; i++) { curr_tgt = lmv_find_target(lmv, &hur_in->hur_user_item[i].hui_fid); + if (IS_ERR(curr_tgt)) + return PTR_ERR(curr_tgt); if (obd_uuid_equals(&curr_tgt->ltd_uuid, &tgt_mds->ltd_uuid)) { hur_out->hur_user_item[nr_out] = hur_in->hur_user_item[i]; @@ -765,13 +762,14 @@ static void lmv_hsm_req_build(struct lmv_obd *lmv, hur_out->hur_request.hr_itemcount = nr_out; memcpy(hur_data(hur_out), hur_data(hur_in), hur_in->hur_request.hr_data_len); + + return 0; } static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, unsigned int cmd, int len, struct lustre_kernelcomm *lk, void __user *uarg) { - int rc = 0; __u32 i; /* unregister request (call from llapi_hsm_copytool_fini) */ @@ -791,9 +789,7 @@ static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, unsigned int cmd, int len, * Unreached coordinators will get EPIPE on next requests * and will unregister automatically. */ - rc = libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group); - - return rc; + return libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group); } static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len, @@ -1044,15 +1040,17 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, } else { /* split fid list to their respective MDS */ for (i = 0; i < count; i++) { - unsigned int nr, reqlen; - int rc1; struct hsm_user_request *req; + size_t reqlen; + int nr, rc1; tgt = lmv->tgts[i]; if (!tgt || !tgt->ltd_exp) continue; nr = lmv_hsm_req_count(lmv, hur, tgt); + if (nr < 0) + return nr; if (nr == 0) /* nothing for this MDS */ continue; @@ -1064,10 +1062,13 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, if (!req) return -ENOMEM; - lmv_hsm_req_build(lmv, hur, tgt, req); + rc1 = lmv_hsm_req_build(lmv, hur, tgt, req); + if (rc1 < 0) + goto hsm_req_err; rc1 = obd_iocontrol(cmd, tgt->ltd_exp, reqlen, req, uarg); +hsm_req_err: if (rc1 != 0 && rc == 0) rc = rc1; kvfree(req); @@ -1276,7 +1277,6 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg) lmv->desc.ld_active_tgt_count = 0; lmv->max_def_easize = 0; lmv->max_easize = 0; - lmv->lmv_placement = PLACEMENT_CHAR_POLICY; spin_lock_init(&lmv->lmv_lock); mutex_init(&lmv->lmv_init_mutex); @@ -1425,8 +1425,7 @@ static int lmv_getstatus(struct obd_export *exp, if (rc) return rc; - rc = md_getstatus(lmv->tgts[0]->ltd_exp, fid); - return rc; + return md_getstatus(lmv->tgts[0]->ltd_exp, fid); } static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid, @@ -1447,10 +1446,8 @@ static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid, if (IS_ERR(tgt)) return PTR_ERR(tgt); - rc = md_getxattr(tgt->ltd_exp, fid, valid, name, input, + return md_getxattr(tgt->ltd_exp, fid, valid, name, input, input_size, output_size, flags, request); - - return rc; } static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid, @@ -1472,11 +1469,9 @@ static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid, if (IS_ERR(tgt)) return PTR_ERR(tgt); - rc = md_setxattr(tgt->ltd_exp, fid, valid, name, input, + return md_setxattr(tgt->ltd_exp, fid, valid, name, input, input_size, output_size, flags, suppgid, request); - - return rc; } static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data, @@ -1500,9 +1495,7 @@ static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data, return 0; } - rc = md_getattr(tgt->ltd_exp, op_data, request); - - return rc; + return md_getattr(tgt->ltd_exp, op_data, request); } static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid) @@ -1549,8 +1542,7 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data, return PTR_ERR(tgt); CDEBUG(D_INODE, "CLOSE "DFID"\n", PFID(&op_data->op_fid1)); - rc = md_close(tgt->ltd_exp, op_data, mod, request); - return rc; + return md_close(tgt->ltd_exp, op_data, mod, request); } /** @@ -1743,10 +1735,8 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, CDEBUG(D_INODE, "ENQUEUE '%s' on " DFID " -> mds #%u\n", LL_IT2STR(it), PFID(&op_data->op_fid1), tgt->ltd_idx); - rc = md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh, + return md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh, extra_lock_flags); - - return rc; } static int @@ -1894,9 +1884,7 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data, if (rc != 0) return rc; - rc = md_link(tgt->ltd_exp, op_data, request); - - return rc; + return md_link(tgt->ltd_exp, op_data, request); } static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data, @@ -2109,8 +2097,7 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid, if (IS_ERR(tgt)) return PTR_ERR(tgt); - rc = md_sync(tgt->ltd_exp, fid, request); - return rc; + return md_sync(tgt->ltd_exp, fid, request); } /** @@ -2428,17 +2415,14 @@ static int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data, return rc; if (unlikely(lsm)) { - rc = lmv_read_striped_page(exp, op_data, cb_op, offset, ppage); - return rc; + return lmv_read_striped_page(exp, op_data, cb_op, offset, ppage); } tgt = lmv_find_target(lmv, &op_data->op_fid1); if (IS_ERR(tgt)) return PTR_ERR(tgt); - rc = md_read_page(tgt->ltd_exp, op_data, cb_op, offset, ppage); - - return rc; + return md_read_page(tgt->ltd_exp, op_data, cb_op, offset, ppage); } /** @@ -2922,13 +2906,11 @@ static int lmv_set_lock_data(struct obd_export *exp, { struct lmv_obd *lmv = &exp->exp_obd->u.lmv; struct lmv_tgt_desc *tgt = lmv->tgts[0]; - int rc; if (!tgt || !tgt->ltd_exp) return -EINVAL; - rc = md_set_lock_data(tgt->ltd_exp, lockh, data, bits); - return rc; + return md_set_lock_data(tgt->ltd_exp, lockh, data, bits); } static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags, @@ -3033,25 +3015,40 @@ static int lmv_clear_open_replay_data(struct obd_export *exp, } static int lmv_intent_getattr_async(struct obd_export *exp, - struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo) + struct md_enqueue_info *minfo) { struct md_op_data *op_data = &minfo->mi_data; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; - struct lmv_tgt_desc *tgt = NULL; + struct lmv_tgt_desc *ptgt = NULL; + struct lmv_tgt_desc *ctgt = NULL; int rc; + if (!fid_is_sane(&op_data->op_fid2)) + return -EINVAL; + rc = lmv_check_connect(obd); if (rc) return rc; - tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1); - if (IS_ERR(tgt)) - return PTR_ERR(tgt); + ptgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1); + if (IS_ERR(ptgt)) + return PTR_ERR(ptgt); - rc = md_intent_getattr_async(tgt->ltd_exp, minfo, einfo); - return rc; + ctgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid2); + if (IS_ERR(ctgt)) + return PTR_ERR(ctgt); + + /* + * if child is on remote MDT, we need 2 async RPCs to fetch both LOOKUP + * lock on parent, and UPDATE lock on child MDT, which makes all + * complicated. Considering remote dir is rare case, and not supporting + * it in statahead won't cause any issue, drop its support for now. + */ + if (ptgt != ctgt) + return -ENOTSUPP; + + return md_intent_getattr_async(ptgt->ltd_exp, minfo); } static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, @@ -3070,8 +3067,7 @@ static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, if (IS_ERR(tgt)) return PTR_ERR(tgt); - rc = md_revalidate_lock(tgt->ltd_exp, it, fid, bits); - return rc; + return md_revalidate_lock(tgt->ltd_exp, it, fid, bits); } static int @@ -3113,8 +3109,7 @@ static int lmv_quotactl(struct obd_device *unused, struct obd_export *exp, } if (oqctl->qc_cmd != Q_GETOQUOTA) { - rc = obd_quotactl(tgt->ltd_exp, oqctl); - return rc; + return obd_quotactl(tgt->ltd_exp, oqctl); } for (i = 0; i < lmv->desc.ld_tgt_count; i++) { @@ -3234,13 +3229,11 @@ static struct md_ops lmv_md_ops = { static int __init lmv_init(void) { struct lprocfs_static_vars lvars; - int rc; lprocfs_lmv_init_vars(&lvars); - rc = class_register_type(&lmv_obd_ops, &lmv_md_ops, + return class_register_type(&lmv_obd_ops, &lmv_md_ops, LUSTRE_LMV_NAME, NULL); - return rc; } static void lmv_exit(void) diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c index 20bbdfc21d15..ff458020b96a 100644 --- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c +++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c @@ -50,73 +50,6 @@ static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr, } LUSTRE_RO_ATTR(numobd); -static const char *placement_name[] = { - [PLACEMENT_CHAR_POLICY] = "CHAR", - [PLACEMENT_NID_POLICY] = "NID", - [PLACEMENT_INVAL_POLICY] = "INVAL" -}; - -static enum placement_policy placement_name2policy(char *name, int len) -{ - int i; - - for (i = 0; i < PLACEMENT_MAX_POLICY; i++) { - if (!strncmp(placement_name[i], name, len)) - return i; - } - return PLACEMENT_INVAL_POLICY; -} - -static const char *placement_policy2name(enum placement_policy placement) -{ - LASSERT(placement < PLACEMENT_MAX_POLICY); - return placement_name[placement]; -} - -static ssize_t placement_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct obd_device *dev = container_of(kobj, struct obd_device, - obd_kobj); - struct lmv_obd *lmv; - - lmv = &dev->u.lmv; - return sprintf(buf, "%s\n", placement_policy2name(lmv->lmv_placement)); -} - -#define MAX_POLICY_STRING_SIZE 64 - -static ssize_t placement_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, - size_t count) -{ - 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; - - memcpy(dummy, buffer, MAX_POLICY_STRING_SIZE); - - if (count > MAX_POLICY_STRING_SIZE) - count = MAX_POLICY_STRING_SIZE; - - if (dummy[count - 1] == '\n') - count--; - dummy[count] = '\0'; - - 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 { - return -EINVAL; - } - return count; -} -LUSTRE_RW_ATTR(placement); - static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -147,7 +80,13 @@ static void *lmv_tgt_seq_start(struct seq_file *p, loff_t *pos) struct obd_device *dev = p->private; struct lmv_obd *lmv = &dev->u.lmv; - return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos]; + while (*pos < lmv->tgts_size) { + if (lmv->tgts[*pos]) + return lmv->tgts[*pos]; + ++*pos; + } + + return NULL; } static void lmv_tgt_seq_stop(struct seq_file *p, void *v) @@ -159,8 +98,15 @@ static void *lmv_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos) { struct obd_device *dev = p->private; struct lmv_obd *lmv = &dev->u.lmv; + ++*pos; - return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos]; + while (*pos < lmv->tgts_size) { + if (lmv->tgts[*pos]) + return lmv->tgts[*pos]; + ++*pos; + } + + return NULL; } static int lmv_tgt_seq_show(struct seq_file *p, void *v) @@ -213,7 +159,6 @@ const struct file_operations lmv_proc_target_fops = { static struct attribute *lmv_attrs[] = { &lustre_attr_activeobd.attr, &lustre_attr_numobd.attr, - &lustre_attr_placement.attr, NULL, }; diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index 002326c282a7..e0f0756ee883 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -1056,9 +1056,12 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, * - in setattr, for truncate */ /* the truncate is for size > 0 so triggers a restore */ - if (cl_io_is_trunc(io)) + if (cl_io_is_trunc(io)) { io->ci_restore_needed = 1; - result = -ENODATA; + result = -ENODATA; + } else { + result = 1; + } break; case CIT_READ: case CIT_WRITE: diff --git a/drivers/staging/lustre/lustre/lov/lov_lock.c b/drivers/staging/lustre/lustre/lov/lov_lock.c index f3a0583f28f5..8502128e8248 100644 --- a/drivers/staging/lustre/lustre/lov/lov_lock.c +++ b/drivers/staging/lustre/lustre/lov/lov_lock.c @@ -134,6 +134,11 @@ static struct lov_lock *lov_lock_sub_init(const struct lu_env *env, struct lov_layout_raid0 *r0 = lov_r0(loo); struct lov_lock *lovlck; + CDEBUG(D_INODE, "%p: lock/io FID " DFID "/" DFID ", lock/io clobj %p/%p\n", + loo, PFID(lu_object_fid(lov2lu(loo))), + PFID(lu_object_fid(&obj->co_lu)), + lov2cl(loo), obj); + file_start = cl_offset(lov2cl(loo), lock->cll_descr.cld_start); file_end = cl_offset(lov2cl(loo), lock->cll_descr.cld_end + 1) - 1; diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 63b064523c6a..b3161fb6d4b5 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -592,8 +592,6 @@ static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, CDEBUG(D_CONFIG, "idx=%d ltd_gen=%d ld_tgt_count=%d\n", index, tgt->ltd_gen, lov->desc.ld_tgt_count); - rc = obd_notify(obd, tgt_obd, OBD_NOTIFY_CREATE, &index); - if (lov->lov_connects == 0) { /* lov_connect hasn't been called yet. We'll do the * lov_connect_obd on this target when that fn first runs, diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index 76d4256fa828..977579c9c519 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -266,6 +266,13 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev, if (result != 0) goto out; + if (!dev->ld_target[ost_idx]) { + CERROR("%s: OST %04x is not initialized\n", + lov2obd(dev->ld_lov)->obd_name, ost_idx); + result = -EIO; + goto out; + } + subdev = lovsub2cl_dev(dev->ld_target[ost_idx]); subconf->u.coc_oinfo = oinfo; LASSERTF(subdev, "not init ost %d\n", ost_idx); @@ -650,12 +657,16 @@ static enum lov_layout_type lov_type(struct lov_stripe_md *lsm) static inline void lov_conf_freeze(struct lov_object *lov) { + CDEBUG(D_INODE, "To take share lov(%p) owner %p/%p\n", + lov, lov->lo_owner, current); if (lov->lo_owner != current) down_read(&lov->lo_type_guard); } static inline void lov_conf_thaw(struct lov_object *lov) { + CDEBUG(D_INODE, "To release share lov(%p) owner %p/%p\n", + lov, lov->lo_owner, current); if (lov->lo_owner != current) up_read(&lov->lo_type_guard); } @@ -698,10 +709,14 @@ static void lov_conf_lock(struct lov_object *lov) down_write(&lov->lo_type_guard); LASSERT(!lov->lo_owner); lov->lo_owner = current; + CDEBUG(D_INODE, "Took exclusive lov(%p) owner %p\n", + lov, lov->lo_owner); } static void lov_conf_unlock(struct lov_object *lov) { + CDEBUG(D_INODE, "To release exclusive lov(%p) owner %p\n", + lov, lov->lo_owner); lov->lo_owner = NULL; up_write(&lov->lo_type_guard); } @@ -725,6 +740,7 @@ static int lov_layout_change(const struct lu_env *unused, struct lov_object *lov, struct lov_stripe_md *lsm, const struct cl_object_conf *conf) { + struct lov_device *lov_dev = lov_object_dev(lov); enum lov_layout_type llt = lov_type(lsm); union lov_layout_state *state = &lov->u; const struct lov_layout_operations *old_ops; @@ -760,14 +776,21 @@ static int lov_layout_change(const struct lu_env *unused, LASSERT(!atomic_read(&lov->lo_active_ios)); + CDEBUG(D_INODE, DFID "Apply new layout lov %p, type %d\n", + PFID(lu_object_fid(lov2lu(lov))), lov, llt); + lov->lo_type = LLT_EMPTY; /* page bufsize fixup */ cl_object_header(&lov->lo_cl)->coh_page_bufsize -= lov_page_slice_fixup(lov, NULL); - rc = new_ops->llo_init(env, lov_object_dev(lov), lov, lsm, conf, state); + rc = new_ops->llo_init(env, lov_dev, lov, lsm, conf, state); if (rc) { + struct obd_device *obd = lov2obd(lov_dev->ld_lov); + + CERROR("%s: cannot apply new layout on " DFID " : rc = %d\n", + obd->obd_name, PFID(lu_object_fid(lov2lu(lov))), rc); new_ops->llo_delete(env, lov, state); new_ops->llo_fini(env, lov, state); /* this file becomes an EMPTY file. */ @@ -923,6 +946,11 @@ int lov_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io) { CL_IO_SLICE_CLEAN(lov_env_io(env), lis_cl); + + CDEBUG(D_INODE, DFID "io %p type %d ignore/verify layout %d/%d\n", + PFID(lu_object_fid(&obj->co_lu)), io, io->ci_type, + io->ci_ignore_layout, io->ci_verify_layout); + return LOV_2DISPATCH_MAYLOCK(cl2lov(obj), llo_io_init, !io->ci_ignore_layout, env, obj, io); } @@ -1453,14 +1481,11 @@ static int lov_object_layout_get(const struct lu_env *env, if (!lsm) { cl->cl_size = 0; cl->cl_layout_gen = CL_LAYOUT_GEN_EMPTY; - cl->cl_is_released = false; - return 0; } cl->cl_size = lov_mds_md_size(lsm->lsm_stripe_count, lsm->lsm_magic); cl->cl_layout_gen = lsm->lsm_layout_gen; - cl->cl_is_released = lsm_is_released(lsm); rc = lov_lsm_pack(lsm, buf->lb_buf, buf->lb_len); lov_lsm_put(lsm); diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 6c93d180aef7..2e1bd47337fd 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -136,7 +136,7 @@ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf, lmmv1->lmm_layout_gen = cpu_to_le16(lsm->lsm_layout_gen); if (lsm->lsm_magic == LOV_MAGIC_V3) { - CLASSERT(sizeof(lsm->lsm_pool_name) == + BUILD_BUG_ON(sizeof(lsm->lsm_pool_name) != sizeof(lmmv3->lmm_pool_name)); strlcpy(lmmv3->lmm_pool_name, lsm->lsm_pool_name, sizeof(lmmv3->lmm_pool_name)); @@ -198,7 +198,8 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, __u16 *stripe_count) return rc; } -struct lov_stripe_md *lov_lsm_alloc(u16 stripe_count, u32 pattern, u32 magic) +static struct lov_stripe_md *lov_lsm_alloc(u16 stripe_count, u32 pattern, + u32 magic) { struct lov_stripe_md *lsm; unsigned int i; @@ -356,8 +357,8 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm, /* FIXME: Bug 1185 - copy fields properly when structs change */ /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */ - CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3)); - CLASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lmmk->lmm_objects[0])); + BUILD_BUG_ON(sizeof(lum) != sizeof(struct lov_mds_md_v3)); + BUILD_BUG_ON(sizeof(lum.lmm_objects[0]) != sizeof(lmmk->lmm_objects[0])); if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC && (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1) || diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index d43cc88ae641..3a747913fb4f 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -344,9 +344,6 @@ int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, continue; } - if (!lov->lov_tgts[i]->ltd_active) - lov_check_and_wait_active(lov, i); - /* skip targets that have been explicitly disabled by the * administrator */ @@ -355,6 +352,9 @@ int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, continue; } + if (!lov->lov_tgts[i]->ltd_active) + lov_check_and_wait_active(lov, i); + req = kzalloc(sizeof(*req), GFP_NOFS); if (!req) { rc = -ENOMEM; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index 881c6a0676a6..fecedc8819ed 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -116,8 +116,7 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, struct lu_fid *fid, __u64 *bits); int mdc_intent_getattr_async(struct obd_export *exp, - struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo); + struct md_enqueue_info *minfo); enum ldlm_mode mdc_lock_match(struct obd_export *exp, __u64 flags, const struct lu_fid *fid, enum ldlm_type type, diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index f35e1f9afdef..b1853ff7f8b9 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -125,7 +125,7 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, char *tmp; __u64 flags; - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_create)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->cr_opcode = REINT_CREATE; @@ -189,7 +189,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, char *tmp; __u64 cr_flags; - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_create)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); /* XXX do something about time, uid, gid */ @@ -313,7 +313,7 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, struct mdt_rec_setattr *rec; struct lov_user_md *lum = NULL; - CLASSERT(sizeof(struct mdt_rec_reint) == + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_setattr)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); mdc_setattr_pack_rec(rec, op_data); @@ -336,7 +336,7 @@ void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { struct mdt_rec_unlink *rec; - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_unlink)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? @@ -359,7 +359,7 @@ void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { struct mdt_rec_link *rec; - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_link)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_link)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->lk_opcode = REINT_LINK; @@ -407,7 +407,7 @@ void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data, { struct mdt_rec_rename *rec; - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_rename)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_rename)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); /* XXX do something about time, uid, gid */ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 54ebb9952d66..392b0e38a91e 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -49,7 +49,6 @@ struct mdc_getattr_args { struct obd_export *ga_exp; struct md_enqueue_info *ga_minfo; - struct ldlm_enqueue_info *ga_einfo; }; int it_open_error(int phase, struct lookup_intent *it) @@ -722,7 +721,7 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, LASSERT(!policy); saved_flags |= LDLM_FL_HAS_INTENT; - if (it->it_op & (IT_OPEN | IT_UNLINK | IT_GETATTR | IT_READDIR)) + if (it->it_op & (IT_UNLINK | IT_GETATTR | IT_READDIR)) policy = &update_policy; else if (it->it_op & IT_LAYOUT) policy = &layout_policy; @@ -1111,7 +1110,7 @@ static int mdc_intent_getattr_async_interpret(const struct lu_env *env, struct mdc_getattr_args *ga = args; struct obd_export *exp = ga->ga_exp; struct md_enqueue_info *minfo = ga->ga_minfo; - struct ldlm_enqueue_info *einfo = ga->ga_einfo; + struct ldlm_enqueue_info *einfo = &minfo->mi_einfo; struct lookup_intent *it; struct lustre_handle *lockh; struct obd_device *obddev; @@ -1147,14 +1146,12 @@ static int mdc_intent_getattr_async_interpret(const struct lu_env *env, rc = mdc_finish_intent_lock(exp, req, &minfo->mi_data, it, lockh); out: - kfree(einfo); minfo->mi_cb(req, minfo, rc); return 0; } int mdc_intent_getattr_async(struct obd_export *exp, - struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo) + struct md_enqueue_info *minfo) { struct md_op_data *op_data = &minfo->mi_data; struct lookup_intent *it = &minfo->mi_it; @@ -1162,10 +1159,6 @@ int mdc_intent_getattr_async(struct obd_export *exp, struct mdc_getattr_args *ga; struct obd_device *obddev = class_exp2obd(exp); struct ldlm_res_id res_id; - /*XXX: Both MDS_INODELOCK_LOOKUP and MDS_INODELOCK_UPDATE are needed - * for statahead currently. Consider CMD in future, such two bits - * maybe managed by different MDS, should be adjusted then. - */ union ldlm_policy_data policy = { .l_inodebits = { MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE } }; @@ -1188,19 +1181,18 @@ int mdc_intent_getattr_async(struct obd_export *exp, return rc; } - rc = ldlm_cli_enqueue(exp, &req, einfo, &res_id, &policy, &flags, NULL, - 0, LVB_T_NONE, &minfo->mi_lockh, 1); + rc = ldlm_cli_enqueue(exp, &req, &minfo->mi_einfo, &res_id, &policy, + &flags, NULL, 0, LVB_T_NONE, &minfo->mi_lockh, 1); if (rc < 0) { obd_put_request_slot(&obddev->u.cli); ptlrpc_req_finished(req); return rc; } - CLASSERT(sizeof(*ga) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*ga) > sizeof(req->rq_async_args)); ga = ptlrpc_req_async_args(req); ga->ga_exp = exp; ga->ga_minfo = minfo; - ga->ga_einfo = einfo; req->rq_interpret_reply = mdc_intent_getattr_async_interpret; ptlrpcd_add_req(req); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 2cfd913f9bc5..6bc2fb858680 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -295,7 +295,7 @@ static int mdc_xattr_common(struct obd_export *exp, if (opcode == MDS_REINT) { struct mdt_rec_setxattr *rec; - CLASSERT(sizeof(struct mdt_rec_setxattr) == + BUILD_BUG_ON(sizeof(struct mdt_rec_setxattr) != sizeof(struct mdt_rec_reint)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->sx_opcode = REINT_SETXATTR; @@ -762,6 +762,7 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data, rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_CLOSE); if (rc) { ptlrpc_request_free(req); + req = NULL; goto out; } @@ -2465,13 +2466,6 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp, LASSERT(imp->imp_obd == obd); switch (event) { - case IMP_EVENT_DISCON: { -#if 0 - /* XXX Pass event up to OBDs stack. used only for FLD now */ - rc = obd_notify_observer(obd, obd, OBD_NOTIFY_DISCON, NULL); -#endif - break; - } case IMP_EVENT_INACTIVE: { struct client_obd *cli = &obd->u.cli; /* @@ -2503,6 +2497,7 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp, case IMP_EVENT_OCD: rc = obd_notify_observer(obd, obd, OBD_NOTIFY_OCD, NULL); break; + case IMP_EVENT_DISCON: case IMP_EVENT_DEACTIVATE: case IMP_EVENT_ACTIVATE: break; diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index b9c522a3c7a4..6a76605b3c3d 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -142,10 +142,10 @@ static void config_log_put(struct config_llog_data *cld) if (cld->cld_recover) config_log_put(cld->cld_recover); - if (cld->cld_sptlrpc) - config_log_put(cld->cld_sptlrpc); if (cld->cld_params) config_log_put(cld->cld_params); + if (cld->cld_sptlrpc) + config_log_put(cld->cld_sptlrpc); if (cld_is_sptlrpc(cld)) sptlrpc_conf_log_stop(cld->cld_logname); @@ -175,13 +175,10 @@ struct config_llog_data *config_log_find(char *logname, /* instance may be NULL, should check name */ if (strcmp(logname, cld->cld_logname) == 0) { found = cld; + config_log_get(found); break; } } - if (found) { - atomic_inc(&found->cld_refcount); - LASSERT(found->cld_stopping == 0 || cld_is_sptlrpc(found) == 0); - } spin_unlock(&config_list_lock); return found; } @@ -203,6 +200,12 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, if (!cld) return ERR_PTR(-ENOMEM); + rc = mgc_logname2resid(logname, &cld->cld_resid, type); + if (rc) { + kfree(cld); + return ERR_PTR(rc); + } + strcpy(cld->cld_logname, logname); if (cfg) cld->cld_cfg = *cfg; @@ -223,17 +226,10 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, cld->cld_cfg.cfg_obdname = obd->obd_name; } - rc = mgc_logname2resid(logname, &cld->cld_resid, type); - spin_lock(&config_list_lock); list_add(&cld->cld_list_chain, &config_llog_list); spin_unlock(&config_list_lock); - if (rc) { - config_log_put(cld); - return ERR_PTR(rc); - } - if (cld_is_sptlrpc(cld)) { rc = mgc_process_log(obd, cld); if (rc && rc != -ENOENT) @@ -284,14 +280,15 @@ config_params_log_add(struct obd_device *obd, * We have one active log per "mount" - client instance or servername. * Each instance may be at a different point in the log. */ -static int config_log_add(struct obd_device *obd, char *logname, - struct config_llog_instance *cfg, - struct super_block *sb) +static struct config_llog_data * +config_log_add(struct obd_device *obd, char *logname, + struct config_llog_instance *cfg, struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); struct config_llog_data *cld; struct config_llog_data *sptlrpc_cld; struct config_llog_data *params_cld; + bool locked = false; char seclogname[32]; char *ptr; int rc; @@ -305,7 +302,7 @@ static int config_log_add(struct obd_device *obd, char *logname, ptr = strrchr(logname, '-'); if (!ptr || ptr - logname > 8) { CERROR("logname %s is too long\n", logname); - return -EINVAL; + return ERR_PTR(-EINVAL); } memcpy(seclogname, logname, ptr - logname); @@ -326,14 +323,14 @@ static int config_log_add(struct obd_device *obd, char *logname, rc = PTR_ERR(params_cld); CERROR("%s: can't create params log: rc = %d\n", obd->obd_name, rc); - goto out_err1; + goto out_sptlrpc; } cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb); if (IS_ERR(cld)) { CERROR("can't create log: %s\n", logname); rc = PTR_ERR(cld); - goto out_err2; + goto out_params; } cld->cld_sptlrpc = sptlrpc_cld; @@ -350,33 +347,52 @@ static int config_log_add(struct obd_device *obd, char *logname, CERROR("%s: sptlrpc log name not correct, %s: rc = %d\n", obd->obd_name, seclogname, -EINVAL); config_log_put(cld); - return -EINVAL; + rc = -EINVAL; + goto out_cld; } recover_cld = config_recover_log_add(obd, seclogname, cfg, sb); if (IS_ERR(recover_cld)) { rc = PTR_ERR(recover_cld); - goto out_err3; + goto out_cld; } + + mutex_lock(&cld->cld_lock); + locked = true; cld->cld_recover = recover_cld; } - return 0; + if (!locked) + mutex_lock(&cld->cld_lock); + cld->cld_params = params_cld; + cld->cld_sptlrpc = sptlrpc_cld; + mutex_unlock(&cld->cld_lock); + + return cld; -out_err3: +out_cld: config_log_put(cld); -out_err2: +out_params: config_log_put(params_cld); -out_err1: +out_sptlrpc: config_log_put(sptlrpc_cld); out_err: - return rc; + return ERR_PTR(rc); } static DEFINE_MUTEX(llog_process_lock); +static inline void config_mark_cld_stop(struct config_llog_data *cld) +{ + mutex_lock(&cld->cld_lock); + spin_lock(&config_list_lock); + cld->cld_stopping = 1; + spin_unlock(&config_list_lock); + mutex_unlock(&cld->cld_lock); +} + /** Stop watching for updates on this log. */ static int config_log_end(char *logname, struct config_llog_instance *cfg) @@ -406,36 +422,32 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) return rc; } + spin_lock(&config_list_lock); cld->cld_stopping = 1; + spin_unlock(&config_list_lock); cld_recover = cld->cld_recover; cld->cld_recover = NULL; + + cld_params = cld->cld_params; + cld->cld_params = NULL; + cld_sptlrpc = cld->cld_sptlrpc; + cld->cld_sptlrpc = NULL; mutex_unlock(&cld->cld_lock); if (cld_recover) { - mutex_lock(&cld_recover->cld_lock); - cld_recover->cld_stopping = 1; - mutex_unlock(&cld_recover->cld_lock); + config_mark_cld_stop(cld_recover); config_log_put(cld_recover); } - spin_lock(&config_list_lock); - cld_sptlrpc = cld->cld_sptlrpc; - cld->cld_sptlrpc = NULL; - cld_params = cld->cld_params; - cld->cld_params = NULL; - spin_unlock(&config_list_lock); - - if (cld_sptlrpc) - config_log_put(cld_sptlrpc); - if (cld_params) { - mutex_lock(&cld_params->cld_lock); - cld_params->cld_stopping = 1; - mutex_unlock(&cld_params->cld_lock); + config_mark_cld_stop(cld_params); config_log_put(cld_params); } + if (cld_sptlrpc) + config_log_put(cld_sptlrpc); + /* drop the ref from the find */ config_log_put(cld); /* drop the start ref */ @@ -531,11 +543,10 @@ static int mgc_requeue_thread(void *data) /* Keep trying failed locks periodically */ spin_lock(&config_list_lock); rq_state |= RQ_RUNNING; - while (1) { + while (!(rq_state & RQ_STOP)) { struct l_wait_info lwi; struct config_llog_data *cld, *cld_prev; int rand = cfs_rand() & MGC_TIMEOUT_RAND_CENTISEC; - int stopped = !!(rq_state & RQ_STOP); int to; /* Any new or requeued lostlocks will change the state */ @@ -571,44 +582,40 @@ static int mgc_requeue_thread(void *data) spin_lock(&config_list_lock); rq_state &= ~RQ_PRECLEANUP; list_for_each_entry(cld, &config_llog_list, cld_list_chain) { - if (!cld->cld_lostlock) + if (!cld->cld_lostlock || cld->cld_stopping) continue; + /* + * hold reference to avoid being freed during + * subsequent processing. + */ + config_log_get(cld); + cld->cld_lostlock = 0; spin_unlock(&config_list_lock); - LASSERT(atomic_read(&cld->cld_refcount) > 0); - - /* Whether we enqueued again or not in mgc_process_log, - * we're done with the ref from the old enqueue - */ if (cld_prev) config_log_put(cld_prev); cld_prev = cld; - cld->cld_lostlock = 0; - if (likely(!stopped)) + if (likely(!(rq_state & RQ_STOP))) { do_requeue(cld); - - spin_lock(&config_list_lock); + spin_lock(&config_list_lock); + } else { + spin_lock(&config_list_lock); + break; + } } spin_unlock(&config_list_lock); if (cld_prev) config_log_put(cld_prev); - /* break after scanning the list so that we can drop - * refcount to losing lock clds - */ - if (unlikely(stopped)) { - spin_lock(&config_list_lock); - break; - } - /* Wait a bit to see if anyone else needs a requeue */ lwi = (struct l_wait_info) { 0 }; l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP), &lwi); spin_lock(&config_list_lock); } + /* spinlock and while guarantee RQ_NOW and RQ_LATER are not set */ rq_state &= ~RQ_RUNNING; spin_unlock(&config_list_lock); @@ -624,32 +631,24 @@ static int mgc_requeue_thread(void *data) */ static void mgc_requeue_add(struct config_llog_data *cld) { + bool wakeup = false; + CDEBUG(D_INFO, "log %s: requeue (r=%d sp=%d st=%x)\n", cld->cld_logname, atomic_read(&cld->cld_refcount), cld->cld_stopping, rq_state); LASSERT(atomic_read(&cld->cld_refcount) > 0); mutex_lock(&cld->cld_lock); - if (cld->cld_stopping || cld->cld_lostlock) { - mutex_unlock(&cld->cld_lock); - return; - } - /* this refcount will be released in mgc_requeue_thread. */ - config_log_get(cld); - cld->cld_lostlock = 1; - mutex_unlock(&cld->cld_lock); - - /* Hold lock for rq_state */ spin_lock(&config_list_lock); - if (rq_state & RQ_STOP) { - spin_unlock(&config_list_lock); - cld->cld_lostlock = 0; - config_log_put(cld); - } else { + if (!(rq_state & RQ_STOP) && !cld->cld_stopping && !cld->cld_lostlock) { + cld->cld_lostlock = 1; rq_state |= RQ_NOW; - spin_unlock(&config_list_lock); - wake_up(&rq_waitq); + wakeup = true; } + spin_unlock(&config_list_lock); + mutex_unlock(&cld->cld_lock); + if (wakeup) + wake_up(&rq_waitq); } static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd) @@ -812,6 +811,8 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, /* held at mgc_process_log(). */ LASSERT(atomic_read(&cld->cld_refcount) > 0); + + lock->l_ast_data = NULL; /* Are we done with this log? */ if (cld->cld_stopping) { CDEBUG(D_MGC, "log %s: stopping, won't requeue\n", @@ -1661,16 +1662,18 @@ restart: goto restart; } else { mutex_lock(&cld->cld_lock); + spin_lock(&config_list_lock); cld->cld_lostlock = 1; + spin_unlock(&config_list_lock); } } else { /* mark cld_lostlock so that it will requeue * after MGC becomes available. */ + spin_lock(&config_list_lock); cld->cld_lostlock = 1; + spin_unlock(&config_list_lock); } - /* Get extra reference, it will be put in requeue thread */ - config_log_get(cld); } if (cld_is_recover(cld)) { @@ -1681,7 +1684,9 @@ restart: CERROR("%s: recover log %s failed: rc = %d not fatal.\n", mgc->obd_name, cld->cld_logname, rc); rc = 0; + spin_lock(&config_list_lock); cld->cld_lostlock = 1; + spin_unlock(&config_list_lock); } } } else { @@ -1749,12 +1754,9 @@ static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) cfg->cfg_last_idx); /* We're only called through here on the initial mount */ - rc = config_log_add(obd, logname, cfg, sb); - if (rc) - break; - cld = config_log_find(logname, cfg); - if (!cld) { - rc = -ENOENT; + cld = config_log_add(obd, logname, cfg, sb); + if (IS_ERR(cld)) { + rc = PTR_ERR(cld); break; } @@ -1770,11 +1772,15 @@ static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) imp_connect_data, IMP_RECOV)) { rc = mgc_process_log(obd, cld->cld_recover); } else { - struct config_llog_data *cir = cld->cld_recover; + struct config_llog_data *cir; + mutex_lock(&cld->cld_lock); + cir = cld->cld_recover; cld->cld_recover = NULL; + mutex_unlock(&cld->cld_lock); config_log_put(cir); } + if (rc) CERROR("Cannot process recover llog %d\n", rc); } @@ -1792,7 +1798,6 @@ static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) "%s: can't process params llog: rc = %d\n", obd->obd_name, rc); } - config_log_put(cld); break; } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 3f42457b0d7d..ee7d67761191 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1119,9 +1119,9 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor, LASSERT(atomic_read(&anchor->csi_sync_nr) == 0); /* wait until cl_sync_io_note() has done wakeup */ - while (unlikely(atomic_read(&anchor->csi_barrier) != 0)) { + while (unlikely(atomic_read(&anchor->csi_barrier) != 0)) cpu_relax(); - } + return rc; } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index f5d4e23c64b7..703cb67ce42e 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -54,6 +54,7 @@ #include <linux/list.h> #include "../../include/linux/libcfs/libcfs_hash.h" /* for cfs_hash stuff */ #include "../include/cl_object.h" +#include "../include/lu_object.h" #include "cl_internal.h" static struct kmem_cache *cl_env_kmem; @@ -61,8 +62,6 @@ static struct kmem_cache *cl_env_kmem; /** Lock class of cl_object_header::coh_attr_guard */ static struct lock_class_key cl_attr_guard_class; -extern __u32 lu_context_tags_default; -extern __u32 lu_session_tags_default; /** * Initialize cl_object_header. */ diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 7971562a3efd..abcf951208d2 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -60,7 +60,7 @@ enum { LU_CACHE_PERCENT_DEFAULT = 20 }; -#define LU_CACHE_NR_MAX_ADJUST 128 +#define LU_CACHE_NR_MAX_ADJUST 512 #define LU_CACHE_NR_UNLIMITED -1 #define LU_CACHE_NR_DEFAULT LU_CACHE_NR_UNLIMITED #define LU_CACHE_NR_LDISKFS_LIMIT LU_CACHE_NR_UNLIMITED @@ -151,7 +151,7 @@ void lu_object_put(const struct lu_env *env, struct lu_object *o) LASSERT(list_empty(&top->loh_lru)); list_add_tail(&top->loh_lru, &bkt->lsb_lru); bkt->lsb_lru_len++; - lprocfs_counter_incr(site->ls_stats, LU_SS_LRU_LEN); + percpu_counter_inc(&site->ls_lru_len_counter); CDEBUG(D_INODE, "Add %p to site lru. hash: %p, bkt: %p, lru_len: %ld\n", o, site->ls_obj_hash, bkt, bkt->lsb_lru_len); cfs_hash_bd_unlock(site->ls_obj_hash, &bd, 1); @@ -202,7 +202,7 @@ void lu_object_unhash(const struct lu_env *env, struct lu_object *o) list_del_init(&top->loh_lru); bkt = cfs_hash_bd_extra_get(obj_hash, &bd); bkt->lsb_lru_len--; - lprocfs_counter_decr(site->ls_stats, LU_SS_LRU_LEN); + percpu_counter_dec(&site->ls_lru_len_counter); } cfs_hash_bd_del_locked(obj_hash, &bd, &top->loh_hash); cfs_hash_bd_unlock(obj_hash, &bd, 1); @@ -329,8 +329,11 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o) /** * Free \a nr objects from the cold end of the site LRU list. + * if canblock is false, then don't block awaiting for another + * instance of lu_site_purge() to complete */ -int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr) +int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s, + int nr, bool canblock) { struct lu_object_header *h; struct lu_object_header *temp; @@ -360,7 +363,11 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr) * It doesn't make any sense to make purge threads parallel, that can * only bring troubles to us. See LU-5331. */ - mutex_lock(&s->ls_purge_mutex); + if (canblock) + mutex_lock(&s->ls_purge_mutex); + else if (!mutex_trylock(&s->ls_purge_mutex)) + goto out; + did_sth = 0; cfs_hash_for_each_bucket(s->ls_obj_hash, &bd, i) { if (i < start) @@ -379,7 +386,7 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr) &bd2, &h->loh_hash); list_move(&h->loh_lru, &dispose); bkt->lsb_lru_len--; - lprocfs_counter_decr(s->ls_stats, LU_SS_LRU_LEN); + percpu_counter_dec(&s->ls_lru_len_counter); if (did_sth == 0) did_sth = 1; @@ -414,10 +421,10 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr) } /* race on s->ls_purge_start, but nobody cares */ s->ls_purge_start = i % CFS_HASH_NBKT(s->ls_obj_hash); - +out: return nr; } -EXPORT_SYMBOL(lu_site_purge); +EXPORT_SYMBOL(lu_site_purge_objects); /* * Object printing. @@ -578,7 +585,7 @@ static struct lu_object *htable_lookup(struct lu_site *s, if (!list_empty(&h->loh_lru)) { list_del_init(&h->loh_lru); bkt->lsb_lru_len--; - lprocfs_counter_decr(s->ls_stats, LU_SS_LRU_LEN); + percpu_counter_dec(&s->ls_lru_len_counter); } return lu_object_top(h); } @@ -625,9 +632,12 @@ static void lu_object_limit(const struct lu_env *env, struct lu_device *dev) size = cfs_hash_size_get(dev->ld_site->ls_obj_hash); nr = (__u64)lu_cache_nr; - if (size > nr) - lu_site_purge(env, dev->ld_site, - min_t(__u64, size - nr, LU_CACHE_NR_MAX_ADJUST)); + if (size <= nr) + return; + + lu_site_purge_objects(env, dev->ld_site, + min_t(__u64, size - nr, LU_CACHE_NR_MAX_ADJUST), + false); } static struct lu_object *lu_object_new(const struct lu_env *env, @@ -820,7 +830,7 @@ EXPORT_SYMBOL(lu_device_type_fini); * Global list of all sites on this node */ static LIST_HEAD(lu_sites); -static DEFINE_MUTEX(lu_sites_guard); +static DECLARE_RWSEM(lu_sites_guard); /** * Global environment used by site shrinker. @@ -994,9 +1004,15 @@ int lu_site_init(struct lu_site *s, struct lu_device *top) unsigned long bits; unsigned long i; char name[16]; + int rc; memset(s, 0, sizeof(*s)); mutex_init(&s->ls_purge_mutex); + + rc = percpu_counter_init(&s->ls_lru_len_counter, 0, GFP_NOFS); + if (rc) + return -ENOMEM; + snprintf(name, sizeof(name), "lu_site_%s", top->ld_type->ldt_name); for (bits = lu_htable_order(top); bits >= LU_SITE_BITS_MIN; bits--) { s->ls_obj_hash = cfs_hash_create(name, bits, bits, @@ -1042,12 +1058,6 @@ int lu_site_init(struct lu_site *s, struct lu_device *top) 0, "cache_death_race", "cache_death_race"); lprocfs_counter_init(s->ls_stats, LU_SS_LRU_PURGED, 0, "lru_purged", "lru_purged"); - /* - * Unlike other counters, lru_len can be decremented so - * need lc_sum instead of just lc_count - */ - lprocfs_counter_init(s->ls_stats, LU_SS_LRU_LEN, - LPROCFS_CNTR_AVGMINMAX, "lru_len", "lru_len"); INIT_LIST_HEAD(&s->ls_linkage); s->ls_top_dev = top; @@ -1069,9 +1079,11 @@ EXPORT_SYMBOL(lu_site_init); */ void lu_site_fini(struct lu_site *s) { - mutex_lock(&lu_sites_guard); + down_write(&lu_sites_guard); list_del_init(&s->ls_linkage); - mutex_unlock(&lu_sites_guard); + up_write(&lu_sites_guard); + + percpu_counter_destroy(&s->ls_lru_len_counter); if (s->ls_obj_hash) { cfs_hash_putref(s->ls_obj_hash); @@ -1097,11 +1109,11 @@ int lu_site_init_finish(struct lu_site *s) { int result; - mutex_lock(&lu_sites_guard); + down_write(&lu_sites_guard); result = lu_context_refill(&lu_shrink_env.le_ctx); if (result == 0) list_add(&s->ls_linkage, &lu_sites); - mutex_unlock(&lu_sites_guard); + up_write(&lu_sites_guard); return result; } EXPORT_SYMBOL(lu_site_init_finish); @@ -1820,12 +1832,15 @@ static void lu_site_stats_get(struct cfs_hash *hs, } /* - * lu_cache_shrink_count returns the number of cached objects that are - * candidates to be freed by shrink_slab(). A counter, which tracks - * the number of items in the site's lru, is maintained in the per cpu - * stats of each site. The counter is incremented when an object is added - * to a site's lru and decremented when one is removed. The number of - * free-able objects is the sum of all per cpu counters for all sites. + * lu_cache_shrink_count() returns an approximate number of cached objects + * that can be freed by shrink_slab(). A counter, which tracks the + * number of items in the site's lru, is maintained in a percpu_counter + * for each site. The percpu values are incremented and decremented as + * objects are added or removed from the lru. The percpu values are summed + * and saved whenever a percpu value exceeds a threshold. Thus the saved, + * summed value at any given time may not accurately reflect the current + * lru length. But this value is sufficiently accurate for the needs of + * a shrinker. * * Using a per cpu counter is a compromise solution to concurrent access: * lu_object_put() can update the counter without locking the site and @@ -1842,11 +1857,10 @@ static unsigned long lu_cache_shrink_count(struct shrinker *sk, if (!(sc->gfp_mask & __GFP_FS)) return 0; - mutex_lock(&lu_sites_guard); - list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) { - cached += ls_stats_read(s->ls_stats, LU_SS_LRU_LEN); - } - mutex_unlock(&lu_sites_guard); + down_read(&lu_sites_guard); + list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) + cached += percpu_counter_read_positive(&s->ls_lru_len_counter); + up_read(&lu_sites_guard); cached = (cached / 100) * sysctl_vfs_cache_pressure; CDEBUG(D_INODE, "%ld objects cached, cache pressure %d\n", @@ -1877,7 +1891,7 @@ static unsigned long lu_cache_shrink_scan(struct shrinker *sk, */ return SHRINK_STOP; - mutex_lock(&lu_sites_guard); + down_write(&lu_sites_guard); list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) { freed = lu_site_purge(&lu_shrink_env, s, remain); remain -= freed; @@ -1888,7 +1902,7 @@ static unsigned long lu_cache_shrink_scan(struct shrinker *sk, list_move_tail(&s->ls_linkage, &splice); } list_splice(&splice, lu_sites.prev); - mutex_unlock(&lu_sites_guard); + up_write(&lu_sites_guard); return sc->nr_to_scan - remain; } @@ -1925,9 +1939,9 @@ int lu_global_init(void) * conservatively. This should not be too bad, because this * environment is global. */ - mutex_lock(&lu_sites_guard); + down_write(&lu_sites_guard); result = lu_env_init(&lu_shrink_env, LCT_SHRINKER); - mutex_unlock(&lu_sites_guard); + up_write(&lu_sites_guard); if (result != 0) return result; @@ -1953,9 +1967,9 @@ void lu_global_fini(void) * Tear shrinker environment down _after_ de-registering * lu_global_key, because the latter has a value in the former. */ - mutex_lock(&lu_sites_guard); + down_write(&lu_sites_guard); lu_env_fini(&lu_shrink_env); - mutex_unlock(&lu_sites_guard); + up_write(&lu_sites_guard); lu_ref_global_fini(); } @@ -1965,13 +1979,6 @@ static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx) struct lprocfs_counter ret; lprocfs_stats_collect(stats, idx, &ret); - if (idx == LU_SS_LRU_LEN) - /* - * protect against counter on cpu A being decremented - * before counter is incremented on cpu B; unlikely - */ - return (__u32)((ret.lc_sum > 0) ? ret.lc_sum : 0); - return (__u32)ret.lc_count; } @@ -1986,7 +1993,7 @@ int lu_site_stats_print(const struct lu_site *s, struct seq_file *m) memset(&stats, 0, sizeof(stats)); lu_site_stats_get(s->ls_obj_hash, &stats, 1); - seq_printf(m, "%d/%d %d/%ld %d %d %d %d %d %d %d %d\n", + seq_printf(m, "%d/%d %d/%ld %d %d %d %d %d %d %d\n", stats.lss_busy, stats.lss_total, stats.lss_populated, @@ -1997,8 +2004,7 @@ int lu_site_stats_print(const struct lu_site *s, struct seq_file *m) ls_stats_read(s->ls_stats, LU_SS_CACHE_MISS), ls_stats_read(s->ls_stats, LU_SS_CACHE_RACE), ls_stats_read(s->ls_stats, LU_SS_CACHE_DEATH_RACE), - ls_stats_read(s->ls_stats, LU_SS_LRU_PURGED), - ls_stats_read(s->ls_stats, LU_SS_LRU_LEN)); + ls_stats_read(s->ls_stats, LU_SS_LRU_PURGED)); return 0; } EXPORT_SYMBOL(lu_site_stats_print); diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 2283e920d839..8e0d4b1d86dc 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -877,7 +877,7 @@ static int lmd_parse_mgs(struct lustre_mount_data *lmd, char **ptr) */ static int lmd_parse(char *options, struct lustre_mount_data *lmd) { - char *s1, *s2, *s3, *devname = NULL; + char *s1, *s2, *devname = NULL; struct lustre_mount_data *raw = (struct lustre_mount_data *)options; int rc = 0; @@ -906,6 +906,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) while (*s1) { int clear = 0; int time_min = OBD_RECOVERY_TIME_MIN; + char *s3; /* Skip whitespace and extra commas */ while (*s1 == ' ' || *s1 == ',') diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c index c52b9e07d7dd..b1dfa1622ae7 100644 --- a/drivers/staging/lustre/lustre/obdclass/obdo.c +++ b/drivers/staging/lustre/lustre/obdclass/obdo.c @@ -40,6 +40,7 @@ #include "../include/obd_class.h" #include "../include/lustre/lustre_idl.h" +#include "../include/lustre_obdo.h" void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent) { @@ -124,3 +125,56 @@ void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj) ioobj->ioo_max_brw = 0; } EXPORT_SYMBOL(obdo_to_ioobj); + +/** + * Create an obdo to send over the wire + */ +void lustre_set_wire_obdo(const struct obd_connect_data *ocd, + struct obdo *wobdo, const struct obdo *lobdo) +{ + *wobdo = *lobdo; + wobdo->o_flags &= ~OBD_FL_LOCAL_MASK; + if (!ocd) + return; + + if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) && + fid_seq_is_echo(ostid_seq(&lobdo->o_oi))) { + /* + * Currently OBD_FL_OSTID will only be used when 2.4 echo + * client communicate with pre-2.4 server + */ + wobdo->o_oi.oi.oi_id = fid_oid(&lobdo->o_oi.oi_fid); + wobdo->o_oi.oi.oi_seq = fid_seq(&lobdo->o_oi.oi_fid); + } +} +EXPORT_SYMBOL(lustre_set_wire_obdo); + +/** + * Create a local obdo from a wire based odbo + */ +void lustre_get_wire_obdo(const struct obd_connect_data *ocd, + struct obdo *lobdo, const struct obdo *wobdo) +{ + u32 local_flags = 0; + + if (lobdo->o_valid & OBD_MD_FLFLAGS) + local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK; + + *lobdo = *wobdo; + if (local_flags) { + lobdo->o_valid |= OBD_MD_FLFLAGS; + lobdo->o_flags &= ~OBD_FL_LOCAL_MASK; + lobdo->o_flags |= local_flags; + } + if (!ocd) + return; + + if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) && + fid_seq_is_echo(wobdo->o_oi.oi.oi_seq)) { + /* see above */ + lobdo->o_oi.oi_fid.f_seq = wobdo->o_oi.oi.oi_seq; + lobdo->o_oi.oi_fid.f_oid = wobdo->o_oi.oi.oi_id; + lobdo->o_oi.oi_fid.f_ver = 0; + } +} +EXPORT_SYMBOL(lustre_get_wire_obdo); diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index b0f030c6c9c9..0490478393df 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -142,10 +142,7 @@ static const char *oes_strings[] = { static inline struct osc_extent *rb_extent(struct rb_node *n) { - if (!n) - return NULL; - - return container_of(n, struct osc_extent, oe_node); + return rb_entry_safe(n, struct osc_extent, oe_node); } static inline struct osc_extent *next_extent(struct osc_extent *ext) @@ -247,7 +244,7 @@ static int osc_extent_sanity_check0(struct osc_extent *ext, goto out; } - if (ext->oe_dlmlock) { + if (ext->oe_dlmlock && !ldlm_is_failed(ext->oe_dlmlock)) { struct ldlm_extent *extent; extent = &ext->oe_dlmlock->l_policy_data.l_extent; @@ -1004,6 +1001,7 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, env = cl_env_get(&refcheck); io = &osc_env_info(env)->oti_io; io->ci_obj = cl_object_top(osc2cl(obj)); + io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc < 0) goto out; @@ -1884,16 +1882,32 @@ static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli, oap, osc, rc); } +struct extent_rpc_data { + struct list_head *erd_rpc_list; + unsigned int erd_page_count; + unsigned int erd_max_pages; + unsigned int erd_max_chunks; +}; + +static inline unsigned osc_extent_chunks(const struct osc_extent *ext) +{ + struct client_obd *cli = osc_cli(ext->oe_obj); + unsigned ppc_bits = cli->cl_chunkbits - PAGE_SHIFT; + + return (ext->oe_end >> ppc_bits) - (ext->oe_start >> ppc_bits) + 1; +} + /** * Try to add extent to one RPC. We need to think about the following things: * - # of pages must not be over max_pages_per_rpc * - extent must be compatible with previous ones */ static int try_to_add_extent_for_io(struct client_obd *cli, - struct osc_extent *ext, struct list_head *rpclist, - unsigned int *pc, unsigned int *max_pages) + struct osc_extent *ext, + struct extent_rpc_data *data) { struct osc_extent *tmp; + unsigned int chunk_count; struct osc_async_page *oap = list_first_entry(&ext->oe_pages, struct osc_async_page, oap_pending_item); @@ -1901,19 +1915,22 @@ static int try_to_add_extent_for_io(struct client_obd *cli, EASSERT((ext->oe_state == OES_CACHE || ext->oe_state == OES_LOCK_DONE), ext); - *max_pages = max(ext->oe_mppr, *max_pages); - if (*pc + ext->oe_nr_pages > *max_pages) + chunk_count = osc_extent_chunks(ext); + if (chunk_count > data->erd_max_chunks) + return 0; + + data->erd_max_pages = max(ext->oe_mppr, data->erd_max_pages); + if (data->erd_page_count + ext->oe_nr_pages > data->erd_max_pages) return 0; - list_for_each_entry(tmp, rpclist, oe_link) { + list_for_each_entry(tmp, data->erd_rpc_list, oe_link) { struct osc_async_page *oap2; oap2 = list_first_entry(&tmp->oe_pages, struct osc_async_page, oap_pending_item); EASSERT(tmp->oe_owner == current, tmp); if (oap2cl_page(oap)->cp_type != oap2cl_page(oap2)->cp_type) { - CDEBUG(D_CACHE, "Do not permit different type of IO" - " for a same RPC\n"); + CDEBUG(D_CACHE, "Do not permit different type of IO in one RPC\n"); return 0; } @@ -1926,12 +1943,41 @@ static int try_to_add_extent_for_io(struct client_obd *cli, break; } - *pc += ext->oe_nr_pages; - list_move_tail(&ext->oe_link, rpclist); + data->erd_max_chunks -= chunk_count; + data->erd_page_count += ext->oe_nr_pages; + list_move_tail(&ext->oe_link, data->erd_rpc_list); ext->oe_owner = current; return 1; } +static inline unsigned osc_max_write_chunks(const struct client_obd *cli) +{ + /* + * LU-8135: + * + * The maximum size of a single transaction is about 64MB in ZFS. + * #define DMU_MAX_ACCESS (64 * 1024 * 1024) + * + * Since ZFS is a copy-on-write file system, a single dirty page in + * a chunk will result in the rewrite of the whole chunk, therefore + * an RPC shouldn't be allowed to contain too many chunks otherwise + * it will make transaction size much bigger than 64MB, especially + * with big block size for ZFS. + * + * This piece of code is to make sure that OSC won't send write RPCs + * with too many chunks. The maximum chunk size that an RPC can cover + * is set to PTLRPC_MAX_BRW_SIZE, which is defined to 16MB. Ideally + * OST should tell the client what the biggest transaction size is, + * but it's good enough for now. + * + * This limitation doesn't apply to ldiskfs, which allows as many + * chunks in one RPC as we want. However, it won't have any benefits + * to have too many discontiguous pages in one RPC. Therefore, it + * can only have 256 chunks at most in one RPC. + */ + return min(PTLRPC_MAX_BRW_SIZE >> cli->cl_chunkbits, 256); +} + /** * In order to prevent multiple ptlrpcd from breaking contiguous extents, * get_write_extent() takes all appropriate extents in atomic. @@ -1951,26 +1997,28 @@ static unsigned int get_write_extents(struct osc_object *obj, struct client_obd *cli = osc_cli(obj); struct osc_extent *ext; struct osc_extent *temp; - unsigned int page_count = 0; - unsigned int max_pages = cli->cl_max_pages_per_rpc; + struct extent_rpc_data data = { + .erd_rpc_list = rpclist, + .erd_page_count = 0, + .erd_max_pages = cli->cl_max_pages_per_rpc, + .erd_max_chunks = osc_max_write_chunks(cli), + }; LASSERT(osc_object_is_locked(obj)); list_for_each_entry_safe(ext, temp, &obj->oo_hp_exts, oe_link) { LASSERT(ext->oe_state == OES_CACHE); - if (!try_to_add_extent_for_io(cli, ext, rpclist, &page_count, - &max_pages)) - return page_count; - EASSERT(ext->oe_nr_pages <= max_pages, ext); + if (!try_to_add_extent_for_io(cli, ext, &data)) + return data.erd_page_count; + EASSERT(ext->oe_nr_pages <= data.erd_max_pages, ext); } - if (page_count == max_pages) - return page_count; + if (data.erd_page_count == data.erd_max_pages) + return data.erd_page_count; while (!list_empty(&obj->oo_urgent_exts)) { ext = list_entry(obj->oo_urgent_exts.next, struct osc_extent, oe_link); - if (!try_to_add_extent_for_io(cli, ext, rpclist, &page_count, - &max_pages)) - return page_count; + if (!try_to_add_extent_for_io(cli, ext, &data)) + return data.erd_page_count; if (!ext->oe_intree) continue; @@ -1981,13 +2029,12 @@ static unsigned int get_write_extents(struct osc_object *obj, ext->oe_owner)) continue; - if (!try_to_add_extent_for_io(cli, ext, rpclist, - &page_count, &max_pages)) - return page_count; + if (!try_to_add_extent_for_io(cli, ext, &data)) + return data.erd_page_count; } } - if (page_count == max_pages) - return page_count; + if (data.erd_page_count == data.erd_max_pages) + return data.erd_page_count; ext = first_extent(obj); while (ext) { @@ -1998,13 +2045,12 @@ static unsigned int get_write_extents(struct osc_object *obj, continue; } - if (!try_to_add_extent_for_io(cli, ext, rpclist, &page_count, - &max_pages)) - return page_count; + if (!try_to_add_extent_for_io(cli, ext, &data)) + return data.erd_page_count; ext = next_extent(ext); } - return page_count; + return data.erd_page_count; } static int @@ -2089,27 +2135,29 @@ osc_send_read_rpc(const struct lu_env *env, struct client_obd *cli, struct osc_extent *ext; struct osc_extent *next; LIST_HEAD(rpclist); - unsigned int page_count = 0; - unsigned int max_pages = cli->cl_max_pages_per_rpc; + struct extent_rpc_data data = { + .erd_rpc_list = &rpclist, + .erd_page_count = 0, + .erd_max_pages = cli->cl_max_pages_per_rpc, + .erd_max_chunks = UINT_MAX, + }; int rc = 0; LASSERT(osc_object_is_locked(osc)); list_for_each_entry_safe(ext, next, &osc->oo_reading_exts, oe_link) { EASSERT(ext->oe_state == OES_LOCK_DONE, ext); - if (!try_to_add_extent_for_io(cli, ext, &rpclist, &page_count, - &max_pages)) + if (!try_to_add_extent_for_io(cli, ext, &data)) break; osc_extent_state_set(ext, OES_RPC); - EASSERT(ext->oe_nr_pages <= max_pages, ext); + EASSERT(ext->oe_nr_pages <= data.erd_max_pages, ext); } - LASSERT(page_count <= max_pages); + LASSERT(data.erd_page_count <= data.erd_max_pages); - osc_update_pending(osc, OBD_BRW_READ, -page_count); + osc_update_pending(osc, OBD_BRW_READ, -data.erd_page_count); if (!list_empty(&rpclist)) { osc_object_unlock(osc); - LASSERT(page_count > 0); rc = osc_build_rpc(env, cli, &rpclist, OBD_BRW_READ); LASSERT(list_empty(&rpclist)); @@ -2710,8 +2758,8 @@ int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj, /** * Called by osc_io_setattr_start() to freeze and destroy covering extents. */ -int osc_cache_truncate_start(const struct lu_env *env, struct osc_io *oio, - struct osc_object *obj, __u64 size) +int osc_cache_truncate_start(const struct lu_env *env, struct osc_object *obj, + u64 size, struct osc_extent **extp) { struct client_obd *cli = osc_cli(obj); struct osc_extent *ext; @@ -2808,9 +2856,11 @@ again: /* we need to hold this extent in OES_TRUNC state so * that no writeback will happen. This is to avoid * BUG 17397. + * Only partial truncate can reach here, if @size is + * not zero, the caller should provide a valid @extp. */ - LASSERT(!oio->oi_trunc); - oio->oi_trunc = osc_extent_get(ext); + LASSERT(!*extp); + *extp = osc_extent_get(ext); OSC_EXTENT_DUMP(D_CACHE, ext, "trunc at %llu\n", size); } @@ -2836,13 +2886,10 @@ again: /** * Called after osc_io_setattr_end to add oio->oi_trunc back to cache. */ -void osc_cache_truncate_end(const struct lu_env *env, struct osc_io *oio, - struct osc_object *obj) +void osc_cache_truncate_end(const struct lu_env *env, struct osc_extent *ext) { - struct osc_extent *ext = oio->oi_trunc; - - oio->oi_trunc = NULL; if (ext) { + struct osc_object *obj = ext->oe_obj; bool unplug = false; EASSERT(ext->oe_nr_pages > 0, ext); @@ -3183,8 +3230,10 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, /* page is top page. */ info->oti_next_index = osc_index(ops) + 1; if (cl_page_own(env, io, page) == 0) { - KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageDirty(cl_page_vmpage(page)))); + if (page->cp_type == CPT_CACHEABLE && + PageDirty(cl_page_vmpage(page))) + CL_PAGE_DEBUG(D_ERROR, env, page, + "discard dirty page?\n"); /* discard the page */ cl_page_discard(env, io, page); diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index cce55a9689f0..c09ab97d64ae 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -159,6 +159,10 @@ struct osc_object { /* Protect osc_lock this osc_object has */ spinlock_t oo_ol_spin; struct list_head oo_ol_list; + + /** number of active IOs of this object */ + atomic_t oo_nr_ios; + wait_queue_head_t oo_io_waitq; }; static inline void osc_object_lock(struct osc_object *obj) @@ -399,10 +403,9 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, 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); -int osc_cache_truncate_start(const struct lu_env *env, struct osc_io *oio, - struct osc_object *obj, __u64 size); -void osc_cache_truncate_end(const struct lu_env *env, struct osc_io *oio, - struct osc_object *obj); +int osc_cache_truncate_start(const struct lu_env *env, struct osc_object *obj, + u64 size, struct osc_extent **extp); +void osc_cache_truncate_end(const struct lu_env *env, struct osc_extent *ext); int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj, pgoff_t start, pgoff_t end, int hp, int discard); int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj, diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index 688783dcc1e4..8abd83f26716 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -114,9 +114,9 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, struct ptlrpc_request_set *rqset, int async, int agl); int osc_match_base(struct obd_export *exp, struct ldlm_res_id *res_id, - __u32 type, union ldlm_policy_data *policy, __u32 mode, - __u64 *flags, void *data, struct lustre_handle *lockh, - int unref); + enum ldlm_type type, union ldlm_policy_data *policy, + enum ldlm_mode mode, __u64 *flags, void *data, + struct lustre_handle *lockh, int unref); int osc_setattr_async(struct obd_export *exp, struct obdo *oa, obd_enqueue_update_f upcall, void *cookie, @@ -181,6 +181,8 @@ static inline struct osc_device *obd2osc_dev(const struct obd_device *d) return container_of0(d->obd_lu_dev, struct osc_device, od_cl.cd_lu_dev); } +extern struct lu_kmem_descr osc_caches[]; + extern struct kmem_cache *osc_quota_kmem; struct osc_quota_info { /** linkage for quota hash table */ @@ -218,4 +220,15 @@ struct ldlm_lock *osc_dlmlock_at_pgoff(const struct lu_env *env, struct osc_object *obj, pgoff_t index, enum osc_dap_flags flags); +int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc); + +/** osc shrink list to link all osc client obd */ +extern struct list_head osc_shrink_list; +/** spin lock to protect osc_shrink_list */ +extern spinlock_t osc_shrink_lock; +unsigned long osc_cache_shrink_count(struct shrinker *sk, + struct shrink_control *sc); +unsigned long osc_cache_shrink_scan(struct shrinker *sk, + struct shrink_control *sc); + #endif /* OSC_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 228a97c098fe..0b4cc4283b05 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -37,6 +37,8 @@ #define DEBUG_SUBSYSTEM S_OSC +#include "../include/lustre_obdo.h" + #include "osc_cl_internal.h" /** \addtogroup osc @@ -97,6 +99,7 @@ static int osc_io_read_ahead(const struct lu_env *env, ldlm_lock_decref(&lockh, dlmlock->l_req_mode); } + ra->cra_rpc_size = osc_cli(osc)->cl_max_pages_per_rpc; ra->cra_end = cl_index(osc2cl(osc), dlmlock->l_policy_data.l_extent.end); ra->cra_release = osc_read_ahead_release; @@ -136,7 +139,7 @@ static int osc_io_submit(const struct lu_env *env, LASSERT(qin->pl_nr > 0); - CDEBUG(D_CACHE, "%d %d\n", qin->pl_nr, crt); + CDEBUG(D_CACHE | D_READA, "%d %d\n", qin->pl_nr, crt); osc = cl2osc(ios->cis_obj); cli = osc_cli(osc); @@ -207,6 +210,18 @@ static int osc_io_submit(const struct lu_env *env, if (queued > 0) result = osc_queue_sync_pages(env, osc, &list, cmd, brw_flags); + /* Update c/mtime for sync write. LU-7310 */ + if (qout->pl_nr > 0 && !result) { + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct cl_object *obj = ios->cis_obj; + + cl_object_attr_lock(obj); + attr->cat_mtime = LTIME_S(CURRENT_TIME); + attr->cat_ctime = attr->cat_mtime; + cl_object_attr_update(env, obj, attr, CAT_MTIME | CAT_CTIME); + cl_object_attr_unlock(obj); + } + CDEBUG(D_INFO, "%d/%d %d\n", qin->pl_nr, qout->pl_nr, result); return qout->pl_nr > 0 ? 0 : result; } @@ -330,8 +345,25 @@ static int osc_io_commit_async(const struct lu_env *env, return result; } -static int osc_io_rw_iter_init(const struct lu_env *env, - const struct cl_io_slice *ios) +static int osc_io_iter_init(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct osc_object *osc = cl2osc(ios->cis_obj); + struct obd_import *imp = osc_cli(osc)->cl_import; + int rc = -EIO; + + spin_lock(&imp->imp_lock); + if (likely(!imp->imp_invalid)) { + atomic_inc(&osc->oo_nr_ios); + rc = 0; + } + spin_unlock(&imp->imp_lock); + + return rc; +} + +static int osc_io_write_iter_init(const struct lu_env *env, + const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; struct osc_io *oio = osc_env_io(env); @@ -342,7 +374,7 @@ static int osc_io_rw_iter_init(const struct lu_env *env, unsigned long max_pages; if (cl_io_is_append(io)) - return 0; + return osc_io_iter_init(env, ios); npages = io->u.ci_rw.crw_count >> PAGE_SHIFT; if (io->u.ci_rw.crw_pos & ~PAGE_MASK) @@ -374,11 +406,21 @@ static int osc_io_rw_iter_init(const struct lu_env *env, (void)ptlrpcd_queue_work(cli->cl_lru_work); } - return 0; + return osc_io_iter_init(env, ios); } -static void osc_io_rw_iter_fini(const struct lu_env *env, - const struct cl_io_slice *ios) +static void osc_io_iter_fini(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct osc_object *osc = cl2osc(ios->cis_obj); + + LASSERT(atomic_read(&osc->oo_nr_ios) > 0); + if (atomic_dec_and_test(&osc->oo_nr_ios)) + wake_up_all(&osc->oo_io_waitq); +} + +static void osc_io_write_iter_fini(const struct lu_env *env, + const struct cl_io_slice *ios) { struct osc_io *oio = osc_env_io(env); struct osc_object *osc = cl2osc(ios->cis_obj); @@ -389,6 +431,8 @@ static void osc_io_rw_iter_fini(const struct lu_env *env, oio->oi_lru_reserved = 0; } oio->oi_write_osclock = NULL; + + osc_io_iter_fini(env, ios); } static int osc_io_fault_start(const struct lu_env *env, @@ -479,7 +523,8 @@ static int osc_io_setattr_start(const struct lu_env *env, /* truncate cache dirty pages first */ if (cl_io_is_trunc(io)) - result = osc_cache_truncate_start(env, oio, cl2osc(obj), size); + result = osc_cache_truncate_start(env, cl2osc(obj), size, + &oio->oi_trunc); if (result == 0 && oio->oi_lockless == 0) { cl_object_attr_lock(obj); @@ -589,10 +634,8 @@ static void osc_io_setattr_end(const struct lu_env *env, __u64 size = io->u.ci_setattr.sa_attr.lvb_size; osc_trunc_check(env, io, oio, size); - if (oio->oi_trunc) { - osc_cache_truncate_end(env, oio, cl2osc(obj)); - oio->oi_trunc = NULL; - } + osc_cache_truncate_end(env, oio->oi_trunc); + oio->oi_trunc = NULL; } } @@ -669,7 +712,7 @@ static int osc_io_data_version_start(const struct lu_env *env, ptlrpc_request_set_replen(req); req->rq_interpret_reply = osc_data_version_interpret; - CLASSERT(sizeof(*dva) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*dva) > sizeof(req->rq_async_args)); dva = ptlrpc_req_async_args(req); dva->dva_oio = oio; @@ -832,17 +875,21 @@ static void osc_io_end(const struct lu_env *env, static const struct cl_io_operations osc_io_ops = { .op = { [CIT_READ] = { + .cio_iter_init = osc_io_iter_init, + .cio_iter_fini = osc_io_iter_fini, .cio_start = osc_io_read_start, .cio_fini = osc_io_fini }, [CIT_WRITE] = { - .cio_iter_init = osc_io_rw_iter_init, - .cio_iter_fini = osc_io_rw_iter_fini, + .cio_iter_init = osc_io_write_iter_init, + .cio_iter_fini = osc_io_write_iter_fini, .cio_start = osc_io_write_start, .cio_end = osc_io_end, .cio_fini = osc_io_fini }, [CIT_SETATTR] = { + .cio_iter_init = osc_io_iter_init, + .cio_iter_fini = osc_io_iter_fini, .cio_start = osc_io_setattr_start, .cio_end = osc_io_setattr_end }, @@ -851,6 +898,8 @@ static const struct cl_io_operations osc_io_ops = { .cio_end = osc_io_data_version_end, }, [CIT_FAULT] = { + .cio_iter_init = osc_io_iter_init, + .cio_iter_fini = osc_io_iter_fini, .cio_start = osc_io_fault_start, .cio_end = osc_io_end, .cio_fini = osc_io_fini diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index e0c3324857dd..d3e5ca7db7b2 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -78,6 +78,9 @@ static int osc_object_init(const struct lu_env *env, struct lu_object *obj, INIT_LIST_HEAD(&osc->oo_write_item); INIT_LIST_HEAD(&osc->oo_read_item); + atomic_set(&osc->oo_nr_ios, 0); + init_waitqueue_head(&osc->oo_io_waitq); + osc->oo_root.rb_node = NULL; INIT_LIST_HEAD(&osc->oo_hp_exts); INIT_LIST_HEAD(&osc->oo_urgent_exts); @@ -112,6 +115,7 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj) LASSERT(atomic_read(&osc->oo_nr_reads) == 0); LASSERT(atomic_read(&osc->oo_nr_writes) == 0); LASSERT(list_empty(&osc->oo_ol_list)); + LASSERT(!atomic_read(&osc->oo_nr_ios)); lu_object_fini(obj); kmem_cache_free(osc_object_kmem, osc); @@ -444,4 +448,19 @@ struct lu_object *osc_object_alloc(const struct lu_env *env, return obj; } +int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc) +{ + struct l_wait_info lwi = { 0 }; + + CDEBUG(D_INODE, "Invalidate osc object: %p, # of active IOs: %d\n", + osc, atomic_read(&osc->oo_nr_ios)); + + l_wait_event(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios), &lwi); + + /* Discard all pages of this object. */ + osc_cache_truncate_start(env, osc, 0, NULL); + + return 0; +} + /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index e356e4af08e1..ab9d0d7bb943 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -370,12 +370,17 @@ static int osc_cache_too_much(struct client_obd *cli) return lru_shrink_min(cli); } else { time64_t duration = ktime_get_real_seconds(); + long timediff; /* knock out pages by duration of no IO activity */ duration -= cli->cl_lru_last_used; - duration >>= 6; /* approximately 1 minute */ - if (duration > 0 && - pages >= div64_s64((s64)budget, duration)) + /* + * The difference shouldn't be more than 70 years + * so we can safely case to a long. Round to + * approximately 1 minute. + */ + timediff = (long)(duration >> 6); + if (timediff > 0 && pages >= budget / timediff) return lru_shrink_min(cli); } return 0; @@ -943,4 +948,91 @@ bool osc_over_unstable_soft_limit(struct client_obd *cli) cli->cl_max_rpcs_in_flight; } +/** + * Return how many LRU pages in the cache of all OSC devices + * + * Return: return # of cached LRU pages times reclaimation tendency + * SHRINK_STOP if it cannot do any scanning in this time + */ +unsigned long osc_cache_shrink_count(struct shrinker *sk, + struct shrink_control *sc) +{ + struct client_obd *cli; + unsigned long cached = 0; + + spin_lock(&osc_shrink_lock); + list_for_each_entry(cli, &osc_shrink_list, cl_shrink_list) + cached += atomic_long_read(&cli->cl_lru_in_list); + spin_unlock(&osc_shrink_lock); + + return (cached * sysctl_vfs_cache_pressure) / 100; +} + +/** + * Scan and try to reclaim sc->nr_to_scan cached LRU pages + * + * Return: number of cached LRU pages reclaimed + * SHRINK_STOP if it cannot do any scanning in this time + * + * Linux kernel will loop calling this shrinker scan routine with + * sc->nr_to_scan = SHRINK_BATCH(128 for now) until kernel got enough memory. + * + * If sc->nr_to_scan is 0, the VM is querying the cache size, we don't need + * to scan and try to reclaim LRU pages, just return 0 and + * osc_cache_shrink_count() will report the LRU page number. + */ +unsigned long osc_cache_shrink_scan(struct shrinker *sk, + struct shrink_control *sc) +{ + struct client_obd *stop_anchor = NULL; + struct client_obd *cli; + struct lu_env *env; + long shrank = 0; + int refcheck; + int rc; + + if (!sc->nr_to_scan) + return 0; + + if (!(sc->gfp_mask & __GFP_FS)) + return SHRINK_STOP; + + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return SHRINK_STOP; + + spin_lock(&osc_shrink_lock); + while (!list_empty(&osc_shrink_list)) { + cli = list_entry(osc_shrink_list.next, struct client_obd, + cl_shrink_list); + + if (!stop_anchor) + stop_anchor = cli; + else if (cli == stop_anchor) + break; + + list_move_tail(&cli->cl_shrink_list, &osc_shrink_list); + spin_unlock(&osc_shrink_lock); + + /* shrink no more than max_pages_per_rpc for an OSC */ + rc = osc_lru_shrink(env, cli, (sc->nr_to_scan - shrank) > + cli->cl_max_pages_per_rpc ? + cli->cl_max_pages_per_rpc : + sc->nr_to_scan - shrank, true); + if (rc > 0) + shrank += rc; + + if (shrank >= sc->nr_to_scan) + goto out; + + spin_lock(&osc_shrink_lock); + } + spin_unlock(&osc_shrink_lock); + +out: + cl_env_put(env, &refcheck); + + return shrank; +} + /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 7143564ae7e7..c4cfe18c3294 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -43,6 +43,7 @@ #include "../include/lprocfs_status.h" #include "../include/lustre/lustre_ioctl.h" #include "../include/lustre_debug.h" +#include "../include/lustre_obdo.h" #include "../include/lustre_param.h" #include "../include/lustre_fid.h" #include "../include/obd_class.h" @@ -250,7 +251,7 @@ int osc_setattr_async(struct obd_export *exp, struct obdo *oa, req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_setattr_interpret; - CLASSERT(sizeof(*sa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*sa) > sizeof(req->rq_async_args)); sa = ptlrpc_req_async_args(req); sa->sa_oa = oa; sa->sa_upcall = upcall; @@ -348,7 +349,7 @@ int osc_punch_base(struct obd_export *exp, struct obdo *oa, ptlrpc_request_set_replen(req); req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_setattr_interpret; - CLASSERT(sizeof(*sa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*sa) > sizeof(req->rq_async_args)); sa = ptlrpc_req_async_args(req); sa->sa_oa = oa; sa->sa_upcall = upcall; @@ -429,7 +430,7 @@ int osc_sync_base(struct osc_object *obj, struct obdo *oa, ptlrpc_request_set_replen(req); req->rq_interpret_reply = osc_sync_interpret; - CLASSERT(sizeof(*fa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*fa) > sizeof(req->rq_async_args)); fa = ptlrpc_req_async_args(req); fa->fa_obj = obj; fa->fa_oa = oa; @@ -1170,7 +1171,7 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, } ptlrpc_request_set_replen(req); - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); aa->aa_oa = oa; aa->aa_requested_nob = requested_nob; @@ -1757,7 +1758,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, cl_req_attr_set(env, osc2cl(obj), crattr); lustre_msg_set_jobid(req->rq_reqmsg, crattr->cra_jobid); - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); INIT_LIST_HEAD(&aa->aa_oaps); list_splice_init(&rpc_list, &aa->aa_oaps); @@ -2038,7 +2039,7 @@ no_match: if (!rc) { struct osc_enqueue_args *aa; - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); aa->oa_exp = exp; aa->oa_mode = einfo->ei_mode; @@ -2080,9 +2081,9 @@ no_match: } int osc_match_base(struct obd_export *exp, struct ldlm_res_id *res_id, - __u32 type, union ldlm_policy_data *policy, __u32 mode, - __u64 *flags, void *data, struct lustre_handle *lockh, - int unref) + enum ldlm_type type, union ldlm_policy_data *policy, + enum ldlm_mode mode, __u64 *flags, void *data, + struct lustre_handle *lockh, int unref) { struct obd_device *obd = exp->exp_obd; __u64 lflags = *flags; @@ -2195,7 +2196,7 @@ static int osc_statfs_async(struct obd_export *exp, } req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_statfs_interpret; - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); aa->aa_oi = oinfo; @@ -2400,7 +2401,7 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, struct osc_brw_async_args *aa; struct obdo *oa; - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); oa = kmem_cache_zalloc(obdo_cachep, GFP_NOFS); if (!oa) { @@ -2479,6 +2480,33 @@ static int osc_disconnect(struct obd_export *exp) return rc; } +static int osc_ldlm_resource_invalidate(struct cfs_hash *hs, + struct cfs_hash_bd *bd, + struct hlist_node *hnode, void *arg) +{ + struct ldlm_resource *res = cfs_hash_object(hs, hnode); + struct osc_object *osc = NULL; + struct lu_env *env = arg; + struct ldlm_lock *lock; + + lock_res(res); + list_for_each_entry(lock, &res->lr_granted, l_res_link) { + if (lock->l_ast_data && !osc) { + osc = lock->l_ast_data; + cl_object_get(osc2cl(osc)); + } + lock->l_ast_data = NULL; + } + unlock_res(res); + + if (osc) { + osc_object_invalidate(env, osc); + cl_object_put(env, osc2cl(osc)); + } + + return 0; +} + static int osc_import_event(struct obd_device *obd, struct obd_import *imp, enum obd_import_event event) @@ -2506,17 +2534,18 @@ static int osc_import_event(struct obd_device *obd, struct lu_env *env; int refcheck; + ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY); + env = cl_env_get(&refcheck); if (!IS_ERR(env)) { - /* Reset grants */ - cli = &obd->u.cli; - /* all pages go to failing rpcs due to the invalid - * import - */ - osc_io_unplug(env, cli, NULL); + osc_io_unplug(env, &obd->u.cli, NULL); - ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY); + cfs_hash_for_each_nolock(ns->ns_rs_hash, + osc_ldlm_resource_invalidate, + env, 0); cl_env_put(env, &refcheck); + + ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY); } else { rc = PTR_ERR(env); } @@ -2646,6 +2675,11 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) INIT_LIST_HEAD(&cli->cl_grant_shrink_list); ns_register_cancel(obd->obd_namespace, osc_cancel_weight); + + spin_lock(&osc_shrink_lock); + list_add_tail(&cli->cl_shrink_list, &osc_shrink_list); + spin_unlock(&osc_shrink_lock); + return rc; out_ptlrpcd_work: @@ -2699,6 +2733,10 @@ static int osc_cleanup(struct obd_device *obd) struct client_obd *cli = &obd->u.cli; int rc; + spin_lock(&osc_shrink_lock); + list_del(&cli->cl_shrink_list); + spin_unlock(&osc_shrink_lock); + /* lru cleanup */ if (cli->cl_cache) { LASSERT(atomic_read(&cli->cl_cache->ccc_users) > 0); @@ -2766,7 +2804,14 @@ static struct obd_ops osc_obd_ops = { .quotactl = osc_quotactl, }; -extern struct lu_kmem_descr osc_caches[]; +struct list_head osc_shrink_list = LIST_HEAD_INIT(osc_shrink_list); +DEFINE_SPINLOCK(osc_shrink_lock); + +static struct shrinker osc_cache_shrinker = { + .count_objects = osc_cache_shrink_count, + .scan_objects = osc_cache_shrink_scan, + .seeks = DEFAULT_SEEKS, +}; static int __init osc_init(void) { @@ -2792,6 +2837,8 @@ static int __init osc_init(void) if (rc) goto out_kmem; + register_shrinker(&osc_cache_shrinker); + /* This is obviously too much memory, only prevent overflow here */ if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0) { rc = -EINVAL; @@ -2830,6 +2877,7 @@ out_kmem: static void /*__exit*/ osc_exit(void) { + unregister_shrinker(&osc_cache_shrinker); class_unregister_type(LUSTRE_OSC_NAME); lu_kmem_fini(osc_caches); ptlrpc_free_rq_pool(osc_rq_pool); diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 804741362bc0..04a98a08ece1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -1160,7 +1160,7 @@ static int ptlrpc_import_delay_req(struct obd_import *imp, if (atomic_read(&imp->imp_inval_count) != 0) { DEBUG_REQ(D_ERROR, req, "invalidate in flight"); *status = -EIO; - } else if (imp->imp_dlm_fake || req->rq_no_delay) { + } else if (req->rq_no_delay) { *status = -EWOULDBLOCK; } else if (req->rq_allow_replay && (imp->imp_state == LUSTRE_IMP_REPLAY || @@ -2662,11 +2662,16 @@ free_req: list_for_each_entry_safe(req, saved, &imp->imp_committed_list, rq_replay_list) { LASSERT(req->rq_transno != 0); - if (req->rq_import_generation < imp->imp_generation) { - DEBUG_REQ(D_RPCTRACE, req, "free stale open request"); - ptlrpc_free_request(req); - } else if (!req->rq_replay) { - DEBUG_REQ(D_RPCTRACE, req, "free closed open request"); + if (req->rq_import_generation < imp->imp_generation || + !req->rq_replay) { + DEBUG_REQ(D_RPCTRACE, req, "free %s open request", + req->rq_import_generation < + imp->imp_generation ? "stale" : "closed"); + + if (imp->imp_replay_cursor == &req->rq_replay_list) + imp->imp_replay_cursor = + req->rq_replay_list.next; + ptlrpc_free_request(req); } } @@ -3070,7 +3075,7 @@ void ptlrpc_init_xid(void) } /* Always need to be aligned to a power-of-two for multi-bulk BRW */ - CLASSERT(((PTLRPC_BULK_OPS_COUNT - 1) & PTLRPC_BULK_OPS_COUNT) == 0); + BUILD_BUG_ON(((PTLRPC_BULK_OPS_COUNT - 1) & PTLRPC_BULK_OPS_COUNT) != 0); ptlrpc_last_xid &= PTLRPC_BULK_OPS_MASK; } @@ -3123,8 +3128,11 @@ void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req) req->rq_mbits = ptlrpc_next_xid(); } else { /* old version transfers rq_xid to peer as matchbits */ - req->rq_mbits = ptlrpc_next_xid(); - req->rq_xid = req->rq_mbits; + spin_lock(&req->rq_import->imp_lock); + list_del_init(&req->rq_unreplied_list); + ptlrpc_assign_next_xid_nolock(req); + req->rq_mbits = req->rq_xid; + spin_unlock(&req->rq_import->imp_lock); } CDEBUG(D_HA, "resend bulk old x%llu new x%llu\n", @@ -3256,7 +3264,7 @@ void *ptlrpcd_alloc_work(struct obd_import *imp, req->rq_no_resend = 1; req->rq_pill.rc_fmt = (void *)&worker_format; - CLASSERT(sizeof(*args) <= sizeof(req->rq_async_args)); + BUILD_BUG_ON(sizeof(*args) > sizeof(req->rq_async_args)); args = ptlrpc_req_async_args(req); args->cb = cb; args->cbdata = cbdata; diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 49f3e6368415..dc0fe9d660da 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -277,7 +277,7 @@ static void ptlrpc_req_add_history(struct ptlrpc_service_part *svcpt, * then we hope there will be less RPCs per bucket at some * point, and sequence will catch up again */ - svcpt->scp_hist_seq += (1U << REQS_SEQ_SHIFT(svcpt)); + svcpt->scp_hist_seq += (1ULL << REQS_SEQ_SHIFT(svcpt)); new_seq = svcpt->scp_hist_seq; } @@ -420,7 +420,8 @@ void reply_out_callback(lnet_event_t *ev) rs->rs_on_net = 0; if (!rs->rs_no_ack || rs->rs_transno <= - rs->rs_export->exp_obd->obd_last_committed) + rs->rs_export->exp_obd->obd_last_committed || + list_empty(&rs->rs_obd_list)) ptlrpc_schedule_difficult_reply(rs); spin_unlock(&rs->rs_lock); diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index e8280194001c..93e172fe9ce4 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -703,7 +703,7 @@ int ptlrpc_connect_import(struct obd_import *imp) ptlrpc_request_set_replen(request); request->rq_interpret_reply = ptlrpc_connect_interpret; - CLASSERT(sizeof(*aa) <= sizeof(request->rq_async_args)); + BUILD_BUG_ON(sizeof(*aa) > sizeof(request->rq_async_args)); aa = ptlrpc_req_async_args(request); memset(aa, 0, sizeof(*aa)); diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index 99d7c667df28..356d73511ea3 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -42,8 +42,6 @@ * of the format that the request conforms to. */ -#if !defined(__REQ_LAYOUT_USER__) - #define DEBUG_SUBSYSTEM S_RPC #include <linux/module.h> @@ -57,8 +55,6 @@ #include "../include/obd.h" #include "../include/obd_support.h" -/* __REQ_LAYOUT_USER__ */ -#endif /* struct ptlrpc_request, lustre_msg* */ #include "../include/lustre_req_layout.h" #include "../include/lustre_acl.h" @@ -1181,6 +1177,23 @@ struct req_format RQF_FLD_QUERY = DEFINE_REQ_FMT0("FLD_QUERY", fld_query_client, fld_query_server); EXPORT_SYMBOL(RQF_FLD_QUERY); +/* + * The 'fld_read_server' uses 'RMF_GENERIC_DATA' to hold the 'FLD_QUERY' + * RPC reply that is composed of 'struct lu_seq_range_array'. But there + * is not registered swabber function for 'RMF_GENERIC_DATA'. So the RPC + * peers need to handle the RPC reply with fixed little-endian format. + * + * In theory, we can define new structure with some swabber registered to + * handle the 'FLD_QUERY' RPC reply result automatically. But from the + * implementation view, it is not easy to be done within current "struct + * req_msg_field" framework. Because the sequence range array in the RPC + * reply is not fixed length, instead, its length depends on 'lu_seq_range' + * count, that is unknown when prepare the RPC buffer. Generally, for such + * flexible length RPC usage, there will be a field in the RPC layout to + * indicate the data length. But for the 'FLD_READ' RPC, we have no way to + * do that unless we add new length filed that will broken the on-wire RPC + * protocol and cause interoperability trouble with old peer. + */ struct req_format RQF_FLD_READ = DEFINE_REQ_FMT0("FLD_READ", fld_read_client, fld_read_server); EXPORT_SYMBOL(RQF_FLD_READ); @@ -1541,8 +1554,6 @@ struct req_format RQF_OST_GET_INFO_FIEMAP = ost_get_fiemap_server); EXPORT_SYMBOL(RQF_OST_GET_INFO_FIEMAP); -#if !defined(__REQ_LAYOUT_USER__) - /* Convenience macro */ #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)] @@ -2221,6 +2232,3 @@ void req_capsule_shrink(struct req_capsule *pill, 1); } EXPORT_SYMBOL(req_capsule_shrink); - -/* __REQ_LAYOUT_USER__ */ -#endif diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index da1209e40f03..b8701841ab4a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -522,13 +522,14 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) */ spin_lock(&imp->imp_lock); ptlrpc_assign_next_xid_nolock(request); - request->rq_mbits = request->rq_xid; min_xid = ptlrpc_known_replied_xid(imp); spin_unlock(&imp->imp_lock); lustre_msg_set_last_xid(request->rq_reqmsg, min_xid); DEBUG_REQ(D_RPCTRACE, request, "Allocating new xid for resend on EINPROGRESS"); - } else if (request->rq_bulk) { + } + + if (request->rq_bulk) { ptlrpc_set_bulk_mbits(request); lustre_msg_set_mbits(request->rq_reqmsg, request->rq_mbits); } diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c index 7b6ffb195834..ef19dbe2ea5c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c +++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c @@ -1559,9 +1559,6 @@ out: return rc; } -/* ptlrpc/nrs_fifo.c */ -extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo; - /** * Adds all policies that ship with the ptlrpc module, to NRS core's list of * policies \e nrs_core.nrs_policies. diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 13f00b7cbbe5..9456a1825918 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -469,6 +469,7 @@ int lustre_shrink_msg(struct lustre_msg *msg, int segment, default: LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic); } + return 0; } EXPORT_SYMBOL(lustre_shrink_msg); @@ -509,8 +510,8 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len) __swab32s(&m->lm_repsize); __swab32s(&m->lm_cksum); __swab32s(&m->lm_flags); - CLASSERT(offsetof(typeof(*m), lm_padding_2) != 0); - CLASSERT(offsetof(typeof(*m), lm_padding_3) != 0); + BUILD_BUG_ON(offsetof(typeof(*m), lm_padding_2) == 0); + BUILD_BUG_ON(offsetof(typeof(*m), lm_padding_3) == 0); } required_len = lustre_msg_hdr_size_v2(m->lm_bufcount); @@ -1525,18 +1526,18 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *b) __swab64s(&b->pb_pre_versions[2]); __swab64s(&b->pb_pre_versions[3]); __swab64s(&b->pb_mbits); - CLASSERT(offsetof(typeof(*b), pb_padding0) != 0); - CLASSERT(offsetof(typeof(*b), pb_padding1) != 0); - CLASSERT(offsetof(typeof(*b), pb_padding64_0) != 0); - CLASSERT(offsetof(typeof(*b), pb_padding64_1) != 0); - CLASSERT(offsetof(typeof(*b), pb_padding64_2) != 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_padding0) == 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_padding1) == 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_padding64_0) == 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_padding64_1) == 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_padding64_2) == 0); /* While we need to maintain compatibility between * clients and servers without ptlrpc_body_v2 (< 2.3) * do not swab any fields beyond pb_jobid, as we are * using this swab function for both ptlrpc_body * and ptlrpc_body_v2. */ - CLASSERT(offsetof(typeof(*b), pb_jobid) != 0); + BUILD_BUG_ON(offsetof(typeof(*b), pb_jobid) == 0); } void lustre_swab_connect(struct obd_connect_data *ocd) @@ -1567,23 +1568,23 @@ void lustre_swab_connect(struct obd_connect_data *ocd) __swab64s(&ocd->ocd_maxbytes); if (ocd->ocd_connect_flags & OBD_CONNECT_MULTIMODRPCS) __swab16s(&ocd->ocd_maxmodrpcs); - CLASSERT(offsetof(typeof(*ocd), padding0)); - CLASSERT(offsetof(typeof(*ocd), padding1) != 0); + BUILD_BUG_ON(!offsetof(typeof(*ocd), padding0)); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding1) == 0); if (ocd->ocd_connect_flags & OBD_CONNECT_FLAGS2) __swab64s(&ocd->ocd_connect_flags2); - CLASSERT(offsetof(typeof(*ocd), padding3) != 0); - CLASSERT(offsetof(typeof(*ocd), padding4) != 0); - CLASSERT(offsetof(typeof(*ocd), padding5) != 0); - CLASSERT(offsetof(typeof(*ocd), padding6) != 0); - CLASSERT(offsetof(typeof(*ocd), padding7) != 0); - CLASSERT(offsetof(typeof(*ocd), padding8) != 0); - CLASSERT(offsetof(typeof(*ocd), padding9) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingA) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingB) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingC) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingD) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingE) != 0); - CLASSERT(offsetof(typeof(*ocd), paddingF) != 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding3) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding4) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding5) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding6) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding7) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding8) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), padding9) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingA) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingB) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingC) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingD) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingE) == 0); + BUILD_BUG_ON(offsetof(typeof(*ocd), paddingF) == 0); } static void lustre_swab_obdo(struct obdo *o) @@ -1613,9 +1614,9 @@ static void lustre_swab_obdo(struct obdo *o) __swab32s(&o->o_uid_h); __swab32s(&o->o_gid_h); __swab64s(&o->o_data_version); - CLASSERT(offsetof(typeof(*o), o_padding_4) != 0); - CLASSERT(offsetof(typeof(*o), o_padding_5) != 0); - CLASSERT(offsetof(typeof(*o), o_padding_6) != 0); + BUILD_BUG_ON(offsetof(typeof(*o), o_padding_4) == 0); + BUILD_BUG_ON(offsetof(typeof(*o), o_padding_5) == 0); + BUILD_BUG_ON(offsetof(typeof(*o), o_padding_6) == 0); } void lustre_swab_obd_statfs(struct obd_statfs *os) @@ -1631,15 +1632,15 @@ void lustre_swab_obd_statfs(struct obd_statfs *os) __swab32s(&os->os_namelen); __swab64s(&os->os_maxbytes); __swab32s(&os->os_state); - CLASSERT(offsetof(typeof(*os), os_fprecreated) != 0); - CLASSERT(offsetof(typeof(*os), os_spare2) != 0); - CLASSERT(offsetof(typeof(*os), os_spare3) != 0); - CLASSERT(offsetof(typeof(*os), os_spare4) != 0); - CLASSERT(offsetof(typeof(*os), os_spare5) != 0); - CLASSERT(offsetof(typeof(*os), os_spare6) != 0); - CLASSERT(offsetof(typeof(*os), os_spare7) != 0); - CLASSERT(offsetof(typeof(*os), os_spare8) != 0); - CLASSERT(offsetof(typeof(*os), os_spare9) != 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_fprecreated) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare2) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare3) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare4) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare5) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare6) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare7) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare8) == 0); + BUILD_BUG_ON(offsetof(typeof(*os), os_spare9) == 0); } void lustre_swab_obd_ioobj(struct obd_ioobj *ioo) @@ -1679,7 +1680,7 @@ void lustre_swab_gl_desc(union ldlm_gl_desc *desc) __swab64s(&desc->lquota_desc.gl_hardlimit); __swab64s(&desc->lquota_desc.gl_softlimit); __swab64s(&desc->lquota_desc.gl_time); - CLASSERT(offsetof(typeof(desc->lquota_desc), gl_pad2) != 0); + BUILD_BUG_ON(offsetof(typeof(desc->lquota_desc), gl_pad2) == 0); } void lustre_swab_ost_lvb_v1(struct ost_lvb_v1 *lvb) @@ -1738,24 +1739,24 @@ void lustre_swab_mdt_body(struct mdt_body *b) __swab32s(&b->mbo_flags); __swab32s(&b->mbo_rdev); __swab32s(&b->mbo_nlink); - CLASSERT(offsetof(typeof(*b), mbo_unused2) != 0); + BUILD_BUG_ON(offsetof(typeof(*b), mbo_unused2) == 0); __swab32s(&b->mbo_suppgid); __swab32s(&b->mbo_eadatasize); __swab32s(&b->mbo_aclsize); __swab32s(&b->mbo_max_mdsize); - CLASSERT(offsetof(typeof(*b), mbo_unused3)); + BUILD_BUG_ON(!offsetof(typeof(*b), mbo_unused3)); __swab32s(&b->mbo_uid_h); __swab32s(&b->mbo_gid_h); - CLASSERT(offsetof(typeof(*b), mbo_padding_5) != 0); + BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_5) == 0); } void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b) { /* handle is opaque */ /* mio_handle is opaque */ - CLASSERT(offsetof(typeof(*b), mio_unused1)); - CLASSERT(offsetof(typeof(*b), mio_unused2)); - CLASSERT(offsetof(typeof(*b), mio_padding)); + BUILD_BUG_ON(!offsetof(typeof(*b), mio_unused1)); + BUILD_BUG_ON(!offsetof(typeof(*b), mio_unused2)); + BUILD_BUG_ON(!offsetof(typeof(*b), mio_padding)); } void lustre_swab_mgs_target_info(struct mgs_target_info *mti) @@ -1768,7 +1769,7 @@ void lustre_swab_mgs_target_info(struct mgs_target_info *mti) __swab32s(&mti->mti_flags); __swab32s(&mti->mti_instance); __swab32s(&mti->mti_nid_count); - CLASSERT(sizeof(lnet_nid_t) == sizeof(__u64)); + BUILD_BUG_ON(sizeof(lnet_nid_t) != sizeof(__u64)); for (i = 0; i < MTI_NIDS_MAX; i++) __swab64s(&mti->mti_nids[i]); } @@ -1784,13 +1785,13 @@ void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *entry) /* mne_nid_(count|type) must be one byte size because we're gonna * access it w/o swapping. */ - CLASSERT(sizeof(entry->mne_nid_count) == sizeof(__u8)); - CLASSERT(sizeof(entry->mne_nid_type) == sizeof(__u8)); + BUILD_BUG_ON(sizeof(entry->mne_nid_count) != sizeof(__u8)); + BUILD_BUG_ON(sizeof(entry->mne_nid_type) != sizeof(__u8)); /* remove this assertion if ipv6 is supported. */ LASSERT(entry->mne_nid_type == 0); for (i = 0; i < entry->mne_nid_count; i++) { - CLASSERT(sizeof(lnet_nid_t) == sizeof(__u64)); + BUILD_BUG_ON(sizeof(lnet_nid_t) != sizeof(__u64)); __swab64s(&entry->u.nids[i]); } } @@ -1828,7 +1829,7 @@ static void lustre_swab_obd_dqblk(struct obd_dqblk *b) __swab64s(&b->dqb_btime); __swab64s(&b->dqb_itime); __swab32s(&b->dqb_valid); - CLASSERT(offsetof(typeof(*b), dqb_padding) != 0); + BUILD_BUG_ON(offsetof(typeof(*b), dqb_padding) == 0); } void lustre_swab_obd_quotactl(struct obd_quotactl *q) @@ -1899,7 +1900,7 @@ void lustre_swab_mdt_rec_reint (struct mdt_rec_reint *rr) __swab32s(&rr->rr_flags_h); __swab32s(&rr->rr_umask); - CLASSERT(offsetof(typeof(*rr), rr_padding_4) != 0); + BUILD_BUG_ON(offsetof(typeof(*rr), rr_padding_4) == 0); }; void lustre_swab_lov_desc(struct lov_desc *ld) @@ -1948,7 +1949,7 @@ void lustre_swab_lmv_user_md(struct lmv_user_md *lum) __swab32s(&lum->lum_stripe_offset); __swab32s(&lum->lum_hash_type); __swab32s(&lum->lum_type); - CLASSERT(offsetof(typeof(*lum), lum_padding1)); + BUILD_BUG_ON(!offsetof(typeof(*lum), lum_padding1)); } EXPORT_SYMBOL(lustre_swab_lmv_user_md); @@ -2037,7 +2038,7 @@ void lustre_swab_ldlm_intent(struct ldlm_intent *i) static void lustre_swab_ldlm_resource_desc(struct ldlm_resource_desc *r) { __swab32s(&r->lr_type); - CLASSERT(offsetof(typeof(*r), lr_padding) != 0); + BUILD_BUG_ON(offsetof(typeof(*r), lr_padding) == 0); lustre_swab_ldlm_res_id(&r->lr_name); } @@ -2060,7 +2061,7 @@ void lustre_swab_ldlm_request(struct ldlm_request *rq) void lustre_swab_ldlm_reply(struct ldlm_reply *r) { __swab32s(&r->lock_flags); - CLASSERT(offsetof(typeof(*r), lock_padding) != 0); + BUILD_BUG_ON(offsetof(typeof(*r), lock_padding) == 0); lustre_swab_ldlm_lock_desc(&r->lock_desc); /* lock_handle opaque */ __swab64s(&r->lock_policy_res1); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pers.c b/drivers/staging/lustre/lustre/ptlrpc/pers.c index 94e9fa85d774..601acb84f343 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pers.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pers.c @@ -45,7 +45,7 @@ void ptlrpc_fill_bulk_md(lnet_md_t *md, struct ptlrpc_bulk_desc *desc, { int offset = mdidx * LNET_MAX_IOV; - CLASSERT(PTLRPC_MAX_BRW_PAGES < LI_POISON); + BUILD_BUG_ON(PTLRPC_MAX_BRW_PAGES >= LI_POISON); LASSERT(mdidx < desc->bd_md_max_brw); LASSERT(desc->bd_iov_count <= PTLRPC_MAX_BRW_PAGES); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index e0f859ca6223..8e6a805487ec 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -226,6 +226,9 @@ struct ptlrpc_nrs_policy *nrs_request_policy(struct ptlrpc_nrs_request *nrq) sizeof(NRS_LPROCFS_QUANTUM_NAME_REG __stringify(LPROCFS_NRS_QUANTUM_MAX) " " \ NRS_LPROCFS_QUANTUM_NAME_HP __stringify(LPROCFS_NRS_QUANTUM_MAX)) +/* ptlrpc/nrs_fifo.c */ +extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo; + /* recovd_thread.c */ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 1f55d642aa75..59b5813bd559 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -82,7 +82,8 @@ struct ptlrpcd { */ static int max_ptlrpcds; module_param(max_ptlrpcds, int, 0644); -MODULE_PARM_DESC(max_ptlrpcds, "Max ptlrpcd thread count to be started."); +MODULE_PARM_DESC(max_ptlrpcds, + "Max ptlrpcd thread count to be started (obsolete)."); /* * ptlrpcd_bind_policy is obsolete, but retained to ensure that @@ -102,7 +103,7 @@ MODULE_PARM_DESC(ptlrpcd_bind_policy, static int ptlrpcd_per_cpt_max; module_param(ptlrpcd_per_cpt_max, int, 0644); MODULE_PARM_DESC(ptlrpcd_per_cpt_max, - "Max ptlrpcd thread count to be started per cpt."); + "Max ptlrpcd thread count to be started per CPT."); /* * ptlrpcd_partner_group_size: The desired number of threads in each @@ -562,15 +563,6 @@ int ptlrpcd_start(struct ptlrpcd_ctl *pc) return 0; } - /* - * So far only "client" ptlrpcd uses an environment. In the future, - * ptlrpcd thread (or a thread-set) has to be given an argument, - * describing its "scope". - */ - rc = lu_context_init(&pc->pc_env.le_ctx, LCT_CL_THREAD | LCT_REMEMBER); - if (rc != 0) - goto out; - task = kthread_run(ptlrpcd, pc, "%s", pc->pc_name); if (IS_ERR(task)) { rc = PTR_ERR(task); @@ -593,9 +585,6 @@ out_set: spin_unlock(&pc->pc_lock); ptlrpc_set_destroy(set); } - lu_context_fini(&pc->pc_env.le_ctx); - -out: clear_bit(LIOD_START, &pc->pc_flags); return rc; } @@ -623,7 +612,6 @@ void ptlrpcd_free(struct ptlrpcd_ctl *pc) } wait_for_completion(&pc->pc_finishing); - lu_context_fini(&pc->pc_env.le_ctx); spin_lock(&pc->pc_lock); pc->pc_set = NULL; diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c index c00449036884..7b58545c2de4 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/recover.c +++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c @@ -78,28 +78,11 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) imp->imp_last_transno_checked = 0; ptlrpc_free_committed(imp); last_transno = imp->imp_last_replay_transno; - spin_unlock(&imp->imp_lock); CDEBUG(D_HA, "import %p from %s committed %llu last %llu\n", imp, obd2cli_tgt(imp->imp_obd), imp->imp_peer_committed_transno, last_transno); - /* Do I need to hold a lock across this iteration? We shouldn't be - * racing with any additions to the list, because we're in recovery - * and are therefore not processing additional requests to add. Calls - * to ptlrpc_free_committed might commit requests, but nothing "newer" - * than the one we're replaying (it can't be committed until it's - * replayed, and we're doing that here). l_f_e_safe protects against - * problems with the current request being committed, in the unlikely - * event of that race. So, in conclusion, I think that it's safe to - * perform this list-walk without the imp_lock held. - * - * But, the {mdc,osc}_replay_open callbacks both iterate - * request lists, and have comments saying they assume the - * imp_lock is being held by ptlrpc_replay, but it's not. it's - * just a little race... - */ - /* Replay all the committed open requests on committed_list first */ if (!list_empty(&imp->imp_committed_list)) { tmp = imp->imp_committed_list.prev; @@ -107,10 +90,6 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) /* The last request on committed_list hasn't been replayed */ if (req->rq_transno > last_transno) { - /* Since the imp_committed_list is immutable before - * all of it's requests being replayed, it's safe to - * use a cursor to accelerate the search - */ if (!imp->imp_resend_replay || imp->imp_replay_cursor == &imp->imp_committed_list) imp->imp_replay_cursor = imp->imp_replay_cursor->next; @@ -124,6 +103,7 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) break; req = NULL; + LASSERT(!list_empty(imp->imp_replay_cursor)); imp->imp_replay_cursor = imp->imp_replay_cursor->next; } @@ -156,7 +136,6 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) if (req && imp->imp_resend_replay) lustre_msg_add_flags(req->rq_reqmsg, MSG_RESENT); - spin_lock(&imp->imp_lock); /* The resend replay request may have been removed from the * unreplied list. */ @@ -221,6 +200,7 @@ int ptlrpc_resend(struct obd_import *imp) } spin_unlock(&imp->imp_lock); + OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT, 2); return 0; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 70c70558e177..b8091c118302 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -1264,20 +1264,15 @@ static int ptlrpc_server_hpreq_init(struct ptlrpc_service_part *svcpt, */ if (req->rq_ops->hpreq_check) { rc = req->rq_ops->hpreq_check(req); - /** - * XXX: Out of all current - * ptlrpc_hpreq_ops::hpreq_check(), only - * ldlm_cancel_hpreq_check() can return an error code; - * other functions assert in similar places, which seems - * odd. What also does not seem right is that handlers - * for those RPCs do not assert on the same checks, but - * rather handle the error cases. e.g. see - * ost_rw_hpreq_check(), and ost_brw_read(), - * ost_brw_write(). + if (rc == -ESTALE) { + req->rq_status = rc; + ptlrpc_error(req); + } + /** can only return error, + * 0 for normal request, + * or 1 for high priority request */ - if (rc < 0) - return rc; - LASSERT(rc == 0 || rc == 1); + LASSERT(rc <= 1); } spin_lock_bh(&req->rq_export->exp_rpc_lock); diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c index a04e36cf6dd4..367f7e24e3da 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c +++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c @@ -61,7 +61,7 @@ void lustre_assert_wire_constants(void) MDS_DIR_END_OFF); LASSERTF(DEAD_HANDLE_MAGIC == 0xdeadbeefcafebabeULL, "found 0x%.16llxULL\n", DEAD_HANDLE_MAGIC); - CLASSERT(MTI_NAME_MAXLEN == 64); + BUILD_BUG_ON(MTI_NAME_MAXLEN != 64); LASSERTF(OST_REPLY == 0, "found %lld\n", (long long)OST_REPLY); LASSERTF(OST_GETATTR == 1, "found %lld\n", @@ -306,16 +306,16 @@ void lustre_assert_wire_constants(void) (long long)LCK_MAXMODE); LASSERTF(LCK_MODE_NUM == 8, "found %lld\n", (long long)LCK_MODE_NUM); - CLASSERT(LDLM_PLAIN == 10); - CLASSERT(LDLM_EXTENT == 11); - CLASSERT(LDLM_FLOCK == 12); - CLASSERT(LDLM_IBITS == 13); - CLASSERT(LDLM_MAX_TYPE == 14); - CLASSERT(LUSTRE_RES_ID_SEQ_OFF == 0); - CLASSERT(LUSTRE_RES_ID_VER_OID_OFF == 1); - CLASSERT(LUSTRE_RES_ID_QUOTA_SEQ_OFF == 2); - CLASSERT(LUSTRE_RES_ID_QUOTA_VER_OID_OFF == 3); - CLASSERT(LUSTRE_RES_ID_HSH_OFF == 3); + BUILD_BUG_ON(LDLM_PLAIN != 10); + BUILD_BUG_ON(LDLM_EXTENT != 11); + BUILD_BUG_ON(LDLM_FLOCK != 12); + BUILD_BUG_ON(LDLM_IBITS != 13); + BUILD_BUG_ON(LDLM_MAX_TYPE != 14); + BUILD_BUG_ON(LUSTRE_RES_ID_SEQ_OFF != 0); + BUILD_BUG_ON(LUSTRE_RES_ID_VER_OID_OFF != 1); + BUILD_BUG_ON(LUSTRE_RES_ID_QUOTA_SEQ_OFF != 2); + BUILD_BUG_ON(LUSTRE_RES_ID_QUOTA_VER_OID_OFF != 3); + BUILD_BUG_ON(LUSTRE_RES_ID_HSH_OFF != 3); LASSERTF(OBD_PING == 400, "found %lld\n", (long long)OBD_PING); LASSERTF(OBD_LOG_CANCEL == 401, "found %lld\n", @@ -661,7 +661,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct ptlrpc_body_v3, pb_slv)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_slv) == 8, "found %lld\n", (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_slv)); - CLASSERT(PTLRPC_NUM_VERSIONS == 4); + BUILD_BUG_ON(PTLRPC_NUM_VERSIONS != 4); LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_pre_versions) == 88, "found %lld\n", (long long)(int)offsetof(struct ptlrpc_body_v3, pb_pre_versions)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_pre_versions) == 32, "found %lld\n", @@ -682,7 +682,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding64_2)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2) == 8, "found %lld\n", (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2)); - CLASSERT(LUSTRE_JOBID_SIZE == 32); + BUILD_BUG_ON(LUSTRE_JOBID_SIZE != 32); LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n", (long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_jobid) == 32, "found %lld\n", @@ -1319,27 +1319,27 @@ void lustre_assert_wire_constants(void) OBD_MD_FLGETATTRLOCK); LASSERTF(OBD_MD_FLDATAVERSION == (0x0010000000000000ULL), "found 0x%.16llxULL\n", OBD_MD_FLDATAVERSION); - CLASSERT(OBD_FL_INLINEDATA == 0x00000001); - CLASSERT(OBD_FL_OBDMDEXISTS == 0x00000002); - CLASSERT(OBD_FL_DELORPHAN == 0x00000004); - CLASSERT(OBD_FL_NORPC == 0x00000008); - CLASSERT(OBD_FL_IDONLY == 0x00000010); - CLASSERT(OBD_FL_RECREATE_OBJS == 0x00000020); - CLASSERT(OBD_FL_DEBUG_CHECK == 0x00000040); - CLASSERT(OBD_FL_NO_USRQUOTA == 0x00000100); - CLASSERT(OBD_FL_NO_GRPQUOTA == 0x00000200); - CLASSERT(OBD_FL_CREATE_CROW == 0x00000400); - CLASSERT(OBD_FL_SRVLOCK == 0x00000800); - CLASSERT(OBD_FL_CKSUM_CRC32 == 0x00001000); - CLASSERT(OBD_FL_CKSUM_ADLER == 0x00002000); - CLASSERT(OBD_FL_CKSUM_CRC32C == 0x00004000); - CLASSERT(OBD_FL_CKSUM_RSVD2 == 0x00008000); - CLASSERT(OBD_FL_CKSUM_RSVD3 == 0x00010000); - CLASSERT(OBD_FL_SHRINK_GRANT == 0x00020000); - CLASSERT(OBD_FL_MMAP == 0x00040000); - CLASSERT(OBD_FL_RECOV_RESEND == 0x00080000); - CLASSERT(OBD_FL_NOSPC_BLK == 0x00100000); - CLASSERT(OBD_FL_LOCAL_MASK == 0xf0000000); + BUILD_BUG_ON(OBD_FL_INLINEDATA != 0x00000001); + BUILD_BUG_ON(OBD_FL_OBDMDEXISTS != 0x00000002); + BUILD_BUG_ON(OBD_FL_DELORPHAN != 0x00000004); + BUILD_BUG_ON(OBD_FL_NORPC != 0x00000008); + BUILD_BUG_ON(OBD_FL_IDONLY != 0x00000010); + BUILD_BUG_ON(OBD_FL_RECREATE_OBJS != 0x00000020); + BUILD_BUG_ON(OBD_FL_DEBUG_CHECK != 0x00000040); + BUILD_BUG_ON(OBD_FL_NO_USRQUOTA != 0x00000100); + BUILD_BUG_ON(OBD_FL_NO_GRPQUOTA != 0x00000200); + BUILD_BUG_ON(OBD_FL_CREATE_CROW != 0x00000400); + BUILD_BUG_ON(OBD_FL_SRVLOCK != 0x00000800); + BUILD_BUG_ON(OBD_FL_CKSUM_CRC32 != 0x00001000); + BUILD_BUG_ON(OBD_FL_CKSUM_ADLER != 0x00002000); + BUILD_BUG_ON(OBD_FL_CKSUM_CRC32C != 0x00004000); + BUILD_BUG_ON(OBD_FL_CKSUM_RSVD2 != 0x00008000); + BUILD_BUG_ON(OBD_FL_CKSUM_RSVD3 != 0x00010000); + BUILD_BUG_ON(OBD_FL_SHRINK_GRANT != 0x00020000); + BUILD_BUG_ON(OBD_FL_MMAP != 0x00040000); + BUILD_BUG_ON(OBD_FL_RECOV_RESEND != 0x00080000); + BUILD_BUG_ON(OBD_FL_NOSPC_BLK != 0x00100000); + BUILD_BUG_ON(OBD_FL_LOCAL_MASK != 0xf0000000); /* Checks for struct lov_ost_data_v1 */ LASSERTF((int)sizeof(struct lov_ost_data_v1) == 24, "found %lld\n", @@ -1388,7 +1388,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lov_mds_md_v1, lmm_objects[0])); LASSERTF((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_objects[0]) == 24, "found %lld\n", (long long)(int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_objects[0])); - CLASSERT(LOV_MAGIC_V1 == (0x0BD10000 | 0x0BD0)); + BUILD_BUG_ON(LOV_MAGIC_V1 != (0x0BD10000 | 0x0BD0)); /* Checks for struct lov_mds_md_v3 */ LASSERTF((int)sizeof(struct lov_mds_md_v3) == 48, "found %lld\n", @@ -1417,7 +1417,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lov_mds_md_v3, lmm_layout_gen)); LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen) == 2, "found %lld\n", (long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen)); - CLASSERT(LOV_MAXPOOLNAME == 15); + BUILD_BUG_ON(LOV_MAXPOOLNAME != 15); LASSERTF((int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]) == 48, "found %lld\n", (long long)(int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16])); LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_pool_name[16]) == 1, "found %lld\n", @@ -1426,7 +1426,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lov_mds_md_v3, lmm_objects[0])); LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_objects[0]) == 24, "found %lld\n", (long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_objects[0])); - CLASSERT(LOV_MAGIC_V3 == (0x0BD30000 | 0x0BD0)); + BUILD_BUG_ON(LOV_MAGIC_V3 != (0x0BD30000 | 0x0BD0)); LASSERTF(LOV_PATTERN_RAID0 == 0x00000001UL, "found 0x%.8xUL\n", (unsigned int)LOV_PATTERN_RAID0); LASSERTF(LOV_PATTERN_RAID1 == 0x00000002UL, "found 0x%.8xUL\n", @@ -1479,11 +1479,11 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0])); LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]) == 16, "found %lld\n", (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0])); - CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0); - CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0); - CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff); - CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000); - CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000); + BUILD_BUG_ON(LMV_MAGIC_V1 != 0x0CD20CD0); + BUILD_BUG_ON(LMV_MAGIC_STRIPE != 0x0CD40CD0); + BUILD_BUG_ON(LMV_HASH_TYPE_MASK != 0x0000ffff); + BUILD_BUG_ON(LMV_HASH_FLAG_MIGRATION != 0x80000000); + BUILD_BUG_ON(LMV_HASH_FLAG_DEAD != 0x40000000); /* Checks for struct obd_statfs */ LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n", @@ -2761,12 +2761,12 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lov_desc, ld_uuid)); LASSERTF((int)sizeof(((struct lov_desc *)0)->ld_uuid) == 40, "found %lld\n", (long long)(int)sizeof(((struct lov_desc *)0)->ld_uuid)); - CLASSERT(LOV_DESC_MAGIC == 0xB0CCDE5C); + BUILD_BUG_ON(LOV_DESC_MAGIC != 0xB0CCDE5C); /* Checks for struct ldlm_res_id */ LASSERTF((int)sizeof(struct ldlm_res_id) == 32, "found %lld\n", (long long)(int)sizeof(struct ldlm_res_id)); - CLASSERT(RES_NAME_SIZE == 4); + BUILD_BUG_ON(RES_NAME_SIZE != 4); LASSERTF((int)offsetof(struct ldlm_res_id, name[4]) == 32, "found %lld\n", (long long)(int)offsetof(struct ldlm_res_id, name[4])); LASSERTF((int)sizeof(((struct ldlm_res_id *)0)->name[4]) == 8, "found %lld\n", @@ -3037,7 +3037,7 @@ void lustre_assert_wire_constants(void) /* Checks for struct mgs_send_param */ LASSERTF((int)sizeof(struct mgs_send_param) == 1024, "found %lld\n", (long long)(int)sizeof(struct mgs_send_param)); - CLASSERT(MGS_PARAM_MAXLEN == 1024); + BUILD_BUG_ON(MGS_PARAM_MAXLEN != 1024); LASSERTF((int)offsetof(struct mgs_send_param, mgs_param[1024]) == 1024, "found %lld\n", (long long)(int)offsetof(struct mgs_send_param, mgs_param[1024])); LASSERTF((int)sizeof(((struct mgs_send_param *)0)->mgs_param[1024]) == 1, "found %lld\n", @@ -3090,16 +3090,16 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llog_logid, lgl_ogen)); LASSERTF((int)sizeof(((struct llog_logid *)0)->lgl_ogen) == 4, "found %lld\n", (long long)(int)sizeof(((struct llog_logid *)0)->lgl_ogen)); - CLASSERT(OST_SZ_REC == 274730752); - CLASSERT(MDS_UNLINK_REC == 274801668); - CLASSERT(MDS_UNLINK64_REC == 275325956); - CLASSERT(MDS_SETATTR64_REC == 275325953); - CLASSERT(OBD_CFG_REC == 274857984); - CLASSERT(LLOG_GEN_REC == 274989056); - CLASSERT(CHANGELOG_REC == 275120128); - CLASSERT(CHANGELOG_USER_REC == 275185664); - CLASSERT(LLOG_HDR_MAGIC == 275010873); - CLASSERT(LLOG_LOGID_MAGIC == 275010875); + BUILD_BUG_ON(OST_SZ_REC != 274730752); + BUILD_BUG_ON(MDS_UNLINK_REC != 274801668); + BUILD_BUG_ON(MDS_UNLINK64_REC != 275325956); + BUILD_BUG_ON(MDS_SETATTR64_REC != 275325953); + BUILD_BUG_ON(OBD_CFG_REC != 274857984); + BUILD_BUG_ON(LLOG_GEN_REC != 274989056); + BUILD_BUG_ON(CHANGELOG_REC != 275120128); + BUILD_BUG_ON(CHANGELOG_USER_REC != 275185664); + BUILD_BUG_ON(LLOG_HDR_MAGIC != 275010873); + BUILD_BUG_ON(LLOG_LOGID_MAGIC != 275010875); /* Checks for struct llog_catid */ LASSERTF((int)sizeof(struct llog_catid) == 32, "found %lld\n", @@ -3519,30 +3519,30 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llogd_body, lgd_cur_offset)); LASSERTF((int)sizeof(((struct llogd_body *)0)->lgd_cur_offset) == 8, "found %lld\n", (long long)(int)sizeof(((struct llogd_body *)0)->lgd_cur_offset)); - CLASSERT(LLOG_ORIGIN_HANDLE_CREATE == 501); - CLASSERT(LLOG_ORIGIN_HANDLE_NEXT_BLOCK == 502); - CLASSERT(LLOG_ORIGIN_HANDLE_READ_HEADER == 503); - CLASSERT(LLOG_ORIGIN_HANDLE_WRITE_REC == 504); - CLASSERT(LLOG_ORIGIN_HANDLE_CLOSE == 505); - CLASSERT(LLOG_ORIGIN_CONNECT == 506); - CLASSERT(LLOG_CATINFO == 507); - CLASSERT(LLOG_ORIGIN_HANDLE_PREV_BLOCK == 508); - CLASSERT(LLOG_ORIGIN_HANDLE_DESTROY == 509); - CLASSERT(LLOG_FIRST_OPC == 501); - CLASSERT(LLOG_LAST_OPC == 510); - CLASSERT(LLOG_CONFIG_ORIG_CTXT == 0); - CLASSERT(LLOG_CONFIG_REPL_CTXT == 1); - CLASSERT(LLOG_MDS_OST_ORIG_CTXT == 2); - CLASSERT(LLOG_MDS_OST_REPL_CTXT == 3); - CLASSERT(LLOG_SIZE_ORIG_CTXT == 4); - CLASSERT(LLOG_SIZE_REPL_CTXT == 5); - CLASSERT(LLOG_TEST_ORIG_CTXT == 8); - CLASSERT(LLOG_TEST_REPL_CTXT == 9); - CLASSERT(LLOG_CHANGELOG_ORIG_CTXT == 12); - CLASSERT(LLOG_CHANGELOG_REPL_CTXT == 13); - CLASSERT(LLOG_CHANGELOG_USER_ORIG_CTXT == 14); - CLASSERT(LLOG_AGENT_ORIG_CTXT == 15); - CLASSERT(LLOG_MAX_CTXTS == 16); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_CREATE != 501); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_NEXT_BLOCK != 502); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_READ_HEADER != 503); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_WRITE_REC != 504); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_CLOSE != 505); + BUILD_BUG_ON(LLOG_ORIGIN_CONNECT != 506); + BUILD_BUG_ON(LLOG_CATINFO != 507); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_PREV_BLOCK != 508); + BUILD_BUG_ON(LLOG_ORIGIN_HANDLE_DESTROY != 509); + BUILD_BUG_ON(LLOG_FIRST_OPC != 501); + BUILD_BUG_ON(LLOG_LAST_OPC != 510); + BUILD_BUG_ON(LLOG_CONFIG_ORIG_CTXT != 0); + BUILD_BUG_ON(LLOG_CONFIG_REPL_CTXT != 1); + BUILD_BUG_ON(LLOG_MDS_OST_ORIG_CTXT != 2); + BUILD_BUG_ON(LLOG_MDS_OST_REPL_CTXT != 3); + BUILD_BUG_ON(LLOG_SIZE_ORIG_CTXT != 4); + BUILD_BUG_ON(LLOG_SIZE_REPL_CTXT != 5); + BUILD_BUG_ON(LLOG_TEST_ORIG_CTXT != 8); + BUILD_BUG_ON(LLOG_TEST_REPL_CTXT != 9); + BUILD_BUG_ON(LLOG_CHANGELOG_ORIG_CTXT != 12); + BUILD_BUG_ON(LLOG_CHANGELOG_REPL_CTXT != 13); + BUILD_BUG_ON(LLOG_CHANGELOG_USER_ORIG_CTXT != 14); + BUILD_BUG_ON(LLOG_AGENT_ORIG_CTXT != 15); + BUILD_BUG_ON(LLOG_MAX_CTXTS != 16); /* Checks for struct llogd_conn_body */ LASSERTF((int)sizeof(struct llogd_conn_body) == 40, "found %lld\n", @@ -3659,7 +3659,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lustre_capa, lc_expiry)); LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_expiry) == 4, "found %lld\n", (long long)(int)sizeof(((struct lustre_capa *)0)->lc_expiry)); - CLASSERT(CAPA_HMAC_MAX_LEN == 64); + BUILD_BUG_ON(CAPA_HMAC_MAX_LEN != 64); LASSERTF((int)offsetof(struct lustre_capa, lc_hmac[64]) == 120, "found %lld\n", (long long)(int)offsetof(struct lustre_capa, lc_hmac[64])); LASSERTF((int)sizeof(((struct lustre_capa *)0)->lc_hmac[64]) == 1, "found %lld\n", @@ -3680,7 +3680,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lustre_capa_key, lk_padding)); LASSERTF((int)sizeof(((struct lustre_capa_key *)0)->lk_padding) == 4, "found %lld\n", (long long)(int)sizeof(((struct lustre_capa_key *)0)->lk_padding)); - CLASSERT(CAPA_HMAC_KEY_MAX_LEN == 56); + BUILD_BUG_ON(CAPA_HMAC_KEY_MAX_LEN != 56); LASSERTF((int)offsetof(struct lustre_capa_key, lk_key[56]) == 72, "found %lld\n", (long long)(int)offsetof(struct lustre_capa_key, lk_key[56])); LASSERTF((int)sizeof(((struct lustre_capa_key *)0)->lk_key[56]) == 1, "found %lld\n", @@ -3741,9 +3741,9 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct fiemap, fm_extents)); LASSERTF((int)sizeof(((struct fiemap *)0)->fm_extents) == 0, "found %lld\n", (long long)(int)sizeof(((struct fiemap *)0)->fm_extents)); - CLASSERT(FIEMAP_FLAG_SYNC == 0x00000001); - CLASSERT(FIEMAP_FLAG_XATTR == 0x00000002); - CLASSERT(FIEMAP_FLAG_DEVICE_ORDER == 0x40000000); + BUILD_BUG_ON(FIEMAP_FLAG_SYNC != 0x00000001); + BUILD_BUG_ON(FIEMAP_FLAG_XATTR != 0x00000002); + BUILD_BUG_ON(FIEMAP_FLAG_DEVICE_ORDER != 0x40000000); /* Checks for struct fiemap_extent */ LASSERTF((int)sizeof(struct fiemap_extent) == 56, "found %lld\n", @@ -3768,18 +3768,18 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct fiemap_extent, fe_reserved[0])); LASSERTF((int)sizeof(((struct fiemap_extent *)0)->fe_reserved[0]) == 4, "found %lld\n", (long long)(int)sizeof(((struct fiemap_extent *)0)->fe_reserved[0])); - CLASSERT(FIEMAP_EXTENT_LAST == 0x00000001); - CLASSERT(FIEMAP_EXTENT_UNKNOWN == 0x00000002); - CLASSERT(FIEMAP_EXTENT_DELALLOC == 0x00000004); - CLASSERT(FIEMAP_EXTENT_ENCODED == 0x00000008); - CLASSERT(FIEMAP_EXTENT_DATA_ENCRYPTED == 0x00000080); - CLASSERT(FIEMAP_EXTENT_NOT_ALIGNED == 0x00000100); - CLASSERT(FIEMAP_EXTENT_DATA_INLINE == 0x00000200); - CLASSERT(FIEMAP_EXTENT_DATA_TAIL == 0x00000400); - CLASSERT(FIEMAP_EXTENT_UNWRITTEN == 0x00000800); - CLASSERT(FIEMAP_EXTENT_MERGED == 0x00001000); - CLASSERT(FIEMAP_EXTENT_NO_DIRECT == 0x40000000); - CLASSERT(FIEMAP_EXTENT_NET == 0x80000000); + BUILD_BUG_ON(FIEMAP_EXTENT_LAST != 0x00000001); + BUILD_BUG_ON(FIEMAP_EXTENT_UNKNOWN != 0x00000002); + BUILD_BUG_ON(FIEMAP_EXTENT_DELALLOC != 0x00000004); + BUILD_BUG_ON(FIEMAP_EXTENT_ENCODED != 0x00000008); + BUILD_BUG_ON(FIEMAP_EXTENT_DATA_ENCRYPTED != 0x00000080); + BUILD_BUG_ON(FIEMAP_EXTENT_NOT_ALIGNED != 0x00000100); + BUILD_BUG_ON(FIEMAP_EXTENT_DATA_INLINE != 0x00000200); + BUILD_BUG_ON(FIEMAP_EXTENT_DATA_TAIL != 0x00000400); + BUILD_BUG_ON(FIEMAP_EXTENT_UNWRITTEN != 0x00000800); + BUILD_BUG_ON(FIEMAP_EXTENT_MERGED != 0x00001000); + BUILD_BUG_ON(FIEMAP_EXTENT_NO_DIRECT != 0x40000000); + BUILD_BUG_ON(FIEMAP_EXTENT_NET != 0x80000000); /* Checks for type posix_acl_xattr_entry */ LASSERTF((int)sizeof(struct posix_acl_xattr_entry) == 8, "found %lld\n", @@ -3828,7 +3828,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct link_ea_header, padding2)); LASSERTF((int)sizeof(((struct link_ea_header *)0)->padding2) == 4, "found %lld\n", (long long)(int)sizeof(((struct link_ea_header *)0)->padding2)); - CLASSERT(LINK_EA_MAGIC == 0x11EAF1DFUL); + BUILD_BUG_ON(LINK_EA_MAGIC != 0x11EAF1DFUL); /* Checks for struct link_ea_entry */ LASSERTF((int)sizeof(struct link_ea_entry) == 18, "found %lld\n", diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index ffb8fa72c3da..abd0e2d57c20 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -27,6 +27,8 @@ source "drivers/staging/media/davinci_vpfe/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" +source "drivers/staging/media/platform/bcm2835/Kconfig" + source "drivers/staging/media/s5p-cec/Kconfig" # Keep LIRC at the end, as it has sub-menus diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index a28e82cf6447..dc89325c463d 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ +obj-$(CONFIG_VIDEO_BCM2835) += platform/bcm2835/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += st-cec/ diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 37bd439ee08b..d605c41d0424 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -300,7 +300,7 @@ struct bcm2048_device { }; static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */ -module_param(radio_nr, int, 0); +module_param(radio_nr, int, 0000); MODULE_PARM_DESC(radio_nr, "Minor number for radio device (-1 ==> auto assign)"); diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index bf077f8342f6..32109cdd73a6 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -74,7 +74,7 @@ static bool debug; static bool interface; -module_param(interface, bool, S_IRUGO); +module_param(interface, bool, 0444); module_param(debug, bool, 0644); /** diff --git a/drivers/staging/media/platform/bcm2835/Kconfig b/drivers/staging/media/platform/bcm2835/Kconfig new file mode 100644 index 000000000000..7c5245dc3225 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/Kconfig @@ -0,0 +1,10 @@ +config VIDEO_BCM2835 + tristate "Broadcom BCM2835 camera driver" + depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) + depends on BCM2835_VCHIQ + depends on ARM + select VIDEOBUF2_VMALLOC + help + Say Y here to enable camera host interface devices for + Broadcom BCM2835 SoC. This operates over the VCHIQ interface + to a service running on VideoCore. diff --git a/drivers/staging/media/platform/bcm2835/Makefile b/drivers/staging/media/platform/bcm2835/Makefile new file mode 100644 index 000000000000..8307f30517d5 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/Makefile @@ -0,0 +1,10 @@ +bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ + bcm2835-camera.o \ + controls.o \ + mmal-vchiq.o + +obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o + +ccflags-y += \ + -Idrivers/staging/vc04_services \ + -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/media/platform/bcm2835/TODO b/drivers/staging/media/platform/bcm2835/TODO new file mode 100644 index 000000000000..61a509992b9a --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/TODO @@ -0,0 +1,39 @@ +1) Support dma-buf memory management. + +In order to zero-copy import camera images into the 3D or display +pipelines, we need to export our buffers through dma-buf so that the +vc4 driver can import them. This may involve bringing in the VCSM +driver (which allows long-term management of regions of memory in the +space that the VPU reserved and Linux otherwise doesn't have access +to), or building some new protocol that allows VCSM-style management +of Linux's CMA memory. + +2) Avoid extra copies for padding of images. + +We expose V4L2_PIX_FMT_* formats that have a specified stride/height +padding in the V4L2 spec, but that padding doesn't match what the +hardware can do. If we exposed the native padding requirements +through the V4L2 "multiplanar" formats, the firmware would have one +less copy it needed to do. + +3) Port to ARM64 + +The bulk_receive() does some manual cache flushing that are 32-bit ARM +only, which we should convert to proper cross-platform APIs. + +4) Convert to be a platform driver. + +Right now when the module probes, it tries to initialize VCHI and +errors out if it wasn't ready yet. If bcm2835-v4l2 was built in, then +VCHI generally isn't ready because it depends on both the firmware and +mailbox drivers having already loaded. + +We should have VCHI create a platform device once it's initialized, +and have this driver bind to it, so that we automatically load the +v4l2 module after VCHI loads. + +5) Drop the gstreamer workaround. + +This was a temporary workaround for a bug that was fixed mid-2014, and +we should remove it before stabilizing the driver. + diff --git a/drivers/staging/media/platform/bcm2835/bcm2835-camera.c b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c new file mode 100644 index 000000000000..ca15a698e018 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/bcm2835-camera.c @@ -0,0 +1,2024 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <media/videobuf2-vmalloc.h> +#include <media/videobuf2-dma-contig.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> +#include <media/v4l2-common.h> +#include <linux/delay.h> + +#include "mmal-common.h" +#include "mmal-encodings.h" +#include "mmal-vchiq.h" +#include "mmal-msg.h" +#include "mmal-parameters.h" +#include "bcm2835-camera.h" + +#define BM2835_MMAL_VERSION "0.0.2" +#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2" +#define MIN_WIDTH 32 +#define MIN_HEIGHT 32 +#define MIN_BUFFER_SIZE (80 * 1024) + +#define MAX_VIDEO_MODE_WIDTH 1280 +#define MAX_VIDEO_MODE_HEIGHT 720 + +#define MAX_BCM2835_CAMERAS 2 + +MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture"); +MODULE_AUTHOR("Vincent Sanders"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(BM2835_MMAL_VERSION); + +int bcm2835_v4l2_debug; +module_param_named(debug, bcm2835_v4l2_debug, int, 0644); +MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2"); + +#define UNSET (-1) +static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET }; +module_param_array(video_nr, int, NULL, 0644); +MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect"); + +static int max_video_width = MAX_VIDEO_MODE_WIDTH; +static int max_video_height = MAX_VIDEO_MODE_HEIGHT; +module_param(max_video_width, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(max_video_width, "Threshold for video mode"); +module_param(max_video_height, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(max_video_height, "Threshold for video mode"); + +/* Gstreamer bug https://bugzilla.gnome.org/show_bug.cgi?id=726521 + * v4l2src does bad (and actually wrong) things when the vidioc_enum_framesizes + * function says type V4L2_FRMSIZE_TYPE_STEPWISE, which we do by default. + * It's happier if we just don't say anything at all, when it then + * sets up a load of defaults that it thinks might work. + * If gst_v4l2src_is_broken is non-zero, then we remove the function from + * our function table list (actually switch to an alternate set, but same + * result). + */ +static int gst_v4l2src_is_broken; +module_param(gst_v4l2src_is_broken, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(gst_v4l2src_is_broken, "If non-zero, enable workaround for Gstreamer"); + +/* global device data array */ +static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS]; + +#define FPS_MIN 1 +#define FPS_MAX 90 + +/* timeperframe: min/max and default */ +static const struct v4l2_fract + tpf_min = {.numerator = 1, .denominator = FPS_MAX}, + tpf_max = {.numerator = 1, .denominator = FPS_MIN}, + tpf_default = {.numerator = 1000, .denominator = 30000}; + +/* video formats */ +static struct mmal_fmt formats[] = { + { + .name = "4:2:0, planar, YUV", + .fourcc = V4L2_PIX_FMT_YUV420, + .flags = 0, + .mmal = MMAL_ENCODING_I420, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 1, + }, + { + .name = "4:2:2, packed, YUYV", + .fourcc = V4L2_PIX_FMT_YUYV, + .flags = 0, + .mmal = MMAL_ENCODING_YUYV, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 2, + }, + { + .name = "RGB24 (LE)", + .fourcc = V4L2_PIX_FMT_RGB24, + .flags = 0, + .mmal = MMAL_ENCODING_RGB24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 3, + }, + { + .name = "JPEG", + .fourcc = V4L2_PIX_FMT_JPEG, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal = MMAL_ENCODING_JPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, + .ybbp = 0, + }, + { + .name = "H264", + .fourcc = V4L2_PIX_FMT_H264, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal = MMAL_ENCODING_H264, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, + .ybbp = 0, + }, + { + .name = "MJPEG", + .fourcc = V4L2_PIX_FMT_MJPEG, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal = MMAL_ENCODING_MJPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, + .ybbp = 0, + }, + { + .name = "4:2:2, packed, YVYU", + .fourcc = V4L2_PIX_FMT_YVYU, + .flags = 0, + .mmal = MMAL_ENCODING_YVYU, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 2, + }, + { + .name = "4:2:2, packed, VYUY", + .fourcc = V4L2_PIX_FMT_VYUY, + .flags = 0, + .mmal = MMAL_ENCODING_VYUY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 2, + }, + { + .name = "4:2:2, packed, UYVY", + .fourcc = V4L2_PIX_FMT_UYVY, + .flags = 0, + .mmal = MMAL_ENCODING_UYVY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 2, + }, + { + .name = "4:2:0, planar, NV12", + .fourcc = V4L2_PIX_FMT_NV12, + .flags = 0, + .mmal = MMAL_ENCODING_NV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 1, + }, + { + .name = "RGB24 (BE)", + .fourcc = V4L2_PIX_FMT_BGR24, + .flags = 0, + .mmal = MMAL_ENCODING_BGR24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 3, + }, + { + .name = "4:2:0, planar, YVU", + .fourcc = V4L2_PIX_FMT_YVU420, + .flags = 0, + .mmal = MMAL_ENCODING_YV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 1, + }, + { + .name = "4:2:0, planar, NV21", + .fourcc = V4L2_PIX_FMT_NV21, + .flags = 0, + .mmal = MMAL_ENCODING_NV21, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 1, + }, + { + .name = "RGB32 (BE)", + .fourcc = V4L2_PIX_FMT_BGR32, + .flags = 0, + .mmal = MMAL_ENCODING_BGRA, + .depth = 32, + .mmal_component = MMAL_COMPONENT_CAMERA, + .ybbp = 4, + }, +}; + +static struct mmal_fmt *get_format(struct v4l2_format *f) +{ + struct mmal_fmt *fmt; + unsigned int k; + + for (k = 0; k < ARRAY_SIZE(formats); k++) { + fmt = &formats[k]; + if (fmt->fourcc == f->fmt.pix.pixelformat) + break; + } + + if (k == ARRAY_SIZE(formats)) + return NULL; + + return &formats[k]; +} + +/* ------------------------------------------------------------------ + Videobuf queue operations + ------------------------------------------------------------------*/ + +static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_ctxs[]) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + unsigned long size; + + /* refuse queue setup if port is not configured */ + if (dev->capture.port == NULL) { + v4l2_err(&dev->v4l2_dev, + "%s: capture port not configured\n", __func__); + return -EINVAL; + } + + size = dev->capture.port->current_buffer.size; + if (size == 0) { + v4l2_err(&dev->v4l2_dev, + "%s: capture port buffer size is zero\n", __func__); + return -EINVAL; + } + + if (*nbuffers < (dev->capture.port->current_buffer.num + 2)) + *nbuffers = (dev->capture.port->current_buffer.num + 2); + + *nplanes = 1; + + sizes[0] = size; + + /* + * videobuf2-vmalloc allocator is context-less so no need to set + * alloc_ctxs array. + */ + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", + __func__, dev); + + return 0; +} + +static int buffer_prepare(struct vb2_buffer *vb) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + unsigned long size; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", + __func__, dev); + + BUG_ON(dev->capture.port == NULL); + BUG_ON(dev->capture.fmt == NULL); + + size = dev->capture.stride * dev->capture.height; + if (vb2_plane_size(vb, 0) < size) { + v4l2_err(&dev->v4l2_dev, + "%s data will not fit into plane (%lu < %lu)\n", + __func__, vb2_plane_size(vb, 0), size); + return -EINVAL; + } + + return 0; +} + +static inline bool is_capturing(struct bm2835_mmal_dev *dev) +{ + return dev->capture.camera_port == + &dev-> + component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_CAPTURE]; +} + +static void buffer_cb(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + int status, + struct mmal_buffer *buf, + unsigned long length, u32 mmal_flags, s64 dts, s64 pts) +{ + struct bm2835_mmal_dev *dev = port->cb_ctx; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", + __func__, status, buf, length, mmal_flags, pts); + + if (status != 0) { + /* error in transfer */ + if (buf != NULL) { + /* there was a buffer with the error so return it */ + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + } + return; + } else if (length == 0) { + /* stream ended */ + if (buf != NULL) { + /* this should only ever happen if the port is + * disabled and there are buffers still queued + */ + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + pr_debug("Empty buffer"); + } else if (dev->capture.frame_count) { + /* grab another frame */ + if (is_capturing(dev)) { + pr_debug("Grab another frame"); + vchiq_mmal_port_parameter_set( + instance, + dev->capture. + camera_port, + MMAL_PARAMETER_CAPTURE, + &dev->capture. + frame_count, + sizeof(dev->capture.frame_count)); + } + } else { + /* signal frame completion */ + complete(&dev->capture.frame_cmplt); + } + } else { + if (dev->capture.frame_count) { + if (dev->capture.vc_start_timestamp != -1 && + pts != 0) { + struct timeval timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; + u32 div = 0; + u32 rem = 0; + + div = + div_u64_rem(runtime_us, USEC_PER_SEC, &rem); + timestamp.tv_sec = + dev->capture.kernel_start_ts.tv_sec + div; + timestamp.tv_usec = + dev->capture.kernel_start_ts.tv_usec + rem; + + if (timestamp.tv_usec >= + USEC_PER_SEC) { + timestamp.tv_sec++; + timestamp.tv_usec -= + USEC_PER_SEC; + } + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Convert start time %d.%06d and %llu " + "with offset %llu to %d.%06d\n", + (int)dev->capture.kernel_start_ts. + tv_sec, + (int)dev->capture.kernel_start_ts. + tv_usec, + dev->capture.vc_start_timestamp, pts, + (int)timestamp.tv_sec, + (int)timestamp.tv_usec); + buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + + timestamp.tv_usec * 1000ULL; + } else { + buf->vb.vb2_buf.timestamp = ktime_get_ns(); + } + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && + is_capturing(dev)) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Grab another frame as buffer has EOS"); + vchiq_mmal_port_parameter_set( + instance, + dev->capture. + camera_port, + MMAL_PARAMETER_CAPTURE, + &dev->capture. + frame_count, + sizeof(dev->capture.frame_count)); + } + } else { + /* signal frame completion */ + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + complete(&dev->capture.frame_cmplt); + } + } +} + +static int enable_camera(struct bm2835_mmal_dev *dev) +{ + int ret; + + if (!dev->camera_use_count) { + ret = vchiq_mmal_port_parameter_set( + dev->instance, + &dev->component[MMAL_COMPONENT_CAMERA]->control, + MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num, + sizeof(dev->camera_num)); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, + "Failed setting camera num, ret %d\n", ret); + return -EINVAL; + } + + ret = vchiq_mmal_component_enable( + dev->instance, + dev->component[MMAL_COMPONENT_CAMERA]); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, + "Failed enabling camera, ret %d\n", ret); + return -EINVAL; + } + } + dev->camera_use_count++; + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, "enabled camera (refcount %d)\n", + dev->camera_use_count); + return 0; +} + +static int disable_camera(struct bm2835_mmal_dev *dev) +{ + int ret; + + if (!dev->camera_use_count) { + v4l2_err(&dev->v4l2_dev, + "Disabled the camera when already disabled\n"); + return -EINVAL; + } + dev->camera_use_count--; + if (!dev->camera_use_count) { + unsigned int i = 0xFFFFFFFF; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Disabling camera\n"); + ret = + vchiq_mmal_component_disable( + dev->instance, + dev->component[MMAL_COMPONENT_CAMERA]); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, + "Failed disabling camera, ret %d\n", ret); + return -EINVAL; + } + vchiq_mmal_port_parameter_set( + dev->instance, + &dev->component[MMAL_COMPONENT_CAMERA]->control, + MMAL_PARAMETER_CAMERA_NUM, &i, + sizeof(i)); + } + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Camera refcount now %d\n", dev->camera_use_count); + return 0; +} + +static void buffer_queue(struct vb2_buffer *vb) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); + struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); + int ret; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: dev:%p buf:%p\n", __func__, dev, buf); + + buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); + buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); + + ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf); + if (ret < 0) + v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n", + __func__); +} + +static int start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + int ret; + int parameter_size; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", + __func__, dev); + + /* ensure a format has actually been set */ + if (dev->capture.port == NULL) + return -EINVAL; + + if (enable_camera(dev) < 0) { + v4l2_err(&dev->v4l2_dev, "Failed to enable camera\n"); + return -EINVAL; + } + + /*init_completion(&dev->capture.frame_cmplt); */ + + /* enable frame capture */ + dev->capture.frame_count = 1; + + /* if the preview is not already running, wait for a few frames for AGC + * to settle down. + */ + if (!dev->component[MMAL_COMPONENT_PREVIEW]->enabled) + msleep(300); + + /* enable the connection from camera to encoder (if applicable) */ + if (dev->capture.camera_port != dev->capture.port + && dev->capture.camera_port) { + ret = vchiq_mmal_port_enable(dev->instance, + dev->capture.camera_port, NULL); + if (ret) { + v4l2_err(&dev->v4l2_dev, + "Failed to enable encode tunnel - error %d\n", + ret); + return -1; + } + } + + /* Get VC timestamp at this point in time */ + parameter_size = sizeof(dev->capture.vc_start_timestamp); + if (vchiq_mmal_port_parameter_get(dev->instance, + dev->capture.camera_port, + MMAL_PARAMETER_SYSTEM_TIME, + &dev->capture.vc_start_timestamp, + ¶meter_size)) { + v4l2_err(&dev->v4l2_dev, + "Failed to get VC start time - update your VC f/w\n"); + + /* Flag to indicate just to rely on kernel timestamps */ + dev->capture.vc_start_timestamp = -1; + } else + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Start time %lld size %d\n", + dev->capture.vc_start_timestamp, parameter_size); + + v4l2_get_timestamp(&dev->capture.kernel_start_ts); + + /* enable the camera port */ + dev->capture.port->cb_ctx = dev; + ret = + vchiq_mmal_port_enable(dev->instance, dev->capture.port, buffer_cb); + if (ret) { + v4l2_err(&dev->v4l2_dev, + "Failed to enable capture port - error %d. " + "Disabling camera port again\n", ret); + + vchiq_mmal_port_disable(dev->instance, + dev->capture.camera_port); + if (disable_camera(dev) < 0) { + v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n"); + return -EINVAL; + } + return -1; + } + + /* capture the first frame */ + vchiq_mmal_port_parameter_set(dev->instance, + dev->capture.camera_port, + MMAL_PARAMETER_CAPTURE, + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); + return 0; +} + +/* abort streaming and wait for last buffer */ +static void stop_streaming(struct vb2_queue *vq) +{ + int ret; + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", + __func__, dev); + + init_completion(&dev->capture.frame_cmplt); + dev->capture.frame_count = 0; + + /* ensure a format has actually been set */ + if (dev->capture.port == NULL) { + v4l2_err(&dev->v4l2_dev, + "no capture port - stream not started?\n"); + return; + } + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "stopping capturing\n"); + + /* stop capturing frames */ + vchiq_mmal_port_parameter_set(dev->instance, + dev->capture.camera_port, + MMAL_PARAMETER_CAPTURE, + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); + + /* wait for last frame to complete */ + ret = wait_for_completion_timeout(&dev->capture.frame_cmplt, HZ); + if (ret <= 0) + v4l2_err(&dev->v4l2_dev, + "error %d waiting for frame completion\n", ret); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "disabling connection\n"); + + /* disable the connection from camera to encoder */ + ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); + if (!ret && dev->capture.camera_port != dev->capture.port) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "disabling port\n"); + ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port); + } else if (dev->capture.camera_port != dev->capture.port) { + v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n", + ret); + } + + if (disable_camera(dev) < 0) + v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n"); +} + +static void bm2835_mmal_lock(struct vb2_queue *vq) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + + mutex_lock(&dev->mutex); +} + +static void bm2835_mmal_unlock(struct vb2_queue *vq) +{ + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + + mutex_unlock(&dev->mutex); +} + +static struct vb2_ops bm2835_mmal_video_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .wait_prepare = bm2835_mmal_unlock, + .wait_finish = bm2835_mmal_lock, +}; + +/* ------------------------------------------------------------------ + IOCTL operations + ------------------------------------------------------------------*/ + +static int set_overlay_params(struct bm2835_mmal_dev *dev, + struct vchiq_mmal_port *port) +{ + int ret; + struct mmal_parameter_displayregion prev_config = { + .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA | + MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN, + .layer = PREVIEW_LAYER, + .alpha = dev->overlay.global_alpha, + .fullscreen = 0, + .dest_rect = { + .x = dev->overlay.w.left, + .y = dev->overlay.w.top, + .width = dev->overlay.w.width, + .height = dev->overlay.w.height, + }, + }; + ret = vchiq_mmal_port_parameter_set(dev->instance, port, + MMAL_PARAMETER_DISPLAYREGION, + &prev_config, sizeof(prev_config)); + + return ret; +} + +/* overlay ioctl */ +static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct mmal_fmt *fmt; + + if (f->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + fmt = &formats[f->index]; + + strlcpy(f->description, fmt->name, sizeof(f->description)); + f->pixelformat = fmt->fourcc; + f->flags = fmt->flags; + + return 0; +} + +static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + + f->fmt.win = dev->overlay; + + return 0; +} + +static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + + f->fmt.win.field = V4L2_FIELD_NONE; + f->fmt.win.chromakey = 0; + f->fmt.win.clips = NULL; + f->fmt.win.clipcount = 0; + f->fmt.win.bitmap = NULL; + + v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1, + &f->fmt.win.w.height, MIN_HEIGHT, dev->max_height, + 1, 0); + v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1, + &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height, + 1, 0); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Overlay: Now w/h %dx%d l/t %dx%d\n", + f->fmt.win.w.width, f->fmt.win.w.height, + f->fmt.win.w.left, f->fmt.win.w.top); + + v4l2_dump_win_format(1, + bcm2835_v4l2_debug, + &dev->v4l2_dev, + &f->fmt.win, + __func__); + return 0; +} + +static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + + vidioc_try_fmt_vid_overlay(file, priv, f); + + dev->overlay = f->fmt.win; + if (dev->component[MMAL_COMPONENT_PREVIEW]->enabled) { + set_overlay_params(dev, + &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); + } + + return 0; +} + +static int vidioc_overlay(struct file *file, void *f, unsigned int on) +{ + int ret; + struct bm2835_mmal_dev *dev = video_drvdata(file); + struct vchiq_mmal_port *src; + struct vchiq_mmal_port *dst; + + if ((on && dev->component[MMAL_COMPONENT_PREVIEW]->enabled) || + (!on && !dev->component[MMAL_COMPONENT_PREVIEW]->enabled)) + return 0; /* already in requested state */ + + src = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_PREVIEW]; + + if (!on) { + /* disconnect preview ports and disable component */ + ret = vchiq_mmal_port_disable(dev->instance, src); + if (!ret) + ret = + vchiq_mmal_port_connect_tunnel(dev->instance, src, + NULL); + if (ret >= 0) + ret = vchiq_mmal_component_disable( + dev->instance, + dev->component[MMAL_COMPONENT_PREVIEW]); + + disable_camera(dev); + return ret; + } + + /* set preview port format and connect it to output */ + dst = &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]; + + ret = vchiq_mmal_port_set_format(dev->instance, src); + if (ret < 0) + goto error; + + ret = set_overlay_params(dev, dst); + if (ret < 0) + goto error; + + if (enable_camera(dev) < 0) + goto error; + + ret = vchiq_mmal_component_enable( + dev->instance, + dev->component[MMAL_COMPONENT_PREVIEW]); + if (ret < 0) + goto error; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "connecting %p to %p\n", + src, dst); + ret = vchiq_mmal_port_connect_tunnel(dev->instance, src, dst); + if (!ret) + ret = vchiq_mmal_port_enable(dev->instance, src, NULL); +error: + return ret; +} + +static int vidioc_g_fbuf(struct file *file, void *fh, + struct v4l2_framebuffer *a) +{ + /* The video overlay must stay within the framebuffer and can't be + positioned independently. */ + struct bm2835_mmal_dev *dev = video_drvdata(file); + struct vchiq_mmal_port *preview_port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_PREVIEW]; + + a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | + V4L2_FBUF_CAP_GLOBAL_ALPHA; + a->flags = V4L2_FBUF_FLAG_OVERLAY; + a->fmt.width = preview_port->es.video.width; + a->fmt.height = preview_port->es.video.height; + a->fmt.pixelformat = V4L2_PIX_FMT_YUV420; + a->fmt.bytesperline = preview_port->es.video.width; + a->fmt.sizeimage = (preview_port->es.video.width * + preview_port->es.video.height * 3) >> 1; + a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; + + return 0; +} + +/* input ioctls */ +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + /* only a single camera input */ + if (inp->index != 0) + return -EINVAL; + + inp->type = V4L2_INPUT_TYPE_CAMERA; + sprintf(inp->name, "Camera %u", inp->index); + return 0; +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + + return 0; +} + +/* capture ioctls */ +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + u32 major; + u32 minor; + + vchiq_mmal_version(dev->instance, &major, &minor); + + strcpy(cap->driver, "bm2835 mmal"); + snprintf(cap->card, sizeof(cap->card), "mmal service %d.%d", + major, minor); + + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s", dev->v4l2_dev.name); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + + return 0; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct mmal_fmt *fmt; + + if (f->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + fmt = &formats[f->index]; + + strlcpy(f->description, fmt->name, sizeof(f->description)); + f->pixelformat = fmt->fourcc; + f->flags = fmt->flags; + + return 0; +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + + f->fmt.pix.width = dev->capture.width; + f->fmt.pix.height = dev->capture.height; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.pixelformat = dev->capture.fmt->fourcc; + f->fmt.pix.bytesperline = dev->capture.stride; + f->fmt.pix.sizeimage = dev->capture.buffersize; + + if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_RGB24) + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + else if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_JPEG) + f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + else + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; + + v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix, + __func__); + return 0; +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + struct mmal_fmt *mfmt; + + mfmt = get_format(f); + if (!mfmt) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Fourcc format (0x%08x) unknown.\n", + f->fmt.pix.pixelformat); + f->fmt.pix.pixelformat = formats[0].fourcc; + mfmt = get_format(f); + } + + f->fmt.pix.field = V4L2_FIELD_NONE; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Clipping/aligning %dx%d format %08X\n", + f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat); + + v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1, + &f->fmt.pix.height, MIN_HEIGHT, dev->max_height, + 1, 0); + f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; + + /* Image buffer has to be padded to allow for alignment, even though + * we then remove that padding before delivering the buffer. + */ + f->fmt.pix.sizeimage = ((f->fmt.pix.height + 15) & ~15) * + (((f->fmt.pix.width + 31) & ~31) * mfmt->depth) >> 3; + + if ((mfmt->flags & V4L2_FMT_FLAG_COMPRESSED) && + f->fmt.pix.sizeimage < MIN_BUFFER_SIZE) + f->fmt.pix.sizeimage = MIN_BUFFER_SIZE; + + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) + f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + else + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Now %dx%d format %08X\n", + f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat); + + v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix, + __func__); + return 0; +} + +static int mmal_setup_components(struct bm2835_mmal_dev *dev, + struct v4l2_format *f) +{ + int ret; + struct vchiq_mmal_port *port = NULL, *camera_port = NULL; + struct vchiq_mmal_component *encode_component = NULL; + struct mmal_fmt *mfmt = get_format(f); + + BUG_ON(!mfmt); + + if (dev->capture.encode_component) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "vid_cap - disconnect previous tunnel\n"); + + /* Disconnect any previous connection */ + vchiq_mmal_port_connect_tunnel(dev->instance, + dev->capture.camera_port, NULL); + dev->capture.camera_port = NULL; + ret = vchiq_mmal_component_disable(dev->instance, + dev->capture. + encode_component); + if (ret) + v4l2_err(&dev->v4l2_dev, + "Failed to disable encode component %d\n", + ret); + + dev->capture.encode_component = NULL; + } + /* format dependent port setup */ + switch (mfmt->mmal_component) { + case MMAL_COMPONENT_CAMERA: + /* Make a further decision on port based on resolution */ + if (f->fmt.pix.width <= max_video_width + && f->fmt.pix.height <= max_video_height) + camera_port = port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_VIDEO]; + else + camera_port = port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_CAPTURE]; + break; + case MMAL_COMPONENT_IMAGE_ENCODE: + encode_component = dev->component[MMAL_COMPONENT_IMAGE_ENCODE]; + port = &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->output[0]; + camera_port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_CAPTURE]; + break; + case MMAL_COMPONENT_VIDEO_ENCODE: + encode_component = dev->component[MMAL_COMPONENT_VIDEO_ENCODE]; + port = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + camera_port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_VIDEO]; + break; + default: + break; + } + + if (!port) + return -EINVAL; + + if (encode_component) + camera_port->format.encoding = MMAL_ENCODING_OPAQUE; + else + camera_port->format.encoding = mfmt->mmal; + + if (dev->rgb_bgr_swapped) { + if (camera_port->format.encoding == MMAL_ENCODING_RGB24) + camera_port->format.encoding = MMAL_ENCODING_BGR24; + else if (camera_port->format.encoding == MMAL_ENCODING_BGR24) + camera_port->format.encoding = MMAL_ENCODING_RGB24; + } + + camera_port->format.encoding_variant = 0; + camera_port->es.video.width = f->fmt.pix.width; + camera_port->es.video.height = f->fmt.pix.height; + camera_port->es.video.crop.x = 0; + camera_port->es.video.crop.y = 0; + camera_port->es.video.crop.width = f->fmt.pix.width; + camera_port->es.video.crop.height = f->fmt.pix.height; + camera_port->es.video.frame_rate.num = 0; + camera_port->es.video.frame_rate.den = 1; + camera_port->es.video.color_space = MMAL_COLOR_SPACE_JPEG_JFIF; + + ret = vchiq_mmal_port_set_format(dev->instance, camera_port); + + if (!ret + && camera_port == + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_VIDEO]) { + bool overlay_enabled = + !!dev->component[MMAL_COMPONENT_PREVIEW]->enabled; + struct vchiq_mmal_port *preview_port = + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_PREVIEW]; + /* Preview and encode ports need to match on resolution */ + if (overlay_enabled) { + /* Need to disable the overlay before we can update + * the resolution + */ + ret = + vchiq_mmal_port_disable(dev->instance, + preview_port); + if (!ret) + ret = + vchiq_mmal_port_connect_tunnel( + dev->instance, + preview_port, + NULL); + } + preview_port->es.video.width = f->fmt.pix.width; + preview_port->es.video.height = f->fmt.pix.height; + preview_port->es.video.crop.x = 0; + preview_port->es.video.crop.y = 0; + preview_port->es.video.crop.width = f->fmt.pix.width; + preview_port->es.video.crop.height = f->fmt.pix.height; + preview_port->es.video.frame_rate.num = + dev->capture.timeperframe.denominator; + preview_port->es.video.frame_rate.den = + dev->capture.timeperframe.numerator; + ret = vchiq_mmal_port_set_format(dev->instance, preview_port); + if (overlay_enabled) { + ret = vchiq_mmal_port_connect_tunnel( + dev->instance, + preview_port, + &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); + if (!ret) + ret = vchiq_mmal_port_enable(dev->instance, + preview_port, + NULL); + } + } + + if (ret) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s failed to set format %dx%d %08X\n", __func__, + f->fmt.pix.width, f->fmt.pix.height, + f->fmt.pix.pixelformat); + /* ensure capture is not going to be tried */ + dev->capture.port = NULL; + } else { + if (encode_component) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "vid_cap - set up encode comp\n"); + + /* configure buffering */ + camera_port->current_buffer.size = + camera_port->recommended_buffer.size; + camera_port->current_buffer.num = + camera_port->recommended_buffer.num; + + ret = + vchiq_mmal_port_connect_tunnel( + dev->instance, + camera_port, + &encode_component->input[0]); + if (ret) { + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "%s failed to create connection\n", + __func__); + /* ensure capture is not going to be tried */ + dev->capture.port = NULL; + } else { + port->es.video.width = f->fmt.pix.width; + port->es.video.height = f->fmt.pix.height; + port->es.video.crop.x = 0; + port->es.video.crop.y = 0; + port->es.video.crop.width = f->fmt.pix.width; + port->es.video.crop.height = f->fmt.pix.height; + port->es.video.frame_rate.num = + dev->capture.timeperframe.denominator; + port->es.video.frame_rate.den = + dev->capture.timeperframe.numerator; + + port->format.encoding = mfmt->mmal; + port->format.encoding_variant = 0; + /* Set any encoding specific parameters */ + switch (mfmt->mmal_component) { + case MMAL_COMPONENT_VIDEO_ENCODE: + port->format.bitrate = + dev->capture.encode_bitrate; + break; + case MMAL_COMPONENT_IMAGE_ENCODE: + /* Could set EXIF parameters here */ + break; + default: + break; + } + ret = vchiq_mmal_port_set_format(dev->instance, + port); + if (ret) + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "%s failed to set format %dx%d fmt %08X\n", + __func__, + f->fmt.pix.width, + f->fmt.pix.height, + f->fmt.pix.pixelformat + ); + } + + if (!ret) { + ret = vchiq_mmal_component_enable( + dev->instance, + encode_component); + if (ret) { + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "%s Failed to enable encode components\n", + __func__); + } + } + if (!ret) { + /* configure buffering */ + port->current_buffer.num = 1; + port->current_buffer.size = + f->fmt.pix.sizeimage; + if (port->format.encoding == + MMAL_ENCODING_JPEG) { + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "JPG - buf size now %d was %d\n", + f->fmt.pix.sizeimage, + port->current_buffer.size); + port->current_buffer.size = + (f->fmt.pix.sizeimage < + (100 << 10)) + ? (100 << 10) : f->fmt.pix. + sizeimage; + } + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "vid_cap - cur_buf.size set to %d\n", + f->fmt.pix.sizeimage); + port->current_buffer.alignment = 0; + } + } else { + /* configure buffering */ + camera_port->current_buffer.num = 1; + camera_port->current_buffer.size = f->fmt.pix.sizeimage; + camera_port->current_buffer.alignment = 0; + } + + if (!ret) { + dev->capture.fmt = mfmt; + dev->capture.stride = f->fmt.pix.bytesperline; + dev->capture.width = camera_port->es.video.crop.width; + dev->capture.height = camera_port->es.video.crop.height; + dev->capture.buffersize = port->current_buffer.size; + + /* select port for capture */ + dev->capture.port = port; + dev->capture.camera_port = camera_port; + dev->capture.encode_component = encode_component; + v4l2_dbg(1, bcm2835_v4l2_debug, + &dev->v4l2_dev, + "Set dev->capture.fmt %08X, %dx%d, stride %d, size %d", + port->format.encoding, + dev->capture.width, dev->capture.height, + dev->capture.stride, dev->capture.buffersize); + } + } + + /* todo: Need to convert the vchiq/mmal error into a v4l2 error. */ + return ret; +} + +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + int ret; + struct bm2835_mmal_dev *dev = video_drvdata(file); + struct mmal_fmt *mfmt; + + /* try the format to set valid parameters */ + ret = vidioc_try_fmt_vid_cap(file, priv, f); + if (ret) { + v4l2_err(&dev->v4l2_dev, + "vid_cap - vidioc_try_fmt_vid_cap failed\n"); + return ret; + } + + /* if a capture is running refuse to set format */ + if (vb2_is_busy(&dev->capture.vb_vidq)) { + v4l2_info(&dev->v4l2_dev, "%s device busy\n", __func__); + return -EBUSY; + } + + /* If the format is unsupported v4l2 says we should switch to + * a supported one and not return an error. */ + mfmt = get_format(f); + if (!mfmt) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Fourcc format (0x%08x) unknown.\n", + f->fmt.pix.pixelformat); + f->fmt.pix.pixelformat = formats[0].fourcc; + mfmt = get_format(f); + } + + ret = mmal_setup_components(dev, f); + if (ret != 0) { + v4l2_err(&dev->v4l2_dev, + "%s: failed to setup mmal components: %d\n", + __func__, ret); + ret = -EINVAL; + } + + return ret; +} + +static int vidioc_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + static const struct v4l2_frmsize_stepwise sizes = { + MIN_WIDTH, 0, 2, + MIN_HEIGHT, 0, 2 + }; + int i; + + if (fsize->index) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(formats); i++) + if (formats[i].fourcc == fsize->pixel_format) + break; + if (i == ARRAY_SIZE(formats)) + return -EINVAL; + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise = sizes; + fsize->stepwise.max_width = dev->max_width; + fsize->stepwise.max_height = dev->max_height; + return 0; +} + +/* timeperframe is arbitrary and continuous */ +static int vidioc_enum_frameintervals(struct file *file, void *priv, + struct v4l2_frmivalenum *fival) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + int i; + + if (fival->index) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(formats); i++) + if (formats[i].fourcc == fival->pixel_format) + break; + if (i == ARRAY_SIZE(formats)) + return -EINVAL; + + /* regarding width & height - we support any within range */ + if (fival->width < MIN_WIDTH || fival->width > dev->max_width || + fival->height < MIN_HEIGHT || fival->height > dev->max_height) + return -EINVAL; + + fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; + + /* fill in stepwise (step=1.0 is required by V4L2 spec) */ + fival->stepwise.min = tpf_min; + fival->stepwise.max = tpf_max; + fival->stepwise.step = (struct v4l2_fract) {1, 1}; + + return 0; +} + +static int vidioc_g_parm(struct file *file, void *priv, + struct v4l2_streamparm *parm) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + parm->parm.capture.timeperframe = dev->capture.timeperframe; + parm->parm.capture.readbuffers = 1; + return 0; +} + +#define FRACT_CMP(a, OP, b) \ + ((u64)(a).numerator * (b).denominator OP \ + (u64)(b).numerator * (a).denominator) + +static int vidioc_s_parm(struct file *file, void *priv, + struct v4l2_streamparm *parm) +{ + struct bm2835_mmal_dev *dev = video_drvdata(file); + struct v4l2_fract tpf; + struct mmal_parameter_rational fps_param; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + tpf = parm->parm.capture.timeperframe; + + /* tpf: {*, 0} resets timing; clip to [min, max]*/ + tpf = tpf.denominator ? tpf : tpf_default; + tpf = FRACT_CMP(tpf, <, tpf_min) ? tpf_min : tpf; + tpf = FRACT_CMP(tpf, >, tpf_max) ? tpf_max : tpf; + + dev->capture.timeperframe = tpf; + parm->parm.capture.timeperframe = tpf; + parm->parm.capture.readbuffers = 1; + parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + + fps_param.num = 0; /* Select variable fps, and then use + * FPS_RANGE to select the actual limits. + */ + fps_param.den = 1; + set_framerate_params(dev); + + return 0; +} + +static const struct v4l2_ioctl_ops camera0_ioctl_ops = { + /* overlay */ + .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, + .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, + .vidioc_overlay = vidioc_overlay, + .vidioc_g_fbuf = vidioc_g_fbuf, + + /* inputs */ + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + + /* capture */ + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + + /* buffer management */ + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_s_parm = vidioc_s_parm, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static const struct v4l2_ioctl_ops camera0_ioctl_ops_gstreamer = { + /* overlay */ + .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, + .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, + .vidioc_overlay = vidioc_overlay, + .vidioc_g_fbuf = vidioc_g_fbuf, + + /* inputs */ + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + + /* capture */ + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + + /* buffer management */ + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + /* Remove this function ptr to fix gstreamer bug + .vidioc_enum_framesizes = vidioc_enum_framesizes, */ + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_s_parm = vidioc_s_parm, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +/* ------------------------------------------------------------------ + Driver init/finalise + ------------------------------------------------------------------*/ + +static const struct v4l2_file_operations camera0_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ + .mmap = vb2_fop_mmap, +}; + +static struct video_device vdev_template = { + .name = "camera0", + .fops = &camera0_fops, + .ioctl_ops = &camera0_ioctl_ops, + .release = video_device_release_empty, +}; + +/* Returns the number of cameras, and also the max resolution supported + * by those cameras. + */ +static int get_num_cameras(struct vchiq_mmal_instance *instance, + unsigned int resolutions[][2], int num_resolutions) +{ + int ret; + struct vchiq_mmal_component *cam_info_component; + struct mmal_parameter_camera_info_t cam_info = {0}; + int param_size = sizeof(cam_info); + int i; + + /* create a camera_info component */ + ret = vchiq_mmal_component_init(instance, "camera_info", + &cam_info_component); + if (ret < 0) + /* Unusual failure - let's guess one camera. */ + return 1; + + if (vchiq_mmal_port_parameter_get(instance, + &cam_info_component->control, + MMAL_PARAMETER_CAMERA_INFO, + &cam_info, + ¶m_size)) { + pr_info("Failed to get camera info\n"); + } + for (i = 0; + i < (cam_info.num_cameras > num_resolutions ? + num_resolutions : + cam_info.num_cameras); + i++) { + resolutions[i][0] = cam_info.cameras[i].max_width; + resolutions[i][1] = cam_info.cameras[i].max_height; + } + + vchiq_mmal_component_finalise(instance, + cam_info_component); + + return cam_info.num_cameras; +} + +static int set_camera_parameters(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *camera, + struct bm2835_mmal_dev *dev) +{ + int ret; + struct mmal_parameter_camera_config cam_config = { + .max_stills_w = dev->max_width, + .max_stills_h = dev->max_height, + .stills_yuv422 = 1, + .one_shot_stills = 1, + .max_preview_video_w = (max_video_width > 1920) ? + max_video_width : 1920, + .max_preview_video_h = (max_video_height > 1088) ? + max_video_height : 1088, + .num_preview_video_frames = 3, + .stills_capture_circular_buffer_height = 0, + .fast_preview_resume = 0, + .use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RAW_STC + }; + + ret = vchiq_mmal_port_parameter_set(instance, &camera->control, + MMAL_PARAMETER_CAMERA_CONFIG, + &cam_config, sizeof(cam_config)); + return ret; +} + +#define MAX_SUPPORTED_ENCODINGS 20 + +/* MMAL instance and component init */ +static int __init mmal_init(struct bm2835_mmal_dev *dev) +{ + int ret; + struct mmal_es_format *format; + u32 bool_true = 1; + u32 supported_encodings[MAX_SUPPORTED_ENCODINGS]; + int param_size; + struct vchiq_mmal_component *camera; + + ret = vchiq_mmal_init(&dev->instance); + if (ret < 0) + return ret; + + /* get the camera component ready */ + ret = vchiq_mmal_component_init(dev->instance, "ril.camera", + &dev->component[MMAL_COMPONENT_CAMERA]); + if (ret < 0) + goto unreg_mmal; + + camera = dev->component[MMAL_COMPONENT_CAMERA]; + if (camera->outputs < MMAL_CAMERA_PORT_COUNT) { + ret = -EINVAL; + goto unreg_camera; + } + + ret = set_camera_parameters(dev->instance, + camera, + dev); + if (ret < 0) + goto unreg_camera; + + /* There was an error in the firmware that meant the camera component + * produced BGR instead of RGB. + * This is now fixed, but in order to support the old firmwares, we + * have to check. + */ + dev->rgb_bgr_swapped = true; + param_size = sizeof(supported_encodings); + ret = vchiq_mmal_port_parameter_get(dev->instance, + &camera->output[MMAL_CAMERA_PORT_CAPTURE], + MMAL_PARAMETER_SUPPORTED_ENCODINGS, + &supported_encodings, + ¶m_size); + if (ret == 0) { + int i; + + for (i = 0; i < param_size / sizeof(u32); i++) { + if (supported_encodings[i] == MMAL_ENCODING_BGR24) { + /* Found BGR24 first - old firmware. */ + break; + } + if (supported_encodings[i] == MMAL_ENCODING_RGB24) { + /* Found RGB24 first + * new firmware, so use RGB24. + */ + dev->rgb_bgr_swapped = false; + break; + } + } + } + format = &camera->output[MMAL_CAMERA_PORT_PREVIEW].format; + + format->encoding = MMAL_ENCODING_OPAQUE; + format->encoding_variant = MMAL_ENCODING_I420; + + format->es->video.width = 1024; + format->es->video.height = 768; + format->es->video.crop.x = 0; + format->es->video.crop.y = 0; + format->es->video.crop.width = 1024; + format->es->video.crop.height = 768; + format->es->video.frame_rate.num = 0; /* Rely on fps_range */ + format->es->video.frame_rate.den = 1; + + format = &camera->output[MMAL_CAMERA_PORT_VIDEO].format; + + format->encoding = MMAL_ENCODING_OPAQUE; + format->encoding_variant = MMAL_ENCODING_I420; + + format->es->video.width = 1024; + format->es->video.height = 768; + format->es->video.crop.x = 0; + format->es->video.crop.y = 0; + format->es->video.crop.width = 1024; + format->es->video.crop.height = 768; + format->es->video.frame_rate.num = 0; /* Rely on fps_range */ + format->es->video.frame_rate.den = 1; + + vchiq_mmal_port_parameter_set(dev->instance, + &camera->output[MMAL_CAMERA_PORT_VIDEO], + MMAL_PARAMETER_NO_IMAGE_PADDING, + &bool_true, sizeof(bool_true)); + + format = &camera->output[MMAL_CAMERA_PORT_CAPTURE].format; + + format->encoding = MMAL_ENCODING_OPAQUE; + + format->es->video.width = 2592; + format->es->video.height = 1944; + format->es->video.crop.x = 0; + format->es->video.crop.y = 0; + format->es->video.crop.width = 2592; + format->es->video.crop.height = 1944; + format->es->video.frame_rate.num = 0; /* Rely on fps_range */ + format->es->video.frame_rate.den = 1; + + dev->capture.width = format->es->video.width; + dev->capture.height = format->es->video.height; + dev->capture.fmt = &formats[0]; + dev->capture.encode_component = NULL; + dev->capture.timeperframe = tpf_default; + dev->capture.enc_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; + dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; + + vchiq_mmal_port_parameter_set(dev->instance, + &camera->output[MMAL_CAMERA_PORT_CAPTURE], + MMAL_PARAMETER_NO_IMAGE_PADDING, + &bool_true, sizeof(bool_true)); + + /* get the preview component ready */ + ret = vchiq_mmal_component_init( + dev->instance, "ril.video_render", + &dev->component[MMAL_COMPONENT_PREVIEW]); + if (ret < 0) + goto unreg_camera; + + if (dev->component[MMAL_COMPONENT_PREVIEW]->inputs < 1) { + ret = -EINVAL; + pr_debug("too few input ports %d needed %d\n", + dev->component[MMAL_COMPONENT_PREVIEW]->inputs, 1); + goto unreg_preview; + } + + /* get the image encoder component ready */ + ret = vchiq_mmal_component_init( + dev->instance, "ril.image_encode", + &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]); + if (ret < 0) + goto unreg_preview; + + if (dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->inputs < 1) { + ret = -EINVAL; + v4l2_err(&dev->v4l2_dev, "too few input ports %d needed %d\n", + dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->inputs, + 1); + goto unreg_image_encoder; + } + + /* get the video encoder component ready */ + ret = vchiq_mmal_component_init(dev->instance, "ril.video_encode", + &dev-> + component[MMAL_COMPONENT_VIDEO_ENCODE]); + if (ret < 0) + goto unreg_image_encoder; + + if (dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->inputs < 1) { + ret = -EINVAL; + v4l2_err(&dev->v4l2_dev, "too few input ports %d needed %d\n", + dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->inputs, + 1); + goto unreg_vid_encoder; + } + + { + struct vchiq_mmal_port *encoder_port = + &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + encoder_port->format.encoding = MMAL_ENCODING_H264; + ret = vchiq_mmal_port_set_format(dev->instance, + encoder_port); + } + + { + unsigned int enable = 1; + + vchiq_mmal_port_parameter_set( + dev->instance, + &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->control, + MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, + &enable, sizeof(enable)); + + vchiq_mmal_port_parameter_set(dev->instance, + &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->control, + MMAL_PARAMETER_MINIMISE_FRAGMENTATION, + &enable, + sizeof(enable)); + } + ret = bm2835_mmal_set_all_camera_controls(dev); + if (ret < 0) + goto unreg_vid_encoder; + + return 0; + +unreg_vid_encoder: + pr_err("Cleanup: Destroy video encoder\n"); + vchiq_mmal_component_finalise( + dev->instance, + dev->component[MMAL_COMPONENT_VIDEO_ENCODE]); + +unreg_image_encoder: + pr_err("Cleanup: Destroy image encoder\n"); + vchiq_mmal_component_finalise( + dev->instance, + dev->component[MMAL_COMPONENT_IMAGE_ENCODE]); + +unreg_preview: + pr_err("Cleanup: Destroy video render\n"); + vchiq_mmal_component_finalise(dev->instance, + dev->component[MMAL_COMPONENT_PREVIEW]); + +unreg_camera: + pr_err("Cleanup: Destroy camera\n"); + vchiq_mmal_component_finalise(dev->instance, + dev->component[MMAL_COMPONENT_CAMERA]); + +unreg_mmal: + vchiq_mmal_finalise(dev->instance); + return ret; +} + +static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev, + struct video_device *vfd) +{ + int ret; + + *vfd = vdev_template; + if (gst_v4l2src_is_broken) { + v4l2_info(&dev->v4l2_dev, + "Work-around for gstreamer issue is active.\n"); + vfd->ioctl_ops = &camera0_ioctl_ops_gstreamer; + } + + vfd->v4l2_dev = &dev->v4l2_dev; + + vfd->lock = &dev->mutex; + + vfd->queue = &dev->capture.vb_vidq; + + /* video device needs to be able to access instance data */ + video_set_drvdata(vfd, dev); + + ret = video_register_device(vfd, + VFL_TYPE_GRABBER, + video_nr[dev->camera_num]); + if (ret < 0) + return ret; + + v4l2_info(vfd->v4l2_dev, + "V4L2 device registered as %s - stills mode > %dx%d\n", + video_device_node_name(vfd), + max_video_width, max_video_height); + + return 0; +} + +static void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev) +{ + if (!dev) + return; + + v4l2_info(&dev->v4l2_dev, "unregistering %s\n", + video_device_node_name(&dev->vdev)); + + video_unregister_device(&dev->vdev); + + if (dev->capture.encode_component) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "mmal_exit - disconnect tunnel\n"); + vchiq_mmal_port_connect_tunnel(dev->instance, + dev->capture.camera_port, NULL); + vchiq_mmal_component_disable(dev->instance, + dev->capture.encode_component); + } + vchiq_mmal_component_disable(dev->instance, + dev->component[MMAL_COMPONENT_CAMERA]); + + vchiq_mmal_component_finalise(dev->instance, + dev-> + component[MMAL_COMPONENT_VIDEO_ENCODE]); + + vchiq_mmal_component_finalise(dev->instance, + dev-> + component[MMAL_COMPONENT_IMAGE_ENCODE]); + + vchiq_mmal_component_finalise(dev->instance, + dev->component[MMAL_COMPONENT_PREVIEW]); + + vchiq_mmal_component_finalise(dev->instance, + dev->component[MMAL_COMPONENT_CAMERA]); + + v4l2_ctrl_handler_free(&dev->ctrl_handler); + + v4l2_device_unregister(&dev->v4l2_dev); + + kfree(dev); +} + +static struct v4l2_format default_v4l2_format = { + .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG, + .fmt.pix.width = 1024, + .fmt.pix.bytesperline = 0, + .fmt.pix.height = 768, + .fmt.pix.sizeimage = 1024 * 768, +}; + +static int __init bm2835_mmal_init(void) +{ + int ret; + struct bm2835_mmal_dev *dev; + struct vb2_queue *q; + int camera; + unsigned int num_cameras; + struct vchiq_mmal_instance *instance; + unsigned int resolutions[MAX_BCM2835_CAMERAS][2]; + + ret = vchiq_mmal_init(&instance); + if (ret < 0) + return ret; + + num_cameras = get_num_cameras(instance, + resolutions, + MAX_BCM2835_CAMERAS); + if (num_cameras > MAX_BCM2835_CAMERAS) + num_cameras = MAX_BCM2835_CAMERAS; + + for (camera = 0; camera < num_cameras; camera++) { + dev = kzalloc(sizeof(struct bm2835_mmal_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->camera_num = camera; + dev->max_width = resolutions[camera][0]; + dev->max_height = resolutions[camera][1]; + + /* setup device defaults */ + dev->overlay.w.left = 150; + dev->overlay.w.top = 50; + dev->overlay.w.width = 1024; + dev->overlay.w.height = 768; + dev->overlay.clipcount = 0; + dev->overlay.field = V4L2_FIELD_NONE; + dev->overlay.global_alpha = 255; + + dev->capture.fmt = &formats[3]; /* JPEG */ + + /* v4l device registration */ + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), + "%s", BM2835_MMAL_MODULE_NAME); + ret = v4l2_device_register(NULL, &dev->v4l2_dev); + if (ret) + goto free_dev; + + /* setup v4l controls */ + ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); + if (ret < 0) + goto unreg_dev; + dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; + + /* mmal init */ + dev->instance = instance; + ret = mmal_init(dev); + if (ret < 0) + goto unreg_dev; + + /* initialize queue */ + q = &dev->capture.vb_vidq; + memset(q, 0, sizeof(*q)); + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct mmal_buffer); + q->ops = &bm2835_mmal_video_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + ret = vb2_queue_init(q); + if (ret < 0) + goto unreg_dev; + + /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */ + mutex_init(&dev->mutex); + + /* initialise video devices */ + ret = bm2835_mmal_init_device(dev, &dev->vdev); + if (ret < 0) + goto unreg_dev; + + /* Really want to call vidioc_s_fmt_vid_cap with the default + * format, but currently the APIs don't join up. + */ + ret = mmal_setup_components(dev, &default_v4l2_format); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, + "%s: could not setup components\n", __func__); + goto unreg_dev; + } + + v4l2_info(&dev->v4l2_dev, + "Broadcom 2835 MMAL video capture ver %s loaded.\n", + BM2835_MMAL_VERSION); + + gdev[camera] = dev; + } + return 0; + +unreg_dev: + v4l2_ctrl_handler_free(&dev->ctrl_handler); + v4l2_device_unregister(&dev->v4l2_dev); + +free_dev: + kfree(dev); + + for ( ; camera > 0; camera--) { + bcm2835_cleanup_instance(gdev[camera]); + gdev[camera] = NULL; + } + pr_info("%s: error %d while loading driver\n", + BM2835_MMAL_MODULE_NAME, ret); + + return ret; +} + +static void __exit bm2835_mmal_exit(void) +{ + int camera; + struct vchiq_mmal_instance *instance = gdev[0]->instance; + + for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) { + bcm2835_cleanup_instance(gdev[camera]); + gdev[camera] = NULL; + } + vchiq_mmal_finalise(instance); +} + +module_init(bm2835_mmal_init); +module_exit(bm2835_mmal_exit); diff --git a/drivers/staging/media/platform/bcm2835/bcm2835-camera.h b/drivers/staging/media/platform/bcm2835/bcm2835-camera.h new file mode 100644 index 000000000000..e6aeb7e7e381 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/bcm2835-camera.h @@ -0,0 +1,145 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + * + * core driver device + */ + +#define V4L2_CTRL_COUNT 29 /* number of v4l controls */ + +enum { + MMAL_COMPONENT_CAMERA = 0, + MMAL_COMPONENT_PREVIEW, + MMAL_COMPONENT_IMAGE_ENCODE, + MMAL_COMPONENT_VIDEO_ENCODE, + MMAL_COMPONENT_COUNT +}; + +enum { + MMAL_CAMERA_PORT_PREVIEW = 0, + MMAL_CAMERA_PORT_VIDEO, + MMAL_CAMERA_PORT_CAPTURE, + MMAL_CAMERA_PORT_COUNT +}; + +#define PREVIEW_LAYER 2 + +extern int bcm2835_v4l2_debug; + +struct bm2835_mmal_dev { + /* v4l2 devices */ + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct mutex mutex; + + /* controls */ + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *ctrls[V4L2_CTRL_COUNT]; + enum v4l2_scene_mode scene_mode; + struct mmal_colourfx colourfx; + int hflip; + int vflip; + int red_gain; + int blue_gain; + enum mmal_parameter_exposuremode exposure_mode_user; + enum v4l2_exposure_auto_type exposure_mode_v4l2_user; + /* active exposure mode may differ if selected via a scene mode */ + enum mmal_parameter_exposuremode exposure_mode_active; + enum mmal_parameter_exposuremeteringmode metering_mode; + unsigned int manual_shutter_speed; + bool exp_auto_priority; + bool manual_iso_enabled; + uint32_t iso; + + /* allocated mmal instance and components */ + struct vchiq_mmal_instance *instance; + struct vchiq_mmal_component *component[MMAL_COMPONENT_COUNT]; + int camera_use_count; + + struct v4l2_window overlay; + + struct { + unsigned int width; /* width */ + unsigned int height; /* height */ + unsigned int stride; /* stride */ + unsigned int buffersize; /* buffer size with padding */ + struct mmal_fmt *fmt; + struct v4l2_fract timeperframe; + + /* H264 encode bitrate */ + int encode_bitrate; + /* H264 bitrate mode. CBR/VBR */ + int encode_bitrate_mode; + /* H264 profile */ + enum v4l2_mpeg_video_h264_profile enc_profile; + /* H264 level */ + enum v4l2_mpeg_video_h264_level enc_level; + /* JPEG Q-factor */ + int q_factor; + + struct vb2_queue vb_vidq; + + /* VC start timestamp for streaming */ + s64 vc_start_timestamp; + /* Kernel start timestamp for streaming */ + struct timeval kernel_start_ts; + + struct vchiq_mmal_port *port; /* port being used for capture */ + /* camera port being used for capture */ + struct vchiq_mmal_port *camera_port; + /* component being used for encode */ + struct vchiq_mmal_component *encode_component; + /* number of frames remaining which driver should capture */ + unsigned int frame_count; + /* last frame completion */ + struct completion frame_cmplt; + + } capture; + + unsigned int camera_num; + unsigned int max_width; + unsigned int max_height; + unsigned int rgb_bgr_swapped; +}; + +int bm2835_mmal_init_controls( + struct bm2835_mmal_dev *dev, + struct v4l2_ctrl_handler *hdl); + +int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev); +int set_framerate_params(struct bm2835_mmal_dev *dev); + +/* Debug helpers */ + +#define v4l2_dump_pix_format(level, debug, dev, pix_fmt, desc) \ +{ \ + v4l2_dbg(level, debug, dev, \ +"%s: w %u h %u field %u pfmt 0x%x bpl %u sz_img %u colorspace 0x%x priv %u\n", \ + desc == NULL ? "" : desc, \ + (pix_fmt)->width, (pix_fmt)->height, (pix_fmt)->field, \ + (pix_fmt)->pixelformat, (pix_fmt)->bytesperline, \ + (pix_fmt)->sizeimage, (pix_fmt)->colorspace, (pix_fmt)->priv); \ +} +#define v4l2_dump_win_format(level, debug, dev, win_fmt, desc) \ +{ \ + v4l2_dbg(level, debug, dev, \ +"%s: w %u h %u l %u t %u field %u chromakey %06X clip %p " \ +"clipcount %u bitmap %p\n", \ + desc == NULL ? "" : desc, \ + (win_fmt)->w.width, (win_fmt)->w.height, \ + (win_fmt)->w.left, (win_fmt)->w.top, \ + (win_fmt)->field, \ + (win_fmt)->chromakey, \ + (win_fmt)->clips, (win_fmt)->clipcount, \ + (win_fmt)->bitmap); \ +} diff --git a/drivers/staging/media/platform/bcm2835/controls.c b/drivers/staging/media/platform/bcm2835/controls.c new file mode 100644 index 000000000000..a40987b2e75d --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/controls.c @@ -0,0 +1,1335 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <media/videobuf2-vmalloc.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> +#include <media/v4l2-common.h> + +#include "mmal-common.h" +#include "mmal-vchiq.h" +#include "mmal-parameters.h" +#include "bcm2835-camera.h" + +/* The supported V4L2_CID_AUTO_EXPOSURE_BIAS values are from -4.0 to +4.0. + * MMAL values are in 1/6th increments so the MMAL range is -24 to +24. + * V4L2 docs say value "is expressed in terms of EV, drivers should interpret + * the values as 0.001 EV units, where the value 1000 stands for +1 EV." + * V4L2 is limited to a max of 32 values in a menu, so count in 1/3rds from + * -4 to +4 + */ +static const s64 ev_bias_qmenu[] = { + -4000, -3667, -3333, + -3000, -2667, -2333, + -2000, -1667, -1333, + -1000, -667, -333, + 0, 333, 667, + 1000, 1333, 1667, + 2000, 2333, 2667, + 3000, 3333, 3667, + 4000 +}; + +/* Supported ISO values (*1000) + * ISOO = auto ISO + */ +static const s64 iso_qmenu[] = { + 0, 100000, 200000, 400000, 800000, +}; +static const uint32_t iso_values[] = { + 0, 100, 200, 400, 800, +}; + +static const s64 mains_freq_qmenu[] = { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO +}; + +/* Supported video encode modes */ +static const s64 bitrate_mode_qmenu[] = { + (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, +}; + +enum bm2835_mmal_ctrl_type { + MMAL_CONTROL_TYPE_STD, + MMAL_CONTROL_TYPE_STD_MENU, + MMAL_CONTROL_TYPE_INT_MENU, + MMAL_CONTROL_TYPE_CLUSTER, /* special cluster entry */ +}; + +struct bm2835_mmal_v4l2_ctrl; + +typedef int(bm2835_mmal_v4l2_ctrl_cb)( + struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl); + +struct bm2835_mmal_v4l2_ctrl { + u32 id; /* v4l2 control identifier */ + enum bm2835_mmal_ctrl_type type; + /* control minimum value or + * mask for MMAL_CONTROL_TYPE_STD_MENU */ + s32 min; + s32 max; /* maximum value of control */ + s32 def; /* default value of control */ + s32 step; /* step size of the control */ + const s64 *imenu; /* integer menu array */ + u32 mmal_id; /* mmal parameter id */ + bm2835_mmal_v4l2_ctrl_cb *setter; + bool ignore_errors; +}; + +struct v4l2_to_mmal_effects_setting { + u32 v4l2_effect; + u32 mmal_effect; + s32 col_fx_enable; + s32 col_fx_fixed_cbcr; + u32 u; + u32 v; + u32 num_effect_params; + u32 effect_params[MMAL_MAX_IMAGEFX_PARAMETERS]; +}; + +static const struct v4l2_to_mmal_effects_setting + v4l2_to_mmal_effects_values[] = { + { V4L2_COLORFX_NONE, MMAL_PARAM_IMAGEFX_NONE, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_BW, MMAL_PARAM_IMAGEFX_NONE, + 1, 0, 128, 128, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SEPIA, MMAL_PARAM_IMAGEFX_NONE, + 1, 0, 87, 151, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_NEGATIVE, MMAL_PARAM_IMAGEFX_NEGATIVE, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_EMBOSS, MMAL_PARAM_IMAGEFX_EMBOSS, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SKETCH, MMAL_PARAM_IMAGEFX_SKETCH, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SKY_BLUE, MMAL_PARAM_IMAGEFX_PASTEL, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_GRASS_GREEN, MMAL_PARAM_IMAGEFX_WATERCOLOUR, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SKIN_WHITEN, MMAL_PARAM_IMAGEFX_WASHEDOUT, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_VIVID, MMAL_PARAM_IMAGEFX_SATURATION, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_AQUA, MMAL_PARAM_IMAGEFX_NONE, + 1, 0, 171, 121, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_ART_FREEZE, MMAL_PARAM_IMAGEFX_HATCH, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SILHOUETTE, MMAL_PARAM_IMAGEFX_FILM, + 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} }, + { V4L2_COLORFX_SOLARIZATION, MMAL_PARAM_IMAGEFX_SOLARIZE, + 0, 0, 0, 0, 5, {1, 128, 160, 160, 48} }, + { V4L2_COLORFX_ANTIQUE, MMAL_PARAM_IMAGEFX_COLOURBALANCE, + 0, 0, 0, 0, 3, {108, 274, 238, 0, 0} }, + { V4L2_COLORFX_SET_CBCR, MMAL_PARAM_IMAGEFX_NONE, + 1, 1, 0, 0, 0, {0, 0, 0, 0, 0} } +}; + +struct v4l2_mmal_scene_config { + enum v4l2_scene_mode v4l2_scene; + enum mmal_parameter_exposuremode exposure_mode; + enum mmal_parameter_exposuremeteringmode metering_mode; +}; + +static const struct v4l2_mmal_scene_config scene_configs[] = { + /* V4L2_SCENE_MODE_NONE automatically added */ + { + V4L2_SCENE_MODE_NIGHT, + MMAL_PARAM_EXPOSUREMODE_NIGHT, + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE + }, + { + V4L2_SCENE_MODE_SPORTS, + MMAL_PARAM_EXPOSUREMODE_SPORTS, + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE + }, +}; + +/* control handlers*/ + +static int ctrl_set_rational(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + struct mmal_parameter_rational rational_value; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + rational_value.num = ctrl->val; + rational_value.den = 100; + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &rational_value, + sizeof(rational_value)); +} + +static int ctrl_set_value(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + u32_value = ctrl->val; + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_iso(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *control; + + if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min) + return 1; + + if (ctrl->id == V4L2_CID_ISO_SENSITIVITY) + dev->iso = iso_values[ctrl->val]; + else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO) + dev->manual_iso_enabled = + (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL ? + true : + false); + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + if (dev->manual_iso_enabled) + u32_value = dev->iso; + else + u32_value = 0; + + return vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_ISO, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + s32 s32_value; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + s32_value = (ctrl->val - 12) * 2; /* Convert from index to 1/6ths */ + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &s32_value, sizeof(s32_value)); +} + +static int ctrl_set_rotate(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret; + u32 u32_value; + struct vchiq_mmal_component *camera; + + camera = dev->component[MMAL_COMPONENT_CAMERA]; + + u32_value = ((ctrl->val % 360) / 90) * 90; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + if (ret < 0) + return ret; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + if (ret < 0) + return ret; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + + return ret; +} + +static int ctrl_set_flip(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret; + u32 u32_value; + struct vchiq_mmal_component *camera; + + if (ctrl->id == V4L2_CID_HFLIP) + dev->hflip = ctrl->val; + else + dev->vflip = ctrl->val; + + camera = dev->component[MMAL_COMPONENT_CAMERA]; + + if (dev->hflip && dev->vflip) + u32_value = MMAL_PARAM_MIRROR_BOTH; + else if (dev->hflip) + u32_value = MMAL_PARAM_MIRROR_HORIZONTAL; + else if (dev->vflip) + u32_value = MMAL_PARAM_MIRROR_VERTICAL; + else + u32_value = MMAL_PARAM_MIRROR_NONE; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + if (ret < 0) + return ret; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + if (ret < 0) + return ret; + + ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2], + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + + return ret; +} + +static int ctrl_set_exposure(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user; + u32 shutter_speed = 0; + struct vchiq_mmal_port *control; + int ret = 0; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED) { + /* V4L2 is in 100usec increments. + * MMAL is 1usec. + */ + dev->manual_shutter_speed = ctrl->val * 100; + } else if (mmal_ctrl->mmal_id == MMAL_PARAMETER_EXPOSURE_MODE) { + switch (ctrl->val) { + case V4L2_EXPOSURE_AUTO: + exp_mode = MMAL_PARAM_EXPOSUREMODE_AUTO; + break; + + case V4L2_EXPOSURE_MANUAL: + exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF; + break; + } + dev->exposure_mode_user = exp_mode; + dev->exposure_mode_v4l2_user = ctrl->val; + } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { + dev->exp_auto_priority = ctrl->val; + } + + if (dev->scene_mode == V4L2_SCENE_MODE_NONE) { + if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF) + shutter_speed = dev->manual_shutter_speed; + + ret = vchiq_mmal_port_parameter_set(dev->instance, + control, + MMAL_PARAMETER_SHUTTER_SPEED, + &shutter_speed, + sizeof(shutter_speed)); + ret += vchiq_mmal_port_parameter_set(dev->instance, + control, + MMAL_PARAMETER_EXPOSURE_MODE, + &exp_mode, + sizeof(u32)); + dev->exposure_mode_active = exp_mode; + } + /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should + * always apply irrespective of scene mode. + */ + ret += set_framerate_params(dev); + + return ret; +} + +static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + switch (ctrl->val) { + case V4L2_EXPOSURE_METERING_AVERAGE: + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE; + break; + + case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED: + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT; + break; + + case V4L2_EXPOSURE_METERING_SPOT: + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT; + break; + + /* todo matrix weighting not added to Linux API till 3.9 + case V4L2_EXPOSURE_METERING_MATRIX: + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX; + break; + */ + } + + if (dev->scene_mode == V4L2_SCENE_MODE_NONE) { + struct vchiq_mmal_port *control; + u32 u32_value = dev->metering_mode; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); + } else + return 0; +} + +static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + switch (ctrl->val) { + case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED: + u32_value = MMAL_PARAM_FLICKERAVOID_OFF; + break; + case V4L2_CID_POWER_LINE_FREQUENCY_50HZ: + u32_value = MMAL_PARAM_FLICKERAVOID_50HZ; + break; + case V4L2_CID_POWER_LINE_FREQUENCY_60HZ: + u32_value = MMAL_PARAM_FLICKERAVOID_60HZ; + break; + case V4L2_CID_POWER_LINE_FREQUENCY_AUTO: + u32_value = MMAL_PARAM_FLICKERAVOID_AUTO; + break; + } + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + switch (ctrl->val) { + case V4L2_WHITE_BALANCE_MANUAL: + u32_value = MMAL_PARAM_AWBMODE_OFF; + break; + + case V4L2_WHITE_BALANCE_AUTO: + u32_value = MMAL_PARAM_AWBMODE_AUTO; + break; + + case V4L2_WHITE_BALANCE_INCANDESCENT: + u32_value = MMAL_PARAM_AWBMODE_INCANDESCENT; + break; + + case V4L2_WHITE_BALANCE_FLUORESCENT: + u32_value = MMAL_PARAM_AWBMODE_FLUORESCENT; + break; + + case V4L2_WHITE_BALANCE_FLUORESCENT_H: + u32_value = MMAL_PARAM_AWBMODE_TUNGSTEN; + break; + + case V4L2_WHITE_BALANCE_HORIZON: + u32_value = MMAL_PARAM_AWBMODE_HORIZON; + break; + + case V4L2_WHITE_BALANCE_DAYLIGHT: + u32_value = MMAL_PARAM_AWBMODE_SUNLIGHT; + break; + + case V4L2_WHITE_BALANCE_FLASH: + u32_value = MMAL_PARAM_AWBMODE_FLASH; + break; + + case V4L2_WHITE_BALANCE_CLOUDY: + u32_value = MMAL_PARAM_AWBMODE_CLOUDY; + break; + + case V4L2_WHITE_BALANCE_SHADE: + u32_value = MMAL_PARAM_AWBMODE_SHADE; + break; + } + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_awb_gains(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + struct vchiq_mmal_port *control; + struct mmal_parameter_awbgains gains; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + if (ctrl->id == V4L2_CID_RED_BALANCE) + dev->red_gain = ctrl->val; + else if (ctrl->id == V4L2_CID_BLUE_BALANCE) + dev->blue_gain = ctrl->val; + + gains.r_gain.num = dev->red_gain; + gains.b_gain.num = dev->blue_gain; + gains.r_gain.den = gains.b_gain.den = 1000; + + return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &gains, sizeof(gains)); +} + +static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret = -EINVAL; + int i, j; + struct vchiq_mmal_port *control; + struct mmal_parameter_imagefx_parameters imagefx; + + for (i = 0; i < ARRAY_SIZE(v4l2_to_mmal_effects_values); i++) { + if (ctrl->val == v4l2_to_mmal_effects_values[i].v4l2_effect) { + imagefx.effect = + v4l2_to_mmal_effects_values[i].mmal_effect; + imagefx.num_effect_params = + v4l2_to_mmal_effects_values[i].num_effect_params; + + if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS) + imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS; + + for (j = 0; j < imagefx.num_effect_params; j++) + imagefx.effect_parameter[j] = + v4l2_to_mmal_effects_values[i].effect_params[j]; + + dev->colourfx.enable = + v4l2_to_mmal_effects_values[i].col_fx_enable; + if (!v4l2_to_mmal_effects_values[i].col_fx_fixed_cbcr) { + dev->colourfx.u = + v4l2_to_mmal_effects_values[i].u; + dev->colourfx.v = + v4l2_to_mmal_effects_values[i].v; + } + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + ret = vchiq_mmal_port_parameter_set( + dev->instance, control, + MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, + &imagefx, sizeof(imagefx)); + if (ret) + goto exit; + + ret = vchiq_mmal_port_parameter_set( + dev->instance, control, + MMAL_PARAMETER_COLOUR_EFFECT, + &dev->colourfx, sizeof(dev->colourfx)); + } + } + +exit: + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "mmal_ctrl:%p ctrl id:0x%x ctrl val:%d imagefx:0x%x color_effect:%s u:%d v:%d ret %d(%d)\n", + mmal_ctrl, ctrl->id, ctrl->val, imagefx.effect, + dev->colourfx.enable ? "true" : "false", + dev->colourfx.u, dev->colourfx.v, + ret, (ret == 0 ? 0 : -EINVAL)); + return (ret == 0 ? 0 : EINVAL); +} + +static int ctrl_set_colfx(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret = -EINVAL; + struct vchiq_mmal_port *control; + + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + dev->colourfx.enable = (ctrl->val & 0xff00) >> 8; + dev->colourfx.enable = ctrl->val & 0xff; + + ret = vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_COLOUR_EFFECT, + &dev->colourfx, + sizeof(dev->colourfx)); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n", + __func__, mmal_ctrl, ctrl->id, ctrl->val, ret, + (ret == 0 ? 0 : -EINVAL)); + return (ret == 0 ? 0 : EINVAL); +} + +static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret; + struct vchiq_mmal_port *encoder_out; + + dev->capture.encode_bitrate = ctrl->val; + + encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + + ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out, + mmal_ctrl->mmal_id, + &ctrl->val, sizeof(ctrl->val)); + ret = 0; + return ret; +} + +static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 bitrate_mode; + struct vchiq_mmal_port *encoder_out; + + encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + + dev->capture.encode_bitrate_mode = ctrl->val; + switch (ctrl->val) { + default: + case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: + bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: + bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT; + break; + } + + vchiq_mmal_port_parameter_set(dev->instance, encoder_out, + mmal_ctrl->mmal_id, + &bitrate_mode, + sizeof(bitrate_mode)); + return 0; +} + +static int ctrl_set_image_encode_output(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *jpeg_out; + + jpeg_out = &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->output[0]; + + u32_value = ctrl->val; + + return vchiq_mmal_port_parameter_set(dev->instance, jpeg_out, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + u32 u32_value; + struct vchiq_mmal_port *vid_enc_ctl; + + vid_enc_ctl = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + + u32_value = ctrl->val; + + return vchiq_mmal_port_parameter_set(dev->instance, vid_enc_ctl, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); +} + +static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + struct mmal_parameter_video_profile param; + int ret = 0; + + if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) { + switch (ctrl->val) { + case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: + case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: + dev->capture.enc_profile = ctrl->val; + break; + default: + ret = -EINVAL; + break; + } + } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) { + switch (ctrl->val) { + case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: + case V4L2_MPEG_VIDEO_H264_LEVEL_1B: + case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: + case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: + case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: + case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: + case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: + case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: + case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: + case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: + case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: + case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: + dev->capture.enc_level = ctrl->val; + break; + default: + ret = -EINVAL; + break; + } + } + + if (!ret) { + switch (dev->capture.enc_profile) { + case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: + param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: + param.profile = + MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + param.profile = MMAL_VIDEO_PROFILE_H264_MAIN; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: + param.profile = MMAL_VIDEO_PROFILE_H264_HIGH; + break; + default: + /* Should never get here */ + break; + } + + switch (dev->capture.enc_level) { + case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: + param.level = MMAL_VIDEO_LEVEL_H264_1; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1B: + param.level = MMAL_VIDEO_LEVEL_H264_1b; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: + param.level = MMAL_VIDEO_LEVEL_H264_11; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: + param.level = MMAL_VIDEO_LEVEL_H264_12; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: + param.level = MMAL_VIDEO_LEVEL_H264_13; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: + param.level = MMAL_VIDEO_LEVEL_H264_2; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: + param.level = MMAL_VIDEO_LEVEL_H264_21; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: + param.level = MMAL_VIDEO_LEVEL_H264_22; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: + param.level = MMAL_VIDEO_LEVEL_H264_3; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: + param.level = MMAL_VIDEO_LEVEL_H264_31; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: + param.level = MMAL_VIDEO_LEVEL_H264_32; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: + param.level = MMAL_VIDEO_LEVEL_H264_4; + break; + default: + /* Should never get here */ + break; + } + + ret = vchiq_mmal_port_parameter_set(dev->instance, + &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0], + mmal_ctrl->mmal_id, + ¶m, sizeof(param)); + } + return ret; +} + +static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) +{ + int ret = 0; + int shutter_speed; + struct vchiq_mmal_port *control; + + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, + "scene mode selected %d, was %d\n", ctrl->val, + dev->scene_mode); + control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + + if (ctrl->val == dev->scene_mode) + return 0; + + if (ctrl->val == V4L2_SCENE_MODE_NONE) { + /* Restore all user selections */ + dev->scene_mode = V4L2_SCENE_MODE_NONE; + + if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF) + shutter_speed = dev->manual_shutter_speed; + else + shutter_speed = 0; + + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n", + __func__, shutter_speed, dev->exposure_mode_user, + dev->metering_mode); + ret = vchiq_mmal_port_parameter_set(dev->instance, + control, + MMAL_PARAMETER_SHUTTER_SPEED, + &shutter_speed, + sizeof(shutter_speed)); + ret += vchiq_mmal_port_parameter_set(dev->instance, + control, + MMAL_PARAMETER_EXPOSURE_MODE, + &dev->exposure_mode_user, + sizeof(u32)); + dev->exposure_mode_active = dev->exposure_mode_user; + ret += vchiq_mmal_port_parameter_set(dev->instance, + control, + MMAL_PARAMETER_EXP_METERING_MODE, + &dev->metering_mode, + sizeof(u32)); + ret += set_framerate_params(dev); + } else { + /* Set up scene mode */ + int i; + const struct v4l2_mmal_scene_config *scene = NULL; + int shutter_speed; + enum mmal_parameter_exposuremode exposure_mode; + enum mmal_parameter_exposuremeteringmode metering_mode; + + for (i = 0; i < ARRAY_SIZE(scene_configs); i++) { + if (scene_configs[i].v4l2_scene == + ctrl->val) { + scene = &scene_configs[i]; + break; + } + } + if (!scene) + return -EINVAL; + if (i >= ARRAY_SIZE(scene_configs)) + return -EINVAL; + + /* Set all the values */ + dev->scene_mode = ctrl->val; + + if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF) + shutter_speed = dev->manual_shutter_speed; + else + shutter_speed = 0; + exposure_mode = scene->exposure_mode; + metering_mode = scene->metering_mode; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n", + __func__, shutter_speed, exposure_mode, metering_mode); + + ret = vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_SHUTTER_SPEED, + &shutter_speed, + sizeof(shutter_speed)); + ret += vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_EXPOSURE_MODE, + &exposure_mode, + sizeof(u32)); + dev->exposure_mode_active = exposure_mode; + ret += vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_EXPOSURE_MODE, + &exposure_mode, + sizeof(u32)); + ret += vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_EXP_METERING_MODE, + &metering_mode, + sizeof(u32)); + ret += set_framerate_params(dev); + } + if (ret) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: Setting scene to %d, ret=%d\n", + __func__, ctrl->val, ret); + ret = -EINVAL; + } + return 0; +} + +static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct bm2835_mmal_dev *dev = + container_of(ctrl->handler, struct bm2835_mmal_dev, + ctrl_handler); + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv; + int ret; + + if ((mmal_ctrl == NULL) || + (mmal_ctrl->id != ctrl->id) || + (mmal_ctrl->setter == NULL)) { + pr_warn("mmal_ctrl:%p ctrl id:%d\n", mmal_ctrl, ctrl->id); + return -EINVAL; + } + + ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl); + if (ret) + pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n", + ctrl->id, mmal_ctrl->mmal_id, ret); + if (mmal_ctrl->ignore_errors) + ret = 0; + return ret; +} + +static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = { + .s_ctrl = bm2835_mmal_s_ctrl, +}; + +static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { + { + V4L2_CID_SATURATION, MMAL_CONTROL_TYPE_STD, + -100, 100, 0, 1, NULL, + MMAL_PARAMETER_SATURATION, + &ctrl_set_rational, + false + }, + { + V4L2_CID_SHARPNESS, MMAL_CONTROL_TYPE_STD, + -100, 100, 0, 1, NULL, + MMAL_PARAMETER_SHARPNESS, + &ctrl_set_rational, + false + }, + { + V4L2_CID_CONTRAST, MMAL_CONTROL_TYPE_STD, + -100, 100, 0, 1, NULL, + MMAL_PARAMETER_CONTRAST, + &ctrl_set_rational, + false + }, + { + V4L2_CID_BRIGHTNESS, MMAL_CONTROL_TYPE_STD, + 0, 100, 50, 1, NULL, + MMAL_PARAMETER_BRIGHTNESS, + &ctrl_set_rational, + false + }, + { + V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU, + 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu, + MMAL_PARAMETER_ISO, + &ctrl_set_iso, + false + }, + { + V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, + 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, + MMAL_PARAMETER_ISO, + &ctrl_set_iso, + false + }, + { + V4L2_CID_IMAGE_STABILIZATION, MMAL_CONTROL_TYPE_STD, + 0, 1, 0, 1, NULL, + MMAL_PARAMETER_VIDEO_STABILISATION, + &ctrl_set_value, + false + }, +/* { + 0, MMAL_CONTROL_TYPE_CLUSTER, 3, 1, 0, NULL, 0, NULL + }, */ + { + V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, + ~0x03, 3, V4L2_EXPOSURE_AUTO, 0, NULL, + MMAL_PARAMETER_EXPOSURE_MODE, + &ctrl_set_exposure, + false + }, +/* todo this needs mixing in with set exposure + { + V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, + }, + */ + { + V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD, + /* Units of 100usecs */ + 1, 1 * 1000 * 10, 100 * 10, 1, NULL, + MMAL_PARAMETER_SHUTTER_SPEED, + &ctrl_set_exposure, + false + }, + { + V4L2_CID_AUTO_EXPOSURE_BIAS, MMAL_CONTROL_TYPE_INT_MENU, + 0, ARRAY_SIZE(ev_bias_qmenu) - 1, + (ARRAY_SIZE(ev_bias_qmenu) + 1) / 2 - 1, 0, ev_bias_qmenu, + MMAL_PARAMETER_EXPOSURE_COMP, + &ctrl_set_value_ev, + false + }, + { + V4L2_CID_EXPOSURE_AUTO_PRIORITY, MMAL_CONTROL_TYPE_STD, + 0, 1, + 0, 1, NULL, + 0, /* Dummy MMAL ID as it gets mapped into FPS range*/ + &ctrl_set_exposure, + false + }, + { + V4L2_CID_EXPOSURE_METERING, + MMAL_CONTROL_TYPE_STD_MENU, + ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, + MMAL_PARAMETER_EXP_METERING_MODE, + &ctrl_set_metering_mode, + false + }, + { + V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, + MMAL_CONTROL_TYPE_STD_MENU, + ~0x3ff, 9, V4L2_WHITE_BALANCE_AUTO, 0, NULL, + MMAL_PARAMETER_AWB_MODE, + &ctrl_set_awb_mode, + false + }, + { + V4L2_CID_RED_BALANCE, MMAL_CONTROL_TYPE_STD, + 1, 7999, 1000, 1, NULL, + MMAL_PARAMETER_CUSTOM_AWB_GAINS, + &ctrl_set_awb_gains, + false + }, + { + V4L2_CID_BLUE_BALANCE, MMAL_CONTROL_TYPE_STD, + 1, 7999, 1000, 1, NULL, + MMAL_PARAMETER_CUSTOM_AWB_GAINS, + &ctrl_set_awb_gains, + false + }, + { + V4L2_CID_COLORFX, MMAL_CONTROL_TYPE_STD_MENU, + 0, 15, V4L2_COLORFX_NONE, 0, NULL, + MMAL_PARAMETER_IMAGE_EFFECT, + &ctrl_set_image_effect, + false + }, + { + V4L2_CID_COLORFX_CBCR, MMAL_CONTROL_TYPE_STD, + 0, 0xffff, 0x8080, 1, NULL, + MMAL_PARAMETER_COLOUR_EFFECT, + &ctrl_set_colfx, + false + }, + { + V4L2_CID_ROTATE, MMAL_CONTROL_TYPE_STD, + 0, 360, 0, 90, NULL, + MMAL_PARAMETER_ROTATION, + &ctrl_set_rotate, + false + }, + { + V4L2_CID_HFLIP, MMAL_CONTROL_TYPE_STD, + 0, 1, 0, 1, NULL, + MMAL_PARAMETER_MIRROR, + &ctrl_set_flip, + false + }, + { + V4L2_CID_VFLIP, MMAL_CONTROL_TYPE_STD, + 0, 1, 0, 1, NULL, + MMAL_PARAMETER_MIRROR, + &ctrl_set_flip, + false + }, + { + V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU, + 0, ARRAY_SIZE(bitrate_mode_qmenu) - 1, + 0, 0, bitrate_mode_qmenu, + MMAL_PARAMETER_RATECONTROL, + &ctrl_set_bitrate_mode, + false + }, + { + V4L2_CID_MPEG_VIDEO_BITRATE, MMAL_CONTROL_TYPE_STD, + 25 * 1000, 25 * 1000 * 1000, 10 * 1000 * 1000, 25 * 1000, NULL, + MMAL_PARAMETER_VIDEO_BIT_RATE, + &ctrl_set_bitrate, + false + }, + { + V4L2_CID_JPEG_COMPRESSION_QUALITY, MMAL_CONTROL_TYPE_STD, + 1, 100, + 30, 1, NULL, + MMAL_PARAMETER_JPEG_Q_FACTOR, + &ctrl_set_image_encode_output, + false + }, + { + V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, + 0, ARRAY_SIZE(mains_freq_qmenu) - 1, + 1, 1, NULL, + MMAL_PARAMETER_FLICKER_AVOID, + &ctrl_set_flicker_avoidance, + false + }, + { + V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, MMAL_CONTROL_TYPE_STD, + 0, 1, + 0, 1, NULL, + MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, + &ctrl_set_video_encode_param_output, + true /* Errors ignored as requires latest firmware to work */ + }, + { + V4L2_CID_MPEG_VIDEO_H264_PROFILE, + MMAL_CONTROL_TYPE_STD_MENU, + ~((1<<V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + (1<<V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + (1<<V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + (1<<V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1, NULL, + MMAL_PARAMETER_PROFILE, + &ctrl_set_video_encode_profile_level, + false + }, + { + V4L2_CID_MPEG_VIDEO_H264_LEVEL, MMAL_CONTROL_TYPE_STD_MENU, + ~((1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + (1<<V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), + V4L2_MPEG_VIDEO_H264_LEVEL_4_0, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 1, NULL, + MMAL_PARAMETER_PROFILE, + &ctrl_set_video_encode_profile_level, + false + }, + { + V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, + -1, /* Min is computed at runtime */ + V4L2_SCENE_MODE_TEXT, + V4L2_SCENE_MODE_NONE, 1, NULL, + MMAL_PARAMETER_PROFILE, + &ctrl_set_scene_mode, + false + }, + { + V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, MMAL_CONTROL_TYPE_STD, + 0, 0x7FFFFFFF, 60, 1, NULL, + MMAL_PARAMETER_INTRAPERIOD, + &ctrl_set_video_encode_param_output, + false + }, +}; + +int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev) +{ + int c; + int ret = 0; + + for (c = 0; c < V4L2_CTRL_COUNT; c++) { + if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) { + ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c], + &v4l2_ctrls[c]); + if (!v4l2_ctrls[c].ignore_errors && ret) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Failed when setting default values for ctrl %d\n", + c); + break; + } + } + } + return ret; +} + +int set_framerate_params(struct bm2835_mmal_dev *dev) +{ + struct mmal_parameter_fps_range fps_range; + int ret; + + if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) && + (dev->exp_auto_priority)) { + /* Variable FPS. Define min FPS as 1fps. + * Max as max defined FPS. + */ + fps_range.fps_low.num = 1; + fps_range.fps_low.den = 1; + fps_range.fps_high.num = dev->capture.timeperframe.denominator; + fps_range.fps_high.den = dev->capture.timeperframe.numerator; + } else { + /* Fixed FPS - set min and max to be the same */ + fps_range.fps_low.num = fps_range.fps_high.num = + dev->capture.timeperframe.denominator; + fps_range.fps_low.den = fps_range.fps_high.den = + dev->capture.timeperframe.numerator; + } + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Set fps range to %d/%d to %d/%d\n", + fps_range.fps_low.num, + fps_range.fps_low.den, + fps_range.fps_high.num, + fps_range.fps_high.den); + + ret = vchiq_mmal_port_parameter_set(dev->instance, + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_PREVIEW], + MMAL_PARAMETER_FPS_RANGE, + &fps_range, sizeof(fps_range)); + ret += vchiq_mmal_port_parameter_set(dev->instance, + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_VIDEO], + MMAL_PARAMETER_FPS_RANGE, + &fps_range, sizeof(fps_range)); + ret += vchiq_mmal_port_parameter_set(dev->instance, + &dev->component[MMAL_COMPONENT_CAMERA]-> + output[MMAL_CAMERA_PORT_CAPTURE], + MMAL_PARAMETER_FPS_RANGE, + &fps_range, sizeof(fps_range)); + if (ret) + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Failed to set fps ret %d\n", ret); + + return ret; +} + +int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl_handler *hdl) +{ + int c; + const struct bm2835_mmal_v4l2_ctrl *ctrl; + + v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT); + + for (c = 0; c < V4L2_CTRL_COUNT; c++) { + ctrl = &v4l2_ctrls[c]; + + switch (ctrl->type) { + case MMAL_CONTROL_TYPE_STD: + dev->ctrls[c] = v4l2_ctrl_new_std(hdl, + &bm2835_mmal_ctrl_ops, ctrl->id, + ctrl->min, ctrl->max, ctrl->step, ctrl->def); + break; + + case MMAL_CONTROL_TYPE_STD_MENU: + { + int mask = ctrl->min; + + if (ctrl->id == V4L2_CID_SCENE_MODE) { + /* Special handling to work out the mask + * value based on the scene_configs array + * at runtime. Reduces the chance of + * mismatches. + */ + int i; + mask = 1<<V4L2_SCENE_MODE_NONE; + for (i = 0; + i < ARRAY_SIZE(scene_configs); + i++) { + mask |= 1<<scene_configs[i].v4l2_scene; + } + mask = ~mask; + } + + dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, + &bm2835_mmal_ctrl_ops, ctrl->id, + ctrl->max, mask, ctrl->def); + break; + } + + case MMAL_CONTROL_TYPE_INT_MENU: + dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, + &bm2835_mmal_ctrl_ops, ctrl->id, + ctrl->max, ctrl->def, ctrl->imenu); + break; + + case MMAL_CONTROL_TYPE_CLUSTER: + /* skip this entry when constructing controls */ + continue; + } + + if (hdl->error) + break; + + dev->ctrls[c]->priv = (void *)ctrl; + } + + if (hdl->error) { + pr_err("error adding control %d/%d id 0x%x\n", c, + V4L2_CTRL_COUNT, ctrl->id); + return hdl->error; + } + + for (c = 0; c < V4L2_CTRL_COUNT; c++) { + ctrl = &v4l2_ctrls[c]; + + switch (ctrl->type) { + case MMAL_CONTROL_TYPE_CLUSTER: + v4l2_ctrl_auto_cluster(ctrl->min, + &dev->ctrls[c + 1], + ctrl->max, + ctrl->def); + break; + + case MMAL_CONTROL_TYPE_STD: + case MMAL_CONTROL_TYPE_STD_MENU: + case MMAL_CONTROL_TYPE_INT_MENU: + break; + } + } + + return 0; +} diff --git a/drivers/staging/media/platform/bcm2835/mmal-common.h b/drivers/staging/media/platform/bcm2835/mmal-common.h new file mode 100644 index 000000000000..840fd139e033 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-common.h @@ -0,0 +1,53 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + * + * MMAL structures + * + */ + +#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) +#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') + +/** Special value signalling that time is not known */ +#define MMAL_TIME_UNKNOWN (1LL<<63) + +/* mapping between v4l and mmal video modes */ +struct mmal_fmt { + char *name; + u32 fourcc; /* v4l2 format id */ + int flags; /* v4l2 flags field */ + u32 mmal; + int depth; + u32 mmal_component; /* MMAL component index to be used to encode */ + u32 ybbp; /* depth of first Y plane for planar formats */ +}; + +/* buffer for one video frame */ +struct mmal_buffer { + /* v4l buffer data -- must be first */ + struct vb2_v4l2_buffer vb; + + /* list of buffers available */ + struct list_head list; + + void *buffer; /* buffer pointer */ + unsigned long buffer_size; /* size of allocated buffer */ +}; + +/* */ +struct mmal_colourfx { + s32 enable; + u32 u; + u32 v; +}; diff --git a/drivers/staging/media/platform/bcm2835/mmal-encodings.h b/drivers/staging/media/platform/bcm2835/mmal-encodings.h new file mode 100644 index 000000000000..024d620dc1df --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-encodings.h @@ -0,0 +1,127 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ +#ifndef MMAL_ENCODINGS_H +#define MMAL_ENCODINGS_H + +#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') +#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') +#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') +#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') +#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') +#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') +#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') +#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') +#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') +#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') +#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') +#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') +#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') +#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') +#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') + +#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') +#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') +#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') +#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') +#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') +#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') + +#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') +#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') +#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') +#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') +#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') +#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') +#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') +#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') +#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') +#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') +#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') +#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') +#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') +#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') +#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') +#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') +#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') +#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') +#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') +#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') +#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') + +/** SAND Video (YUVUV128) format, native format understood by VideoCore. + * This format is *not* opaque - if requested you will receive full frames + * of YUV_UV video. + */ +#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') + +/** VideoCore opaque image format, image handles are returned to + * the host but not the actual image data. + */ +#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') + +/** An EGL image handle + */ +#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') + +/* }@ */ + +/** \name Pre-defined audio encodings */ +/* @{ */ +#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') +#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') +#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') +#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') +#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') +#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') + +/* Pre-defined H264 encoding variants */ + +/** ISO 14496-10 Annex B byte stream format */ +#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 +/** ISO 14496-15 AVC stream format */ +#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') +/** Implicitly delineated NAL units without emulation prevention */ +#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') + + +/** \defgroup MmalColorSpace List of pre-defined video color spaces + * This defines a list of common color spaces. This list isn't exhaustive and + * is only provided as a convenience to avoid clients having to use FourCC + * codes directly. However components are allowed to define and use their own + * FourCC codes. + */ +/* @{ */ + +/** Unknown color space */ +#define MMAL_COLOR_SPACE_UNKNOWN 0 +/** ITU-R BT.601-5 [SDTV] */ +#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') +/** ITU-R BT.709-3 [HDTV] */ +#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') +/** JPEG JFIF */ +#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') +/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ +#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') +/** Society of Motion Picture and Television Engineers 240M (1999) */ +#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') +/** ITU-R BT.470-2 System M */ +#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') +/** ITU-R BT.470-2 System BG */ +#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') +/** JPEG JFIF, but with 16..255 luma */ +#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') +/* @} MmalColorSpace List */ + +#endif /* MMAL_ENCODINGS_H */ diff --git a/drivers/staging/media/platform/bcm2835/mmal-msg-common.h b/drivers/staging/media/platform/bcm2835/mmal-msg-common.h new file mode 100644 index 000000000000..66e8a6edf628 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-msg-common.h @@ -0,0 +1,50 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +#ifndef MMAL_MSG_COMMON_H +#define MMAL_MSG_COMMON_H + +enum mmal_msg_status { + MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ + MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ + MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ + MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ + MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ + MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ + MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ + MMAL_MSG_STATUS_EIO, /**< I/O error */ + MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ + MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ + MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ + MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ + MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ + MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ + MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ + MMAL_MSG_STATUS_EFAULT, /**< Bad address */ +}; + +struct mmal_rect { + s32 x; /**< x coordinate (from left) */ + s32 y; /**< y coordinate (from top) */ + s32 width; /**< width */ + s32 height; /**< height */ +}; + +struct mmal_rational { + s32 num; /**< Numerator */ + s32 den; /**< Denominator */ +}; + +#endif /* MMAL_MSG_COMMON_H */ diff --git a/drivers/staging/media/platform/bcm2835/mmal-msg-format.h b/drivers/staging/media/platform/bcm2835/mmal-msg-format.h new file mode 100644 index 000000000000..123d86ef582b --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-msg-format.h @@ -0,0 +1,81 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +#ifndef MMAL_MSG_FORMAT_H +#define MMAL_MSG_FORMAT_H + +#include "mmal-msg-common.h" + +/* MMAL_ES_FORMAT_T */ + + +struct mmal_audio_format { + u32 channels; /**< Number of audio channels */ + u32 sample_rate; /**< Sample rate */ + + u32 bits_per_sample; /**< Bits per sample */ + u32 block_align; /**< Size of a block of data */ +}; + +struct mmal_video_format { + u32 width; /**< Width of frame in pixels */ + u32 height; /**< Height of frame in rows of pixels */ + struct mmal_rect crop; /**< Visible region of the frame */ + struct mmal_rational frame_rate; /**< Frame rate */ + struct mmal_rational par; /**< Pixel aspect ratio */ + + /* FourCC specifying the color space of the video stream. See the + * \ref MmalColorSpace "pre-defined color spaces" for some examples. + */ + u32 color_space; +}; + +struct mmal_subpicture_format { + u32 x_offset; + u32 y_offset; +}; + +union mmal_es_specific_format { + struct mmal_audio_format audio; + struct mmal_video_format video; + struct mmal_subpicture_format subpicture; +}; + +/** Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ +struct mmal_es_format { + u32 type; /* enum mmal_es_type */ + + u32 encoding; /* FourCC specifying encoding of the elementary stream.*/ + u32 encoding_variant; /* FourCC specifying the specific + * encoding variant of the elementary + * stream. + */ + + union mmal_es_specific_format *es; /* TODO: pointers in + * message serialisation?!? + */ + /* Type specific + * information for the + * elementary stream + */ + + u32 bitrate; /**< Bitrate in bits per second */ + u32 flags; /**< Flags describing properties of the elementary stream. */ + + u32 extradata_size; /**< Size of the codec specific data */ + u8 *extradata; /**< Codec specific data */ +}; + +#endif /* MMAL_MSG_FORMAT_H */ diff --git a/drivers/staging/media/platform/bcm2835/mmal-msg-port.h b/drivers/staging/media/platform/bcm2835/mmal-msg-port.h new file mode 100644 index 000000000000..a55c1ea2eceb --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-msg-port.h @@ -0,0 +1,107 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +/* MMAL_PORT_TYPE_T */ +enum mmal_port_type { + MMAL_PORT_TYPE_UNKNOWN = 0, /**< Unknown port type */ + MMAL_PORT_TYPE_CONTROL, /**< Control port */ + MMAL_PORT_TYPE_INPUT, /**< Input port */ + MMAL_PORT_TYPE_OUTPUT, /**< Output port */ + MMAL_PORT_TYPE_CLOCK, /**< Clock port */ +}; + +/** The port is pass-through and doesn't need buffer headers allocated */ +#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 +/** The port wants to allocate the buffer payloads. + * This signals a preference that payload allocation should be done + * on this port for efficiency reasons. */ +#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 +/** The port supports format change events. + * This applies to input ports and is used to let the client know + * whether the port supports being reconfigured via a format + * change event (i.e. without having to disable the port). */ +#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 + +/* mmal port structure (MMAL_PORT_T) + * + * most elements are informational only, the pointer values for + * interogation messages are generally provided as additional + * strucures within the message. When used to set values only teh + * buffer_num, buffer_size and userdata parameters are writable. + */ +struct mmal_port { + void *priv; /* Private member used by the framework */ + const char *name; /* Port name. Used for debugging purposes (RO) */ + + u32 type; /* Type of the port (RO) enum mmal_port_type */ + u16 index; /* Index of the port in its type list (RO) */ + u16 index_all; /* Index of the port in the list of all ports (RO) */ + + u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ + struct mmal_es_format *format; /* Format of the elementary stream */ + + u32 buffer_num_min; /* Minimum number of buffers the port + * requires (RO). This is set by the + * component. + */ + + u32 buffer_size_min; /* Minimum size of buffers the port + * requires (RO). This is set by the + * component. + */ + + u32 buffer_alignment_min; /* Minimum alignment requirement for + * the buffers (RO). A value of + * zero means no special alignment + * requirements. This is set by the + * component. + */ + + u32 buffer_num_recommended; /* Number of buffers the port + * recommends for optimal + * performance (RO). A value of + * zero means no special + * recommendation. This is set + * by the component. + */ + + u32 buffer_size_recommended; /* Size of buffers the port + * recommends for optimal + * performance (RO). A value of + * zero means no special + * recommendation. This is set + * by the component. + */ + + u32 buffer_num; /* Actual number of buffers the port will use. + * This is set by the client. + */ + + u32 buffer_size; /* Actual maximum size of the buffers that + * will be sent to the port. This is set by + * the client. + */ + + void *component; /* Component this port belongs to (Read Only) */ + + void *userdata; /* Field reserved for use by the client */ + + u32 capabilities; /* Flags describing the capabilities of a + * port (RO). Bitwise combination of \ref + * portcapabilities "Port capabilities" + * values. + */ + +}; diff --git a/drivers/staging/media/platform/bcm2835/mmal-msg.h b/drivers/staging/media/platform/bcm2835/mmal-msg.h new file mode 100644 index 000000000000..67b1076015a5 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-msg.h @@ -0,0 +1,404 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +/* all the data structures which serialise the MMAL protocol. note + * these are directly mapped onto the recived message data. + * + * BEWARE: They seem to *assume* pointers are u32 and that there is no + * structure padding! + * + * NOTE: this implementation uses kernel types to ensure sizes. Rather + * than assigning values to enums to force their size the + * implementation uses fixed size types and not the enums (though the + * comments have the actual enum type + */ + +#define VC_MMAL_VER 15 +#define VC_MMAL_MIN_VER 10 +#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") + +/* max total message size is 512 bytes */ +#define MMAL_MSG_MAX_SIZE 512 +/* with six 32bit header elements max payload is therefore 488 bytes */ +#define MMAL_MSG_MAX_PAYLOAD 488 + +#include "mmal-msg-common.h" +#include "mmal-msg-format.h" +#include "mmal-msg-port.h" + +enum mmal_msg_type { + MMAL_MSG_TYPE_QUIT = 1, + MMAL_MSG_TYPE_SERVICE_CLOSED, + MMAL_MSG_TYPE_GET_VERSION, + MMAL_MSG_TYPE_COMPONENT_CREATE, + MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ + MMAL_MSG_TYPE_COMPONENT_ENABLE, + MMAL_MSG_TYPE_COMPONENT_DISABLE, + MMAL_MSG_TYPE_PORT_INFO_GET, + MMAL_MSG_TYPE_PORT_INFO_SET, + MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ + MMAL_MSG_TYPE_BUFFER_FROM_HOST, + MMAL_MSG_TYPE_BUFFER_TO_HOST, + MMAL_MSG_TYPE_GET_STATS, + MMAL_MSG_TYPE_PORT_PARAMETER_SET, + MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ + MMAL_MSG_TYPE_EVENT_TO_HOST, + MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, + MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, + MMAL_MSG_TYPE_CONSUME_MEM, + MMAL_MSG_TYPE_LMK, /* 20 */ + MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, + MMAL_MSG_TYPE_DRM_GET_LHS32, + MMAL_MSG_TYPE_DRM_GET_TIME, + MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, + MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ + MMAL_MSG_TYPE_HOST_LOG, + MMAL_MSG_TYPE_MSG_LAST +}; + +/* port action request messages differ depending on the action type */ +enum mmal_msg_port_action_type { + MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unkown action */ + MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ + MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ + MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ + MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ + MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ + MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ +}; + +struct mmal_msg_header { + u32 magic; + u32 type; /** enum mmal_msg_type */ + + /* Opaque handle to the control service */ + struct mmal_control_service *control_service; + + struct mmal_msg_context *context; /** a u32 per message context */ + u32 status; /** The status of the vchiq operation */ + u32 padding; +}; + +/* Send from VC to host to report version */ +struct mmal_msg_version { + u32 flags; + u32 major; + u32 minor; + u32 minimum; +}; + +/* request to VC to create component */ +struct mmal_msg_component_create { + void *client_component; /* component context */ + char name[128]; + u32 pid; /* For debug */ +}; + +/* reply from VC to component creation request */ +struct mmal_msg_component_create_reply { + u32 status; /** enum mmal_msg_status - how does this differ to + * the one in the header? + */ + u32 component_handle; /* VideoCore handle for component */ + u32 input_num; /* Number of input ports */ + u32 output_num; /* Number of output ports */ + u32 clock_num; /* Number of clock ports */ +}; + +/* request to VC to destroy a component */ +struct mmal_msg_component_destroy { + u32 component_handle; +}; + +struct mmal_msg_component_destroy_reply { + u32 status; /** The component destruction status */ +}; + + +/* request and reply to VC to enable a component */ +struct mmal_msg_component_enable { + u32 component_handle; +}; + +struct mmal_msg_component_enable_reply { + u32 status; /** The component enable status */ +}; + + +/* request and reply to VC to disable a component */ +struct mmal_msg_component_disable { + u32 component_handle; +}; + +struct mmal_msg_component_disable_reply { + u32 status; /** The component disable status */ +}; + +/* request to VC to get port information */ +struct mmal_msg_port_info_get { + u32 component_handle; /* component handle port is associated with */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 index; /* port index to query */ +}; + +/* reply from VC to get port info request */ +struct mmal_msg_port_info_get_reply { + u32 status; /** enum mmal_msg_status */ + u32 component_handle; /* component handle port is associated with */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 port_index; /* port indexed in query */ + s32 found; /* unused */ + u32 port_handle; /**< Handle to use for this port */ + struct mmal_port port; + struct mmal_es_format format; /* elementry stream format */ + union mmal_es_specific_format es; /* es type specific data */ + u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ +}; + +/* request to VC to set port information */ +struct mmal_msg_port_info_set { + u32 component_handle; + u32 port_type; /* enum mmal_msg_port_type */ + u32 port_index; /* port indexed in query */ + struct mmal_port port; + struct mmal_es_format format; + union mmal_es_specific_format es; + u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +}; + +/* reply from VC to port info set request */ +struct mmal_msg_port_info_set_reply { + u32 status; + u32 component_handle; /* component handle port is associated with */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 index; /* port indexed in query */ + s32 found; /* unused */ + u32 port_handle; /**< Handle to use for this port */ + struct mmal_port port; + struct mmal_es_format format; + union mmal_es_specific_format es; + u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +}; + + +/* port action requests that take a mmal_port as a parameter */ +struct mmal_msg_port_action_port { + u32 component_handle; + u32 port_handle; + u32 action; /* enum mmal_msg_port_action_type */ + struct mmal_port port; +}; + +/* port action requests that take handles as a parameter */ +struct mmal_msg_port_action_handle { + u32 component_handle; + u32 port_handle; + u32 action; /* enum mmal_msg_port_action_type */ + u32 connect_component_handle; + u32 connect_port_handle; +}; + +struct mmal_msg_port_action_reply { + u32 status; /** The port action operation status */ +}; + + + + +/* MMAL buffer transfer */ + +/** Size of space reserved in a buffer message for short messages. */ +#define MMAL_VC_SHORT_DATA 128 + +/** Signals that the current payload is the end of the stream of data */ +#define MMAL_BUFFER_HEADER_FLAG_EOS (1<<0) +/** Signals that the start of the current payload starts a frame */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME_START (1<<1) +/** Signals that the end of the current payload ends a frame */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME_END (1<<2) +/** Signals that the current payload contains only complete frames (>1) */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME \ + (MMAL_BUFFER_HEADER_FLAG_FRAME_START|MMAL_BUFFER_HEADER_FLAG_FRAME_END) +/** Signals that the current payload is a keyframe (i.e. self decodable) */ +#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME (1<<3) +/** Signals a discontinuity in the stream of data (e.g. after a seek). + * Can be used for instance by a decoder to reset its state */ +#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY (1<<4) +/** Signals a buffer containing some kind of config data for the component + * (e.g. codec config data) */ +#define MMAL_BUFFER_HEADER_FLAG_CONFIG (1<<5) +/** Signals an encrypted payload */ +#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED (1<<6) +/** Signals a buffer containing side information */ +#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO (1<<7) +/** Signals a buffer which is the snapshot/postview image from a stills + * capture + */ +#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT (1<<8) +/** Signals a buffer which contains data known to be corrupted */ +#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED (1<<9) +/** Signals that a buffer failed to be transmitted */ +#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED (1<<10) + +struct mmal_driver_buffer { + u32 magic; + u32 component_handle; + u32 port_handle; + void *client_context; +}; + +/* buffer header */ +struct mmal_buffer_header { + struct mmal_buffer_header *next; /* next header */ + void *priv; /* framework private data */ + u32 cmd; + void *data; + u32 alloc_size; + u32 length; + u32 offset; + u32 flags; + s64 pts; + s64 dts; + void *type; + void *user_data; +}; + +struct mmal_buffer_header_type_specific { + union { + struct { + u32 planes; + u32 offset[4]; + u32 pitch[4]; + u32 flags; + } video; + } u; +}; + +struct mmal_msg_buffer_from_host { + /* The front 32 bytes of the buffer header are copied + * back to us in the reply to allow for context. This + * area is used to store two mmal_driver_buffer structures to + * allow for multiple concurrent service users. + */ + /* control data */ + struct mmal_driver_buffer drvbuf; + + /* referenced control data for passthrough buffer management */ + struct mmal_driver_buffer drvbuf_ref; + struct mmal_buffer_header buffer_header; /* buffer header itself */ + struct mmal_buffer_header_type_specific buffer_header_type_specific; + s32 is_zero_copy; + s32 has_reference; + + /** allows short data to be xfered in control message */ + u32 payload_in_message; + u8 short_data[MMAL_VC_SHORT_DATA]; +}; + + +/* port parameter setting */ + +#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 + +struct mmal_msg_port_parameter_set { + u32 component_handle; /* component */ + u32 port_handle; /* port */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ + uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; +}; + +struct mmal_msg_port_parameter_set_reply { + u32 status; /** enum mmal_msg_status todo: how does this + * differ to the one in the header? + */ +}; + +/* port parameter getting */ + +struct mmal_msg_port_parameter_get { + u32 component_handle; /* component */ + u32 port_handle; /* port */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ +}; + +struct mmal_msg_port_parameter_get_reply { + u32 status; /* Status of mmal_port_parameter_get call */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ + uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; +}; + +/* event messages */ +#define MMAL_WORKER_EVENT_SPACE 256 + +struct mmal_msg_event_to_host { + void *client_component; /* component context */ + + u32 port_type; + u32 port_num; + + u32 cmd; + u32 length; + u8 data[MMAL_WORKER_EVENT_SPACE]; + struct mmal_buffer_header *delayed_buffer; +}; + +/* all mmal messages are serialised through this structure */ +struct mmal_msg { + /* header */ + struct mmal_msg_header h; + /* payload */ + union { + struct mmal_msg_version version; + + struct mmal_msg_component_create component_create; + struct mmal_msg_component_create_reply component_create_reply; + + struct mmal_msg_component_destroy component_destroy; + struct mmal_msg_component_destroy_reply component_destroy_reply; + + struct mmal_msg_component_enable component_enable; + struct mmal_msg_component_enable_reply component_enable_reply; + + struct mmal_msg_component_disable component_disable; + struct mmal_msg_component_disable_reply component_disable_reply; + + struct mmal_msg_port_info_get port_info_get; + struct mmal_msg_port_info_get_reply port_info_get_reply; + + struct mmal_msg_port_info_set port_info_set; + struct mmal_msg_port_info_set_reply port_info_set_reply; + + struct mmal_msg_port_action_port port_action_port; + struct mmal_msg_port_action_handle port_action_handle; + struct mmal_msg_port_action_reply port_action_reply; + + struct mmal_msg_buffer_from_host buffer_from_host; + + struct mmal_msg_port_parameter_set port_parameter_set; + struct mmal_msg_port_parameter_set_reply + port_parameter_set_reply; + struct mmal_msg_port_parameter_get + port_parameter_get; + struct mmal_msg_port_parameter_get_reply + port_parameter_get_reply; + + struct mmal_msg_event_to_host event_to_host; + + u8 payload[MMAL_MSG_MAX_PAYLOAD]; + } u; +}; diff --git a/drivers/staging/media/platform/bcm2835/mmal-parameters.h b/drivers/staging/media/platform/bcm2835/mmal-parameters.h new file mode 100644 index 000000000000..f6abb5cfa49d --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-parameters.h @@ -0,0 +1,689 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + */ + +/* common parameters */ + +/** @name Parameter groups + * Parameters are divided into groups, and then allocated sequentially within + * a group using an enum. + * @{ + */ + +/** Common parameter ID group, used with many types of component. */ +#define MMAL_PARAMETER_GROUP_COMMON (0<<16) +/** Camera-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_CAMERA (1<<16) +/** Video-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_VIDEO (2<<16) +/** Audio-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_AUDIO (3<<16) +/** Clock-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_CLOCK (4<<16) +/** Miracast-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_MIRACAST (5<<16) + +/* Common parameters */ +enum mmal_parameter_common_type { + MMAL_PARAMETER_UNUSED /**< Never a valid parameter ID */ + = MMAL_PARAMETER_GROUP_COMMON, + MMAL_PARAMETER_SUPPORTED_ENCODINGS, /**< MMAL_PARAMETER_ENCODING_T */ + MMAL_PARAMETER_URI, /**< MMAL_PARAMETER_URI_T */ + + /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ + MMAL_PARAMETER_CHANGE_EVENT_REQUEST, + + /** MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ZERO_COPY, + + /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ + MMAL_PARAMETER_BUFFER_REQUIREMENTS, + + MMAL_PARAMETER_STATISTICS, /**< MMAL_PARAMETER_STATISTICS_T */ + MMAL_PARAMETER_CORE_STATISTICS, /**< MMAL_PARAMETER_CORE_STATISTICS_T */ + MMAL_PARAMETER_MEM_USAGE, /**< MMAL_PARAMETER_MEM_USAGE_T */ + MMAL_PARAMETER_BUFFER_FLAG_FILTER, /**< MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_SEEK, /**< MMAL_PARAMETER_SEEK_T */ + MMAL_PARAMETER_POWERMON_ENABLE, /**< MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_LOGGING, /**< MMAL_PARAMETER_LOGGING_T */ + MMAL_PARAMETER_SYSTEM_TIME, /**< MMAL_PARAMETER_UINT64_T */ + MMAL_PARAMETER_NO_IMAGE_PADDING /**< MMAL_PARAMETER_BOOLEAN_T */ +}; + +/* camera parameters */ + +enum mmal_parameter_camera_type { + /* 0 */ + /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ + MMAL_PARAMETER_THUMBNAIL_CONFIGURATION + = MMAL_PARAMETER_GROUP_CAMERA, + MMAL_PARAMETER_CAPTURE_QUALITY, /**< Unused? */ + MMAL_PARAMETER_ROTATION, /**< @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_EXIF_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_EXIF, /**< @ref MMAL_PARAMETER_EXIF_T */ + MMAL_PARAMETER_AWB_MODE, /**< @ref MMAL_PARAM_AWBMODE_T */ + MMAL_PARAMETER_IMAGE_EFFECT, /**< @ref MMAL_PARAMETER_IMAGEFX_T */ + MMAL_PARAMETER_COLOUR_EFFECT, /**< @ref MMAL_PARAMETER_COLOURFX_T */ + MMAL_PARAMETER_FLICKER_AVOID, /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ + MMAL_PARAMETER_FLASH, /**< @ref MMAL_PARAMETER_FLASH_T */ + MMAL_PARAMETER_REDEYE, /**< @ref MMAL_PARAMETER_REDEYE_T */ + MMAL_PARAMETER_FOCUS, /**< @ref MMAL_PARAMETER_FOCUS_T */ + MMAL_PARAMETER_FOCAL_LENGTHS, /**< Unused? */ + MMAL_PARAMETER_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_ZOOM, /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ + MMAL_PARAMETER_MIRROR, /**< @ref MMAL_PARAMETER_MIRROR_T */ + + /* 0x10 */ + MMAL_PARAMETER_CAMERA_NUM, /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_EXPOSURE_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ + MMAL_PARAMETER_EXP_METERING_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ + MMAL_PARAMETER_FOCUS_STATUS, /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ + MMAL_PARAMETER_CAMERA_CONFIG, /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ + MMAL_PARAMETER_CAPTURE_STATUS, /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ + MMAL_PARAMETER_FACE_TRACK, /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ + MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_JPEG_Q_FACTOR, /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_FRAME_RATE, /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ + MMAL_PARAMETER_USE_STC, /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ + MMAL_PARAMETER_CAMERA_INFO, /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ + MMAL_PARAMETER_VIDEO_STABILISATION, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_FACE_TRACK_RESULTS, /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ + MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + + /* 0x20 */ + MMAL_PARAMETER_DPF_FILE, /**< @ref MMAL_PARAMETER_URI_T */ + MMAL_PARAMETER_ENABLE_DPF_FILE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DPF_FAIL_IS_FATAL, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAPTURE_MODE, /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ + MMAL_PARAMETER_FOCUS_REGIONS, /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ + MMAL_PARAMETER_INPUT_CROP, /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ + MMAL_PARAMETER_SENSOR_INFORMATION, /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ + MMAL_PARAMETER_FLASH_SELECT, /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ + MMAL_PARAMETER_FIELD_OF_VIEW, /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ + MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, /**< @ref MMAL_PARAMETER_DRC_T */ + MMAL_PARAMETER_ALGORITHM_CONTROL, /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ + MMAL_PARAMETER_SHARPNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_CONTRAST, /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_BRIGHTNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_SATURATION, /**< @ref MMAL_PARAMETER_RATIONAL_T */ + + /* 0x30 */ + MMAL_PARAMETER_ISO, /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_ANTISHAKE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + + /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ + MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAMERA_BURST_CAPTURE, + + /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_MIN_ISO, + + /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ + MMAL_PARAMETER_CAMERA_USE_CASE, + + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAPTURE_STATS_PASS, + + /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ENABLE_REGISTER_FILE, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, + + /** @ref MMAL_PARAMETER_CONFIGFILE_T */ + MMAL_PARAMETER_CONFIGFILE_REGISTERS, + + /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ + MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, + MMAL_PARAMETER_JPEG_ATTACH_LOG, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ZERO_SHUTTER_LAG, /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ + MMAL_PARAMETER_FPS_RANGE, /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ + MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ + + /* 0x40 */ + MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_FLASH_REQUIRED, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SHUTTER_SPEED, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CUSTOM_AWB_GAINS, /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ +}; + +struct mmal_parameter_rational { + s32 num; /**< Numerator */ + s32 den; /**< Denominator */ +}; + +enum mmal_parameter_camera_config_timestamp_mode { + MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ + MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value + * for the frame timestamp + */ + MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp + * but subtract the + * timestamp of the first + * frame sent to give a + * zero based timestamp. + */ +}; + +struct mmal_parameter_fps_range { + /**< Low end of the permitted framerate range */ + struct mmal_parameter_rational fps_low; + /**< High end of the permitted framerate range */ + struct mmal_parameter_rational fps_high; +}; + + +/* camera configuration parameter */ +struct mmal_parameter_camera_config { + /* Parameters for setting up the image pools */ + u32 max_stills_w; /* Max size of stills capture */ + u32 max_stills_h; + u32 stills_yuv422; /* Allow YUV422 stills capture */ + u32 one_shot_stills; /* Continuous or one shot stills captures. */ + + u32 max_preview_video_w; /* Max size of the preview or video + * capture frames + */ + u32 max_preview_video_h; + u32 num_preview_video_frames; + + /** Sets the height of the circular buffer for stills capture. */ + u32 stills_capture_circular_buffer_height; + + /** Allows preview/encode to resume as fast as possible after the stills + * input frame has been received, and then processes the still frame in + * the background whilst preview/encode has resumed. + * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. + */ + u32 fast_preview_resume; + + /** Selects algorithm for timestamping frames if + * there is no clock component connected. + * enum mmal_parameter_camera_config_timestamp_mode + */ + s32 use_stc_timestamp; +}; + + +enum mmal_parameter_exposuremode { + MMAL_PARAM_EXPOSUREMODE_OFF, + MMAL_PARAM_EXPOSUREMODE_AUTO, + MMAL_PARAM_EXPOSUREMODE_NIGHT, + MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, + MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, + MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, + MMAL_PARAM_EXPOSUREMODE_SPORTS, + MMAL_PARAM_EXPOSUREMODE_SNOW, + MMAL_PARAM_EXPOSUREMODE_BEACH, + MMAL_PARAM_EXPOSUREMODE_VERYLONG, + MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, + MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, + MMAL_PARAM_EXPOSUREMODE_FIREWORKS, +}; + +enum mmal_parameter_exposuremeteringmode { + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, + MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, + MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, + MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, +}; + +enum mmal_parameter_awbmode { + MMAL_PARAM_AWBMODE_OFF, + MMAL_PARAM_AWBMODE_AUTO, + MMAL_PARAM_AWBMODE_SUNLIGHT, + MMAL_PARAM_AWBMODE_CLOUDY, + MMAL_PARAM_AWBMODE_SHADE, + MMAL_PARAM_AWBMODE_TUNGSTEN, + MMAL_PARAM_AWBMODE_FLUORESCENT, + MMAL_PARAM_AWBMODE_INCANDESCENT, + MMAL_PARAM_AWBMODE_FLASH, + MMAL_PARAM_AWBMODE_HORIZON, +}; + +enum mmal_parameter_imagefx { + MMAL_PARAM_IMAGEFX_NONE, + MMAL_PARAM_IMAGEFX_NEGATIVE, + MMAL_PARAM_IMAGEFX_SOLARIZE, + MMAL_PARAM_IMAGEFX_POSTERIZE, + MMAL_PARAM_IMAGEFX_WHITEBOARD, + MMAL_PARAM_IMAGEFX_BLACKBOARD, + MMAL_PARAM_IMAGEFX_SKETCH, + MMAL_PARAM_IMAGEFX_DENOISE, + MMAL_PARAM_IMAGEFX_EMBOSS, + MMAL_PARAM_IMAGEFX_OILPAINT, + MMAL_PARAM_IMAGEFX_HATCH, + MMAL_PARAM_IMAGEFX_GPEN, + MMAL_PARAM_IMAGEFX_PASTEL, + MMAL_PARAM_IMAGEFX_WATERCOLOUR, + MMAL_PARAM_IMAGEFX_FILM, + MMAL_PARAM_IMAGEFX_BLUR, + MMAL_PARAM_IMAGEFX_SATURATION, + MMAL_PARAM_IMAGEFX_COLOURSWAP, + MMAL_PARAM_IMAGEFX_WASHEDOUT, + MMAL_PARAM_IMAGEFX_POSTERISE, + MMAL_PARAM_IMAGEFX_COLOURPOINT, + MMAL_PARAM_IMAGEFX_COLOURBALANCE, + MMAL_PARAM_IMAGEFX_CARTOON, +}; + +enum MMAL_PARAM_FLICKERAVOID_T { + MMAL_PARAM_FLICKERAVOID_OFF, + MMAL_PARAM_FLICKERAVOID_AUTO, + MMAL_PARAM_FLICKERAVOID_50HZ, + MMAL_PARAM_FLICKERAVOID_60HZ, + MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF +}; + +struct mmal_parameter_awbgains { + struct mmal_parameter_rational r_gain; /**< Red gain */ + struct mmal_parameter_rational b_gain; /**< Blue gain */ +}; + +/** Manner of video rate control */ +enum mmal_parameter_rate_control_mode { + MMAL_VIDEO_RATECONTROL_DEFAULT, + MMAL_VIDEO_RATECONTROL_VARIABLE, + MMAL_VIDEO_RATECONTROL_CONSTANT, + MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, + MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES +}; + +enum mmal_video_profile { + MMAL_VIDEO_PROFILE_H263_BASELINE, + MMAL_VIDEO_PROFILE_H263_H320CODING, + MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, + MMAL_VIDEO_PROFILE_H263_ISWV2, + MMAL_VIDEO_PROFILE_H263_ISWV3, + MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, + MMAL_VIDEO_PROFILE_H263_INTERNET, + MMAL_VIDEO_PROFILE_H263_INTERLACE, + MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, + MMAL_VIDEO_PROFILE_MP4V_SIMPLE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, + MMAL_VIDEO_PROFILE_MP4V_CORE, + MMAL_VIDEO_PROFILE_MP4V_MAIN, + MMAL_VIDEO_PROFILE_MP4V_NBIT, + MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, + MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, + MMAL_VIDEO_PROFILE_MP4V_HYBRID, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, + MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, + MMAL_VIDEO_PROFILE_H264_BASELINE, + MMAL_VIDEO_PROFILE_H264_MAIN, + MMAL_VIDEO_PROFILE_H264_EXTENDED, + MMAL_VIDEO_PROFILE_H264_HIGH, + MMAL_VIDEO_PROFILE_H264_HIGH10, + MMAL_VIDEO_PROFILE_H264_HIGH422, + MMAL_VIDEO_PROFILE_H264_HIGH444, + MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, + MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF +}; + +enum mmal_video_level { + MMAL_VIDEO_LEVEL_H263_10, + MMAL_VIDEO_LEVEL_H263_20, + MMAL_VIDEO_LEVEL_H263_30, + MMAL_VIDEO_LEVEL_H263_40, + MMAL_VIDEO_LEVEL_H263_45, + MMAL_VIDEO_LEVEL_H263_50, + MMAL_VIDEO_LEVEL_H263_60, + MMAL_VIDEO_LEVEL_H263_70, + MMAL_VIDEO_LEVEL_MP4V_0, + MMAL_VIDEO_LEVEL_MP4V_0b, + MMAL_VIDEO_LEVEL_MP4V_1, + MMAL_VIDEO_LEVEL_MP4V_2, + MMAL_VIDEO_LEVEL_MP4V_3, + MMAL_VIDEO_LEVEL_MP4V_4, + MMAL_VIDEO_LEVEL_MP4V_4a, + MMAL_VIDEO_LEVEL_MP4V_5, + MMAL_VIDEO_LEVEL_MP4V_6, + MMAL_VIDEO_LEVEL_H264_1, + MMAL_VIDEO_LEVEL_H264_1b, + MMAL_VIDEO_LEVEL_H264_11, + MMAL_VIDEO_LEVEL_H264_12, + MMAL_VIDEO_LEVEL_H264_13, + MMAL_VIDEO_LEVEL_H264_2, + MMAL_VIDEO_LEVEL_H264_21, + MMAL_VIDEO_LEVEL_H264_22, + MMAL_VIDEO_LEVEL_H264_3, + MMAL_VIDEO_LEVEL_H264_31, + MMAL_VIDEO_LEVEL_H264_32, + MMAL_VIDEO_LEVEL_H264_4, + MMAL_VIDEO_LEVEL_H264_41, + MMAL_VIDEO_LEVEL_H264_42, + MMAL_VIDEO_LEVEL_H264_5, + MMAL_VIDEO_LEVEL_H264_51, + MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF +}; + +struct mmal_parameter_video_profile { + enum mmal_video_profile profile; + enum mmal_video_level level; +}; + +/* video parameters */ + +enum mmal_parameter_video_type { + /** @ref MMAL_DISPLAYREGION_T */ + MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, + + /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ + MMAL_PARAMETER_SUPPORTED_PROFILES, + + /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ + MMAL_PARAMETER_PROFILE, + + /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_INTRAPERIOD, + + /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ + MMAL_PARAMETER_RATECONTROL, + + /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ + MMAL_PARAMETER_NALUNITFORMAT, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_MINIMISE_FRAGMENTATION, + + /** @ref MMAL_PARAMETER_UINT32_T. + * Setting the value to zero resets to the default (one slice per frame). + */ + MMAL_PARAMETER_MB_ROWS_PER_SLICE, + + /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ + MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, + + /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ + MMAL_PARAMETER_VIDEO_EEDE_ENABLE, + + /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ + MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, + + /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ + MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, + /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ + MMAL_PARAMETER_VIDEO_INTRA_REFRESH, + + /** @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, + + /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ + MMAL_PARAMETER_VIDEO_BIT_RATE, + + /** @ref MMAL_PARAMETER_FRAME_RATE_T */ + MMAL_PARAMETER_VIDEO_FRAME_RATE, + + /** @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, + + /** @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, + + /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, + + MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ + /** @ref MMAL_PARAMETER_UINT32_T. + * Changing this parameter from the default can reduce frame rate + * because image buffers need to be re-pitched. + */ + MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, + + /** @ref MMAL_PARAMETER_UINT32_T. + * Changing this parameter from the default can reduce frame rate + * because image buffers need to be re-pitched. + */ + MMAL_PARAMETER_VIDEO_ALIGN_VERT, + + /** @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, + + /** @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, + + /**< @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_QP_P, + + /**< @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, + + /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, + + /** @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, + + /* H264 specific parameters */ + + /** @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, + + /** @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, + + /** @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, + + /** @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, + + /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, + + /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ + MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, + + /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, + + /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ + MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, + + /** @ref MMAL_PARAMETER_BYTES_T */ + MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, + + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, + + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, + + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER +}; + +/** Valid mirror modes */ +enum mmal_parameter_mirror { + MMAL_PARAM_MIRROR_NONE, + MMAL_PARAM_MIRROR_VERTICAL, + MMAL_PARAM_MIRROR_HORIZONTAL, + MMAL_PARAM_MIRROR_BOTH, +}; + +enum mmal_parameter_displaytransform { + MMAL_DISPLAY_ROT0 = 0, + MMAL_DISPLAY_MIRROR_ROT0 = 1, + MMAL_DISPLAY_MIRROR_ROT180 = 2, + MMAL_DISPLAY_ROT180 = 3, + MMAL_DISPLAY_MIRROR_ROT90 = 4, + MMAL_DISPLAY_ROT270 = 5, + MMAL_DISPLAY_ROT90 = 6, + MMAL_DISPLAY_MIRROR_ROT270 = 7, +}; + +enum mmal_parameter_displaymode { + MMAL_DISPLAY_MODE_FILL = 0, + MMAL_DISPLAY_MODE_LETTERBOX = 1, +}; + +enum mmal_parameter_displayset { + MMAL_DISPLAY_SET_NONE = 0, + MMAL_DISPLAY_SET_NUM = 1, + MMAL_DISPLAY_SET_FULLSCREEN = 2, + MMAL_DISPLAY_SET_TRANSFORM = 4, + MMAL_DISPLAY_SET_DEST_RECT = 8, + MMAL_DISPLAY_SET_SRC_RECT = 0x10, + MMAL_DISPLAY_SET_MODE = 0x20, + MMAL_DISPLAY_SET_PIXEL = 0x40, + MMAL_DISPLAY_SET_NOASPECT = 0x80, + MMAL_DISPLAY_SET_LAYER = 0x100, + MMAL_DISPLAY_SET_COPYPROTECT = 0x200, + MMAL_DISPLAY_SET_ALPHA = 0x400, +}; + +struct mmal_parameter_displayregion { + /** Bitfield that indicates which fields are set and should be + * used. All other fields will maintain their current value. + * \ref MMAL_DISPLAYSET_T defines the bits that can be + * combined. + */ + u32 set; + + /** Describes the display output device, with 0 typically + * being a directly connected LCD display. The actual values + * will depend on the hardware. Code using hard-wired numbers + * (e.g. 2) is certain to fail. + */ + + u32 display_num; + /** Indicates that we are using the full device screen area, + * rather than a window of the display. If zero, then + * dest_rect is used to specify a region of the display to + * use. + */ + + s32 fullscreen; + /** Indicates any rotation or flipping used to map frames onto + * the natural display orientation. + */ + u32 transform; /* enum mmal_parameter_displaytransform */ + + /** Where to display the frame within the screen, if + * fullscreen is zero. + */ + struct vchiq_mmal_rect dest_rect; + + /** Indicates which area of the frame to display. If all + * values are zero, the whole frame will be used. + */ + struct vchiq_mmal_rect src_rect; + + /** If set to non-zero, indicates that any display scaling + * should disregard the aspect ratio of the frame region being + * displayed. + */ + s32 noaspect; + + /** Indicates how the image should be scaled to fit the + * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates + * that the image should fill the screen by potentially + * cropping the frames. Setting \code mode \endcode to \code + * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the + * source region should be displayed and black bars added if + * necessary. + */ + u32 mode; /* enum mmal_parameter_displaymode */ + + /** If non-zero, defines the width of a source pixel relative + * to \code pixel_y \endcode. If zero, then pixels default to + * being square. + */ + u32 pixel_x; + + /** If non-zero, defines the height of a source pixel relative + * to \code pixel_x \endcode. If zero, then pixels default to + * being square. + */ + u32 pixel_y; + + /** Sets the relative depth of the images, with greater values + * being in front of smaller values. + */ + u32 layer; + + /** Set to non-zero to ensure copy protection is used on + * output. + */ + s32 copyprotect_required; + + /** Level of opacity of the layer, where zero is fully + * transparent and 255 is fully opaque. + */ + u32 alpha; +}; + +#define MMAL_MAX_IMAGEFX_PARAMETERS 5 + +struct mmal_parameter_imagefx_parameters { + enum mmal_parameter_imagefx effect; + u32 num_effect_params; + u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; +}; + +#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 +#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 +#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 + +struct mmal_parameter_camera_info_camera_t { + u32 port_id; + u32 max_width; + u32 max_height; + u32 lens_present; + u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; +}; + +enum mmal_parameter_camera_info_flash_type_t { + /* Make values explicit to ensure they match values in config ini */ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF +}; + +struct mmal_parameter_camera_info_flash_t { + enum mmal_parameter_camera_info_flash_type_t flash_type; +}; + +struct mmal_parameter_camera_info_t { + u32 num_cameras; + u32 num_flashes; + struct mmal_parameter_camera_info_camera_t + cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; + struct mmal_parameter_camera_info_flash_t + flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; +}; diff --git a/drivers/staging/media/platform/bcm2835/mmal-vchiq.c b/drivers/staging/media/platform/bcm2835/mmal-vchiq.c new file mode 100644 index 000000000000..f0639ee6c8b9 --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-vchiq.c @@ -0,0 +1,1913 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + * + * V4L2 driver MMAL vchiq interface code + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/mutex.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/completion.h> +#include <linux/vmalloc.h> +#include <asm/cacheflush.h> +#include <media/videobuf2-vmalloc.h> + +#include "mmal-common.h" +#include "mmal-vchiq.h" +#include "mmal-msg.h" + +#define USE_VCHIQ_ARM +#include "interface/vchi/vchi.h" + +/* maximum number of components supported */ +#define VCHIQ_MMAL_MAX_COMPONENTS 4 + +/*#define FULL_MSG_DUMP 1*/ + +#ifdef DEBUG +static const char *const msg_type_names[] = { + "UNKNOWN", + "QUIT", + "SERVICE_CLOSED", + "GET_VERSION", + "COMPONENT_CREATE", + "COMPONENT_DESTROY", + "COMPONENT_ENABLE", + "COMPONENT_DISABLE", + "PORT_INFO_GET", + "PORT_INFO_SET", + "PORT_ACTION", + "BUFFER_FROM_HOST", + "BUFFER_TO_HOST", + "GET_STATS", + "PORT_PARAMETER_SET", + "PORT_PARAMETER_GET", + "EVENT_TO_HOST", + "GET_CORE_STATS_FOR_PORT", + "OPAQUE_ALLOCATOR", + "CONSUME_MEM", + "LMK", + "OPAQUE_ALLOCATOR_DESC", + "DRM_GET_LHS32", + "DRM_GET_TIME", + "BUFFER_FROM_HOST_ZEROLEN", + "PORT_FLUSH", + "HOST_LOG", +}; +#endif + +static const char *const port_action_type_names[] = { + "UNKNOWN", + "ENABLE", + "DISABLE", + "FLUSH", + "CONNECT", + "DISCONNECT", + "SET_REQUIREMENTS", +}; + +#if defined(DEBUG) +#if defined(FULL_MSG_DUMP) +#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ + do { \ + pr_debug(TITLE" type:%s(%d) length:%d\n", \ + msg_type_names[(MSG)->h.type], \ + (MSG)->h.type, (MSG_LEN)); \ + print_hex_dump(KERN_DEBUG, "<<h: ", DUMP_PREFIX_OFFSET, \ + 16, 4, (MSG), \ + sizeof(struct mmal_msg_header), 1); \ + print_hex_dump(KERN_DEBUG, "<<p: ", DUMP_PREFIX_OFFSET, \ + 16, 4, \ + ((u8 *)(MSG)) + sizeof(struct mmal_msg_header),\ + (MSG_LEN) - sizeof(struct mmal_msg_header), 1); \ + } while (0) +#else +#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ + { \ + pr_debug(TITLE" type:%s(%d) length:%d\n", \ + msg_type_names[(MSG)->h.type], \ + (MSG)->h.type, (MSG_LEN)); \ + } +#endif +#else +#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) +#endif + +/* normal message context */ +struct mmal_msg_context { + union { + struct { + /* work struct for defered callback - must come first */ + struct work_struct work; + /* mmal instance */ + struct vchiq_mmal_instance *instance; + /* mmal port */ + struct vchiq_mmal_port *port; + /* actual buffer used to store bulk reply */ + struct mmal_buffer *buffer; + /* amount of buffer used */ + unsigned long buffer_used; + /* MMAL buffer flags */ + u32 mmal_flags; + /* Presentation and Decode timestamps */ + s64 pts; + s64 dts; + + int status; /* context status */ + + } bulk; /* bulk data */ + + struct { + /* message handle to release */ + VCHI_HELD_MSG_T msg_handle; + /* pointer to received message */ + struct mmal_msg *msg; + /* received message length */ + u32 msg_len; + /* completion upon reply */ + struct completion cmplt; + } sync; /* synchronous response */ + } u; + +}; + +struct vchiq_mmal_instance { + VCHI_SERVICE_HANDLE_T handle; + + /* ensure serialised access to service */ + struct mutex vchiq_mutex; + + /* ensure serialised access to bulk operations */ + struct mutex bulk_mutex; + + /* vmalloc page to receive scratch bulk xfers into */ + void *bulk_scratch; + + /* component to use next */ + int component_idx; + struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS]; +}; + +static struct mmal_msg_context *get_msg_context(struct vchiq_mmal_instance + *instance) +{ + struct mmal_msg_context *msg_context; + + /* todo: should this be allocated from a pool to avoid kmalloc */ + msg_context = kmalloc(sizeof(*msg_context), GFP_KERNEL); + memset(msg_context, 0, sizeof(*msg_context)); + + return msg_context; +} + +static void release_msg_context(struct mmal_msg_context *msg_context) +{ + kfree(msg_context); +} + +/* deals with receipt of event to host message */ +static void event_to_host_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, u32 msg_len) +{ + pr_debug("unhandled event\n"); + pr_debug("component:%p port type:%d num:%d cmd:0x%x length:%d\n", + msg->u.event_to_host.client_component, + msg->u.event_to_host.port_type, + msg->u.event_to_host.port_num, + msg->u.event_to_host.cmd, msg->u.event_to_host.length); +} + +/* workqueue scheduled callback + * + * we do this because it is important we do not call any other vchiq + * sync calls from witin the message delivery thread + */ +static void buffer_work_cb(struct work_struct *work) +{ + struct mmal_msg_context *msg_context = (struct mmal_msg_context *)work; + + msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, + msg_context->u.bulk.port, + msg_context->u.bulk.status, + msg_context->u.bulk.buffer, + msg_context->u.bulk.buffer_used, + msg_context->u.bulk.mmal_flags, + msg_context->u.bulk.dts, + msg_context->u.bulk.pts); + + /* release message context */ + release_msg_context(msg_context); +} + +/* enqueue a bulk receive for a given message context */ +static int bulk_receive(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, + struct mmal_msg_context *msg_context) +{ + unsigned long rd_len; + unsigned long flags = 0; + int ret; + + /* bulk mutex stops other bulk operations while we have a + * receive in progress - released in callback + */ + ret = mutex_lock_interruptible(&instance->bulk_mutex); + if (ret != 0) + return ret; + + rd_len = msg->u.buffer_from_host.buffer_header.length; + + /* take buffer from queue */ + spin_lock_irqsave(&msg_context->u.bulk.port->slock, flags); + if (list_empty(&msg_context->u.bulk.port->buffers)) { + spin_unlock_irqrestore(&msg_context->u.bulk.port->slock, flags); + pr_err("buffer list empty trying to submit bulk receive\n"); + + /* todo: this is a serious error, we should never have + * committed a buffer_to_host operation to the mmal + * port without the buffer to back it up (underflow + * handling) and there is no obvious way to deal with + * this - how is the mmal servie going to react when + * we fail to do the xfer and reschedule a buffer when + * it arrives? perhaps a starved flag to indicate a + * waiting bulk receive? + */ + + mutex_unlock(&instance->bulk_mutex); + + return -EINVAL; + } + + msg_context->u.bulk.buffer = + list_entry(msg_context->u.bulk.port->buffers.next, + struct mmal_buffer, list); + list_del(&msg_context->u.bulk.buffer->list); + + spin_unlock_irqrestore(&msg_context->u.bulk.port->slock, flags); + + /* ensure we do not overrun the available buffer */ + if (rd_len > msg_context->u.bulk.buffer->buffer_size) { + rd_len = msg_context->u.bulk.buffer->buffer_size; + pr_warn("short read as not enough receive buffer space\n"); + /* todo: is this the correct response, what happens to + * the rest of the message data? + */ + } + + /* store length */ + msg_context->u.bulk.buffer_used = rd_len; + msg_context->u.bulk.mmal_flags = + msg->u.buffer_from_host.buffer_header.flags; + msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; + msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; + + // only need to flush L1 cache here, as VCHIQ takes care of the L2 + // cache. + __cpuc_flush_dcache_area(msg_context->u.bulk.buffer->buffer, rd_len); + + /* queue the bulk submission */ + vchi_service_use(instance->handle); + ret = vchi_bulk_queue_receive(instance->handle, + msg_context->u.bulk.buffer->buffer, + /* Actual receive needs to be a multiple + * of 4 bytes + */ + (rd_len + 3) & ~3, + VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | + VCHI_FLAGS_BLOCK_UNTIL_QUEUED, + msg_context); + + vchi_service_release(instance->handle); + + if (ret != 0) { + /* callback will not be clearing the mutex */ + mutex_unlock(&instance->bulk_mutex); + } + + return ret; +} + +/* enque a dummy bulk receive for a given message context */ +static int dummy_bulk_receive(struct vchiq_mmal_instance *instance, + struct mmal_msg_context *msg_context) +{ + int ret; + + /* bulk mutex stops other bulk operations while we have a + * receive in progress - released in callback + */ + ret = mutex_lock_interruptible(&instance->bulk_mutex); + if (ret != 0) + return ret; + + /* zero length indicates this was a dummy transfer */ + msg_context->u.bulk.buffer_used = 0; + + /* queue the bulk submission */ + vchi_service_use(instance->handle); + + ret = vchi_bulk_queue_receive(instance->handle, + instance->bulk_scratch, + 8, + VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | + VCHI_FLAGS_BLOCK_UNTIL_QUEUED, + msg_context); + + vchi_service_release(instance->handle); + + if (ret != 0) { + /* callback will not be clearing the mutex */ + mutex_unlock(&instance->bulk_mutex); + } + + return ret; +} + +/* data in message, memcpy from packet into output buffer */ +static int inline_receive(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, + struct mmal_msg_context *msg_context) +{ + unsigned long flags = 0; + + /* take buffer from queue */ + spin_lock_irqsave(&msg_context->u.bulk.port->slock, flags); + if (list_empty(&msg_context->u.bulk.port->buffers)) { + spin_unlock_irqrestore(&msg_context->u.bulk.port->slock, flags); + pr_err("buffer list empty trying to receive inline\n"); + + /* todo: this is a serious error, we should never have + * committed a buffer_to_host operation to the mmal + * port without the buffer to back it up (with + * underflow handling) and there is no obvious way to + * deal with this. Less bad than the bulk case as we + * can just drop this on the floor but...unhelpful + */ + return -EINVAL; + } + + msg_context->u.bulk.buffer = + list_entry(msg_context->u.bulk.port->buffers.next, + struct mmal_buffer, list); + list_del(&msg_context->u.bulk.buffer->list); + + spin_unlock_irqrestore(&msg_context->u.bulk.port->slock, flags); + + memcpy(msg_context->u.bulk.buffer->buffer, + msg->u.buffer_from_host.short_data, + msg->u.buffer_from_host.payload_in_message); + + msg_context->u.bulk.buffer_used = + msg->u.buffer_from_host.payload_in_message; + + return 0; +} + +/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */ +static int +buffer_from_host(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, struct mmal_buffer *buf) +{ + struct mmal_msg_context *msg_context; + struct mmal_msg m; + int ret; + + pr_debug("instance:%p buffer:%p\n", instance->handle, buf); + + /* bulk mutex stops other bulk operations while we + * have a receive in progress + */ + if (mutex_lock_interruptible(&instance->bulk_mutex)) + return -EINTR; + + /* get context */ + msg_context = get_msg_context(instance); + if (msg_context == NULL) + return -ENOMEM; + + /* store bulk message context for when data arrives */ + msg_context->u.bulk.instance = instance; + msg_context->u.bulk.port = port; + msg_context->u.bulk.buffer = NULL; /* not valid until bulk xfer */ + msg_context->u.bulk.buffer_used = 0; + + /* initialise work structure ready to schedule callback */ + INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); + + /* prep the buffer from host message */ + memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ + + m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST; + m.h.magic = MMAL_MAGIC; + m.h.context = msg_context; + m.h.status = 0; + + /* drvbuf is our private data passed back */ + m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC; + m.u.buffer_from_host.drvbuf.component_handle = port->component->handle; + m.u.buffer_from_host.drvbuf.port_handle = port->handle; + m.u.buffer_from_host.drvbuf.client_context = msg_context; + + /* buffer header */ + m.u.buffer_from_host.buffer_header.cmd = 0; + m.u.buffer_from_host.buffer_header.data = buf->buffer; + m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; + m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ + m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ + m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ + m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; + m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; + + /* clear buffer type sepecific data */ + memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, + sizeof(m.u.buffer_from_host.buffer_header_type_specific)); + + /* no payload in message */ + m.u.buffer_from_host.payload_in_message = 0; + + vchi_service_use(instance->handle); + + ret = vchi_queue_kernel_message(instance->handle, + &m, + sizeof(struct mmal_msg_header) + + sizeof(m.u.buffer_from_host)); + + if (ret != 0) { + release_msg_context(msg_context); + /* todo: is this correct error value? */ + } + + vchi_service_release(instance->handle); + + mutex_unlock(&instance->bulk_mutex); + + return ret; +} + +/* submit a buffer to the mmal sevice + * + * the buffer_from_host uses size data from the ports next available + * mmal_buffer and deals with there being no buffer available by + * incrementing the underflow for later + */ +static int port_buffer_from_host(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + struct mmal_buffer *buf; + unsigned long flags = 0; + + if (!port->enabled) + return -EINVAL; + + /* peek buffer from queue */ + spin_lock_irqsave(&port->slock, flags); + if (list_empty(&port->buffers)) { + port->buffer_underflow++; + spin_unlock_irqrestore(&port->slock, flags); + return -ENOSPC; + } + + buf = list_entry(port->buffers.next, struct mmal_buffer, list); + + spin_unlock_irqrestore(&port->slock, flags); + + /* issue buffer to mmal service */ + ret = buffer_from_host(instance, port, buf); + if (ret) { + pr_err("adding buffer header failed\n"); + /* todo: how should this be dealt with */ + } + + return ret; +} + +/* deals with receipt of buffer to host message */ +static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, u32 msg_len) +{ + struct mmal_msg_context *msg_context; + + pr_debug("buffer_to_host_cb: instance:%p msg:%p msg_len:%d\n", + instance, msg, msg_len); + + if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { + msg_context = msg->u.buffer_from_host.drvbuf.client_context; + } else { + pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n"); + return; + } + + if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { + /* message reception had an error */ + pr_warn("error %d in reply\n", msg->h.status); + + msg_context->u.bulk.status = msg->h.status; + + } else if (msg->u.buffer_from_host.buffer_header.length == 0) { + /* empty buffer */ + if (msg->u.buffer_from_host.buffer_header.flags & + MMAL_BUFFER_HEADER_FLAG_EOS) { + msg_context->u.bulk.status = + dummy_bulk_receive(instance, msg_context); + if (msg_context->u.bulk.status == 0) + return; /* successful bulk submission, bulk + * completion will trigger callback + */ + } else { + /* do callback with empty buffer - not EOS though */ + msg_context->u.bulk.status = 0; + msg_context->u.bulk.buffer_used = 0; + } + } else if (msg->u.buffer_from_host.payload_in_message == 0) { + /* data is not in message, queue a bulk receive */ + msg_context->u.bulk.status = + bulk_receive(instance, msg, msg_context); + if (msg_context->u.bulk.status == 0) + return; /* successful bulk submission, bulk + * completion will trigger callback + */ + + /* failed to submit buffer, this will end badly */ + pr_err("error %d on bulk submission\n", + msg_context->u.bulk.status); + + } else if (msg->u.buffer_from_host.payload_in_message <= + MMAL_VC_SHORT_DATA) { + /* data payload within message */ + msg_context->u.bulk.status = inline_receive(instance, msg, + msg_context); + } else { + pr_err("message with invalid short payload\n"); + + /* signal error */ + msg_context->u.bulk.status = -EINVAL; + msg_context->u.bulk.buffer_used = + msg->u.buffer_from_host.payload_in_message; + } + + /* replace the buffer header */ + port_buffer_from_host(instance, msg_context->u.bulk.port); + + /* schedule the port callback */ + schedule_work(&msg_context->u.bulk.work); +} + +static void bulk_receive_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg_context *msg_context) +{ + /* bulk receive operation complete */ + mutex_unlock(&msg_context->u.bulk.instance->bulk_mutex); + + /* replace the buffer header */ + port_buffer_from_host(msg_context->u.bulk.instance, + msg_context->u.bulk.port); + + msg_context->u.bulk.status = 0; + + /* schedule the port callback */ + schedule_work(&msg_context->u.bulk.work); +} + +static void bulk_abort_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg_context *msg_context) +{ + pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context); + + /* bulk receive operation complete */ + mutex_unlock(&msg_context->u.bulk.instance->bulk_mutex); + + /* replace the buffer header */ + port_buffer_from_host(msg_context->u.bulk.instance, + msg_context->u.bulk.port); + + msg_context->u.bulk.status = -EINTR; + + schedule_work(&msg_context->u.bulk.work); +} + +/* incoming event service callback */ +static void service_callback(void *param, + const VCHI_CALLBACK_REASON_T reason, + void *bulk_ctx) +{ + struct vchiq_mmal_instance *instance = param; + int status; + u32 msg_len; + struct mmal_msg *msg; + VCHI_HELD_MSG_T msg_handle; + + if (!instance) { + pr_err("Message callback passed NULL instance\n"); + return; + } + + switch (reason) { + case VCHI_CALLBACK_MSG_AVAILABLE: + status = vchi_msg_hold(instance->handle, (void **)&msg, + &msg_len, VCHI_FLAGS_NONE, &msg_handle); + if (status) { + pr_err("Unable to dequeue a message (%d)\n", status); + break; + } + + DBG_DUMP_MSG(msg, msg_len, "<<< reply message"); + + /* handling is different for buffer messages */ + switch (msg->h.type) { + case MMAL_MSG_TYPE_BUFFER_FROM_HOST: + vchi_held_msg_release(&msg_handle); + break; + + case MMAL_MSG_TYPE_EVENT_TO_HOST: + event_to_host_cb(instance, msg, msg_len); + vchi_held_msg_release(&msg_handle); + + break; + + case MMAL_MSG_TYPE_BUFFER_TO_HOST: + buffer_to_host_cb(instance, msg, msg_len); + vchi_held_msg_release(&msg_handle); + break; + + default: + /* messages dependent on header context to complete */ + + /* todo: the msg.context really ought to be sanity + * checked before we just use it, afaict it comes back + * and is used raw from the videocore. Perhaps it + * should be verified the address lies in the kernel + * address space. + */ + if (msg->h.context == NULL) { + pr_err("received message context was null!\n"); + vchi_held_msg_release(&msg_handle); + break; + } + + /* fill in context values */ + msg->h.context->u.sync.msg_handle = msg_handle; + msg->h.context->u.sync.msg = msg; + msg->h.context->u.sync.msg_len = msg_len; + + /* todo: should this check (completion_done() + * == 1) for no one waiting? or do we need a + * flag to tell us the completion has been + * interrupted so we can free the message and + * its context. This probably also solves the + * message arriving after interruption todo + * below + */ + + /* complete message so caller knows it happened */ + complete(&msg->h.context->u.sync.cmplt); + break; + } + + break; + + case VCHI_CALLBACK_BULK_RECEIVED: + bulk_receive_cb(instance, bulk_ctx); + break; + + case VCHI_CALLBACK_BULK_RECEIVE_ABORTED: + bulk_abort_cb(instance, bulk_ctx); + break; + + case VCHI_CALLBACK_SERVICE_CLOSED: + /* TODO: consider if this requires action if received when + * driver is not explicitly closing the service + */ + break; + + default: + pr_err("Received unhandled message reason %d\n", reason); + break; + } +} + +static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, + unsigned int payload_len, + struct mmal_msg **msg_out, + VCHI_HELD_MSG_T *msg_handle_out) +{ + struct mmal_msg_context msg_context; + int ret; + + /* payload size must not cause message to exceed max size */ + if (payload_len > + (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) { + pr_err("payload length %d exceeds max:%d\n", payload_len, + (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))); + return -EINVAL; + } + + init_completion(&msg_context.u.sync.cmplt); + + msg->h.magic = MMAL_MAGIC; + msg->h.context = &msg_context; + msg->h.status = 0; + + DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len), + ">>> sync message"); + + vchi_service_use(instance->handle); + + ret = vchi_queue_kernel_message(instance->handle, + msg, + sizeof(struct mmal_msg_header) + + payload_len); + + vchi_service_release(instance->handle); + + if (ret) { + pr_err("error %d queuing message\n", ret); + return ret; + } + + ret = wait_for_completion_timeout(&msg_context.u.sync.cmplt, 3 * HZ); + if (ret <= 0) { + pr_err("error %d waiting for sync completion\n", ret); + if (ret == 0) + ret = -ETIME; + /* todo: what happens if the message arrives after aborting */ + return ret; + } + + *msg_out = msg_context.u.sync.msg; + *msg_handle_out = msg_context.u.sync.msg_handle; + + return 0; +} + +static void dump_port_info(struct vchiq_mmal_port *port) +{ + pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); + + pr_debug("buffer minimum num:%d size:%d align:%d\n", + port->minimum_buffer.num, + port->minimum_buffer.size, port->minimum_buffer.alignment); + + pr_debug("buffer recommended num:%d size:%d align:%d\n", + port->recommended_buffer.num, + port->recommended_buffer.size, + port->recommended_buffer.alignment); + + pr_debug("buffer current values num:%d size:%d align:%d\n", + port->current_buffer.num, + port->current_buffer.size, port->current_buffer.alignment); + + pr_debug("elementry stream: type:%d encoding:0x%x variant:0x%x\n", + port->format.type, + port->format.encoding, port->format.encoding_variant); + + pr_debug(" bitrate:%d flags:0x%x\n", + port->format.bitrate, port->format.flags); + + if (port->format.type == MMAL_ES_TYPE_VIDEO) { + pr_debug + ("es video format: width:%d height:%d colourspace:0x%x\n", + port->es.video.width, port->es.video.height, + port->es.video.color_space); + + pr_debug(" : crop xywh %d,%d,%d,%d\n", + port->es.video.crop.x, + port->es.video.crop.y, + port->es.video.crop.width, port->es.video.crop.height); + pr_debug(" : framerate %d/%d aspect %d/%d\n", + port->es.video.frame_rate.num, + port->es.video.frame_rate.den, + port->es.video.par.num, port->es.video.par.den); + } +} + +static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p) +{ + /* todo do readonly fields need setting at all? */ + p->type = port->type; + p->index = port->index; + p->index_all = 0; + p->is_enabled = port->enabled; + p->buffer_num_min = port->minimum_buffer.num; + p->buffer_size_min = port->minimum_buffer.size; + p->buffer_alignment_min = port->minimum_buffer.alignment; + p->buffer_num_recommended = port->recommended_buffer.num; + p->buffer_size_recommended = port->recommended_buffer.size; + + /* only three writable fields in a port */ + p->buffer_num = port->current_buffer.num; + p->buffer_size = port->current_buffer.size; + p->userdata = port; +} + +static int port_info_set(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + pr_debug("setting port info port %p\n", port); + if (!port) + return -1; + dump_port_info(port); + + m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET; + + m.u.port_info_set.component_handle = port->component->handle; + m.u.port_info_set.port_type = port->type; + m.u.port_info_set.port_index = port->index; + + port_to_mmal_msg(port, &m.u.port_info_set.port); + + /* elementry stream format setup */ + m.u.port_info_set.format.type = port->format.type; + m.u.port_info_set.format.encoding = port->format.encoding; + m.u.port_info_set.format.encoding_variant = + port->format.encoding_variant; + m.u.port_info_set.format.bitrate = port->format.bitrate; + m.u.port_info_set.format.flags = port->format.flags; + + memcpy(&m.u.port_info_set.es, &port->es, + sizeof(union mmal_es_specific_format)); + + m.u.port_info_set.format.extradata_size = port->format.extradata_size; + memcpy(&m.u.port_info_set.extradata, port->format.extradata, + port->format.extradata_size); + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.port_info_set), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + /* return operation status */ + ret = -rmsg->u.port_info_get_reply.status; + + pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, + port->component->handle, port->handle); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* use port info get message to retrieve port information */ +static int port_info_get(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + /* port info time */ + m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET; + m.u.port_info_get.component_handle = port->component->handle; + m.u.port_info_get.port_type = port->type; + m.u.port_info_get.index = port->index; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.port_info_get), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + /* return operation status */ + ret = -rmsg->u.port_info_get_reply.status; + if (ret != MMAL_MSG_STATUS_SUCCESS) + goto release_msg; + + if (rmsg->u.port_info_get_reply.port.is_enabled == 0) + port->enabled = false; + else + port->enabled = true; + + /* copy the values out of the message */ + port->handle = rmsg->u.port_info_get_reply.port_handle; + + /* port type and index cached to use on port info set because + * it does not use a port handle + */ + port->type = rmsg->u.port_info_get_reply.port_type; + port->index = rmsg->u.port_info_get_reply.port_index; + + port->minimum_buffer.num = + rmsg->u.port_info_get_reply.port.buffer_num_min; + port->minimum_buffer.size = + rmsg->u.port_info_get_reply.port.buffer_size_min; + port->minimum_buffer.alignment = + rmsg->u.port_info_get_reply.port.buffer_alignment_min; + + port->recommended_buffer.alignment = + rmsg->u.port_info_get_reply.port.buffer_alignment_min; + port->recommended_buffer.num = + rmsg->u.port_info_get_reply.port.buffer_num_recommended; + + port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num; + port->current_buffer.size = + rmsg->u.port_info_get_reply.port.buffer_size; + + /* stream format */ + port->format.type = rmsg->u.port_info_get_reply.format.type; + port->format.encoding = rmsg->u.port_info_get_reply.format.encoding; + port->format.encoding_variant = + rmsg->u.port_info_get_reply.format.encoding_variant; + port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate; + port->format.flags = rmsg->u.port_info_get_reply.format.flags; + + /* elementry stream format */ + memcpy(&port->es, + &rmsg->u.port_info_get_reply.es, + sizeof(union mmal_es_specific_format)); + port->format.es = &port->es; + + port->format.extradata_size = + rmsg->u.port_info_get_reply.format.extradata_size; + memcpy(port->format.extradata, + rmsg->u.port_info_get_reply.extradata, + port->format.extradata_size); + + pr_debug("received port info\n"); + dump_port_info(port); + +release_msg: + + pr_debug("%s:result:%d component:0x%x port:%d\n", + __func__, ret, port->component->handle, port->handle); + + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* create comonent on vc */ +static int create_component(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component, + const char *name) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + /* build component create message */ + m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; + m.u.component_create.client_component = component; + strncpy(m.u.component_create.name, name, + sizeof(m.u.component_create.name)); + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.component_create), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != m.h.type) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.component_create_reply.status; + if (ret != MMAL_MSG_STATUS_SUCCESS) + goto release_msg; + + /* a valid component response received */ + component->handle = rmsg->u.component_create_reply.component_handle; + component->inputs = rmsg->u.component_create_reply.input_num; + component->outputs = rmsg->u.component_create_reply.output_num; + component->clocks = rmsg->u.component_create_reply.clock_num; + + pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", + component->handle, + component->inputs, component->outputs, component->clocks); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* destroys a component on vc */ +static int destroy_component(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY; + m.u.component_destroy.component_handle = component->handle; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.component_destroy), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != m.h.type) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.component_destroy_reply.status; + +release_msg: + + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* enable a component on vc */ +static int enable_component(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE; + m.u.component_enable.component_handle = component->handle; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.component_enable), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != m.h.type) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.component_enable_reply.status; + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* disable a component on vc */ +static int disable_component(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE; + m.u.component_disable.component_handle = component->handle; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.component_disable), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != m.h.type) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.component_disable_reply.status; + +release_msg: + + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* get version of mmal implementation */ +static int get_version(struct vchiq_mmal_instance *instance, + u32 *major_out, u32 *minor_out) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_GET_VERSION; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.version), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != m.h.type) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + *major_out = rmsg->u.version.major; + *minor_out = rmsg->u.version.minor; + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* do a port action with a port as a parameter */ +static int port_action_port(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + enum mmal_msg_port_action_type action_type) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_PORT_ACTION; + m.u.port_action_port.component_handle = port->component->handle; + m.u.port_action_port.port_handle = port->handle; + m.u.port_action_port.action = action_type; + + port_to_mmal_msg(port, &m.u.port_action_port.port); + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.port_action_port), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.port_action_reply.status; + + pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", + __func__, + ret, port->component->handle, port->handle, + port_action_type_names[action_type], action_type); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* do a port action with handles as parameters */ +static int port_action_handle(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + enum mmal_msg_port_action_type action_type, + u32 connect_component_handle, + u32 connect_port_handle) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_PORT_ACTION; + + m.u.port_action_handle.component_handle = port->component->handle; + m.u.port_action_handle.port_handle = port->handle; + m.u.port_action_handle.action = action_type; + + m.u.port_action_handle.connect_component_handle = + connect_component_handle; + m.u.port_action_handle.connect_port_handle = connect_port_handle; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(m.u.port_action_handle), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.port_action_reply.status; + + pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)" \ + " connect component:0x%x connect port:%d\n", + __func__, + ret, port->component->handle, port->handle, + port_action_type_names[action_type], + action_type, connect_component_handle, connect_port_handle); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +static int port_parameter_set(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter_id, void *value, u32 value_size) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; + + m.u.port_parameter_set.component_handle = port->component->handle; + m.u.port_parameter_set.port_handle = port->handle; + m.u.port_parameter_set.id = parameter_id; + m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size; + memcpy(&m.u.port_parameter_set.value, value, value_size); + + ret = send_synchronous_mmal_msg(instance, &m, + (4 * sizeof(u32)) + value_size, + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) { + /* got an unexpected message type in reply */ + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.port_parameter_set_reply.status; + + pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", + __func__, + ret, port->component->handle, port->handle, parameter_id); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +static int port_parameter_get(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter_id, void *value, u32 *value_size) +{ + int ret; + struct mmal_msg m; + struct mmal_msg *rmsg; + VCHI_HELD_MSG_T rmsg_handle; + + m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET; + + m.u.port_parameter_get.component_handle = port->component->handle; + m.u.port_parameter_get.port_handle = port->handle; + m.u.port_parameter_get.id = parameter_id; + m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size; + + ret = send_synchronous_mmal_msg(instance, &m, + sizeof(struct + mmal_msg_port_parameter_get), + &rmsg, &rmsg_handle); + if (ret) + return ret; + + if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) { + /* got an unexpected message type in reply */ + pr_err("Incorrect reply type %d\n", rmsg->h.type); + ret = -EINVAL; + goto release_msg; + } + + ret = -rmsg->u.port_parameter_get_reply.status; + if (ret) { + /* Copy only as much as we have space for + * but report true size of parameter + */ + memcpy(value, &rmsg->u.port_parameter_get_reply.value, + *value_size); + *value_size = rmsg->u.port_parameter_get_reply.size; + } else + memcpy(value, &rmsg->u.port_parameter_get_reply.value, + rmsg->u.port_parameter_get_reply.size); + + pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, + ret, port->component->handle, port->handle, parameter_id); + +release_msg: + vchi_held_msg_release(&rmsg_handle); + + return ret; +} + +/* disables a port and drains buffers from it */ +static int port_disable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + struct list_head *q, *buf_head; + unsigned long flags = 0; + + if (!port->enabled) + return 0; + + port->enabled = false; + + ret = port_action_port(instance, port, + MMAL_MSG_PORT_ACTION_TYPE_DISABLE); + if (ret == 0) { + /* drain all queued buffers on port */ + spin_lock_irqsave(&port->slock, flags); + + list_for_each_safe(buf_head, q, &port->buffers) { + struct mmal_buffer *mmalbuf; + + mmalbuf = list_entry(buf_head, struct mmal_buffer, + list); + list_del(buf_head); + if (port->buffer_cb) + port->buffer_cb(instance, + port, 0, mmalbuf, 0, 0, + MMAL_TIME_UNKNOWN, + MMAL_TIME_UNKNOWN); + } + + spin_unlock_irqrestore(&port->slock, flags); + + ret = port_info_get(instance, port); + } + + return ret; +} + +/* enable a port */ +static int port_enable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + unsigned int hdr_count; + struct list_head *buf_head; + int ret; + + if (port->enabled) + return 0; + + /* ensure there are enough buffers queued to cover the buffer headers */ + if (port->buffer_cb != NULL) { + hdr_count = 0; + list_for_each(buf_head, &port->buffers) { + hdr_count++; + } + if (hdr_count < port->current_buffer.num) + return -ENOSPC; + } + + ret = port_action_port(instance, port, + MMAL_MSG_PORT_ACTION_TYPE_ENABLE); + if (ret) + goto done; + + port->enabled = true; + + if (port->buffer_cb) { + /* send buffer headers to videocore */ + hdr_count = 1; + list_for_each(buf_head, &port->buffers) { + struct mmal_buffer *mmalbuf; + + mmalbuf = list_entry(buf_head, struct mmal_buffer, + list); + ret = buffer_from_host(instance, port, mmalbuf); + if (ret) + goto done; + + hdr_count++; + if (hdr_count > port->current_buffer.num) + break; + } + } + + ret = port_info_get(instance, port); + +done: + return ret; +} + +/* ------------------------------------------------------------------ + * Exported API + *------------------------------------------------------------------*/ + +int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + ret = port_info_set(instance, port); + if (ret) + goto release_unlock; + + /* read what has actually been set */ + ret = port_info_get(instance, port); + +release_unlock: + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter, void *value, u32 value_size) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + ret = port_parameter_set(instance, port, parameter, value, value_size); + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter, void *value, u32 *value_size) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + ret = port_parameter_get(instance, port, parameter, value, value_size); + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +/* enable a port + * + * enables a port and queues buffers for satisfying callbacks if we + * provide a callback handler + */ +int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + vchiq_mmal_buffer_cb buffer_cb) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + /* already enabled - noop */ + if (port->enabled) { + ret = 0; + goto unlock; + } + + port->buffer_cb = buffer_cb; + + ret = port_enable(instance, port); + +unlock: + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + if (!port->enabled) { + mutex_unlock(&instance->vchiq_mutex); + return 0; + } + + ret = port_disable(instance, port); + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +/* ports will be connected in a tunneled manner so data buffers + * are not handled by client. + */ +int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *src, + struct vchiq_mmal_port *dst) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + /* disconnect ports if connected */ + if (src->connected != NULL) { + ret = port_disable(instance, src); + if (ret) { + pr_err("failed disabling src port(%d)\n", ret); + goto release_unlock; + } + + /* do not need to disable the destination port as they + * are connected and it is done automatically + */ + + ret = port_action_handle(instance, src, + MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, + src->connected->component->handle, + src->connected->handle); + if (ret < 0) { + pr_err("failed disconnecting src port\n"); + goto release_unlock; + } + src->connected->enabled = false; + src->connected = NULL; + } + + if (dst == NULL) { + /* do not make new connection */ + ret = 0; + pr_debug("not making new connection\n"); + goto release_unlock; + } + + /* copy src port format to dst */ + dst->format.encoding = src->format.encoding; + dst->es.video.width = src->es.video.width; + dst->es.video.height = src->es.video.height; + dst->es.video.crop.x = src->es.video.crop.x; + dst->es.video.crop.y = src->es.video.crop.y; + dst->es.video.crop.width = src->es.video.crop.width; + dst->es.video.crop.height = src->es.video.crop.height; + dst->es.video.frame_rate.num = src->es.video.frame_rate.num; + dst->es.video.frame_rate.den = src->es.video.frame_rate.den; + + /* set new format */ + ret = port_info_set(instance, dst); + if (ret) { + pr_debug("setting port info failed\n"); + goto release_unlock; + } + + /* read what has actually been set */ + ret = port_info_get(instance, dst); + if (ret) { + pr_debug("read back port info failed\n"); + goto release_unlock; + } + + /* connect two ports together */ + ret = port_action_handle(instance, src, + MMAL_MSG_PORT_ACTION_TYPE_CONNECT, + dst->component->handle, dst->handle); + if (ret < 0) { + pr_debug("connecting port %d:%d to %d:%d failed\n", + src->component->handle, src->handle, + dst->component->handle, dst->handle); + goto release_unlock; + } + src->connected = dst; + +release_unlock: + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + struct mmal_buffer *buffer) +{ + unsigned long flags = 0; + + spin_lock_irqsave(&port->slock, flags); + list_add_tail(&buffer->list, &port->buffers); + spin_unlock_irqrestore(&port->slock, flags); + + /* the port previously underflowed because it was missing a + * mmal_buffer which has just been added, submit that buffer + * to the mmal service. + */ + if (port->buffer_underflow) { + port_buffer_from_host(instance, port); + port->buffer_underflow--; + } + + return 0; +} + +/* Initialise a mmal component and its ports + * + */ +int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, + const char *name, + struct vchiq_mmal_component **component_out) +{ + int ret; + int idx; /* port index */ + struct vchiq_mmal_component *component; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { + ret = -EINVAL; /* todo is this correct error? */ + goto unlock; + } + + component = &instance->component[instance->component_idx]; + + ret = create_component(instance, component, name); + if (ret < 0) + goto unlock; + + /* ports info needs gathering */ + component->control.type = MMAL_PORT_TYPE_CONTROL; + component->control.index = 0; + component->control.component = component; + spin_lock_init(&component->control.slock); + INIT_LIST_HEAD(&component->control.buffers); + ret = port_info_get(instance, &component->control); + if (ret < 0) + goto release_component; + + for (idx = 0; idx < component->inputs; idx++) { + component->input[idx].type = MMAL_PORT_TYPE_INPUT; + component->input[idx].index = idx; + component->input[idx].component = component; + spin_lock_init(&component->input[idx].slock); + INIT_LIST_HEAD(&component->input[idx].buffers); + ret = port_info_get(instance, &component->input[idx]); + if (ret < 0) + goto release_component; + } + + for (idx = 0; idx < component->outputs; idx++) { + component->output[idx].type = MMAL_PORT_TYPE_OUTPUT; + component->output[idx].index = idx; + component->output[idx].component = component; + spin_lock_init(&component->output[idx].slock); + INIT_LIST_HEAD(&component->output[idx].buffers); + ret = port_info_get(instance, &component->output[idx]); + if (ret < 0) + goto release_component; + } + + for (idx = 0; idx < component->clocks; idx++) { + component->clock[idx].type = MMAL_PORT_TYPE_CLOCK; + component->clock[idx].index = idx; + component->clock[idx].component = component; + spin_lock_init(&component->clock[idx].slock); + INIT_LIST_HEAD(&component->clock[idx].buffers); + ret = port_info_get(instance, &component->clock[idx]); + if (ret < 0) + goto release_component; + } + + instance->component_idx++; + + *component_out = component; + + mutex_unlock(&instance->vchiq_mutex); + + return 0; + +release_component: + destroy_component(instance, component); +unlock: + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +/* + * cause a mmal component to be destroyed + */ +int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + if (component->enabled) + ret = disable_component(instance, component); + + ret = destroy_component(instance, component); + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +/* + * cause a mmal component to be enabled + */ +int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + if (component->enabled) { + mutex_unlock(&instance->vchiq_mutex); + return 0; + } + + ret = enable_component(instance, component); + if (ret == 0) + component->enabled = true; + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +/* + * cause a mmal component to be enabled + */ +int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + if (!component->enabled) { + mutex_unlock(&instance->vchiq_mutex); + return 0; + } + + ret = disable_component(instance, component); + if (ret == 0) + component->enabled = false; + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_version(struct vchiq_mmal_instance *instance, + u32 *major_out, u32 *minor_out) +{ + int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + ret = get_version(instance, major_out, minor_out); + + mutex_unlock(&instance->vchiq_mutex); + + return ret; +} + +int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) +{ + int status = 0; + + if (instance == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; + + vchi_service_use(instance->handle); + + status = vchi_service_close(instance->handle); + if (status != 0) + pr_err("mmal-vchiq: VCHIQ close failed"); + + mutex_unlock(&instance->vchiq_mutex); + + vfree(instance->bulk_scratch); + + kfree(instance); + + return status; +} + +int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) +{ + int status; + struct vchiq_mmal_instance *instance; + static VCHI_CONNECTION_T *vchi_connection; + static VCHI_INSTANCE_T vchi_instance; + SERVICE_CREATION_T params = { + VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), + VC_MMAL_SERVER_NAME, + vchi_connection, + 0, /* rx fifo size (unused) */ + 0, /* tx fifo size (unused) */ + service_callback, + NULL, /* service callback parameter */ + 1, /* unaligned bulk receives */ + 1, /* unaligned bulk transmits */ + 0 /* want crc check on bulk transfers */ + }; + + /* compile time checks to ensure structure size as they are + * directly (de)serialised from memory. + */ + + /* ensure the header structure has packed to the correct size */ + BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24); + + /* ensure message structure does not exceed maximum length */ + BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE); + + /* mmal port struct is correct size */ + BUILD_BUG_ON(sizeof(struct mmal_port) != 64); + + /* create a vchi instance */ + status = vchi_initialise(&vchi_instance); + if (status) { + pr_err("Failed to initialise VCHI instance (status=%d)\n", + status); + return -EIO; + } + + status = vchi_connect(NULL, 0, vchi_instance); + if (status) { + pr_err("Failed to connect VCHI instance (status=%d)\n", status); + return -EIO; + } + + instance = kmalloc(sizeof(*instance), GFP_KERNEL); + memset(instance, 0, sizeof(*instance)); + + mutex_init(&instance->vchiq_mutex); + mutex_init(&instance->bulk_mutex); + + instance->bulk_scratch = vmalloc(PAGE_SIZE); + + params.callback_param = instance; + + status = vchi_service_open(vchi_instance, ¶ms, &instance->handle); + if (status) { + pr_err("Failed to open VCHI service connection (status=%d)\n", + status); + goto err_close_services; + } + + vchi_service_release(instance->handle); + + *out_instance = instance; + + return 0; + +err_close_services: + + vchi_service_close(instance->handle); + vfree(instance->bulk_scratch); + kfree(instance); + return -ENODEV; +} diff --git a/drivers/staging/media/platform/bcm2835/mmal-vchiq.h b/drivers/staging/media/platform/bcm2835/mmal-vchiq.h new file mode 100644 index 000000000000..9d1d11e4a53e --- /dev/null +++ b/drivers/staging/media/platform/bcm2835/mmal-vchiq.h @@ -0,0 +1,178 @@ +/* + * Broadcom BM2835 V4L2 driver + * + * Copyright © 2013 Raspberry Pi (Trading) Ltd. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> + * Dave Stevenson <dsteve@broadcom.com> + * Simon Mellor <simellor@broadcom.com> + * Luke Diamand <luked@broadcom.com> + * + * MMAL interface to VCHIQ message passing + */ + +#ifndef MMAL_VCHIQ_H +#define MMAL_VCHIQ_H + +#include "mmal-msg-format.h" + +#define MAX_PORT_COUNT 4 + +/* Maximum size of the format extradata. */ +#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 + +struct vchiq_mmal_instance; + +enum vchiq_mmal_es_type { + MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ + MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ + MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ + MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ + MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ +}; + +/* rectangle, used lots so it gets its own struct */ +struct vchiq_mmal_rect { + s32 x; + s32 y; + s32 width; + s32 height; +}; + +struct vchiq_mmal_port_buffer { + unsigned int num; /* number of buffers */ + u32 size; /* size of buffers */ + u32 alignment; /* alignment of buffers */ +}; + +struct vchiq_mmal_port; + +typedef void (*vchiq_mmal_buffer_cb)( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + int status, struct mmal_buffer *buffer, + unsigned long length, u32 mmal_flags, s64 dts, s64 pts); + +struct vchiq_mmal_port { + bool enabled; + u32 handle; + u32 type; /* port type, cached to use on port info set */ + u32 index; /* port index, cached to use on port info set */ + + /* component port belongs to, allows simple deref */ + struct vchiq_mmal_component *component; + + struct vchiq_mmal_port *connected; /* port conencted to */ + + /* buffer info */ + struct vchiq_mmal_port_buffer minimum_buffer; + struct vchiq_mmal_port_buffer recommended_buffer; + struct vchiq_mmal_port_buffer current_buffer; + + /* stream format */ + struct mmal_es_format format; + /* elementry stream format */ + union mmal_es_specific_format es; + + /* data buffers to fill */ + struct list_head buffers; + /* lock to serialise adding and removing buffers from list */ + spinlock_t slock; + /* count of how many buffer header refils have failed because + * there was no buffer to satisfy them + */ + int buffer_underflow; + /* callback on buffer completion */ + vchiq_mmal_buffer_cb buffer_cb; + /* callback context */ + void *cb_ctx; +}; + +struct vchiq_mmal_component { + bool enabled; + u32 handle; /* VideoCore handle for component */ + u32 inputs; /* Number of input ports */ + u32 outputs; /* Number of output ports */ + u32 clocks; /* Number of clock ports */ + struct vchiq_mmal_port control; /* control port */ + struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ + struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ + struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ +}; + + +int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); +int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); + +/* Initialise a mmal component and its ports +* +*/ +int vchiq_mmal_component_init( + struct vchiq_mmal_instance *instance, + const char *name, + struct vchiq_mmal_component **component_out); + +int vchiq_mmal_component_finalise( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); + +int vchiq_mmal_component_enable( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); + +int vchiq_mmal_component_disable( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); + + + +/* enable a mmal port + * + * enables a port and if a buffer callback provided enque buffer + * headers as apropriate for the port. + */ +int vchiq_mmal_port_enable( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + vchiq_mmal_buffer_cb buffer_cb); + +/* disable a port + * + * disable a port will dequeue any pending buffers + */ +int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port); + + +int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter, + void *value, + u32 value_size); + +int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + u32 parameter, + void *value, + u32 *value_size); + +int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port); + +int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *src, + struct vchiq_mmal_port *dst); + +int vchiq_mmal_version(struct vchiq_mmal_instance *instance, + u32 *major_out, + u32 *minor_out); + +int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + struct mmal_buffer *buf); + +#endif /* MMAL_VCHIQ_H */ diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 35aee9fbbf02..902824e728ea 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -41,7 +41,7 @@ /* command line parameter to select clock speed */ static char *clock_speed; -module_param(clock_speed, charp, 0); +module_param(clock_speed, charp, 0000); MODULE_PARM_DESC(clock_speed, "MediaLB Clock Speed"); /* @@ -52,7 +52,7 @@ MODULE_PARM_DESC(clock_speed, "MediaLB Clock Speed"); * sub-buffer 1, 2, 4, 8, 16, 32, 64. */ static u8 fcnt = 4; /* (1 << fcnt) frames per subbuffer */ -module_param(fcnt, byte, 0); +module_param(fcnt, byte, 0000); MODULE_PARM_DESC(fcnt, "Num of frames per sub-buffer for sync channels as a power of 2"); static DEFINE_SPINLOCK(dim_lock); diff --git a/drivers/staging/most/hdm-i2c/hdm_i2c.c b/drivers/staging/most/hdm-i2c/hdm_i2c.c index ba0263bb3d12..1d5b22927bcd 100644 --- a/drivers/staging/most/hdm-i2c/hdm_i2c.c +++ b/drivers/staging/most/hdm-i2c/hdm_i2c.c @@ -37,7 +37,7 @@ enum { CH_RX, CH_TX, NUM_CHANNELS }; /* IRQ / Polling option */ static bool polling_req; -module_param(polling_req, bool, S_IRUGO); +module_param(polling_req, bool, 0444); MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); /* Polling Rate */ diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index d6db0bd65be0..65211d1824b7 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -145,7 +145,7 @@ static void wq_netinfo(struct work_struct *wq_obj); static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf) { int retval; - u16 *dma_buf = kzalloc(sizeof(u16), GFP_KERNEL); + __le16 *dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL); u8 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; if (!dma_buf) @@ -154,7 +154,7 @@ static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf) retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), DRCI_READ_REQ, req_type, 0x0000, - reg, dma_buf, sizeof(u16), 5 * HZ); + reg, dma_buf, sizeof(*dma_buf), 5 * HZ); *buf = le16_to_cpu(*dma_buf); kfree(dma_buf); @@ -846,15 +846,15 @@ static struct usb_device_id usbid[] = { #define MOST_DCI_RO_ATTR(_name) \ struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, S_IRUGO, show_value, NULL) + __ATTR(_name, 0444, show_value, NULL) #define MOST_DCI_ATTR(_name) \ struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, S_IRUGO | S_IWUSR, show_value, store_value) + __ATTR(_name, 0644, show_value, store_value) #define MOST_DCI_WO_ATTR(_name) \ struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, S_IWUSR, NULL, store_value) + __ATTR(_name, 0200, NULL, store_value) /** * struct most_dci_attribute - to access the attributes of a dci object diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index c03ca8d9572a..aa7c70ef94f5 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -138,7 +138,7 @@ struct nvec_chip { struct device *dev; int gpio; int irq; - int i2c_addr; + u32 i2c_addr; void __iomem *base; struct clk *i2c_clk; struct reset_control *rst; diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index fcbb0fa03765..3b144a9ea055 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -442,7 +442,7 @@ static struct platform_driver nvec_power_driver = { .remove = nvec_power_remove, .driver = { .name = "nvec-power", - } + } }; module_platform_driver(nvec_power_driver); diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 499952c8ef39..3b7bce3ffd19 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -107,7 +107,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev; - ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); + ser_dev = kzalloc(sizeof(*ser_dev), GFP_KERNEL); if (!ser_dev) return -ENOMEM; diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index fc849d4a1b5d..7f8cf875157c 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -356,8 +356,8 @@ static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget) /* Increment RX stats for virtual ports */ if (port >= CVMX_PIP_NUM_INPUT_PORTS) { - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; } netif_receive_skb(skb); } else { @@ -365,7 +365,7 @@ static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget) * Drop any packet received for a device that * isn't up. */ - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; dev_kfree_skb_irq(skb); } } else { diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 0b8053205091..ff4119e8de42 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -459,7 +459,7 @@ skip_xmit: case QUEUE_DROP: skb->next = to_free_list; to_free_list = skb; - priv->stats.tx_dropped++; + dev->stats.tx_dropped++; break; case QUEUE_HW: cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -1); @@ -534,7 +534,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) if (unlikely(!work)) { printk_ratelimited("%s: Failed to allocate a work queue entry\n", dev->name); - priv->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb_any(skb); return 0; } @@ -545,7 +545,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) printk_ratelimited("%s: Failed to allocate a packet buffer\n", dev->name); cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1); - priv->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb_any(skb); return 0; } @@ -662,8 +662,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Submit the packet to the POW */ cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type, cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work)); - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; dev_consume_skb_any(skb); return 0; } diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 4971aa54756a..429e24adfcf5 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -228,17 +228,17 @@ static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev) cvmx_pko_get_port_status(priv->port, 1, &tx_status); } - priv->stats.rx_packets += rx_status.inb_packets; - priv->stats.tx_packets += tx_status.packets; - priv->stats.rx_bytes += rx_status.inb_octets; - priv->stats.tx_bytes += tx_status.octets; - priv->stats.multicast += rx_status.multicast_packets; - priv->stats.rx_crc_errors += rx_status.inb_errors; - priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets; - priv->stats.rx_dropped += rx_status.dropped_packets; + dev->stats.rx_packets += rx_status.inb_packets; + dev->stats.tx_packets += tx_status.packets; + dev->stats.rx_bytes += rx_status.inb_octets; + dev->stats.tx_bytes += tx_status.octets; + dev->stats.multicast += rx_status.multicast_packets; + dev->stats.rx_crc_errors += rx_status.inb_errors; + dev->stats.rx_frame_errors += rx_status.fcs_align_err_packets; + dev->stats.rx_dropped += rx_status.dropped_packets; } - return &priv->stats; + return &dev->stats; } /** @@ -889,7 +889,8 @@ static int cvm_oct_probe(struct platform_device *pdev) fau -= cvmx_pko_get_num_queues(priv->port) * sizeof(u32); - schedule_delayed_work(&priv->port_periodic_work, HZ); + schedule_delayed_work(&priv->port_periodic_work, + HZ); } } } diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index 9c6852d61c0d..9c3f453adaa0 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h @@ -38,8 +38,6 @@ struct octeon_ethernet { int imode; /* List of outstanding tx buffers per queue */ struct sk_buff_head tx_free_list[16]; - /* Device statistics */ - struct net_device_stats stats; unsigned int last_speed; unsigned int last_link; /* Last negotiated link state */ diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index f45b2ef05f48..684815c98789 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -81,7 +81,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) if (ver < 0xdc02) { dev_err(&dcon->client->dev, - "DCON v1 is unsupported, giving up..\n"); + "DCON v1 is unsupported, giving up..\n"); rc = -ENODEV; goto err; } @@ -90,7 +90,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) dcon_write(dcon, 0x3a, 0xc040); dcon_write(dcon, DCON_REG_MEM_OPT_A, 0x0000); /* clear option bits */ dcon_write(dcon, DCON_REG_MEM_OPT_A, - MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN); + MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN); dcon_write(dcon, DCON_REG_MEM_OPT_B, MEM_SOFT_RESET); /* Colour swizzle, AA, no passthrough, backlight */ @@ -261,14 +261,14 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) dcon->ignore_fb_events = true; err = fb_blank(dcon->fbinfo, - blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); + blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); dcon->ignore_fb_events = false; unlock_fb_info(dcon->fbinfo); console_unlock(); if (err) { dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n", - blank ? "" : "un"); + blank ? "" : "un"); return false; } return true; @@ -293,7 +293,7 @@ static void dcon_source_switch(struct work_struct *work) pr_info("dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(dcon, DCON_REG_MODE, - dcon->disp_mode | MODE_SCAN_INT)) + dcon->disp_mode | MODE_SCAN_INT)) pr_err("couldn't enable scanline interrupt!\n"); else /* Wait up to one second for the scanline interrupt */ @@ -336,7 +336,7 @@ static void dcon_source_switch(struct work_struct *work) pdata->set_dconload(0); dcon->load_time = ktime_get(); - wait_event_timeout(dcon->waitq, dcon->switched, HZ/2); + wait_event_timeout(dcon->waitq, dcon->switched, HZ / 2); if (!dcon->switched) { pr_err("Timeout entering DCON mode; expect a screen glitch.\n"); @@ -646,7 +646,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) dcon, &dcon_bl_ops, &dcon_bl_props); if (IS_ERR(dcon->bl_dev)) { dev_err(&client->dev, "cannot register backlight dev (%ld)\n", - PTR_ERR(dcon->bl_dev)); + PTR_ERR(dcon->bl_dev)); dcon->bl_dev = NULL; } diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index 1e23ef15b263..75c3c2fe9560 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -53,9 +53,8 @@ static int dcon_was_irq(void) /* irq status will appear in PMIO_Rx50[6] on gpio12 */ tmp = inb(VX855_GPI_STATUS_CHG); - return !!(tmp & BIT_GPIO12); - return 0; + return !!(tmp & BIT_GPIO12); } static int dcon_init_xo_1_5(struct dcon_priv *dcon) @@ -108,7 +107,6 @@ static void set_i2c_line(int sda, int scl) outb(tmp, 0x3c5); } - static void dcon_wiggle_xo_1_5(void) { int x; diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 553e8d50352f..1c8fa3a1f5bb 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -26,7 +26,7 @@ void init_mlme_ap_info(struct adapter *padapter) { - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; @@ -43,7 +43,7 @@ void free_mlme_ap_info(struct adapter *padapter) { struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); @@ -59,17 +59,17 @@ void free_mlme_ap_info(struct adapter *padapter) /* free bc/mc sta_info */ psta = rtw_get_bcmc_stainfo(padapter); - spin_lock_bh(&(pstapriv->sta_hash_lock)); + spin_lock_bh(&pstapriv->sta_hash_lock); rtw_free_stainfo(padapter, psta); - spin_unlock_bh(&(pstapriv->sta_hash_lock)); + spin_unlock_bh(&pstapriv->sta_hash_lock); } static void update_BCNTIM(struct adapter *padapter) { struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; unsigned char *pie = pnetwork_mlmeext->IEs; u8 *p, *dst_ie, *premainder_ie = NULL; u8 *pbackup_remainder_ie = NULL; @@ -94,10 +94,9 @@ 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) offset += tmp_len+2; @@ -116,13 +115,12 @@ 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; @@ -157,7 +155,7 @@ static void update_BCNTIM(struct adapter *padapter) } void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, - u8 index, u8 *data, u8 len) + u8 index, u8 *data, u8 len) { struct ndis_802_11_var_ie *pIE; u8 bmatch = false; @@ -201,8 +199,8 @@ void rtw_add_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); } *dst_ie++ = index; @@ -223,7 +221,7 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, } void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork, - u8 index) + u8 index) { u8 *p, *dst_ie = NULL, *premainder_ie = NULL; u8 *pbackup_remainder_ie = NULL; @@ -247,8 +245,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 */ @@ -310,9 +308,9 @@ void expire_timeout_chk(struct adapter *padapter) spin_unlock_bh(&pstapriv->auth_list_lock); - spin_lock_bh(&(pstapriv->sta_hash_lock)); + spin_lock_bh(&pstapriv->sta_hash_lock); rtw_free_stainfo(padapter, psta); - spin_unlock_bh(&(pstapriv->sta_hash_lock)); + spin_unlock_bh(&pstapriv->sta_hash_lock); spin_lock_bh(&pstapriv->auth_list_lock); } @@ -361,8 +359,8 @@ void expire_timeout_chk(struct adapter *padapter) * 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; @@ -456,7 +454,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) unsigned char limit; unsigned int tx_ra_bitmap = 0; struct ht_priv *psta_ht = NULL; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; if (psta) @@ -548,7 +546,7 @@ static void update_bmc_sta(struct adapter *padapter) unsigned char network_type, raid; int i, supportRateNum = 0; unsigned int tx_ra_bitmap = 0; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); @@ -630,9 +628,9 @@ static void update_bmc_sta(struct adapter *padapter) void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta) { - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; struct ht_priv *phtpriv_sta = &psta->htpriv; @@ -700,7 +698,7 @@ static void update_hw_ht_param(struct adapter *padapter) unsigned char max_AMPDU_len; unsigned char min_MPDU_spacing; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; DBG_88E("%s\n", __func__); @@ -733,12 +731,12 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf) u32 acparm; int ie_len; struct registry_priv *pregpriv = &padapter->registrypriv; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct security_priv *psecuritypriv = &(padapter->securitypriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; struct HT_info_element *pht_info = NULL; bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; @@ -869,7 +867,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; u8 *ie = pbss_network->IEs; @@ -905,7 +903,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->Rssi = 0; - ether_addr_copy(pbss_network->MacAddress, myid(&(padapter->eeprompriv))); + ether_addr_copy(pbss_network->MacAddress, myid(&padapter->eeprompriv)); /* beacon interval */ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ @@ -1150,7 +1148,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) if ((NUM_ACL - 1) < pacl_list->num) return -1; - spin_lock_bh(&(pacl_node_q->lock)); + spin_lock_bh(&pacl_node_q->lock); phead = get_list_head(pacl_node_q); plist = phead->next; @@ -1168,12 +1166,12 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) } } - spin_unlock_bh(&(pacl_node_q->lock)); + spin_unlock_bh(&pacl_node_q->lock); if (added) return ret; - spin_lock_bh(&(pacl_node_q->lock)); + spin_lock_bh(&pacl_node_q->lock); for (i = 0; i < NUM_ACL; i++) { paclnode = &pacl_list->aclnode[i]; @@ -1195,7 +1193,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); - spin_unlock_bh(&(pacl_node_q->lock)); + spin_unlock_bh(&pacl_node_q->lock); return ret; } @@ -1210,7 +1208,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); - spin_lock_bh(&(pacl_node_q->lock)); + spin_lock_bh(&pacl_node_q->lock); phead = get_list_head(pacl_node_q); plist = phead->next; @@ -1230,7 +1228,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) } } - spin_unlock_bh(&(pacl_node_q->lock)); + spin_unlock_bh(&pacl_node_q->lock); DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); return 0; @@ -1238,10 +1236,10 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) static void update_bcn_erpinfo_ie(struct adapter *padapter) { - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; unsigned char *p, *ie = pnetwork->IEs; u32 len = 0; @@ -1275,10 +1273,10 @@ static void update_bcn_wps_ie(struct adapter *padapter) u8 *pwps_ie = NULL, *pwps_ie_src; u8 *premainder_ie, *pbackup_remainder_ie = NULL; uint wps_ielen = 0, wps_offset, remainder_ielen; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; unsigned char *ie = pnetwork->IEs; u32 ielen = pnetwork->IELength; @@ -1338,8 +1336,8 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx) if (!padapter) return; - pmlmepriv = &(padapter->mlmepriv); - pmlmeext = &(padapter->mlmeextpriv); + pmlmepriv = &padapter->mlmepriv; + pmlmeext = &padapter->mlmeextpriv; if (!pmlmeext->bstart_bss) return; @@ -1384,7 +1382,7 @@ static int rtw_ht_operation_update(struct adapter *padapter) { u16 cur_op_mode, new_op_mode; int op_mode_changes = 0; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; if (pmlmepriv->htpriv.ht_option) @@ -1477,8 +1475,8 @@ void associated_clients_update(struct adapter *padapter, u8 updated) void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta) { u8 beacon_updated = false; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) { if (!psta->no_short_preamble_set) { @@ -1573,8 +1571,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta) pmlmepriv->num_sta_ht_no_gf++; } DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n", - __func__, (psta->hwaddr), - pmlmepriv->num_sta_ht_no_gf); + __func__, (psta->hwaddr), + pmlmepriv->num_sta_ht_no_gf); } if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) { @@ -1583,8 +1581,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta) pmlmepriv->num_sta_ht_20mhz++; } DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n", - __func__, (psta->hwaddr), - pmlmepriv->num_sta_ht_20mhz); + __func__, (psta->hwaddr), + pmlmepriv->num_sta_ht_20mhz); } } else { if (!psta->no_ht_set) { @@ -1612,8 +1610,8 @@ 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) { u8 beacon_updated = false; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; if (!psta) return beacon_updated; @@ -1708,9 +1706,9 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); - spin_lock_bh(&(pstapriv->sta_hash_lock)); + spin_lock_bh(&pstapriv->sta_hash_lock); rtw_free_stainfo(padapter, psta); - spin_unlock_bh(&(pstapriv->sta_hash_lock)); + spin_unlock_bh(&pstapriv->sta_hash_lock); return beacon_updated; } @@ -1721,7 +1719,7 @@ int rtw_sta_flush(struct adapter *padapter) struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); @@ -1758,7 +1756,7 @@ int rtw_sta_flush(struct adapter *padapter) void sta_info_update(struct adapter *padapter, struct sta_info *psta) { int flags = psta->flags; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; /* update wmm cap. */ if (WLAN_STA_WME&flags) @@ -1795,7 +1793,7 @@ void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta) void start_ap_mode(struct adapter *padapter) { int i; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; @@ -1828,7 +1826,7 @@ void start_ap_mode(struct adapter *padapter) pmlmepriv->wps_assoc_resp_ie = NULL; /* for ACL */ - INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue)); + INIT_LIST_HEAD(&pacl_list->acl_node_q.queue); pacl_list->num = 0; pacl_list->mode = 0; for (i = 0; i < NUM_ACL; i++) { @@ -1843,7 +1841,7 @@ void stop_ap_mode(struct adapter *padapter) struct rtw_wlan_acl_node *paclnode; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; struct __queue *pacl_node_q = &pacl_list->acl_node_q; @@ -1857,7 +1855,7 @@ void stop_ap_mode(struct adapter *padapter) padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; /* for ACL */ - spin_lock_bh(&(pacl_node_q->lock)); + spin_lock_bh(&pacl_node_q->lock); phead = get_list_head(pacl_node_q); plist = phead->next; while (phead != plist) { @@ -1872,7 +1870,7 @@ void stop_ap_mode(struct adapter *padapter) pacl_list->num--; } } - spin_unlock_bh(&(pacl_node_q->lock)); + spin_unlock_bh(&pacl_node_q->lock); DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num); @@ -1882,9 +1880,9 @@ void stop_ap_mode(struct adapter *padapter) rtw_free_all_stainfo(padapter); psta = rtw_get_bcmc_stainfo(padapter); - spin_lock_bh(&(pstapriv->sta_hash_lock)); + spin_lock_bh(&pstapriv->sta_hash_lock); rtw_free_stainfo(padapter, psta); - spin_unlock_bh(&(pstapriv->sta_hash_lock)); + spin_unlock_bh(&pstapriv->sta_hash_lock); rtw_init_bcmc_stainfo(padapter); diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 36109cec8706..14979666dadd 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -1321,9 +1321,6 @@ void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj * spin_lock_bh(&pmlmepriv->lock); - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)) - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - set_fwstate(pmlmepriv, _FW_LINKED); spin_unlock_bh(&pmlmepriv->lock); diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 16cc7706a1e6..b9bdff0490ca 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -253,6 +253,7 @@ static void efuse_read_phymap_from_txpktbuf( u8 lenc[2]; u16 lenbak, aaabak; u16 aaa; + lenc[0] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L); lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L+1); @@ -562,13 +563,14 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse } if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */ - if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { + if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) return false; - } + efuse_addr++; continue; } else if (pg_header != tmp_header) { /* offset PG fail */ struct pgpkt fixPkt; + fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); fixPkt.word_en = tmp_header & 0x0F; fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); @@ -611,6 +613,7 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse bRet = true; } else { struct pgpkt fixPkt; + fixPkt.offset = (tmp_header>>4) & 0x0F; fixPkt.word_en = tmp_header & 0x0F; fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); @@ -819,6 +822,7 @@ bool Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pD u8 Efuse_CalculateWordCnts(u8 word_en) { u8 word_cnts = 0; + if (!(word_en & BIT(0))) word_cnts++; /* 0 : write enable */ if (!(word_en & BIT(1))) diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 914c4923421b..d1cd34011602 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -71,8 +71,8 @@ int rtw_get_bit_value_from_ieee_value(u8 val) unsigned char dot11_rate_table[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0}; /* last element must be zero!! */ - int i = 0; + while (dot11_rate_table[i] != 0) { if (dot11_rate_table[i] == val) return BIT(i); @@ -162,6 +162,7 @@ u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit) { int tmp, i; u8 *p; + if (limit < 1) return NULL; @@ -211,6 +212,7 @@ void rtw_set_supported_rate(u8 *SupportedRates, uint mode) uint rtw_get_rateset_len(u8 *rateset) { uint i = 0; + while (1) { if ((rateset[i]) == 0) break; @@ -998,10 +1000,11 @@ int ieee80211_get_hdrlen(u16 fc) static int rtw_get_cipher_info(struct wlan_network *pnetwork) { - u32 wpa_ielen; + int wpa_ielen; unsigned char *pbuf; int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; int ret = _FAIL; + pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); if (pbuf && (wpa_ielen > 0)) { @@ -1042,7 +1045,7 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork) __le16 le_tmp; u16 wpa_len = 0, rsn_len = 0; struct HT_info_element *pht_info = NULL; - unsigned int len; + int len; unsigned char *p; memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 6ed23f4db38c..67508a6cf0e5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -573,11 +573,6 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; u32 ht_ielen = 0; - if (adapter->registrypriv.mp_mode == 1) { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - return 0; - } - if ((!check_fwstate(pmlmepriv, _FW_LINKED)) && (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) return 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c index c1478cff5854..1b9bc9817a57 100644 --- a/drivers/staging/rtl8188eu/core/rtw_led.c +++ b/drivers/staging/rtl8188eu/core/rtw_led.c @@ -39,7 +39,9 @@ void BlinkTimerCallback(unsigned long data) /* */ void BlinkWorkItemCallback(struct work_struct *work) { - struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem); + struct LED_871x *pLed = container_of(work, struct LED_871x, + BlinkWorkItem); + BlinkHandler(pLed); } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 032f783b0d83..a71928952eca 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -659,6 +659,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) } } else { int s_ret; + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); pmlmepriv->to_join = false; s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); @@ -1256,6 +1257,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) if (mac_id >= 0) { u16 media_status; + media_status = (mac_id<<8)|0; /* MACID|OPMODE:0 means disconnect */ /* for STA, AP, ADHOC mode, report disconnect stauts to FW */ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); @@ -1542,6 +1544,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div)); if (supp_ant_div) { u8 cur_ant; + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant)); DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n", (2 == candidate->network.PhyInfo.Optimum_antenna) ? "A" : "B", diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index d9c114776cab..f45af407f76d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -147,6 +147,7 @@ static const struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = { int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch) { int i; + for (i = 0; ch_set[i].ChannelNum != 0; i++) { if (ch == ch_set[i].ChannelNum) break; @@ -274,9 +275,8 @@ static s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, pxmitpriv->ack_tx = true; pmgntframe->ack_report = 1; - if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { + if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); - } pxmitpriv->ack_tx = false; mutex_unlock(&pxmitpriv->ack_tx_mutex); @@ -371,6 +371,7 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms) u8 *wps_ie; uint wps_ielen; u8 sr = 0; + memcpy(pframe, cur_network->IEs, cur_network->IELength); len_diff = update_hidden_ssid( pframe+_BEACON_IE_OFFSET_ @@ -829,6 +830,7 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta, } else { __le32 le_tmp32; __le16 le_tmp16; + ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress); ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress); @@ -1963,6 +1965,7 @@ static void site_survey(struct adapter *padapter) if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ int i; + for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { /* todo: to issue two probe req??? */ @@ -2050,8 +2053,8 @@ static u8 collect_bss_info(struct adapter *padapter, u32 len; u8 *p; u16 val16, subtype; - u8 *pframe = precv_frame->rx_data; - u32 packet_len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + u32 packet_len = precv_frame->pkt->len; u8 ie_offset; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -2155,6 +2158,7 @@ static u8 collect_bss_info(struct adapter *padapter, p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset); if (p) { struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); + bssid->Configuration.DSConfig = HT_info->primary_channel; } else { /* use current channel */ bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); @@ -2192,6 +2196,7 @@ static u8 collect_bss_info(struct adapter *padapter, /* 20/40 BSS Coexistence check */ if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset); if (p && len > 0) { struct ieee80211_ht_cap *pHT_caps = @@ -2218,6 +2223,7 @@ static void start_create_ibss(struct adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); + pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); @@ -2557,8 +2563,8 @@ static unsigned int OnProbeReq(struct adapter *padapter, struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *cur = &(pmlmeinfo->network); - u8 *pframe = precv_frame->rx_data; - uint len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint len = precv_frame->pkt->len; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) return _SUCCESS; @@ -2605,8 +2611,8 @@ static unsigned int OnBeacon(struct adapter *padapter, struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; - u8 *pframe = precv_frame->rx_data; - uint len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint len = precv_frame->pkt->len; struct wlan_bssid_ex *pbss; int ret = _SUCCESS; struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); @@ -2702,8 +2708,8 @@ static unsigned int OnAuth(struct adapter *padapter, struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 *pframe = precv_frame->rx_data; - uint len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint len = precv_frame->pkt->len; if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) return _FAIL; @@ -2865,8 +2871,8 @@ static unsigned int OnAuthClient(struct adapter *padapter, unsigned int go2asoc = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 *pframe = precv_frame->rx_data; - uint pkt_len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint pkt_len = precv_frame->pkt->len; DBG_88E("%s\n", __func__); @@ -2953,8 +2959,8 @@ static unsigned int OnAssocReq(struct adapter *padapter, struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *cur = &(pmlmeinfo->network); struct sta_priv *pstapriv = &padapter->stapriv; - u8 *pframe = precv_frame->rx_data; - uint pkt_len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint pkt_len = precv_frame->pkt->len; if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) return _FAIL; @@ -3385,8 +3391,8 @@ static unsigned int OnAssocRsp(struct adapter *padapter, struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ - u8 *pframe = precv_frame->rx_data; - uint pkt_len = precv_frame->len; + u8 *pframe = precv_frame->pkt->data; + uint pkt_len = precv_frame->pkt->len; DBG_88E("%s\n", __func__); @@ -3453,11 +3459,10 @@ static unsigned int OnAssocRsp(struct adapter *padapter, UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); report_assoc_result: - if (res > 0) { + if (res > 0) rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); - } else { + else rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); - } report_join_res(padapter, res); @@ -3471,7 +3476,7 @@ static unsigned int OnDeAuth(struct adapter *padapter, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); /* check A3 */ @@ -3526,7 +3531,7 @@ static unsigned int OnDisassoc(struct adapter *padapter, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); /* check A3 */ @@ -3585,7 +3590,7 @@ static unsigned int on_action_spct(struct adapter *padapter, { struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 category; u8 action; @@ -3641,7 +3646,7 @@ static unsigned int OnAction_back(struct adapter *padapter, unsigned short tid, status, reason_code = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; struct sta_priv *pstapriv = &padapter->stapriv; /* check RA matches or not */ if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), @@ -3714,7 +3719,7 @@ static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) { struct adapter *adapter = recv_frame->adapter; struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); - u8 *frame = recv_frame->rx_data; + u8 *frame = recv_frame->pkt->data; u16 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) | (recv_frame->attrib.frag_num & 0xf); @@ -3744,11 +3749,11 @@ static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) static unsigned int on_action_public_p2p(struct recv_frame *precv_frame) { - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; u8 *frame_body; u8 dialogToken = 0; - frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); + frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); dialogToken = frame_body[7]; if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) @@ -3760,7 +3765,7 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame) static unsigned int on_action_public_vendor(struct recv_frame *precv_frame) { unsigned int ret = _FAIL; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); if (!memcmp(frame_body + 2, P2P_OUI, 4)) @@ -3772,7 +3777,7 @@ static unsigned int on_action_public_vendor(struct recv_frame *precv_frame) static unsigned int on_action_public_default(struct recv_frame *precv_frame, u8 action) { unsigned int ret = _FAIL; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 token; @@ -3791,7 +3796,7 @@ static unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int ret = _FAIL; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 category, action; @@ -3862,7 +3867,7 @@ static unsigned int OnAction(struct adapter *padapter, unsigned char category; struct action_handler *ptable; unsigned char *frame_body; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); @@ -4002,9 +4007,8 @@ static void init_channel_list(struct adapter *padapter, struct rt_channel_info * struct p2p_reg_class *reg = NULL; for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { - if (!has_channel(channel_set, chanset_size, ch)) { + if (!has_channel(channel_set, chanset_size, ch)) continue; - } if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) continue; @@ -4119,7 +4123,7 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, struct recv_frame *precv_frame) { u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; if (ptable->func) { /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ @@ -4138,7 +4142,7 @@ void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #endif /* CONFIG_88EU_AP_MODE */ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, @@ -4664,23 +4668,6 @@ void mlmeext_sta_del_event_callback(struct adapter *padapter) Following are the functions for the timer handlers *****************************************************************************/ -void _linked_rx_signal_strehgth_display(struct adapter *padapter); -void _linked_rx_signal_strehgth_display(struct adapter *padapter) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - u8 mac_id; - int UndecoratedSmoothedPWDB; - if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) - mac_id = 0; - else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_) - mac_id = 2; - - rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &mac_id); - - rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); - DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB); -} static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta) { @@ -4707,9 +4694,6 @@ void linked_status_chk(struct adapter *padapter) struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct sta_priv *pstapriv = &padapter->stapriv; - if (padapter->bRxRSSIDisplay) - _linked_rx_signal_strehgth_display(padapter); - if (is_client_associated_to_ap(padapter)) { /* linked infrastructure client mode */ @@ -4767,9 +4751,8 @@ void linked_status_chk(struct adapter *padapter) } } - if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) { + if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0); - } } if (rx_chk == _FAIL) { diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 4032121a06f3..f86c9cebf09a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -180,9 +180,9 @@ int ips_leave(struct adapter *padapter) DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts); result = rtw_ips_pwr_up(padapter); - if (result == _SUCCESS) { + if (result == _SUCCESS) pwrpriv->rf_pwrstate = rf_on; - } + DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n"); if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) { @@ -279,6 +279,7 @@ exit: static void pwr_state_check_handler(unsigned long data) { struct adapter *padapter = (struct adapter *)data; + rtw_ps_cmd(padapter); } diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 3e6edb63d36b..53dc33c3f913 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -80,7 +80,6 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) &(precvpriv->free_recv_queue.queue)); precvframe->pkt = NULL; - precvframe->len = 0; precvframe->adapter = padapter; precvframe++; @@ -149,8 +148,6 @@ int rtw_free_recvframe(struct recv_frame *precvframe, list_del_init(&(precvframe->list)); - precvframe->len = 0; - list_add_tail(&(precvframe->list), get_list_head(pfree_recv_queue)); spin_unlock_bh(&pfree_recv_queue->lock); @@ -211,6 +208,7 @@ u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter) { u32 cnt = 0; struct recv_frame *pending_frame; + while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__); @@ -261,9 +259,9 @@ static int recvframe_chkmic(struct adapter *adapter, } /* icv_len included the mic code */ - datalen = precvframe->len-prxattrib->hdrlen - + datalen = precvframe->pkt->len-prxattrib->hdrlen - prxattrib->iv_len-prxattrib->icv_len-8; - pframe = precvframe->rx_data; + pframe = precvframe->pkt->data; payload = pframe+prxattrib->hdrlen+prxattrib->iv_len; RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n", prxattrib->iv_len, prxattrib->icv_len)); @@ -296,26 +294,27 @@ static int recvframe_chkmic(struct adapter *adapter, *(pframemic-10), *(pframemic-9))); { uint i; + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet (len=%d)======\n", - precvframe->len)); - for (i = 0; i < precvframe->len; i += 8) { + precvframe->pkt->len)); + for (i = 0; i < precvframe->pkt->len; i += 8) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x", - *(precvframe->rx_data+i), - *(precvframe->rx_data+i+1), - *(precvframe->rx_data+i+2), - *(precvframe->rx_data+i+3), - *(precvframe->rx_data+i+4), - *(precvframe->rx_data+i+5), - *(precvframe->rx_data+i+6), - *(precvframe->rx_data+i+7))); + *(precvframe->pkt->data+i), + *(precvframe->pkt->data+i+1), + *(precvframe->pkt->data+i+2), + *(precvframe->pkt->data+i+3), + *(precvframe->pkt->data+i+4), + *(precvframe->pkt->data+i+5), + *(precvframe->pkt->data+i+6), + *(precvframe->pkt->data+i+7))); } RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ====== demp packet end [len=%d]======\n", - precvframe->len)); + precvframe->pkt->len)); RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n hrdlen=%d,\n", @@ -352,7 +351,7 @@ static int recvframe_chkmic(struct adapter *adapter, RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n")); } - recvframe_pull_tail(precvframe, 8); + skb_trim(precvframe->pkt, precvframe->pkt->len - 8); } exit: @@ -372,7 +371,8 @@ static struct recv_frame *decryptor(struct adapter *padapter, RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("prxstat->decrypted=%x prxattrib->encrypt=0x%03x\n", prxattrib->bdecrypted, prxattrib->encrypt)); if (prxattrib->encrypt > 0) { - u8 *iv = precv_frame->rx_data+prxattrib->hdrlen; + u8 *iv = precv_frame->pkt->data+prxattrib->hdrlen; + prxattrib->key_index = (((iv[3])>>6)&0x3); if (prxattrib->key_index > WEP_KEYS) { @@ -440,7 +440,7 @@ static struct recv_frame *portctrl(struct adapter *adapter, auth_alg = adapter->securitypriv.dot11AuthAlgrthm; - ptr = precv_frame->rx_data; + ptr = precv_frame->pkt->data; pfhdr = precv_frame; pattrib = &pfhdr->attrib; psta_addr = pattrib->ta; @@ -529,7 +529,7 @@ static void process_pwrbit_data(struct adapter *padapter, { #ifdef CONFIG_88EU_AP_MODE unsigned char pwrbit; - u8 *ptr = precv_frame->rx_data; + u8 *ptr = precv_frame->pkt->data; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *psta = NULL; @@ -617,7 +617,7 @@ static void count_rx_stats(struct adapter *padapter, struct rx_pkt_attrib *pattrib = &prframe->attrib; struct recv_priv *precvpriv = &padapter->recvpriv; - sz = prframe->len; + sz = prframe->pkt->len; precvpriv->rx_bytes += sz; padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; @@ -647,7 +647,6 @@ int sta2sta_data_frame( int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta) { - u8 *ptr = precv_frame->rx_data; int ret = _SUCCESS; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct sta_priv *pstapriv = &adapter->stapriv; @@ -703,14 +702,6 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, sta_addr = pattrib->src; } - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - - sta_addr = mybssid; } else { ret = _FAIL; } @@ -735,7 +726,7 @@ static int ap2sta_data_frame( struct recv_frame *precv_frame, struct sta_info **psta) { - u8 *ptr = precv_frame->rx_data; + u8 *ptr = precv_frame->pkt->data; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; int ret = _SUCCESS; struct sta_priv *pstapriv = &adapter->stapriv; @@ -799,23 +790,6 @@ static int ap2sta_data_frame( ret = RTW_RX_HANDLED; goto exit; } - } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && - (check_fwstate(pmlmepriv, _FW_LINKED) == true)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - - /* */ - memcpy(pattrib->bssid, mybssid, ETH_ALEN); - - *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ - if (*psta == NULL) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n")); - ret = _FAIL; - goto exit; - } } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* Special case */ ret = RTW_RX_HANDLED; @@ -845,7 +819,7 @@ static int sta2ap_data_frame(struct adapter *adapter, struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct sta_priv *pstapriv = &adapter->stapriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *ptr = precv_frame->rx_data; + u8 *ptr = precv_frame->pkt->data; unsigned char *mybssid = get_bssid(pmlmepriv); int ret = _SUCCESS; @@ -880,6 +854,7 @@ static int sta2ap_data_frame(struct adapter *adapter, } } else { u8 *myhwaddr = myid(&adapter->eeprompriv); + if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { ret = RTW_RX_HANDLED; goto exit; @@ -901,7 +876,7 @@ static int validate_recv_ctrl_frame(struct adapter *padapter, #ifdef CONFIG_88EU_AP_MODE struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct sta_priv *pstapriv = &padapter->stapriv; - u8 *pframe = precv_frame->rx_data; + u8 *pframe = precv_frame->pkt->data; if (GetFrameType(pframe) != WIFI_CTRL_TYPE) return _FAIL; @@ -1038,19 +1013,19 @@ static int validate_recv_mgnt_frame(struct adapter *padapter, /* for rx pkt statistics */ psta = rtw_get_stainfo(&padapter->stapriv, - GetAddr2Ptr(precv_frame->rx_data)); + GetAddr2Ptr(precv_frame->pkt->data)); if (psta) { psta->sta_stats.rx_mgnt_pkts++; - if (GetFrameSubType(precv_frame->rx_data) == WIFI_BEACON) { + if (GetFrameSubType(precv_frame->pkt->data) == WIFI_BEACON) { psta->sta_stats.rx_beacon_pkts++; - } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBEREQ) { + } else if (GetFrameSubType(precv_frame->pkt->data) == WIFI_PROBEREQ) { psta->sta_stats.rx_probereq_pkts++; - } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBERSP) { + } else if (GetFrameSubType(precv_frame->pkt->data) == WIFI_PROBERSP) { if (!memcmp(padapter->eeprompriv.mac_addr, - GetAddr1Ptr(precv_frame->rx_data), ETH_ALEN)) + GetAddr1Ptr(precv_frame->pkt->data), ETH_ALEN)) psta->sta_stats.rx_probersp_pkts++; - else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)) || - is_multicast_mac_addr(GetAddr1Ptr(precv_frame->rx_data))) + else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->pkt->data)) || + is_multicast_mac_addr(GetAddr1Ptr(precv_frame->pkt->data))) psta->sta_stats.rx_probersp_bm_pkts++; else psta->sta_stats.rx_probersp_uo_pkts++; @@ -1068,7 +1043,7 @@ static int validate_recv_data_frame(struct adapter *adapter, u8 bretry; u8 *psa, *pda, *pbssid; struct sta_info *psta = NULL; - u8 *ptr = precv_frame->rx_data; + u8 *ptr = precv_frame->pkt->data; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct security_priv *psecuritypriv = &adapter->securitypriv; int ret = _SUCCESS; @@ -1115,11 +1090,10 @@ static int validate_recv_data_frame(struct adapter *adapter, break; } - if (ret == _FAIL) { + if (ret == _FAIL) goto exit; - } else if (ret == RTW_RX_HANDLED) { + else if (ret == RTW_RX_HANDLED) goto exit; - } if (psta == NULL) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta==NULL\n")); @@ -1191,12 +1165,13 @@ static int validate_recv_frame(struct adapter *adapter, int retval = _SUCCESS; u8 bDumpRxPkt; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; - u8 *ptr = precv_frame->rx_data; + u8 *ptr = precv_frame->pkt->data; u8 ver = (unsigned char)(*ptr)&0x3; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter)); + if (ch_set_idx >= 0) pmlmeext->channel_set[ch_set_idx].rx_count++; } @@ -1265,6 +1240,7 @@ static int validate_recv_frame(struct adapter *adapter, retval = validate_recv_data_frame(adapter, precv_frame); if (retval == _FAIL) { struct recv_priv *precvpriv = &adapter->recvpriv; + precvpriv->rx_drop++; } break; @@ -1303,13 +1279,11 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) u8 *psnap_type; struct ieee80211_snap_hdr *psnap; - struct adapter *adapter = precvframe->adapter; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *ptr = precvframe->rx_data; + u8 *ptr = precvframe->pkt->data; struct rx_pkt_attrib *pattrib = &precvframe->attrib; if (pattrib->encrypt) - recvframe_pull_tail(precvframe, pattrib->icv_len); + skb_trim(precvframe->pkt, precvframe->pkt->len - pattrib->icv_len); psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; @@ -1326,7 +1300,7 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) } rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); - len = precvframe->len - rmv_len; + len = precvframe->pkt->len - rmv_len; RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n===pattrib->hdrlen: %x, pattrib->iv_len:%x===\n\n", pattrib->hdrlen, pattrib->iv_len)); @@ -1335,19 +1309,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) eth_type = ntohs(be_tmp); /* pattrib->ether_type */ pattrib->eth_type = eth_type; - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) { - ptr += rmv_len; - *ptr = 0x87; - *(ptr+1) = 0x12; - - eth_type = 0x8712; - /* append rx status for mp test packets */ - ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); - memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - } + ptr = skb_pull(precvframe->pkt, rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)); + if (!ptr) + return _FAIL; memcpy(ptr, pattrib->dst, ETH_ALEN); memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); @@ -1416,15 +1380,16 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter, wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; - recvframe_pull(pnextrframe, wlanhdr_offset); + skb_pull(pnextrframe->pkt, wlanhdr_offset); /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ - recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); + skb_trim(prframe->pkt, prframe->pkt->len - pfhdr->attrib.icv_len); /* memcpy */ - memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); + memcpy(skb_tail_pointer(pfhdr->pkt), pnfhdr->pkt->data, + pnfhdr->pkt->len); - recvframe_put(prframe, pnfhdr->len); + skb_put(prframe->pkt, pnfhdr->pkt->len); pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; plist = plist->next; @@ -1465,7 +1430,8 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, psta_addr = pfhdr->attrib.ta; psta = rtw_get_stainfo(pstapriv, psta_addr); if (psta == NULL) { - u8 type = GetFrameType(pfhdr->rx_data); + u8 type = GetFrameType(pfhdr->pkt->data); + if (type != WIFI_DATA_TYPE) { psta = rtw_get_bcmc_stainfo(padapter); pdefrag_q = &psta->sta_recvpriv.defrag_q; @@ -1548,18 +1514,18 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue); - nr_subframes = 0; + nr_subframes = 0; pattrib = &prframe->attrib; - recvframe_pull(prframe, prframe->attrib.hdrlen); + skb_pull(prframe->pkt, prframe->attrib.hdrlen); if (prframe->attrib.iv_len > 0) - recvframe_pull(prframe, prframe->attrib.iv_len); + skb_pull(prframe->pkt, prframe->attrib.iv_len); - a_len = prframe->len; + a_len = prframe->pkt->len; - pdata = prframe->rx_data; + pdata = prframe->pkt->data; while (a_len > ETH_HLEN) { /* Offset 12 denote 2 mac address */ @@ -1606,9 +1572,9 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) if (padding_len == 4) padding_len = 0; - if (a_len < padding_len) { + if (a_len < padding_len) goto exit; - } + pdata += padding_len; a_len -= padding_len; } @@ -1646,8 +1612,6 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) } exit: - - prframe->len = 0; rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ return _SUCCESS; @@ -2064,45 +2028,48 @@ static void rtw_signal_stat_timer_hdl(unsigned long data) u8 avg_signal_qual = 0; u8 _alpha = 3; /* this value is based on converging_constant = 5000 and sampling_interval = 1000 */ - if (adapter->recvpriv.is_signal_dbg) { - /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */ - adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg; - adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); - } else { - if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */ - avg_signal_strength = recvpriv->signal_strength_data.avg_val; - /* after avg_vals are acquired, we can re-stat the signal values */ - recvpriv->signal_strength_data.update_req = 1; - } - - if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */ - avg_signal_qual = recvpriv->signal_qual_data.avg_val; - /* after avg_vals are acquired, we can re-stat the signal values */ - recvpriv->signal_qual_data.update_req = 1; - } + if (recvpriv->signal_strength_data.update_req == 0) { + /* update_req is clear, means we got rx */ + avg_signal_strength = recvpriv->signal_strength_data.avg_val; + /* after avg_vals are acquired, we can re-stat the signal + * values + */ + recvpriv->signal_strength_data.update_req = 1; + } - /* update value of signal_strength, rssi, signal_qual */ - if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == false) { - tmp_s = avg_signal_strength+(_alpha-1)*recvpriv->signal_strength; - if (tmp_s % _alpha) - tmp_s = tmp_s/_alpha + 1; - else - tmp_s = tmp_s/_alpha; - if (tmp_s > 100) - tmp_s = 100; + if (recvpriv->signal_qual_data.update_req == 0) { + /* update_req is clear, means we got rx */ + avg_signal_qual = recvpriv->signal_qual_data.avg_val; + /* after avg_vals are acquired, we can re-stat the signal + * values + */ + recvpriv->signal_qual_data.update_req = 1; + } - tmp_q = avg_signal_qual+(_alpha-1)*recvpriv->signal_qual; - if (tmp_q % _alpha) - tmp_q = tmp_q/_alpha + 1; - else - tmp_q = tmp_q/_alpha; - if (tmp_q > 100) - tmp_q = 100; + /* update value of signal_strength, rssi, signal_qual */ + if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == false) { + tmp_s = avg_signal_strength + + (_alpha - 1) * recvpriv->signal_strength; + if (tmp_s % _alpha) + tmp_s = tmp_s / _alpha + 1; + else + tmp_s = tmp_s / _alpha; + if (tmp_s > 100) + tmp_s = 100; + + tmp_q = avg_signal_qual + + (_alpha - 1) * recvpriv->signal_qual; + if (tmp_q % _alpha) + tmp_q = tmp_q / _alpha + 1; + else + tmp_q = tmp_q / _alpha; + if (tmp_q > 100) + tmp_q = 100; - recvpriv->signal_strength = tmp_s; - recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); - recvpriv->signal_qual = tmp_q; - } + recvpriv->signal_strength = tmp_s; + recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); + recvpriv->signal_qual = tmp_q; } + rtw_set_signal_stat_timer(recvpriv); } diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index 85bb441a7214..b283a4903369 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -36,6 +36,7 @@ static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) u32 stateindex; u8 *state; u32 counter; + state = parc4ctx->state; parc4ctx->x = 0; parc4ctx->y = 0; @@ -60,6 +61,7 @@ static u32 arcfour_byte(struct arc4context *parc4ctx) u32 y; u32 sx, sy; u8 *state; + state = parc4ctx->state; x = (parc4ctx->x + 1) & 0xff; sx = state[x]; @@ -75,6 +77,7 @@ static u32 arcfour_byte(struct arc4context *parc4ctx) static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len) { u32 i; + for (i = 0; i < len; i++) dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); } @@ -120,6 +123,7 @@ static __le32 getcrc32(u8 *buf, int len) { u8 *p; u32 crc; + if (bcrc32initialized == 0) crc32_init(); @@ -204,7 +208,7 @@ void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe) struct security_priv *psecuritypriv = &padapter->securitypriv; - pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; + pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data; /* start to decrypt recvframe */ if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) { @@ -213,7 +217,7 @@ void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe) keylength = psecuritypriv->dot11DefKeylen[keyindex]; memcpy(&wepkey[0], iv, 3); memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength); - length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len; + length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len; payload = pframe+prxattrib->iv_len+prxattrib->hdrlen; @@ -242,6 +246,7 @@ static u32 secmicgetuint32(u8 *p) { s32 i; u32 res = 0; + for (i = 0; i < 4; i++) res |= ((u32)(*p++)) << (8*i); return res; @@ -251,6 +256,7 @@ static void secmicputuint32(u8 *p, u32 val) /* Convert from Us3232 to Byte[] in a portable way */ { long i; + for (i = 0; i < 4; i++) { *p++ = (u8)(val & 0xff); val >>= 8; @@ -328,6 +334,7 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod { struct mic_data micdata; u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; + rtw_secmicsetkey(&micdata, key); priority[0] = pri; @@ -378,73 +385,73 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */ { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, }, { /* second half of table is unsigned char-reversed version of first! */ - 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, - 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, - 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, - 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, - 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, - 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, - 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, - 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, - 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, - 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, - 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, - 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, - 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, - 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, - 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, - 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, - 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, - 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, - 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, - 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, - 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, - 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, - 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, - 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, - 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, - 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, - 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, - 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, - 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, - 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, - 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, - 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, + 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, + 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, + 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, + 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, + 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, + 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, + 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, + 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, + 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, + 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, + 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, + 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, + 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, + 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, + 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, + 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, + 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, + 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, + 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, + 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, + 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, + 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, + 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, + 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, + 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, + 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, + 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, + 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, + 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, + 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, + 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, + 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, } }; @@ -652,7 +659,7 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) u32 res = _SUCCESS; - pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; + pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data; /* 4 start to decrypt recvframe */ if (prxattrib->encrypt == _TKIP_) { @@ -672,7 +679,7 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) iv = pframe+prxattrib->hdrlen; payload = pframe+prxattrib->iv_len+prxattrib->hdrlen; - length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len; + length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len; GET_TKIP_PN(iv, dot11txpn); @@ -776,6 +783,7 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); static void xor_128(u8 *a, u8 *b, u8 *out) { int i; + for (i = 0; i < 16; i++) out[i] = a[i] ^ b[i]; } @@ -783,6 +791,7 @@ static void xor_128(u8 *a, u8 *b, u8 *out) static void xor_32(u8 *a, u8 *b, u8 *out) { int i; + for (i = 0; i < 4; i++) out[i] = a[i] ^ b[i]; } @@ -800,6 +809,7 @@ static void next_key(u8 *key, int round) 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x36, 0x36 }; + sbox_key[0] = sbox(key[13]); sbox_key[1] = sbox(key[14]); sbox_key[2] = sbox(key[15]); @@ -853,6 +863,7 @@ static void mix_column(u8 *in, u8 *out) u8 rotr[4]; u8 temp[4]; u8 tempb[4]; + for (i = 0 ; i < 4; i++) { if ((in[i] & 0x80) == 0x80) add1b[i] = 0x1b; @@ -905,6 +916,7 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) u8 intermediatea[16]; u8 intermediateb[16]; u8 round_key[16]; + for (i = 0; i < 16; i++) round_key[i] = key[i]; for (round = 0; round < 11; round++) { @@ -936,6 +948,7 @@ static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector) { int i; + mic_iv[0] = 0x59; if (qc_exists && a4_exists) mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ @@ -984,6 +997,7 @@ static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu) static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists) { int i; + for (i = 0; i < 16; i++) mic_header2[i] = 0x00; @@ -1025,6 +1039,7 @@ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c) { int i; + for (i = 0; i < 16; i++) ctr_preload[i] = 0x00; i = 0; @@ -1050,6 +1065,7 @@ static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) { int i; + for (i = 0; i < 16; i++) out[i] = ina[i] ^ inb[i]; } @@ -1256,6 +1272,7 @@ static int aes_decipher(u8 *key, uint hdrlen, uint qc_exists, a4_exists, i, j, payload_remainder, num_blocks, payload_index; int res = _SUCCESS; + u8 pn_vector[6]; u8 mic_iv[16]; u8 mic_header1[16]; @@ -1452,7 +1469,8 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; u32 res = _SUCCESS; - pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; + + pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data; /* 4 start to encrypt each fragment */ if (prxattrib->encrypt == _AES_) { stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); @@ -1476,7 +1494,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) } else { prwskey = &stainfo->dot118021x_UncstKey.skey[0]; } - length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len; + length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len; res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length); } else { RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n")); diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c index 941d1a069d20..2ecfb117bf3f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c @@ -154,6 +154,7 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv) while (phead != plist) { int i; + psta = container_of(plist, struct sta_info, hash_list); plist = plist->next; diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 2a65ac702129..f6f1b09466a8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -379,6 +379,7 @@ int get_bsstype(unsigned short capability) u16 get_beacon_interval(struct wlan_bssid_ex *bss) { __le16 val; + memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2); return le16_to_cpu(val); @@ -1306,6 +1307,7 @@ void set_sta_rate(struct adapter *padapter, struct sta_info *psta) void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode) { unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX]; + memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX); if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) @@ -1330,6 +1332,7 @@ unsigned char check_assoc_AP(u8 *pframe, uint len) struct ndis_802_11_var_ie *pIE; u8 epigram_vendor_flag; u8 ralink_vendor_flag; + epigram_vendor_flag = 0; ralink_vendor_flag = 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index b60b126b860e..630fdc33d58a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -246,8 +246,7 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) pxmitbuf++; } - if (pxmitpriv->pallocated_xmit_extbuf) - vfree(pxmitpriv->pallocated_xmit_extbuf); + vfree(pxmitpriv->pallocated_xmit_extbuf); rtw_free_hwxmits(padapter); @@ -304,6 +303,7 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame * /* check HT op mode */ if (pattrib->ht_en) { u8 htopmode = pmlmeinfo->HT_protection; + if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) || (!pmlmeext->cur_bwmode && htopmode == 3)) { pattrib->vcs_mode = RTS_CTS; @@ -454,6 +454,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p /* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */ /* to prevent DHCP protocol fail */ u8 tmp[24]; + _rtw_pktfile_read(&pktfile, &tmp[0], 24); pattrib->dhcp_pkt = 0; if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */ @@ -530,7 +531,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p pattrib->encrypt = 0; - if ((pattrib->ether_type != ETH_P_PAE) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) { + if (pattrib->ether_type != ETH_P_PAE) { RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != ETH_P_PAE\n", pattrib->ether_type)); res = _FAIL; goto exit; @@ -1605,6 +1606,7 @@ void rtw_free_hwxmits(struct adapter *padapter) void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry) { int i; + for (i = 0; i < entry; i++, phwxmit++) phwxmit->accnt = 0; } diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index 134fa6c595a8..26e0ef224299 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -534,9 +534,8 @@ static void store_pwrindex_offset(struct adapter *adapter, power_level_offset[11] = data; if (regaddr == rTxAGC_B_Mcs11_Mcs08) power_level_offset[12] = data; - if (regaddr == rTxAGC_B_Mcs15_Mcs12) { + if (regaddr == rTxAGC_B_Mcs15_Mcs12) power_level_offset[13] = data; - } } static void rtl_addr_delay(struct adapter *adapt, diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c index fa2cfd5768de..d9fa290c5f78 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c @@ -150,7 +150,7 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, pkt_info.bPacketToSelf = false; pkt_info.bPacketBeacon = false; - wlanhdr = precvframe->rx_data; + wlanhdr = precvframe->pkt->data; pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && !pattrib->icv_err && !pattrib->crc_err && diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index 85650b2663ec..53e312aaefb5 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -635,7 +635,7 @@ s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) if (res == _SUCCESS) { rtw_dump_xframe(adapt, pxmitframe); } else { - DBG_88E("==> %s xmitframe_coalsece failed\n", __func__); + DBG_88E("==> %s xmitframe_coalesce failed\n", __func__); rtw_free_xmitbuf(pxmitpriv, pxmitbuf); rtw_free_xmitframe(pxmitpriv, pxmitframe); } diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h index e86419e525d8..0fd2a2d9be20 100644 --- a/drivers/staging/rtl8188eu/include/drv_types.h +++ b/drivers/staging/rtl8188eu/include/drv_types.h @@ -168,7 +168,6 @@ struct adapter { u8 bFWReady; u8 bReadPortCancel; u8 bWritePortCancel; - u8 bRxRSSIDisplay; struct mutex hw_init_mutex; }; diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index 9047b6dec9ed..ee3f5ee06529 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -69,9 +69,6 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)); } -int RTW_STATUS_CODE(int error_code); - -#define rtw_update_mem_stat(flag, sz) do {} while (0) u8 *_rtw_malloc(u32 sz); #define rtw_malloc(sz) _rtw_malloc((sz)) @@ -88,10 +85,6 @@ struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv); (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv) void rtw_free_netdev(struct net_device *netdev); -#define NDEV_FMT "%s" -#define NDEV_ARG(ndev) ndev->name -#define ADPT_FMT "%s" -#define ADPT_ARG(adapter) adapter->pnetdev->name #define FUNC_NDEV_FMT "%s(%s)" #define FUNC_NDEV_ARG(ndev) __func__, ndev->name #define FUNC_ADPT_FMT "%s(%s)" diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h index 95590a1a7b1b..9cc4b8c7c166 100644 --- a/drivers/staging/rtl8188eu/include/rtw_debug.h +++ b/drivers/staging/rtl8188eu/include/rtw_debug.h @@ -70,7 +70,7 @@ extern u32 GlobalDebugLevel; #define DBG_88E_LEVEL(_level, fmt, arg...) \ do { \ if (_level <= GlobalDebugLevel) \ - pr_info(DRIVER_PREFIX"ERROR " fmt, ##arg); \ + pr_info(DRIVER_PREFIX fmt, ##arg); \ } while (0) #define DBG_88E(...) \ diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h index 18fb7e7b2273..7324a95bb162 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h @@ -47,14 +47,6 @@ #define WIFI_STA_ALIVE_CHK_STATE 0x00000400 #define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station is under site surveying */ -#define WIFI_MP_STATE 0x00010000 -#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */ -#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */ -#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */ -#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */ -#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */ -#define WIFI_MP_LPBK_STATE 0x00400000 - #define _FW_UNDER_LINKING WIFI_UNDER_LINKING #define _FW_LINKED WIFI_ASOC_STATE #define _FW_UNDER_SURVEY WIFI_SITE_MONITOR @@ -115,183 +107,6 @@ struct rt_link_detect { * to Tx traffic. */ }; -struct profile_info { - u8 ssidlen; - u8 ssid[WLAN_SSID_MAXLEN]; - u8 peermac[ETH_ALEN]; -}; - -struct tx_invite_req_info { - u8 token; - u8 benable; - u8 go_ssid[WLAN_SSID_MAXLEN]; - u8 ssidlen; - u8 go_bssid[ETH_ALEN]; - u8 peer_macaddr[ETH_ALEN]; - u8 operating_ch; /* This information will be set by using the - * p2p_set op_ch=x */ - u8 peer_ch; /* The listen channel for peer P2P device */ -}; - -struct tx_invite_resp_info { - u8 token; /* Used to record the dialog token of p2p invitation - * request frame. */ -}; - -struct tx_provdisc_req_info { - u16 wps_config_method_request; /* Used when sending the - * provisioning request frame*/ - u16 peer_channel_num[2]; /* The channel number which the - * receiver stands. */ - struct ndis_802_11_ssid ssid; - u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ - u8 peerIFAddr[ETH_ALEN]; /* Peer interface address */ - u8 benable; /* This provision discovery - * request frame is trigger - * to send or not */ -}; - -/* When peer device issue prov_disc_req first, we should store the following - * information */ -/* The UI must know this information to know which config method the - * remote p2p device needs. */ -struct rx_provdisc_req_info { - u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ - u8 strconfig_method_desc_of_prov_disc_req[4]; /* description - * for the config method located in the provisioning - * discovery request frame. */ -}; - -struct tx_nego_req_info { - u16 peer_channel_num[2]; /* The channel number. */ - u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ - u8 benable; /* This negotiation request frame is - * trigger to send or not */ -}; - -struct group_id_info { - u8 go_device_addr[ETH_ALEN]; /* The GO's device address of - * this P2P group */ - u8 ssid[WLAN_SSID_MAXLEN]; /* The SSID of this P2P group */ -}; - -struct scan_limit_info { - u8 scan_op_ch_only; /* When this flag is set, the driver - * should only scan the op. channel */ - u8 operation_ch[2]; /* Store the op. chan of invitation */ -}; - -struct wifidirect_info { - struct adapter *padapter; - struct timer_list find_phase_timer; - struct timer_list restore_p2p_state_timer; - - /* Used to do the scanning. After confirming the peer is availalble, - * the driver transmits the P2P frame to peer. */ - struct timer_list pre_tx_scan_timer; - struct timer_list reset_ch_sitesurvey; - struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan - * limit function by using p2p nego */ - struct tx_provdisc_req_info tx_prov_disc_info; - struct rx_provdisc_req_info rx_prov_disc_info; - struct tx_invite_req_info invitereq_info; - /* Store the profile information of persistent group */ - struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM]; - struct tx_invite_resp_info inviteresp_info; - struct tx_nego_req_info nego_req_info; - /* Store the group id info when doing the group negot handshake. */ - struct group_id_info groupid_info; - /* Used for get the limit scan channel from the Invitation procedure */ - struct scan_limit_info rx_invitereq_info; - /* Used for get the limit scan chan from the P2P negotiation handshake*/ - struct scan_limit_info p2p_info; - enum P2P_ROLE role; - enum P2P_STATE pre_p2p_state; - enum P2P_STATE p2p_state; - /* The device address should be the mac address of this device. */ - u8 device_addr[ETH_ALEN]; - u8 interface_addr[ETH_ALEN]; - u8 social_chan[4]; - u8 listen_channel; - u8 operating_channel; - u8 listen_dwell; /* This value should be between 1 and 3 */ - u8 support_rate[8]; - u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; - u8 intent; /* should only include the intent value. */ - u8 p2p_peer_interface_addr[ETH_ALEN]; - u8 p2p_peer_device_addr[ETH_ALEN]; - u8 peer_intent; /* Included the intent value and tie breaker value. */ - /* Device name for displaying on searching device screen */ - u8 device_name[WPS_MAX_DEVICE_NAME_LEN]; - u8 device_name_len; - u8 profileindex; /* Used to point to the index of profileinfo array */ - u8 peer_operating_ch; - u8 find_phase_state_exchange_cnt; - /* The device password ID for group negotiation */ - u16 device_password_id_for_nego; - u8 negotiation_dialog_token; - /* SSID information for group negotitation */ - u8 nego_ssid[WLAN_SSID_MAXLEN]; - u8 nego_ssidlen; - u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; - u8 p2p_group_ssid_len; - /* Flag to know if the persistent function should be supported or not.*/ - u8 persistent_supported; - /* In the Sigma test, the Sigma will provide this enable from the - * sta_set_p2p CAPI. */ - /* 0: disable */ - /* 1: enable */ - u8 session_available; /* Flag to set the WFD session available to - * enable or disable "by Sigma" */ - /* In the Sigma test, the Sigma will disable the session available - * by using the sta_preset CAPI. */ - /* 0: disable */ - /* 1: enable */ - u8 wfd_tdls_enable; /* Flag to enable or disable the TDLS by WFD Sigma*/ - /* 0: disable */ - /* 1: enable */ - u8 wfd_tdls_weaksec; /* Flag to enable or disable the weak security - * function for TDLS by WFD Sigma */ - /* 0: disable */ - /* In this case, the driver can't issue the tdsl - * setup request frame. */ - /* 1: enable */ - /* In this case, the driver can issue the tdls - * setup request frame */ - /* even the current security is weak security. */ - - /* This field will store the WPS value (PIN value or PBC) that UI had - * got from the user. */ - enum P2P_WPSINFO ui_got_wps_info; - u16 supported_wps_cm; /* This field describes the WPS config method - * which this driver supported. */ - /* The value should be the combination of config - * method defined in page104 of WPS v2.0 spec.*/ - /* This field will contain the length of body of P2P Channel List - * attribute of group negotiation response frame. */ - uint channel_list_attr_len; - /* This field will contain the body of P2P Channel List attribute of - * group negotitation response frame. */ - /* We will use the channel_cnt and channel_list fields when constructing - * the group negotiation confirm frame. */ - u8 channel_list_attr[100]; - enum P2P_PS_MODE p2p_ps_mode; /* indicate p2p ps mode */ - enum P2P_PS_STATE p2p_ps_state; /* indicate p2p ps state */ - u8 noa_index; /* Identifies and instance of Notice of Absence timing. */ - u8 ctwindow; /* Client traffic window. A period of time in TU after TBTT. */ - u8 opp_ps; /* opportunistic power save. */ - u8 noa_num; /* number of NoA descriptor in P2P IE. */ - u8 noa_count[P2P_MAX_NOA_NUM]; /* Count for owner, Type of client. */ - /* Max duration for owner, preferred or min acceptable duration for - * client. */ - u32 noa_duration[P2P_MAX_NOA_NUM]; - /* Length of interval for owner, preferred or max acceptable interval - * of client. */ - u32 noa_interval[P2P_MAX_NOA_NUM]; - /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */ - u32 noa_start_time[P2P_MAX_NOA_NUM]; -}; - struct mlme_priv { spinlock_t lock; int fw_state; /* shall we protect this variable? maybe not necessarily... */ diff --git a/drivers/staging/rtl8188eu/include/rtw_recv.h b/drivers/staging/rtl8188eu/include/rtw_recv.h index 052af7b891da..b369f08d4a15 100644 --- a/drivers/staging/rtl8188eu/include/rtw_recv.h +++ b/drivers/staging/rtl8188eu/include/rtw_recv.h @@ -151,8 +151,6 @@ struct recv_stat { __le32 rxdw5; }; -#define EOR BIT(30) - /* accesser of recv_priv: rtw_recv_entry(dispatch / passive level); recv_thread(passive) ; returnpkt(dispatch) @@ -179,8 +177,6 @@ struct recv_priv { struct recv_buf *precv_buf; /* 4 alignment */ struct __queue free_recv_buf_queue; /* For display the phy informatiom */ - u8 is_signal_dbg; /* for debug */ - u8 signal_strength_dbg; /* for debug */ s8 rssi; s8 rxpwdb; u8 signal_strength; @@ -232,11 +228,6 @@ struct recv_frame { struct sk_buff *pkt; struct adapter *adapter; struct rx_pkt_attrib attrib; - uint len; - u8 *rx_head; - u8 *rx_data; - u8 *rx_tail; - u8 *rx_end; struct sta_info *psta; /* for A-MPDU Rx reordering buffer control */ struct recv_reorder_ctrl *preorder_ctrl; @@ -258,70 +249,6 @@ u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter); void rtw_reordering_ctrl_timeout_handler(unsigned long data); -static inline u8 *get_rxmem(struct recv_frame *precvframe) -{ - /* always return rx_head... */ - if (precvframe == NULL) - return NULL; - return precvframe->rx_head; -} - -static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz) -{ - /* rx_data += sz; move rx_data sz bytes hereafter */ - - /* used for extract sz bytes from rx_data, update rx_data and return - * the updated rx_data to the caller */ - - if (precvframe == NULL) - return NULL; - precvframe->rx_data += sz; - if (precvframe->rx_data > precvframe->rx_tail) { - precvframe->rx_data -= sz; - return NULL; - } - precvframe->len -= sz; - return precvframe->rx_data; -} - -static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz) -{ - /* used for append sz bytes from ptr to rx_tail, update rx_tail - * and return the updated rx_tail to the caller */ - /* after putting, rx_tail must be still larger than rx_end. */ - - if (precvframe == NULL) - return NULL; - - precvframe->rx_tail += sz; - - if (precvframe->rx_tail > precvframe->rx_end) { - precvframe->rx_tail -= sz; - return NULL; - } - precvframe->len += sz; - return precvframe->rx_tail; -} - -static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz) -{ - /* rmv data from rx_tail (by yitsen) */ - - /* used for extract sz bytes from rx_end, update rx_end and return - * the updated rx_end to the caller */ - /* after pulling, rx_end must be still larger than rx_data. */ - - if (precvframe == NULL) - return NULL; - precvframe->rx_tail -= sz; - if (precvframe->rx_tail < precvframe->rx_data) { - precvframe->rx_tail += sz; - return NULL; - } - precvframe->len -= sz; - return precvframe->rx_tail; -} - static inline s32 translate_percentage_to_dbm(u32 sig_stren_index) { s32 power; /* in dBm. */ diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h index 2663e60bb6c6..7100d6b01b32 100644 --- a/drivers/staging/rtl8188eu/include/rtw_security.h +++ b/drivers/staging/rtl8188eu/include/rtw_security.h @@ -255,42 +255,6 @@ static inline u32 rotr(u32 val, int bits) #define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) #define TE3(i) rotr(Te0[(i) & 0xff], 24) -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ - ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) - -#define PUTU32(ct, st) { \ -(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ -(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } - -#define WPA_GET_BE32(a) ((((u32)(a)[0]) << 24) | (((u32)(a)[1]) << 16) | \ - (((u32)(a)[2]) << 8) | ((u32)(a)[3])) - -#define WPA_PUT_LE16(a, val) \ - do { \ - (a)[1] = ((u16)(val)) >> 8; \ - (a)[0] = ((u16)(val)) & 0xff; \ - } while (0) - -#define WPA_PUT_BE32(a, val) \ - do { \ - (a)[0] = (u8)((((u32)(val)) >> 24) & 0xff); \ - (a)[1] = (u8)((((u32)(val)) >> 16) & 0xff); \ - (a)[2] = (u8)((((u32)(val)) >> 8) & 0xff); \ - (a)[3] = (u8)(((u32)(val)) & 0xff); \ - } while (0) - -#define WPA_PUT_BE64(a, val) \ - do { \ - (a)[0] = (u8)(((u64)(val)) >> 56); \ - (a)[1] = (u8)(((u64)(val)) >> 48); \ - (a)[2] = (u8)(((u64)(val)) >> 40); \ - (a)[3] = (u8)(((u64)(val)) >> 32); \ - (a)[4] = (u8)(((u64)(val)) >> 24); \ - (a)[5] = (u8)(((u64)(val)) >> 16); \ - (a)[6] = (u8)(((u64)(val)) >> 8); \ - (a)[7] = (u8)(((u64)(val)) & 0xff); \ - } while (0) - /* ===== start - public domain SHA256 implementation ===== */ /* This is based on SHA256 implementation in LibTomCrypt that was released into diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index 9e08e6842eca..cb46d353327b 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -23,7 +23,6 @@ #define WLAN_HDR_A4_LEN 30 #define WLAN_HDR_A3_QOS_LEN 26 #define WLAN_HDR_A4_QOS_LEN 32 -#define WLAN_SSID_MAXLEN 32 #define WLAN_DATA_MAXLEN 2312 #define WLAN_A3_PN_OFFSET 24 @@ -480,30 +479,6 @@ static inline int IsFrameTypeCtrl(unsigned char *pframe) Below is the definition for 802.11n ------------------------------------------------------------------------------*/ -#define SetOrderBit(pbuf) \ - do { \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ - } while (0) - -#define GetOrderBit(pbuf) \ - (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) - - -/** - * struct rtw_ieee80211_bar - HT Block Ack Request - * - * This structure refers to "HT BlockAckReq" as - * described in 802.11n draft section 7.2.1.7.1 - */ -struct rtw_ieee80211_bar { - unsigned short frame_control; - unsigned short duration; - unsigned char ra[6]; - unsigned char ta[6]; - unsigned short control; - unsigned short start_seq_num; -} __packed; - /* 802.11 BAR control masks */ #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 @@ -653,9 +628,6 @@ enum ht_cap_ampdu_factor { #define WPS_ATTR_VENDOR_EXT 0x1049 #define WPS_ATTR_SELECTED_REGISTRAR 0x1041 -/* Value of WPS attribute "WPS_ATTR_DEVICE_NAME */ -#define WPS_MAX_DEVICE_NAME_LEN 32 - /* Value of WPS Request Type Attribute */ #define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 #define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 @@ -758,14 +730,6 @@ enum ht_cap_ampdu_factor { #define P2P_STATUS_FAIL_USER_REJECT 0x0B /* Value of Invitation Flags Attribute */ -#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) - -#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ - P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ - P2P_DEVCAP_CONCURRENT_OPERATION | \ - P2P_DEVCAP_INVITATION_PROC) - -#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) /* Value of Device Capability Bitmap */ #define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) @@ -804,13 +768,8 @@ enum ht_cap_ampdu_factor { #define P2P_PRESENCE_RESPONSE 2 #define P2P_GO_DISC_REQUEST 3 - -#define P2P_MAX_PERSISTENT_GROUP_NUM 10 - #define P2P_PROVISIONING_SCAN_CNT 3 -#define P2P_WILDCARD_SSID_LEN 7 - /* default value, used when: (1)p2p disabled or (2)p2p enabled * but only do 1 scan phase */ #define P2P_FINDPHASE_EX_NONE 0 @@ -839,8 +798,6 @@ enum ht_cap_ampdu_factor { #define P2P_RESET_SCAN_CH 25000 #define P2P_MAX_INTENT 15 -#define P2P_MAX_NOA_NUM 2 - /* WPS Configuration Method */ #define WPS_CM_NONE 0x0000 #define WPS_CM_LABEL 0x0004 @@ -855,64 +812,6 @@ enum ht_cap_ampdu_factor { #define WPS_CM_SW_DISPLAY_P 0x2008 #define WPS_CM_LCD_DISPLAY_P 0x4008 -enum P2P_ROLE { - P2P_ROLE_DISABLE = 0, - P2P_ROLE_DEVICE = 1, - P2P_ROLE_CLIENT = 2, - P2P_ROLE_GO = 3 -}; - -enum P2P_STATE { - P2P_STATE_NONE = 0, /* P2P disable */ - /* P2P had enabled and do nothing */ - P2P_STATE_IDLE = 1, - P2P_STATE_LISTEN = 2, /* In pure listen state */ - P2P_STATE_SCAN = 3, /* In scan phase */ - /* In the listen state of find phase */ - P2P_STATE_FIND_PHASE_LISTEN = 4, - /* In the search state of find phase */ - P2P_STATE_FIND_PHASE_SEARCH = 5, - /* In P2P provisioning discovery */ - P2P_STATE_TX_PROVISION_DIS_REQ = 6, - P2P_STATE_RX_PROVISION_DIS_RSP = 7, - P2P_STATE_RX_PROVISION_DIS_REQ = 8, - /* Doing the group owner negotiation handshake */ - P2P_STATE_GONEGO_ING = 9, - /* finish the group negotiation handshake with success */ - P2P_STATE_GONEGO_OK = 10, - /* finish the group negotiation handshake with failure */ - P2P_STATE_GONEGO_FAIL = 11, - /* receiving the P2P Invitation request and match with the profile. */ - P2P_STATE_RECV_INVITE_REQ_MATCH = 12, - /* Doing the P2P WPS */ - P2P_STATE_PROVISIONING_ING = 13, - /* Finish the P2P WPS */ - P2P_STATE_PROVISIONING_DONE = 14, - /* Transmit the P2P Invitation request */ - P2P_STATE_TX_INVITE_REQ = 15, - /* Receiving the P2P Invitation response */ - P2P_STATE_RX_INVITE_RESP_OK = 16, - /* receiving the P2P Invitation request and dismatch with the profile. */ - P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, - /* receiving the P2P Invitation request and this wifi is GO. */ - P2P_STATE_RECV_INVITE_REQ_GO = 18, - /* receiving the P2P Invitation request to join an existing P2P Group. */ - P2P_STATE_RECV_INVITE_REQ_JOIN = 19, - /* receiving the P2P Invitation response with failure */ - P2P_STATE_RX_INVITE_RESP_FAIL = 20, - /* receiving p2p negotiation response with information is not available */ - P2P_STATE_RX_INFOR_NOREADY = 21, - /* sending p2p negotiation response with information is not available */ - P2P_STATE_TX_INFOR_NOREADY = 22, -}; - -enum P2P_WPSINFO { - P2P_NO_WPSINFO = 0, - P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, - P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, - P2P_GOT_WPSINFO_PBC = 3, -}; - #define P2P_PRIVATE_IOCTL_SET_LEN 64 enum P2P_PROTO_WK_ID { @@ -925,21 +824,6 @@ enum P2P_PROTO_WK_ID { P2P_RO_CH_WK = 6, }; -enum P2P_PS_STATE { - P2P_PS_DISABLE = 0, - P2P_PS_ENABLE = 1, - P2P_PS_SCAN = 2, - P2P_PS_SCAN_DONE = 3, - P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ -}; - -enum P2P_PS_MODE { - P2P_PS_NONE = 0, - P2P_PS_CTWINDOW = 1, - P2P_PS_NOA = 2, - P2P_PS_MIX = 3, /* CTWindow and NoA */ -}; - /* =====================WFD Section===================== */ /* For Wi-Fi Display */ #define WFD_ATTR_DEVICE_INFO 0x00 diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 4de9dbc93380..763eccd0c7c9 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -134,6 +134,7 @@ static char *translate_scan(struct adapter *padapter, if (p && ht_ielen > 0) { struct ieee80211_ht_cap *pht_capie; ht_cap = true; + pht_capie = (struct ieee80211_ht_cap *)(p + 2); memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); bw_40MHz = !!(le16_to_cpu(pht_capie->cap_info) & @@ -285,8 +286,8 @@ static char *translate_scan(struct adapter *padapter, uint cnt = 0, total_ielen; u8 *wpsie_ptr = NULL; uint wps_ielen = 0; - u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; + total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; while (cnt < total_ielen) { @@ -442,7 +443,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, struct sta_info *psta, *pbcmc_sta; struct sta_priv *pstapriv = &padapter->stapriv; - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */ + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { /* sta mode */ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); if (!psta) { ; @@ -523,6 +524,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie /* dump */ { int i; + DBG_88E("\n wpa_ie(length:%d):\n", ielen); for (i = 0; i < ielen; i += 8) DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]); @@ -1084,14 +1086,9 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n")); - if (padapter->registrypriv.mp_mode == 1) { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - ret = -1; - goto exit; - } - } if (_FAIL == rtw_pwr_wakeup(padapter)) { ret = -1; goto exit; @@ -1225,6 +1222,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, u32 cnt = 0; u32 wait_for_surveydone; int wait_status; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n")); RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n")); @@ -1613,6 +1611,7 @@ static int rtw_wx_set_enc(struct net_device *dev, struct iw_point *erq = &(wrqu->encoding); struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); memset(&wep, 0, sizeof(struct ndis_802_11_wep)); diff --git a/drivers/staging/rtl8188eu/os_dep/mon.c b/drivers/staging/rtl8188eu/os_dep/mon.c index c9c9821cfc32..cfe37eb026d6 100644 --- a/drivers/staging/rtl8188eu/os_dep/mon.c +++ b/drivers/staging/rtl8188eu/os_dep/mon.c @@ -92,8 +92,8 @@ void rtl88eu_mon_recv_hook(struct net_device *dev, struct recv_frame *frame) return; attr = &frame->attrib; - data = frame->rx_data; - data_len = frame->len; + data = frame->pkt->data; + data_len = frame->pkt->len; /* Broadcast and multicast frames don't have attr->{iv,icv}_len set */ SET_ICE_IV_LEN(iv_len, icv_len, attr->encrypt); diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 8fc3fadf065f..5f6a24546a91 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -413,7 +413,6 @@ static u8 rtw_init_default_value(struct adapter *padapter) /* misc. */ padapter->bReadPortCancel = false; padapter->bWritePortCancel = false; - padapter->bRxRSSIDisplay = 0; return _SUCCESS; } @@ -426,7 +425,6 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) rtw_hal_def_value_init(padapter); padapter->bReadPortCancel = false; padapter->bWritePortCancel = false; - padapter->bRxRSSIDisplay = 0; pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ padapter->xmitpriv.tx_pkts = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index 6ff836f481da..3be87252fd62 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -21,18 +21,6 @@ #include <linux/vmalloc.h> #include <rtw_ioctl_set.h> -/* - * Translate the OS dependent @param error_code to OS independent - * RTW_STATUS_CODE - * @return: one of RTW_STATUS_CODE - */ -inline int RTW_STATUS_CODE(int error_code) -{ - if (error_code >= 0) - return _SUCCESS; - return _FAIL; -} - u8 *_rtw_malloc(u32 sz) { return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); @@ -41,8 +29,8 @@ u8 *_rtw_malloc(u32 sz) void *rtw_malloc2d(int h, int w, int size) { int j; - void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL); + if (!a) goto out; diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c index b85824ec5354..d14bc2b68d98 100644 --- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c @@ -88,27 +88,6 @@ int rtw_recv_indicatepkt(struct adapter *padapter, goto _recv_indicatepkt_drop; } - RT_TRACE(_module_recv_osdep_c_, _drv_info_, - ("rtw_recv_indicatepkt():skb != NULL !!!\n")); - RT_TRACE(_module_recv_osdep_c_, _drv_info_, - ("rtw_recv_indicatepkt():precv_frame->rx_head =%p precv_frame->hdr.rx_data =%p\n", - precv_frame->rx_head, precv_frame->rx_data)); - RT_TRACE(_module_recv_osdep_c_, _drv_info_, - ("precv_frame->hdr.rx_tail =%p precv_frame->rx_end =%p precv_frame->hdr.len =%d\n", - precv_frame->rx_tail, precv_frame->rx_end, - precv_frame->len)); - - skb->data = precv_frame->rx_data; - - skb_set_tail_pointer(skb, precv_frame->len); - - skb->len = precv_frame->len; - - RT_TRACE(_module_recv_osdep_c_, _drv_info_, - ("skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n", - skb->head, skb->data, skb_tail_pointer(skb), - skb_end_pointer(skb), skb->len)); - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { struct sk_buff *pskb2 = NULL; struct sta_info *psta = NULL; diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 41e1b1d15b81..336e7023f7f7 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -73,6 +73,7 @@ static int g_wifi_on = true; 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], strlen(android_wifi_cmd_str[cmd_num]))) diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index c6316ffa64d3..963235fd7292 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -83,6 +83,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) for (i = 0; i < piface_desc->bNumEndpoints; i++) { int ep_num; + pendp_desc = &phost_iface->endpoint[i].desc; ep_num = usb_endpoint_num(pendp_desc); diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index e2dbe1b4afd3..64397b6f1248 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -73,7 +73,6 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) } INIT_LIST_HEAD(&precvframe->list); - precvframe->len = 0; update_recvframe_attrib_88e(precvframe, prxstat); @@ -125,34 +124,16 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) if (pkt_copy) { pkt_copy->dev = adapt->pnetdev; precvframe->pkt = pkt_copy; - precvframe->rx_head = pkt_copy->data; - precvframe->rx_end = pkt_copy->data + alloc_sz; skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */ skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */ memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); - precvframe->rx_tail = pkt_copy->data; - precvframe->rx_data = pkt_copy->data; + skb_put(precvframe->pkt, skb_len); } else { - if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { - DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n"); - rtw_free_recvframe(precvframe, pfree_recv_queue); - goto _exit_recvbuf2recvframe; - } - precvframe->pkt = skb_clone(pskb, GFP_ATOMIC); - if (precvframe->pkt) { - precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE; - precvframe->rx_head = precvframe->rx_tail; - precvframe->rx_data = precvframe->rx_tail; - precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz; - } else { - DBG_88E("recvbuf2recvframe: skb_clone fail\n"); - rtw_free_recvframe(precvframe, pfree_recv_queue); - goto _exit_recvbuf2recvframe; - } + DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n"); + rtw_free_recvframe(precvframe, pfree_recv_queue); + goto _exit_recvbuf2recvframe; } - recvframe_put(precvframe, skb_len); - switch (haldata->UsbRxAggMode) { case USB_RX_AGG_DMA: case USB_RX_AGG_MIX: @@ -174,19 +155,19 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) } } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX-TXRPT ack for xmit mgmt frames. */ - handle_txrpt_ccx_88e(adapt, precvframe->rx_data); + handle_txrpt_ccx_88e(adapt, precvframe->pkt->data); rtw_free_recvframe(precvframe, pfree_recv_queue); } else if (pattrib->pkt_rpt_type == TX_REPORT2) { ODM_RA_TxRPT2Handle_8188E( &haldata->odmpriv, - precvframe->rx_data, + precvframe->pkt->data, pattrib->pkt_len, pattrib->MacIDValidEntry[0], pattrib->MacIDValidEntry[1] ); rtw_free_recvframe(precvframe, pfree_recv_queue); } else if (pattrib->pkt_rpt_type == HIS_REPORT) { - interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->rx_data); + interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->pkt->data); rtw_free_recvframe(precvframe, pfree_recv_queue); } pkt_cnt--; @@ -471,7 +452,7 @@ u32 usb_read_port(struct adapter *adapter, u32 addr, struct recv_buf *precvbuf) if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) { precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); - if (NULL != precvbuf->pskb) + if (precvbuf->pskb != NULL) precvbuf->reuse = true; } diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index aac395f26652..623075cf0c05 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -11,7 +11,7 @@ * * Contact Information: * wlanfae <wlanfae@realtek.com> -******************************************************************************/ + ******************************************************************************/ #ifndef __INC_DOT11D_H #define __INC_DOT11D_H diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 8a9172aa8178..4c0caa6701a9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -2695,10 +2695,8 @@ static void _rtl92e_pci_disconnect(struct pci_dev *pdev) priv->polling_timer_on = 0; _rtl92e_down(dev, true); rtl92e_dm_deinit(dev); - if (priv->pFirmware) { - vfree(priv->pFirmware); - priv->pFirmware = NULL; - } + vfree(priv->pFirmware); + priv->pFirmware = NULL; _rtl92e_free_rx_ring(dev); for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) _rtl92e_free_tx_ring(dev, i); @@ -2797,9 +2795,9 @@ MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW); MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW); MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW); -module_param(ifname, charp, S_IRUGO|S_IWUSR); -module_param(hwwep, int, S_IRUGO|S_IWUSR); -module_param(channels, int, S_IRUGO|S_IWUSR); +module_param(ifname, charp, 0644); +module_param(hwwep, int, 0644); +module_param(channels, int, 0644); MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)"); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 1430ba27b049..eeda17d6409b 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -3365,23 +3365,21 @@ static int rtllib_wpa_set_encryption(struct rtllib_device *ieee, } else sec.flags &= ~SEC_ACTIVE_KEY; - if (param->u.crypt.alg != NULL) { - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, - param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - - if (strcmp(param->u.crypt.alg, "R-WEP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(param->u.crypt.alg, "R-TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(param->u.crypt.alg, "R-CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } + memcpy(sec.keys[param->u.crypt.idx], + param->u.crypt.key, + param->u.crypt.key_len); + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + + if (strcmp(param->u.crypt.alg, "R-WEP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(param->u.crypt.alg, "R-TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(param->u.crypt.alg, "R-CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; } done: if (ieee->set_security) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 077ea13eb1e7..0d247058bce4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -83,7 +83,7 @@ #define SUPPORT_CKIP_PK 0x10 // bit4 /* defined for skb cb field */ /* At most 28 byte */ -typedef struct cb_desc { +struct cb_desc { /* Tx Desc Related flags (8-9) */ u8 bLastIniPkt:1; u8 bCmdOrInit:1; @@ -139,7 +139,7 @@ typedef struct cb_desc { u8 DrvAggrNum; u16 pkt_size; u8 reserved12; -}cb_desc, *pcb_desc; +}; /*--------------------------Define -------------------------------------------*/ #define MGN_1M 0x02 @@ -329,12 +329,13 @@ typedef struct ieee_param { // linux under 2.6.9 release may not support it, so modify it for common use #define IEEE80211_DATA_LEN 2304 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + * 6.2.1.1.2. + * + * The figure in section 7.1.2 suggests a body size of up to 2312 + * bytes is allowed, which is a bit confusing, I suspect this + * represents the 2304 bytes of real data, plus a possible 8 bytes of + * WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) + */ #define IEEE80211_1ADDR_LEN 10 #define IEEE80211_2ADDR_LEN 16 #define IEEE80211_3ADDR_LEN 24 @@ -685,7 +686,8 @@ struct ieee_ibss_seq { /* NOTE: This data is for statistical purposes; not all hardware provides this * information for frames received. Not setting these will not cause - * any adverse affects. */ + * any adverse affects. + */ struct ieee80211_rx_stats { u32 mac_time[2]; s8 rssi; @@ -754,7 +756,8 @@ struct ieee80211_rx_stats { /* IEEE 802.11 requires that STA supports concurrent reception of at least * three fragmented frames. This define can be increased to support more * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ + * 2 kB of RAM and increasing cache size will slow down frame reassembly. + */ #define IEEE80211_FRAG_CACHE_LEN 4 struct ieee80211_frag_entry { @@ -836,15 +839,15 @@ struct ieee80211_security { /* - 802.11 data frame from AP - ,-------------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `-------------------------------------------------------------------' -Total: 28-2340 bytes -*/ + * 802.11 data frame from AP + * ,-------------------------------------------------------------------. + * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + * |------|------|---------|---------|---------|------|---------|------| + * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + * | | tion | (BSSID) | | | ence | data | | + * `-------------------------------------------------------------------' + * Total: 28-2340 bytes + */ /* Management Frame Information Element Types */ enum ieee80211_mfie { @@ -882,7 +885,8 @@ enum ieee80211_mfie { /* Minimal header; can be used for passing 802.11 frames with sufficient * information to determine what type of underlying data type is actually - * stored in the data. */ + * stored in the data. + */ struct rtl_80211_hdr { __le16 frame_ctl; __le16 duration_id; @@ -980,7 +984,8 @@ struct ieee80211_probe_response { __le16 beacon_interval; __le16 capability; /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN */ + * CF params, IBSS params, TIM (if beacon), RSN + */ struct ieee80211_info_element info_element[0]; } __packed; @@ -1055,7 +1060,8 @@ typedef union _frameqos { /* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs * only use 8, and then use extended rates for the remaining supported * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... */ + * main rates information element... + */ #define MAX_RATES_LENGTH ((u8)12) #define MAX_RATES_EX_LENGTH ((u8)16) #define MAX_NETWORK_COUNT 128 @@ -1677,14 +1683,16 @@ struct ieee80211_device { spinlock_t wpax_suitlist_lock; int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs */ + * of allocated Tx SKBs + */ u32 config; /* WEP and other encryption related settings at the device level */ int open_wep; /* Set to 1 to allow unencrypted frames */ int auth_mode; int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes */ + * WEP key changes + */ /* If the host performs {en,de}cryption, then set to 1 */ int host_encrypt; @@ -1719,7 +1727,8 @@ struct ieee80211_device { int crypt_quiesced; int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames */ + * with RX of broad/multicast frames + */ /* Fragmentation structures */ // each streaming contain a entry @@ -1894,6 +1903,7 @@ struct ieee80211_device { //u32 STA_EDCA_PARAM[4]; //CHANNEL_ACCESS_SETTING ChannelAccessSetting; + struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; /* Callback functions */ void (*set_security)(struct net_device *dev, @@ -2003,7 +2013,8 @@ struct ieee80211_device { void (*InitialGainHandler)(struct net_device *dev, u8 Operation); /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 */ + * allocated beyond this structure by alloc_ieee80211 + */ u8 priv[0]; }; @@ -2032,7 +2043,8 @@ struct ieee80211_device { /* The ieee802.11 stack will manages the netif queue * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. */ + * fragmentation. See softmac.c for details. + */ #define IEEE_SOFTMAC_TX_QUEUE (1<<7) /* Uses only the softmac_data_hard_start_xmit @@ -2255,7 +2267,6 @@ void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); /* ieee80211_crypt_ccmp&tkip&wep.c */ void ieee80211_tkip_null(void); -void ieee80211_ccmp_null(void); int ieee80211_crypto_init(void); void ieee80211_crypto_deinit(void); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c index 9cf90d040cfe..48e80be90ba5 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c @@ -80,7 +80,7 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, struct ieee80211_crypt_data *tmp; unsigned long flags; - if (*crypt == NULL) + if (!(*crypt)) return; tmp = *crypt; @@ -88,7 +88,8 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, /* must not run ops->deinit() while there may be pending encrypt or * decrypt operations. Use a list of delayed deinits to avoid needing - * locking. */ + * locking. + */ spin_lock_irqsave(&ieee->lock, flags); list_add(&tmp->list, &ieee->crypt_deinit_list); @@ -104,11 +105,11 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) unsigned long flags; struct ieee80211_crypto_alg *alg; - if (hcrypt == NULL) + if (!hcrypt) return -1; alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) + if (!alg) return -ENOMEM; alg->ops = ops; @@ -129,13 +130,13 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) struct list_head *ptr; struct ieee80211_crypto_alg *del_alg = NULL; - if (hcrypt == NULL) + if (!hcrypt) return -1; spin_lock_irqsave(&hcrypt->lock, flags); for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + (struct ieee80211_crypto_alg *)ptr; if (alg->ops == ops) { list_del(&alg->list); del_alg = alg; @@ -160,13 +161,13 @@ struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) struct list_head *ptr; struct ieee80211_crypto_alg *found_alg = NULL; - if (hcrypt == NULL) + if (!hcrypt) return NULL; spin_lock_irqsave(&hcrypt->lock, flags); for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + (struct ieee80211_crypto_alg *)ptr; if (strcmp(alg->ops->name, name) == 0) { found_alg = alg; break; @@ -222,13 +223,13 @@ void __exit ieee80211_crypto_deinit(void) { struct list_head *ptr, *n; - if (hcrypt == NULL) + if (!hcrypt) return; for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; ptr = n, n = ptr->next) { struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + (struct ieee80211_crypto_alg *)ptr; list_del(ptr); pr_debug("ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", alg->ops->name); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h index 0b4ea431982d..005bf89aae65 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h @@ -30,7 +30,8 @@ struct ieee80211_crypto_ops { /* init new crypto context (e.g., allocate private data space, * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success */ + * private data on success + */ void * (*init)(int keyidx); /* deinitialize crypto context and free allocated private data */ @@ -46,7 +47,8 @@ struct ieee80211_crypto_ops { int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. */ + * These can be NULL if full MSDU operations are not needed. + */ int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, void *priv); @@ -55,14 +57,16 @@ struct ieee80211_crypto_ops { int (*get_key)(void *key, int len, u8 *seq, void *priv); /* procfs handler for printing out key information and possible - * statistics */ + * statistics + */ char * (*print_stats)(char *p, void *priv); /* maximum number of bytes added by encryption; encrypt buf is * allocated with extra_prefix_len bytes, copy of in_buf, and * extra_postfix_len; encrypt need not use all this space, but * the result must start at the beginning of the buffer and correct - * length must be returned */ + * length must be returned + */ int extra_prefix_len, extra_postfix_len; struct module *owner; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index 2dc25cc2c726..e6648f7723ce 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -67,7 +67,7 @@ static void *ieee80211_ccmp_init(int key_idx) struct ieee80211_ccmp_data *priv; priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) + if (!priv) goto fail; priv->key_idx = key_idx; @@ -90,7 +90,6 @@ fail: return NULL; } - static void ieee80211_ccmp_deinit(void *priv) { struct ieee80211_ccmp_data *_priv = priv; @@ -100,7 +99,6 @@ static void ieee80211_ccmp_deinit(void *priv) kfree(priv); } - static inline void xor_block(u8 *b, u8 *a, size_t len) { int i; @@ -109,8 +107,6 @@ static inline void xor_block(u8 *b, u8 *a, size_t len) b[i] ^= a[i]; } - - static void ccmp_init_blocks(struct crypto_tfm *tfm, struct rtl_80211_hdr_4addr *hdr, u8 *pn, size_t dlen, u8 *b0, u8 *auth, @@ -135,7 +131,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, if (a4_included) aad_len += 6; if (qc_included) { - pos = (u8 *) &hdr->addr4; + pos = (u8 *)&hdr->addr4; if (a4_included) pos += 6; qc = *pos & 0x0f; @@ -161,13 +157,13 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, * A4 (if present) * QC (if present) */ - pos = (u8 *) hdr; + pos = (u8 *)hdr; aad[0] = 0; /* aad_len >> 8 */ aad[1] = aad_len & 0xff; aad[2] = pos[0] & 0x8f; aad[3] = pos[1] & 0xc7; memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); - pos = (u8 *) &hdr->seq_ctl; + pos = (u8 *)&hdr->seq_ctl; aad[22] = pos[0] & 0x0f; aad[23] = 0; /* all bits masked */ memset(aad + 24, 0, 8); @@ -185,19 +181,18 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); ieee80211_ccmp_aes_encrypt(tfm, auth, auth); b0[0] &= 0x07; - b0[14] = b0[15] = 0; + b0[14] = 0; + b0[15] = 0; ieee80211_ccmp_aes_encrypt(tfm, b0, s0); } - - static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_ccmp_data *key = priv; int data_len, i; u8 *pos; struct rtl_80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); if (skb_headroom(skb) < CCMP_HDR_LEN || skb_tailroom(skb) < CCMP_MIC_LEN || @@ -227,8 +222,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = key->tx_pn[1]; *pos++ = key->tx_pn[0]; - - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (!tcb_desc->bHwSec) { int blocks, last, len; u8 *mic; @@ -264,13 +258,12 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return 0; } - static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_ccmp_data *key = priv; u8 keyidx, *pos; struct rtl_80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 pn[6]; if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { @@ -278,7 +271,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; } - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { @@ -327,7 +320,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u8 *a = key->rx_a; int i, blocks, last, len; - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); xor_block(mic, b, CCMP_MIC_LEN); @@ -366,7 +358,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return keyidx; } - static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) { struct ieee80211_ccmp_data *data = priv; @@ -389,15 +380,15 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) data->rx_pn[5] = seq[0]; } crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN); - } else if (len == 0) + } else if (len == 0) { data->key_set = 0; - else + } else { return -1; + } return 0; } - static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) { struct ieee80211_ccmp_data *data = priv; @@ -421,7 +412,6 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) return CCMP_TK_LEN; } - static char *ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; @@ -436,12 +426,6 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv) return p; } -void ieee80211_ccmp_null(void) -{ - /* printk("============>%s()\n", __func__); */ - return; -} - static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { .name = "CCMP", .init = ieee80211_ccmp_init, diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index e68850897adf..2453413757b6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -304,7 +304,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) int len; u8 *pos; struct rtl_80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); int ret = 0; u8 rc4key[16], *icv; u32 crc; @@ -387,7 +387,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 iv32; u16 iv16; struct rtl_80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 rc4key[16]; u8 icv[4]; u32 crc; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index 1999bc5cbbc1..0e8c876c1404 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -88,7 +88,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 klen, len; u8 key[WEP_KEY_LEN + 3]; u8 *pos; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u32 crc; u8 *icv; struct scatterlist sg; @@ -109,7 +109,8 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. */ + * can be used to speedup attacks, so avoid using them. + */ if ((wep->iv & 0xff00) == 0xff00) { u8 B = (wep->iv >> 16) & 0xff; @@ -166,7 +167,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 klen, plen; u8 key[WEP_KEY_LEN + 3]; u8 keyidx, *pos; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u32 crc; u8 icv[4]; struct scatterlist sg; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 30fff6c5696b..5fdfff0816c5 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -1,34 +1,34 @@ /******************************************************************************* - - Copyright(c) 2004 Intel Corporation. All rights reserved. - - Portions of this file are based on the WEP enablement code provided by the - Host AP project hostap-drivers v0.1.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> - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos <ipw2100-admin@linux.intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ + * + * Copyright(c) 2004 Intel Corporation. All rights reserved. + * + * Portions of this file are based on the WEP enablement code provided by the + * Host AP project hostap-drivers v0.1.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> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos <ipw2100-admin@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *******************************************************************************/ #include <linux/compiler.h> /* #include <linux/config.h> */ @@ -141,8 +141,8 @@ struct net_device *alloc_ieee80211(int sizeof_priv) spin_lock_init(&ieee->bw_spinlock); spin_lock_init(&ieee->reorder_spinlock); /* added by WB */ - atomic_set(&(ieee->atm_chnlop), 0); - atomic_set(&(ieee->atm_swbw), 0); + atomic_set(&ieee->atm_chnlop, 0); + atomic_set(&ieee->atm_swbw, 0); ieee->wpax_type_set = 0; ieee->wpa_enabled = 0; @@ -177,7 +177,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv) /* These function were added to load crypte module autoly */ ieee80211_tkip_null(); - ieee80211_ccmp_null(); return dev; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index b1f2fdfcb718..5241c5003ebf 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -345,7 +345,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, return 0; if (ieee->hwsec_active) { - cb_desc *tcb_desc = (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; } hdr = (struct rtl_80211_hdr_4addr *) skb->data; @@ -392,7 +392,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s return 0; if (ieee->hwsec_active) { - cb_desc *tcb_desc = (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; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index d7d85b3f19c4..1bff0e91cc0c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -146,6 +146,7 @@ static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) { int nh; + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM; /* @@ -225,7 +226,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee struct rtl_80211_hdr_3addr *header= (struct rtl_80211_hdr_3addr *) skb->data; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); + spin_lock_irqsave(&ieee->lock, flags); /* called with 2nd param 0, no mgmt lock required */ @@ -364,6 +366,7 @@ struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); static void ieee80211_send_beacon(struct ieee80211_device *ieee) { struct sk_buff *skb; + if(!ieee->ieee_up) return; //unsigned long flags; @@ -427,6 +430,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) { short ch = 0; u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); mutex_lock(&ieee->scan_mutex); @@ -493,6 +497,7 @@ static void ieee80211_softmac_scan_wq(struct work_struct *work) struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); static short watchdog; u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); if(!ieee->ieee_up) return; @@ -2142,7 +2147,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * unsigned int queue_index = txb->queue_index; unsigned long flags; int i; - cb_desc *tcb_desc = NULL; + struct cb_desc *tcb_desc = NULL; spin_lock_irqsave(&ieee->lock, flags); @@ -2152,7 +2157,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * /* update the tx status */ ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size); ieee->stats.tx_packets++; - tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); + tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); if (tcb_desc->bMulticast) { ieee->stats.multicast++; } @@ -2623,6 +2628,7 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee) { short ch = 0; int i = 0; + if (ieee->proto_started) return; @@ -2766,7 +2772,7 @@ static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) { /* This is called when wpa_supplicant loads and closes the driver * interface. */ - printk("%s WPA\n",value ? "enabling" : "disabling"); + printk("%s WPA\n", value ? "enabling" : "disabling"); ieee->wpa_enabled = value; return 0; } @@ -2869,7 +2875,7 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) { - int ret=0; + int ret = 0; unsigned long flags; switch (name) { @@ -2878,7 +2884,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v break; case IEEE_PARAM_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures=value; + ieee->tkip_countermeasures = value; break; case IEEE_PARAM_DROP_UNENCRYPTED: { @@ -2915,7 +2921,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v } case IEEE_PARAM_PRIVACY_INVOKED: - ieee->privacy_invoked=value; + ieee->privacy_invoked = value; break; case IEEE_PARAM_AUTH_ALGS: @@ -2923,7 +2929,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v break; case IEEE_PARAM_IEEE_802_1X: - ieee->ieee802_1x=value; + ieee->ieee802_1x = value; break; case IEEE_PARAM_WPAX_SELECT: // added for WPA2 mixed mode @@ -2934,7 +2940,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v break; default: - printk("Unknown WPA param: %d\n",name); + printk("Unknown WPA param: %d\n", name); ret = -EOPNOTSUPP; } @@ -3056,23 +3062,21 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, } else sec.flags &= ~SEC_ACTIVE_KEY; - if (param->u.crypt.alg != NULL) { - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, - param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } + memcpy(sec.keys[param->u.crypt.idx], + param->u.crypt.key, + param->u.crypt.key_len); + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + + if (strcmp(param->u.crypt.alg, "WEP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; } done: if (ieee->set_security) @@ -3107,7 +3111,7 @@ static inline struct sk_buff *ieee80211_disassociate_skb( if (!skb) return NULL; - disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc)); + disass = (struct ieee80211_disassoc *) skb_put(skb, sizeof(struct ieee80211_disassoc)); disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); disass->header.duration_id = 0; @@ -3129,7 +3133,8 @@ SendDisassociation( { struct ieee80211_network *beacon = &ieee->current_network; struct sk_buff *skb; - skb = ieee80211_disassociate_skb(beacon,ieee,asRsn); + + skb = ieee80211_disassociate_skb(beacon, ieee, asRsn); if (skb) { softmac_mgmt_xmit(skb, ieee); //dev_kfree_skb_any(skb);//edit by thomas @@ -3140,7 +3145,7 @@ EXPORT_SYMBOL(SendDisassociation); int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) { struct ieee_param *param; - int ret=0; + int ret = 0; mutex_lock(&ieee->wx_mutex); //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); @@ -3196,6 +3201,7 @@ EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl); void notify_wx_assoc_event(struct ieee80211_device *ieee) { union iwreq_data wrqu; + wrqu.ap_addr.sa_family = ARPHRD_ETHER; if (ieee->state == IEEE80211_LINKED) memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 1ab0aead298b..5704e4d7aa68 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -1,35 +1,34 @@ /****************************************************************************** - - Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos <ipw2100-admin@linux.intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello <andrea.merello@gmail.com> - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ + * + * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos <ipw2100-admin@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * + * Few modifications for Realtek's Wi-Fi drivers by + * Andrea Merello <andrea.merello@gmail.com> + * + * A special thanks goes to Realtek for their support ! + * + ******************************************************************************/ #include <linux/compiler.h> #include <linux/errno.h> @@ -55,101 +54,101 @@ /* - - -802.11 Data Frame - - -802.11 frame_contorl 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 >-----------' - | - ,--'---,-------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `--------------------------------------------------| |------' -Total: 28 non-data bytes `----.----' - | - .- 'Frame data' expands to <---------------------------' - | - V - ,---------------------------------------------------. -Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - |------|------|---------|----------|------|---------| -Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - | DSAP | SSAP | | | | Packet | - | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - `-----------------------------------------| | -Total: 8 non-data bytes `----.----' - | - .- 'IP Packet' expands, if WEP enabled, to <--' - | - V - ,-----------------------. -Bytes | 4 | 0-2296 | 4 | - |-----|-----------|-----| -Desc. | IV | Encrypted | ICV | - | | IP Packet | | - `-----------------------' -Total: 8 non-data bytes - - -802.3 Ethernet Data Frame - - ,-----------------------------------------. -Bytes | 6 | 6 | 2 | Variable | 4 | - |-------|-------|------|-----------|------| -Desc. | Dest. | Source| Type | IP Packet | fcs | - | MAC | MAC | | | | - `-----------------------------------------' -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. - -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 -* -* ,- skb->data -* | -* | ETHERNET HEADER ,-<-- PAYLOAD -* | | 14 bytes from skb->data -* | 2 bytes for Type --> ,T. | (sizeof ethhdr) -* | | | | -* |,-Dest.--. ,--Src.---. | | | -* | 6 bytes| | 6 bytes | | | | -* v | | | | | | -* 0 | v 1 | v | v 2 -* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -* ^ | ^ | ^ | -* | | | | | | -* | | | | `T' <---- 2 bytes for Type -* | | | | -* | | '---SNAP--' <-------- 6 bytes for SNAP -* | | -* `-IV--' <-------------------- 4 bytes for IV (WEP) -* -* SNAP HEADER -* -*/ + * + * + * 802.11 Data Frame + * + * + * 802.11 frame_contorl 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 >-----------' + * | + * ,--'---,-------------------------------------------------------------. + * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + * |------|------|---------|---------|---------|------|---------|------| + * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | + * | | tion | (BSSID) | | | ence | data | | + * `--------------------------------------------------| |------' + * Total: 28 non-data bytes `----.----' + * | + * .- 'Frame data' expands to <---------------------------' + * | + * V + * ,---------------------------------------------------. + * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | + * |------|------|---------|----------|------|---------| + * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | + * | DSAP | SSAP | | | | Packet | + * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | + * `-----------------------------------------| | + * Total: 8 non-data bytes `----.----' + * | + * .- 'IP Packet' expands, if WEP enabled, to <--' + * | + * V + * ,-----------------------. + * Bytes | 4 | 0-2296 | 4 | + * |-----|-----------|-----| + * Desc. | IV | Encrypted | ICV | + * | | IP Packet | | + * `-----------------------' + * Total: 8 non-data bytes + * + * + * 802.3 Ethernet Data Frame + * + * ,-----------------------------------------. + * Bytes | 6 | 6 | 2 | Variable | 4 | + * |-------|-------|------|-----------|------| + * Desc. | Dest. | Source| Type | IP Packet | fcs | + * | MAC | MAC | | | | + * `-----------------------------------------' + * 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. + * + * 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 + * + * ,- skb->data + * | + * | ETHERNET HEADER ,-<-- PAYLOAD + * | | 14 bytes from skb->data + * | 2 bytes for Type --> ,T. | (sizeof ethhdr) + * | | | | + * |,-Dest.--. ,--Src.---. | | | + * | 6 bytes| | 6 bytes | | | | + * v | | | | | | + * 0 | v 1 | v | v 2 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * ^ | ^ | ^ | + * | | | | | | + * | | | | `T' <---- 2 bytes for Type + * | | | | + * | | '---SNAP--' <-------- 6 bytes for SNAP + * | | + * `-IV--' <-------------------- 4 bytes for IV (WEP) + * + * SNAP HEADER + * + */ static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; @@ -205,11 +204,13 @@ int ieee80211_encrypt_fragment( } /* To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) + */ // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. */ + * call both MSDU and MPDU encryption functions from here. + */ atomic_inc(&crypt->refcnt); res = 0; if (crypt->ops->encrypt_msdu) @@ -250,7 +251,7 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, memset(txb, 0, sizeof(struct ieee80211_txb)); txb->nr_frags = nr_frags; - txb->frag_size = txb_size; + txb->frag_size = __cpu_to_le16(txb_size); for (i = 0; i < nr_frags; i++) { txb->fragments[i] = dev_alloc_skb(txb_size); @@ -304,7 +305,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) #define SN_LESS(a, b) (((a-b)&0x800)!=0) static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, - struct sk_buff *skb, cb_desc *tcb_desc) + struct sk_buff *skb, struct cb_desc *tcb_desc) { PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; PTX_TS_RECORD pTxTs = NULL; @@ -379,7 +380,7 @@ FORCED_AGG_SETTING: } static void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee, - cb_desc *tcb_desc) + struct cb_desc *tcb_desc) { tcb_desc->bUseShortPreamble = false; if (tcb_desc->data_rate == 2) @@ -393,7 +394,7 @@ static void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee, return; } static void -ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc) +ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, struct cb_desc *tcb_desc) { PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; @@ -415,7 +416,7 @@ ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc) } static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, - cb_desc *tcb_desc) + struct cb_desc *tcb_desc) { PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; @@ -436,7 +437,7 @@ static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, } static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, - cb_desc *tcb_desc, + struct cb_desc *tcb_desc, struct sk_buff *skb) { // Common Settings @@ -548,7 +549,7 @@ NO_PROTECTION: static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, - cb_desc *tcb_desc) + struct cb_desc *tcb_desc) { #ifdef TO_DO_LIST if(!IsDataFrame(pFrame)) @@ -615,12 +616,13 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) struct ieee80211_crypt_data *crypt; - cb_desc *tcb_desc; + struct cb_desc *tcb_desc; spin_lock_irqsave(&ieee->lock, flags); /* If there is no driver handler to take the TXB, dont' bother - * creating it... */ + * creating it... + */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { printk(KERN_WARNING "%s: No xmit handler.\n", @@ -683,13 +685,15 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) if (ieee->iw_mode == IW_MODE_INFRA) { fc |= IEEE80211_FCTL_TODS; /* To DS: Addr1 = BSSID, Addr2 = SA, - Addr3 = DA */ + * Addr3 = DA + */ memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); memcpy(&header.addr2, &src, ETH_ALEN); memcpy(&header.addr3, &dest, ETH_ALEN); } else if (ieee->iw_mode == IW_MODE_ADHOC) { /* not From/To DS: Addr1 = DA, Addr2 = SA, - Addr3 = BSSID */ + * Addr3 = BSSID + */ memcpy(&header.addr1, dest, ETH_ALEN); memcpy(&header.addr2, src, ETH_ALEN); memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); @@ -698,7 +702,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) header.frame_ctl = cpu_to_le16(fc); /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) */ + * and broadcast are not fragmented) + */ if (is_multicast_ether_addr(header.addr1)) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; @@ -720,9 +725,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) hdr_len = IEEE80211_3ADDR_LEN; } /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account for - * it when determining the amount of payload space. */ + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account for + * it when determining the amount of payload space. + */ bytes_per_frag = frag_size - hdr_len; if (ieee->config & (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) @@ -734,7 +740,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) crypt->ops->extra_postfix_len; /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment */ + * payload_per_fragment + */ nr_frags = bytes / bytes_per_frag; bytes_last_frag = bytes % bytes_per_frag; if (bytes_last_frag) @@ -743,8 +750,9 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) bytes_last_frag = bytes_per_frag; /* When we allocate the TXB we allocate enough space for the reserve - * and full fragment bytes (bytes_per_frag doesn't include prefix, - * postfix, header, FCS, etc.) */ + * and full fragment bytes (bytes_per_frag doesn't include prefix, + * postfix, header, FCS, etc.) + */ txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); if (unlikely(!txb)) { printk(KERN_WARNING "%s: Could not allocate TXB\n", @@ -752,7 +760,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) goto failed; } txb->encrypted = encrypt; - txb->payload_size = bytes; + txb->payload_size = __cpu_to_le16(bytes); //if (ieee->current_network.QoS_Enable) if(qos_actived) @@ -766,7 +774,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < nr_frags; i++) { skb_frag = txb->fragments[i]; - tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); + tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); if(qos_actived){ skb_frag->priority = skb->priority;//UP2AC(skb->priority); tcb_desc->queue_index = UP2AC(skb->priority); @@ -791,7 +799,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) memcpy(frag_hdr, &header, hdr_len); /* If this is not the last fragment, then add the MOREFRAGS - * bit to the frame control */ + * bit to the frame control + */ if (i != nr_frags - 1) { frag_hdr->frame_ctl = cpu_to_le16( fc | IEEE80211_FCTL_MOREFRAGS); @@ -824,7 +833,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) skb_pull(skb, bytes); /* Encryption routine will move the header forward in order - * to insert the IV between the header and the payload */ + * to insert the IV between the header and the payload + */ if (encrypt) ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); if (ieee->config & @@ -859,7 +869,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) } txb->encrypted = 0; - txb->payload_size = skb->len; + txb->payload_size = __cpu_to_le16(skb->len); memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len); } @@ -867,7 +877,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. if (txb) { - cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bTxEnableFwCalcDur = 1; if (is_multicast_ether_addr(header.addr1)) tcb_desc->bMulticast = 1; @@ -896,7 +906,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) }else{ if ((*ieee->hard_start_xmit)(txb, dev) == 0) { stats->tx_packets++; - stats->tx_bytes += txb->payload_size; + stats->tx_bytes += __le16_to_cpu(txb->payload_size); return 0; } ieee80211_txb_free(txb); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 563d7fed6e1c..e383ec2fb335 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -623,7 +623,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, goto done; } *crypt = new_crypt; - } if (ext->key_len > 0 && (*crypt)->ops->set_key && @@ -725,7 +724,6 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, (ext->alg == IW_ENCODE_ALG_TKIP || ext->alg == IW_ENCODE_ALG_CCMP)) ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; - } return 0; @@ -839,6 +837,5 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) ieee->wpa_ie_len = 0; } return 0; - } EXPORT_SYMBOL(ieee80211_wx_set_gen_ie); diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 98fbb6ef484d..6619b8fb9700 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -14,7 +14,7 @@ * input: PBA_RECORD pBA //BA entry to be enabled * u16 Time //indicate time delay. * output: none -********************************************************************************************************************/ + ********************************************************************************************************************/ static void ActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA, u16 Time) { pBA->bValid = true; @@ -26,7 +26,7 @@ static void ActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA, u16 T *function: deactivate BA entry, including its timer. * input: PBA_RECORD pBA //BA entry to be disabled * output: none -********************************************************************************************************************/ + ********************************************************************************************************************/ static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA) { pBA->bValid = false; @@ -38,7 +38,7 @@ static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA) * PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry. * output: none * notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME -********************************************************************************************************************/ + ********************************************************************************************************************/ static u8 TxTsDeleteBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTs) { PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure @@ -46,15 +46,13 @@ static u8 TxTsDeleteBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTs) u8 bSendDELBA = false; // Delete pending BA - if (pPendingBa->bValid) - { + if (pPendingBa->bValid) { DeActivateBAEntry(ieee, pPendingBa); bSendDELBA = true; } // Delete admitted BA - if (pAdmittedBa->bValid) - { + if (pAdmittedBa->bValid) { DeActivateBAEntry(ieee, pAdmittedBa); bSendDELBA = true; } @@ -68,14 +66,13 @@ static u8 TxTsDeleteBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTs) * PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry. * output: none * notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above -********************************************************************************************************************/ + ********************************************************************************************************************/ static u8 RxTsDeleteBA(struct ieee80211_device *ieee, PRX_TS_RECORD pRxTs) { PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord; u8 bSendDELBA = false; - if (pBa->bValid) - { + if (pBa->bValid) { DeActivateBAEntry(ieee, pBa); bSendDELBA = true; } @@ -88,7 +85,7 @@ static u8 RxTsDeleteBA(struct ieee80211_device *ieee, PRX_TS_RECORD pRxTs) * input: * PBA_RECORD pBA //entry to be reset * output: none -********************************************************************************************************************/ + ********************************************************************************************************************/ void ResetBaEntry(PBA_RECORD pBA) { pBA->bValid = false; @@ -106,7 +103,7 @@ void ResetBaEntry(PBA_RECORD pBA) * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ) * output: none * return: sk_buff* skb //return constructed skb to xmit -*******************************************************************************************************************************/ + *******************************************************************************************************************************/ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, PBA_RECORD pBA, u16 StatusCode, u8 type) { struct sk_buff *skb = NULL; @@ -115,14 +112,12 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); - if (pBA == NULL) - { + if (pBA == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA is NULL\n"); return NULL; } skb = dev_alloc_skb(len + sizeof( struct rtl_80211_hdr_3addr)); //need to add something others? FIXME - if (skb == NULL) - { + if (skb == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); return NULL; } @@ -146,10 +141,9 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P // Dialog Token *tag ++= pBA->DialogToken; - if (ACT_ADDBARSP == type) - { + if (ACT_ADDBARSP == type) { // Status Code - printk("=====>to send ADDBARSP\n"); + printk(KERN_INFO "=====>to send ADDBARSP\n"); put_unaligned_le16(StatusCode, tag); tag += 2; @@ -163,8 +157,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P put_unaligned_le16(pBA->BaTimeoutValue, tag); tag += 2; - if (ACT_ADDBAREQ == type) - { + if (ACT_ADDBAREQ == type) { // BA Start SeqCtrl memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2); tag += 2; @@ -184,7 +177,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P * u16 ReasonCode //status code. * output: none * return: sk_buff* skb //return constructed skb to xmit -********************************************************************************************************************/ + ********************************************************************************************************************/ static struct sk_buff *ieee80211_DELBA( struct ieee80211_device *ieee, u8 *dst, @@ -209,8 +202,7 @@ static struct sk_buff *ieee80211_DELBA( DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; skb = dev_alloc_skb(len + sizeof( struct rtl_80211_hdr_3addr)); //need to add something others? FIXME - if (skb == NULL) - { + if (skb == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); return NULL; } @@ -250,25 +242,22 @@ static struct sk_buff *ieee80211_DELBA( * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA * output: none * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ + ********************************************************************************************************************/ static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD pBA) { struct sk_buff *skb; skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero. - if (skb) - { + if (skb) { softmac_mgmt_xmit(skb, ieee); //add statistic needed here. //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit() //WB } - else - { + else { IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); } - return; } /******************************************************************************************************************** @@ -278,19 +267,17 @@ static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, * u16 StatusCode //RSP StatusCode * output: none * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ + ********************************************************************************************************************/ static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD pBA, u16 StatusCode) { struct sk_buff *skb; skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames - if (skb) - { + if (skb) { softmac_mgmt_xmit(skb, ieee); //same above } - else - { + else { IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); } @@ -305,7 +292,7 @@ static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst, * u16 ReasonCode //DEL ReasonCode * output: none * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ + ********************************************************************************************************************/ static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, @@ -313,16 +300,13 @@ static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst, { struct sk_buff *skb; skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames - if (skb) - { + if (skb) { softmac_mgmt_xmit(skb, ieee); //same above } - else - { + else { IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); } - return ; } /******************************************************************************************************************** @@ -330,7 +314,7 @@ static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst, * input: struct sk_buff * skb //incoming ADDBAReq skb. * return: 0(pass), other(fail) * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ + ********************************************************************************************************************/ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) { struct rtl_80211_hdr_3addr *req = NULL; @@ -361,7 +345,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) pBaTimeoutVal = (u16 *)(tag + 5); pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); - printk("====================>rx ADDBAREQ from :%pM\n", dst); + printk(KERN_INFO "====================>rx ADDBAREQ from :%pM\n", dst); //some other capability is not ready now. if ((ieee->current_network.qos_data.active == 0) || (!ieee->pHTInfo->bCurrentHTSupport)) //|| @@ -379,8 +363,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) dst, (u8)(pBaParamSet->field.TID), RX_DIR, - true) ) - { + true) ) { rc = ADDBA_STATUS_REFUSED; IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__); goto OnADDBAReq_Fail; @@ -390,8 +373,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl... // I want to check StartSeqCtrl to make sure when we start aggregation!!! // - if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) - { + if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { rc = ADDBA_STATUS_INVALID_PARAM; IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __func__); goto OnADDBAReq_Fail; @@ -432,7 +414,7 @@ OnADDBAReq_Fail: * input: struct sk_buff * skb //incoming ADDBAReq skb. * return: 0(pass), other(fail) * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ + ********************************************************************************************************************/ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) { struct rtl_80211_hdr_3addr *rsp = NULL; @@ -480,8 +462,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) dst, (u8)(pBaParamSet->field.TID), TX_DIR, - false) ) - { + false) ) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; @@ -496,34 +477,29 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) // Check if related BA is waiting for setup. // If not, reject by sending DELBA frame. // - if((pAdmittedBA->bValid==true)) - { + if (pAdmittedBA->bValid) { // Since BA is already setup, we ignore all other ADDBA Response. IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n"); return -1; } - else if((!pPendingBA->bValid) ||(*pDialogToken != pPendingBA->DialogToken)) - { + else if((!pPendingBA->bValid) ||(*pDialogToken != pPendingBA->DialogToken)) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n"); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } - else - { + else { IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode); DeActivateBAEntry(ieee, pPendingBA); } - if(*pStatusCode == ADDBA_STATUS_SUCCESS) - { + if(*pStatusCode == ADDBA_STATUS_SUCCESS) { // // Determine ADDBA Rsp content here. // We can compare the value of BA parameter set that Peer returned and Self sent. // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism. // - if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) - { + if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { // Since this is a kind of ADDBA failed, we delay next ADDBA process. pTS->bAddBaReqDelayed = true; DeActivateBAEntry(ieee, pAdmittedBA); @@ -542,8 +518,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) DeActivateBAEntry(ieee, pAdmittedBA); ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); } - else - { + else { // Delay next ADDBA process. pTS->bAddBaReqDelayed = true; } @@ -566,7 +541,7 @@ OnADDBARsp_Reject: * input: struct sk_buff * skb //incoming ADDBAReq skb. * return: 0(pass), other(fail) * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ + ********************************************************************************************************************/ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) { struct rtl_80211_hdr_3addr *delba = NULL; @@ -582,8 +557,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) } if (ieee->current_network.qos_data.active == 0 || - !ieee->pHTInfo->bCurrentHTSupport) - { + !ieee->pHTInfo->bCurrentHTSupport) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); return -1; } @@ -593,8 +567,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) dst = &delba->addr2[0]; pDelBaParamSet = (PDELBA_PARAM_SET)&delba->payload[2]; - if(pDelBaParamSet->field.Initiator == 1) - { + if(pDelBaParamSet->field.Initiator == 1) { PRX_TS_RECORD pRxTs; if (!GetTs( @@ -603,16 +576,14 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) dst, (u8)pDelBaParamSet->field.TID, RX_DIR, - false) ) - { + false) ) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __func__); return -1; } RxTsDeleteBA(ieee, pRxTs); } - else - { + else { PTX_TS_RECORD pTxTs; if (!GetTs( @@ -621,8 +592,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) dst, (u8)pDelBaParamSet->field.TID, TX_DIR, - false) ) - { + false) ) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __func__); return -1; } @@ -650,7 +620,7 @@ TsInitAddBA( { PBA_RECORD pBA = &pTS->TxPendingBARecord; - if(pBA->bValid==true && bOverwritePending==false) + if (pBA->bValid && !bOverwritePending) return; // Set parameters to "Pending" variable set @@ -674,8 +644,7 @@ void TsInitDelBA( struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect) { - if(TxRxSelect == TX_DIR) - { + if(TxRxSelect == TX_DIR) { PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo; if(TxTsDeleteBA(ieee, pTxTs)) @@ -686,8 +655,7 @@ TsInitDelBA( struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SE TxRxSelect, DELBA_REASON_END_BA); } - else if(TxRxSelect == RX_DIR) - { + else if(TxRxSelect == RX_DIR) { PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo; if(RxTsDeleteBA(ieee, pRxTs)) ieee80211_send_DELBA( @@ -703,7 +671,7 @@ TsInitDelBA( struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SE * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer * return: NULL * notice: -********************************************************************************************************************/ + ********************************************************************************************************************/ void BaSetupTimeOut(unsigned long data) { PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; @@ -738,5 +706,4 @@ void RxBaInactTimeout(unsigned long data) &pRxTs->RxAdmittedBARecord, RX_DIR, DELBA_REASON_TIMEOUT); - return ; } diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h index c3aabbaac7ae..5f54d93dfb66 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h @@ -35,7 +35,7 @@ #define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP -typedef enum _HT_MCS_RATE{ +typedef enum _HT_MCS_RATE { HT_MCS0 = 0x00000001, HT_MCS1 = 0x00000002, HT_MCS2 = 0x00000004, @@ -58,7 +58,7 @@ typedef enum _HT_MCS_RATE{ // // Represent Channel Width in HT Capabilities // -typedef enum _HT_CHANNEL_WIDTH{ +typedef enum _HT_CHANNEL_WIDTH { HT_CHANNEL_WIDTH_20 = 0, HT_CHANNEL_WIDTH_20_40 = 1, }HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; @@ -67,14 +67,14 @@ typedef enum _HT_CHANNEL_WIDTH{ // Represent Extension Channel Offset in HT Capabilities // This is available only in 40Mhz mode. // -typedef enum _HT_EXTCHNL_OFFSET{ +typedef enum _HT_EXTCHNL_OFFSET { HT_EXTCHNL_OFFSET_NO_EXT = 0, HT_EXTCHNL_OFFSET_UPPER = 1, HT_EXTCHNL_OFFSET_NO_DEF = 2, HT_EXTCHNL_OFFSET_LOWER = 3, }HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET; -typedef enum _CHNLOP{ +typedef enum _CHNLOP { CHNLOP_NONE = 0, // No Action now CHNLOP_SCAN = 1, // Scan in progress CHNLOP_SWBW = 2, // Bandwidth switching in progress @@ -119,7 +119,7 @@ typedef union _HT_CAPABILITY_MACPARA{ }HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA; */ -typedef enum _HT_ACTION{ +typedef enum _HT_ACTION { ACT_RECOMMAND_WIDTH = 0, ACT_MIMO_PWR_SAVE = 1, ACT_PSMP = 2, @@ -134,14 +134,14 @@ typedef enum _HT_ACTION{ /* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */ -typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{ +typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier { SC_MODE_DUPLICATE = 0, SC_MODE_LOWER = 1, SC_MODE_UPPER = 2, SC_MODE_FULL40MHZ = 3, }HT_BW40_SC_E; -typedef struct _HT_CAPABILITY_ELE{ +typedef struct _HT_CAPABILITY_ELE { //HT capability info u8 AdvCoding:1; @@ -184,7 +184,7 @@ typedef struct _HT_CAPABILITY_ELE{ // Only AP is required to include this element //------------------------------------------------------------ -typedef struct _HT_INFORMATION_ELE{ +typedef struct _HT_INFORMATION_ELE { u8 ControlChl; u8 ExtChlOffset:2; @@ -215,18 +215,18 @@ typedef struct _HT_INFORMATION_ELE{ // MIMO Power Save control field. // This is appear in MIMO Power Save Action Frame // -typedef struct _MIMOPS_CTRL{ +typedef struct _MIMOPS_CTRL { u8 MimoPsEnable:1; u8 MimoPsMode:1; u8 Reserved:6; } MIMOPS_CTRL, *PMIMOPS_CTRL; -typedef enum _HT_SPEC_VER{ +typedef enum _HT_SPEC_VER { HT_SPEC_VER_IEEE = 0, HT_SPEC_VER_EWC = 1, }HT_SPEC_VER, *PHT_SPEC_VER; -typedef enum _HT_AGGRE_MODE_E{ +typedef enum _HT_AGGRE_MODE_E { HT_AGG_AUTO = 0, HT_AGG_FORCE_ENABLE = 1, HT_AGG_FORCE_DISABLE = 2, @@ -238,7 +238,7 @@ typedef enum _HT_AGGRE_MODE_E{ // to default value in HTInitializeHTInfo() //------------------------------------------------------------ -typedef struct _RT_HIGH_THROUGHPUT{ +typedef struct _RT_HIGH_THROUGHPUT { u8 bEnableHT; u8 bCurrentHTSupport; @@ -347,7 +347,7 @@ typedef struct _RT_HIGH_THROUGHPUT{ // when card is configured as "AP mode" //------------------------------------------------------------ -typedef struct _RT_HTINFO_STA_ENTRY{ +typedef struct _RT_HTINFO_STA_ENTRY { u8 bEnableHT; u8 bSupportCck; @@ -377,7 +377,7 @@ typedef struct _RT_HTINFO_STA_ENTRY{ // when card is configured as "STA mode" //------------------------------------------------------------ -typedef struct _BSS_HT{ +typedef struct _BSS_HT { u8 bdSupportHT; @@ -395,7 +395,7 @@ typedef struct _BSS_HT{ u8 bdRT2RTLongSlotTime; } __attribute__ ((packed)) BSS_HT, *PBSS_HT; -typedef struct _MIMO_RSSI{ +typedef struct _MIMO_RSSI { u32 EnableAntenna; u32 AntennaA; u32 AntennaB; @@ -404,12 +404,12 @@ typedef struct _MIMO_RSSI{ u32 Average; }MIMO_RSSI, *PMIMO_RSSI; -typedef struct _MIMO_EVM{ +typedef struct _MIMO_EVM { u32 EVM1; u32 EVM2; }MIMO_EVM, *PMIMO_EVM; -typedef struct _FALSE_ALARM_STATISTICS{ +typedef struct _FALSE_ALARM_STATISTICS { u32 Cnt_Parity_Fail; u32 Cnt_Rate_Illegal; u32 Cnt_Crc8_fail; @@ -442,7 +442,7 @@ extern u8 MCS_FILTER_1SS[16]; #define IS_11N_MCS_RATE(rate) (rate&0x80) -typedef enum _HT_AGGRE_SIZE{ +typedef enum _HT_AGGRE_SIZE { HT_AGG_SIZE_8K = 0, HT_AGG_SIZE_16K = 1, HT_AGG_SIZE_32K = 2, @@ -464,7 +464,7 @@ typedef enum _HT_IOT_PEER // // IOT Action for different AP // -typedef enum _HT_IOT_ACTION{ +typedef enum _HT_IOT_ACTION { HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h index 873969c9f226..e25b69777ee7 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h @@ -14,7 +14,7 @@ typedef enum _TR_SELECT { RX_DIR = 1, } TR_SELECT, *PTR_SELECT; -typedef struct _TS_COMMON_INFO{ +typedef struct _TS_COMMON_INFO { struct list_head List; struct timer_list SetupTimer; struct timer_list InactTimer; @@ -25,7 +25,7 @@ typedef struct _TS_COMMON_INFO{ u8 TClasNum; } TS_COMMON_INFO, *PTS_COMMON_INFO; -typedef struct _TX_TS_RECORD{ +typedef struct _TX_TS_RECORD { TS_COMMON_INFO TsCommonInfo; u16 TxCurSeq; BA_RECORD TxPendingBARecord; /* For BA Originator */ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 6033502eff3d..b4c13fff2c65 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -21,7 +21,7 @@ static void TsInactTimeout(unsigned long data) * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer * return: NULL * notice: -********************************************************************************************************************/ + ********************************************************************************************************************/ static void RxPktPendingTimeout(unsigned long data) { PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; @@ -31,7 +31,6 @@ static void RxPktPendingTimeout(unsigned long data) //u32 flags = 0; unsigned long flags = 0; - struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; u8 index = 0; bool bPktInBuf = false; @@ -55,7 +54,7 @@ static void RxPktPendingTimeout(unsigned long data) pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096; IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum); - stats_IndicateArray[index] = pReorderEntry->prxb; + ieee->stats_IndicateArray[index] = pReorderEntry->prxb; index++; list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); @@ -79,7 +78,7 @@ static void RxPktPendingTimeout(unsigned long data) spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); return; } - ieee80211_indicate_packets(ieee, stats_IndicateArray, index); + ieee80211_indicate_packets(ieee, ieee->stats_IndicateArray, index); } if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) @@ -96,7 +95,7 @@ static void RxPktPendingTimeout(unsigned long data) * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer * return: NULL * notice: -********************************************************************************************************************/ + ********************************************************************************************************************/ static void TsAddBaProcess(unsigned long data) { PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c index f35defc36fd9..c414efc0662e 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ b/drivers/staging/rtl8192u/r8180_93cx6.c @@ -1,22 +1,22 @@ /* - This files contains card eeprom (93c46 or 93c56) programming routines, - memory is addressed by 16 bits words. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to thank the Authors of those projects and the Ndiswrapper - project Authors. -*/ + * This files contains card eeprom (93c46 or 93c56) programming routines, + * memory is addressed by 16 bits words. + * + * This is part of rtl8180 OpenSource driver. + * Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com> + * Released under the terms of GPL (General Public Licence) + * + * Parts of this driver are based on the GPL part of the + * official realtek driver. + * + * Parts of this driver are based on the rtl8180 driver skeleton + * from Patric Schenke & Andres Salomon. + * + * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + * + * We want to thank the Authors of those projects and the Ndiswrapper + * project Authors. + */ #include "r8180_93cx6.h" diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h index 9cf7f587c3ab..643d465e7105 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.h +++ b/drivers/staging/rtl8192u/r8180_93cx6.h @@ -1,17 +1,17 @@ /* - This is part of rtl8187 OpenSource driver - Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to thank the Authors of such projects and the Ndiswrapper - project Authors. -*/ + * This is part of rtl8187 OpenSource driver + * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com> + * Released under the terms of GPL (General Public Licence) + * + * Parts of this driver are based on the GPL part of the + * official realtek driver + * Parts of this driver are based on the rtl8180 driver skeleton + * from Patric Schenke & Andres Salomon + * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + * + * We want to thank the Authors of such projects and the Ndiswrapper + * project Authors. + */ /*This files contains card eeprom (93c46 or 93c56) programming routines*/ /*memory is addressed by WORDS*/ @@ -39,5 +39,4 @@ #define EPROM_TXPW2 0x1b #define EPROM_TXPW1 0x3d - int eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */ diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c index d733fb2ade91..e54f6fad2e68 100644 --- a/drivers/staging/rtl8192u/r8190_rtl8256.c +++ b/drivers/staging/rtl8192u/r8190_rtl8256.c @@ -1,12 +1,12 @@ /* -* This is part of the rtl8192 driver -* released under the GPL (See file COPYING for details). -* -* This files contains programming code for the rtl8256 -* radio frontend. -* -* *Many* thanks to Realtek Corp. for their great support! -*/ + * This is part of the rtl8192 driver + * released under the GPL (See file COPYING for details). + * + * This files contains programming code for the rtl8256 + * radio frontend. + * + * *Many* thanks to Realtek Corp. for their great support! + */ #include "r8192U.h" #include "r8192U_hw.h" diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.h b/drivers/staging/rtl8192u/r8190_rtl8256.h index 1ba4f83b520e..5c325ce9d631 100644 --- a/drivers/staging/rtl8192u/r8190_rtl8256.h +++ b/drivers/staging/rtl8192u/r8190_rtl8256.h @@ -1,14 +1,14 @@ /* - This is part of the rtl8180-sa2400 driver - released under the GPL (See file COPYING for details). - Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com> - - This files contains programming code for the rtl8256 - radio frontend. - - *Many* thanks to Realtek Corp. for their great support! - -*/ + * This is part of the rtl8180-sa2400 driver + * released under the GPL (See file COPYING for details). + * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com> + * + * + * This files contains programming code for the rtl8256 + * radio frontend. + * + * *Many* thanks to Realtek Corp. for their great support! + */ #ifndef RTL8225H #define RTL8225H diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 0b7b04ea0910..a7ba8f37384e 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -626,7 +626,8 @@ typedef struct Stats { long signal_quality; long last_signal_strength_inpercent; /* Correct smoothed ss in dbm, only used in driver - * to report real power now */ + * to report real power now + */ long recv_signal_power; u8 rx_rssi_percentage[4]; u8 rx_evm_percentage[2]; @@ -672,32 +673,40 @@ typedef struct _BB_REGISTER_DEFINITION { /* Tx gain stage: 0x80c~0x80f [4 bytes] */ u32 rfTxGainStage; /* wire parameter control1: 0x820~0x823, 0x828~0x82b, - * 0x830~0x833, 0x838~0x83b [16 bytes] */ + * 0x830~0x833, 0x838~0x83b [16 bytes] + */ u32 rfHSSIPara1; /* wire parameter control2: 0x824~0x827, 0x82c~0x82f, - * 0x834~0x837, 0x83c~0x83f [16 bytes] */ + * 0x834~0x837, 0x83c~0x83f [16 bytes] + */ u32 rfHSSIPara2; /* Tx Rx antenna control: 0x858~0x85f [16 bytes] */ u32 rfSwitchControl; /* AGC parameter control1: 0xc50~0xc53, 0xc58~0xc5b, - * 0xc60~0xc63, 0xc68~0xc6b [16 bytes] */ + * 0xc60~0xc63, 0xc68~0xc6b [16 bytes] + */ u32 rfAGCControl1; /* AGC parameter control2: 0xc54~0xc57, 0xc5c~0xc5f, - * 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] */ + * 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] + */ u32 rfAGCControl2; /* OFDM Rx IQ imbalance matrix: 0xc14~0xc17, 0xc1c~0xc1f, - * 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] */ + * 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] + */ u32 rfRxIQImbalance; /* Rx IQ DC offset and Rx digital filter, Rx DC notch filter: * 0xc10~0xc13, 0xc18~0xc1b, - * 0xc20~0xc23, 0xc28~0xc2b [16 bytes] */ + * 0xc20~0xc23, 0xc28~0xc2b [16 bytes] + */ u32 rfRxAFE; /* OFDM Tx IQ imbalance matrix: 0xc80~0xc83, 0xc88~0xc8b, - * 0xc90~0xc93, 0xc98~0xc9b [16 bytes] */ + * 0xc90~0xc93, 0xc98~0xc9b [16 bytes] + */ u32 rfTxIQImbalance; /* Tx IQ DC Offset and Tx DFIR type: * 0xc84~0xc87, 0xc8c~0xc8f, - * 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] */ + * 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] + */ u32 rfTxAFE; /* LSSI RF readback data: 0x8a0~0x8af [16 bytes] */ u32 rfLSSIReadBack; @@ -776,7 +785,8 @@ typedef struct _phy_ofdm_rx_status_report_819xusb { typedef struct _phy_cck_rx_status_report_819xusb { /* For CCK rate descriptor. This is an unsigned 8:1 variable. * LSB bit presend 0.5. And MSB 7 bts presend a signed value. - * Range from -64~+63.5. */ + * Range from -64~+63.5. + */ u8 adc_pwdb_X[4]; u8 sq_rpt; u8 cck_agc_rpt; @@ -991,7 +1001,8 @@ typedef struct r8192_priv { /* Control channel sub-carrier */ u8 nCur40MhzPrimeSC; /* Test for shorten RF configuration time. - * We save RF reg0 in this variable to reduce RF reading. */ + * We save RF reg0 in this variable to reduce RF reading. + */ u32 RfReg0Value[4]; u8 NumTotalRFPath; bool brfpath_rxenable[4]; @@ -1009,11 +1020,13 @@ typedef struct r8192_priv { bool bstore_last_dtpflag; /* Define to discriminate on High power State or - * on sitesurvey to change Tx gain index */ + * on sitesurvey to change Tx gain index + */ bool bstart_txctrl_bydtp; rate_adaptive rate_adaptive; /* TX power tracking - * OPEN/CLOSE TX POWER TRACKING */ + * OPEN/CLOSE TX POWER TRACKING + */ txbbgain_struct txbbgain_table[TxBBGainTableLength]; u8 txpower_count; /* For 6 sec do tracking again */ bool btxpower_trackingInit; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index fdb03dccb449..b631990b4969 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -503,8 +503,7 @@ static void watch_dog_timer_callback(unsigned long data); /**************************************************************************** * -----------------------------PROCFS STUFF------------------------- -***************************************************************************** - */ + ****************************************************************************/ static struct proc_dir_entry *rtl8192_proc; @@ -715,8 +714,8 @@ static void rtl8192_proc_remove_one(struct net_device *dev) } /**************************************************************************** - -----------------------------MISC STUFF------------------------- -*****************************************************************************/ + * -----------------------------MISC STUFF------------------------- + *****************************************************************************/ short check_nic_enough_desc(struct net_device *dev, int queue_index) { @@ -1009,7 +1008,7 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); int ret; unsigned long flags; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; /* shall not be referred by command packet */ @@ -1035,7 +1034,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); int ret; unsigned long flags; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; @@ -1061,14 +1060,14 @@ static void rtl8192_tx_isr(struct urb *tx_urb) struct sk_buff *skb = (struct sk_buff *)tx_urb->context; struct net_device *dev; struct r8192_priv *priv = NULL; - cb_desc *tcb_desc; + struct cb_desc *tcb_desc; u8 queue_index; if (!skb) return; dev = *(struct net_device **)(skb->cb); - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); queue_index = tcb_desc->queue_index; priv = ieee80211_priv(dev); @@ -1285,7 +1284,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb) struct urb *tx_urb; unsigned int idx_pipe; tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; atomic_inc(&priv->tx_pending[queue_index]); @@ -1328,7 +1327,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb) * 2006.10.30 by Emily * * \param QUEUEID Software Queue -*/ + */ static u8 MapHwQueueToFirmwareQueue(u8 QueueID) { u8 QueueSelect = 0x0; /* default set to */ @@ -1477,7 +1476,7 @@ static u8 MRateToHwRate8190Pci(u8 rate) } -static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc) +static u8 QueryIsShort(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc) { u8 tmp_Short; @@ -1499,11 +1498,11 @@ static void tx_zero_isr(struct urb *tx_urb) * The tx procedure is just as following, * skb->cb will contain all the following information, * priority, morefrag, rate, &dev. - * */ + */ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) { struct r8192_priv *priv = ieee80211_priv(dev); - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data; tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN); @@ -1840,8 +1839,8 @@ static void rtl8192_update_beacon(struct work_struct *work) } /* -* background support to run QoS activate functionality -*/ + * background support to run QoS activate functionality + */ static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; static void rtl8192_qos_activate(struct work_struct *work) @@ -1946,10 +1945,10 @@ static int rtl8192_handle_beacon(struct net_device *dev, } /* -* handling the beaconing responses. if we get different QoS setting -* off the network from the associated setting, adjust the QoS -* setting -*/ + * handling the beaconing responses. if we get different QoS setting + * off the network from the associated setting, adjust the QoS + * setting + */ static int rtl8192_qos_association_resp(struct r8192_priv *priv, struct ieee80211_network *network) { @@ -3045,8 +3044,8 @@ static bool rtl8192_adapter_start(struct net_device *dev) * be used to stop beacon transmission */ /*************************************************************************** - -------------------------------NET STUFF--------------------------- -***************************************************************************/ + * -------------------------------NET STUFF--------------------------- + ***************************************************************************/ static struct net_device_stats *rtl8192_stats(struct net_device *dev) { @@ -3074,9 +3073,9 @@ static bool HalTxCheckStuck819xUsb(struct net_device *dev) } /* -* <Assumption: RT_TX_SPINLOCK is acquired.> -* First added: 2006.11.19 by emily -*/ + * <Assumption: RT_TX_SPINLOCK is acquired.> + * First added: 2006.11.19 by emily + */ static RESET_TYPE TxCheckStuck(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -4156,7 +4155,8 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer, * Output: NONE * * Return: 0-100 percentage - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static u8 rtl819x_query_rxpwrpercentage(s8 antpower) { if ((antpower <= -100) || (antpower >= 20)) @@ -4529,19 +4529,19 @@ static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, } /** -* Function: UpdateReceivedRateHistogramStatistics -* Overview: Record the received data rate -* -* Input: -* struct net_device *dev -* struct ieee80211_rx_stats *stats -* -* Output: -* -* (priv->stats.ReceivedRateHistogram[] is updated) -* Return: -* None -*/ + * Function: UpdateReceivedRateHistogramStatistics + * Overview: Record the received data rate + * + * Input: + * struct net_device *dev + * struct ieee80211_rx_stats *stats + * + * Output: + * + * (priv->stats.ReceivedRateHistogram[] is updated) + * Return: + * None + */ static void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev, struct ieee80211_rx_stats *stats) @@ -4935,8 +4935,8 @@ static const struct net_device_ops rtl8192_netdev_ops = { /**************************************************************************** - ---------------------------- USB_STUFF--------------------------- -*****************************************************************************/ + * ---------------------------- USB_STUFF--------------------------- + *****************************************************************************/ static int rtl8192_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -5177,7 +5177,7 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, } /*************************************************************************** - ------------------- module init / exit stubs ---------------- -****************************************************************************/ + * ------------------- module init / exit stubs ---------------- + ****************************************************************************/ module_init(rtl8192_usb_module_init); module_exit(rtl8192_usb_module_exit); diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h index e07d65d04dbc..174ccf618d3e 100644 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ b/drivers/staging/rtl8192u/r8192U_hw.h @@ -1,18 +1,18 @@ /* - This is part of rtl8187 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official Realtek driver. - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - Parts of this driver are based on the Intel Pro Wireless - 2100 GPL driver. - - We want to thank the Authors of those projects - and the Ndiswrapper project Authors. -*/ + * This is part of rtl8187 OpenSource driver. + * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com> + * Released under the terms of GPL (General Public Licence) + * + * Parts of this driver are based on the GPL part of the + * official Realtek driver. + * Parts of this driver are based on the rtl8180 driver skeleton + * from Patric Schenke & Andres Salomon. + * Parts of this driver are based on the Intel Pro Wireless + * 2100 GPL driver. + * + * We want to thank the Authors of those projects + * and the Ndiswrapper project Authors. + */ /* Mariusz Matuszek added full registers definition with Realtek's name */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index d2f2f246063f..a9545386fbc5 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -562,7 +562,7 @@ static int r8192_wx_set_enc(struct net_device *dev, } if (wrqu->encoding.length == 0x5) { - ieee->pairwise_key_type = KEY_TYPE_WEP40; + ieee->pairwise_key_type = KEY_TYPE_WEP40; EnableHWSecurityConfig8192(dev); setKey(dev, @@ -576,8 +576,8 @@ static int r8192_wx_set_enc(struct net_device *dev, } else if (wrqu->encoding.length == 0xd) { - ieee->pairwise_key_type = KEY_TYPE_WEP104; - EnableHWSecurityConfig8192(dev); + ieee->pairwise_key_type = KEY_TYPE_WEP104; + EnableHWSecurityConfig8192(dev); setKey(dev, key_idx, /* EntryNo */ diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index 545f49ec9c03..3e0731b04619 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -30,16 +30,17 @@ rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) { struct r8192_priv *priv = ieee80211_priv(dev); struct sk_buff *skb; - cb_desc *tcb_desc; + struct cb_desc *tcb_desc; unsigned char *ptr_buf; /* Get TCB and local buffer from common pool. - (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) */ + * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + */ skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); if (!skb) return RT_STATUS_FAILURE; memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; tcb_desc->bLastIniPkt = 0; @@ -76,7 +77,8 @@ rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) * When Who Remark * 05/12/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -87,8 +89,9 @@ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) (pu1Byte)(&rtState)); /* When RF is off, we should not count the packet for hw/sw synchronize - reason, ie. there may be a duration while sw switch is changed and - hw switch is being changed. */ + * reason, ie. there may be a duration while sw switch is changed and + * hw switch is being changed. + */ if (rtState == eRfOff) return; #endif @@ -98,8 +101,9 @@ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) return; #endif /* We can not know the packet length and transmit type: - broadcast or uni or multicast. So the relative statistics - must be collected in tx feedback info. */ + * broadcast or uni or multicast. So the relative statistics + * must be collected in tx feedback info. + */ if (pstx_fb->tok) { priv->stats.txfeedbackok++; priv->stats.txoktotal++; @@ -133,11 +137,8 @@ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) priv->stats.txretrycount += pstx_fb->retry_cnt; priv->stats.txfeedbackretry += pstx_fb->retry_cnt; - } - - /*----------------------------------------------------------------------------- * Function: cmpk_handle_tx_feedback() * @@ -158,7 +159,8 @@ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) * When Who Remark * 05/08/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -168,8 +170,9 @@ static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) /* 1. Extract TX feedback info from RFD to temp structure buffer. */ /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ + * windows OS. So we have to read the content byte by byte or transfer + * endian type before copy the message copy. + */ /* Use pointer to transfer structure memory. */ memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); /* 2. Use tx feedback info to count TX statistics. */ @@ -177,8 +180,8 @@ static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) /* Comment previous method for TX statistic function. */ /* Collect info TX feedback packet to fill TCB. */ /* We can not know the packet length and transmit type: broadcast or uni - or multicast. */ - + * or multicast. + */ } static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) @@ -187,9 +190,9 @@ static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) u16 tx_rate; /* 87B have to S/W beacon for DTM encryption_cmn. */ if (priv->ieee80211->current_network.mode == IEEE_A || - priv->ieee80211->current_network.mode == IEEE_N_5G || - (priv->ieee80211->current_network.mode == IEEE_N_24G && - (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { + priv->ieee80211->current_network.mode == IEEE_N_5G || + (priv->ieee80211->current_network.mode == IEEE_N_24G && + (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { tx_rate = 60; DMESG("send beacon frame tx rate is 6Mbpm\n"); } else { @@ -198,13 +201,8 @@ static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) } rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */ - - } - - - /*----------------------------------------------------------------------------- * Function: cmpk_handle_interrupt_status() * @@ -224,7 +222,8 @@ static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) * When Who Remark * 05/12/2008 amy Add this for rtl8192 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) { cmpk_intr_sta_t rx_intr_status; /* */ @@ -234,15 +233,15 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) /* 1. Extract TX feedback info from RFD to temp structure buffer. */ /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ + * windows OS. So we have to read the content byte by byte or transfer + * endian type before copy the message copy. + */ rx_intr_status.length = pmsg[1]; if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) { DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); return; } - /* Statistics of beacon for ad-hoc mode. */ if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { /* 2 maybe need endian transform? */ @@ -261,17 +260,13 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) cmdpkt_beacontimerinterrupt_819xusb(dev); - } /* Other informations in interrupt status we need? */ - DMESG("<---- cmpk_handle_interrupt_status()\n"); - } - /*----------------------------------------------------------------------------- * Function: cmpk_handle_query_config_rx() * @@ -290,16 +285,17 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) * When Who Remark * 05/12/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) { cmpk_query_cfg_t rx_query_cfg; - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ + * windows OS. So we have to read the content byte by byte or transfer + * endian type before copy the message copy. + */ 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; @@ -309,10 +305,8 @@ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) (pmsg[10] << 8) | (pmsg[11] << 0); rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | (pmsg[14] << 8) | (pmsg[15] << 0); - } - /*----------------------------------------------------------------------------- * Function: cmpk_count_tx_status() * @@ -329,7 +323,8 @@ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) * When Who Remark * 05/12/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_count_tx_status(struct net_device *dev, cmpk_tx_status_t *pstx_status) { @@ -343,8 +338,9 @@ static void cmpk_count_tx_status(struct net_device *dev, (pu1Byte)(&rtState)); /* When RF is off, we should not count the packet for hw/sw synchronize - reason, ie. there may be a duration while sw switch is changed and - hw switch is being changed. */ + * reason, ie. there may be a duration while sw switch is changed and + * hw switch is being changed. + */ if (rtState == eRfOff) return; #endif @@ -374,8 +370,6 @@ static void cmpk_count_tx_status(struct net_device *dev, priv->stats.last_packet_rate = pstx_status->rate; } - - /*----------------------------------------------------------------------------- * Function: cmpk_handle_tx_status() * @@ -392,7 +386,8 @@ static void cmpk_count_tx_status(struct net_device *dev, * When Who Remark * 05/12/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) { cmpk_tx_status_t rx_tx_sts; @@ -400,10 +395,8 @@ static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t)); /* 2. Use tx feedback info to count TX statistics. */ cmpk_count_tx_status(dev, &rx_tx_sts); - } - /*----------------------------------------------------------------------------- * Function: cmpk_handle_tx_rate_history() * @@ -419,7 +412,8 @@ static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) * When Who Remark * 05/12/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) { cmpk_tx_rahis_t *ptxrate; @@ -428,14 +422,14 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) u32 *ptemp; struct r8192_priv *priv = ieee80211_priv(dev); - #ifdef ENABLE_PS pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); /* When RF is off, we should not count the packet for hw/sw synchronize - reason, ie. there may be a duration while sw switch is changed and - hw switch is being changed. */ + * reason, ie. there may be a duration while sw switch is changed and + * hw switch is being changed. + */ if (rtState == eRfOff) return; #endif @@ -443,7 +437,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) ptemp = (u32 *)pmsg; /* Do endian transfer to word alignment(16 bits) for windows system. - You must do different endian transfer for linux and MAC OS */ + * You must do different endian transfer for linux and MAC OS + */ for (i = 0; i < (length/4); i++) { u16 temp1, temp2; @@ -469,10 +464,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) for (j = 0; j < 4; j++) priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; } - } - /*----------------------------------------------------------------------------- * Function: cmpk_message_handle_rx() * @@ -492,7 +485,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) * When Who Remark * 05/06/2008 amy Create Version 0 porting from windows code. * - *---------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------- + */ u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats) { @@ -502,7 +496,8 @@ u32 cmpk_message_handle_rx(struct net_device *dev, u8 *pcmd_buff; /* 0. Check inpt arguments. If is is a command queue message or - pointer is null. */ + * pointer is null. + */ if (pstats == NULL) return 0; /* This is not a command packet. */ @@ -516,10 +511,12 @@ u32 cmpk_message_handle_rx(struct net_device *dev, element_id = pcmd_buff[0]; /* 4. Check every received command packet content according to different - element type. Because FW may aggregate RX command packet to - minimize transmit time between DRV and FW.*/ + * element type. Because FW may aggregate RX command packet to + * minimize transmit time between DRV and FW. + */ /* Add a counter to prevent the lock in the loop from being held too - long */ + * long + */ while (total_length > 0 && exe_cnt++ < 100) { /* We support aggregation of different cmd in the same packet */ element_id = pcmd_buff[0]; @@ -547,7 +544,8 @@ u32 cmpk_message_handle_rx(struct net_device *dev, case RX_TX_PER_PKT_FEEDBACK: /* You must at lease add a switch case element here, - Otherwise, we will jump to default case. */ + * Otherwise, we will jump to default case. + */ cmd_length = CMPK_RX_TX_FB_SIZE; break; @@ -567,5 +565,4 @@ u32 cmpk_message_handle_rx(struct net_device *dev, pcmd_buff += cmd_length; } return 1; /* This is a command packet. */ - } diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.h b/drivers/staging/rtl8192u/r819xU_cmdpkt.h index f490e253ee50..ad0f6003570d 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.h +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.h @@ -55,7 +55,8 @@ typedef struct tag_cmd_pkt_tx_feedback { } cmpk_txfb_t; /* 2. RX side: Interrupt status packet. It includes Beacon State, - * Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */ + * Beacon Timer Interrupt and other useful informations in MAC ISR Reg. + */ typedef struct tag_cmd_pkt_interrupt_status { u8 element_id; /* Command packet type. */ u8 length; /* Command packet length. */ @@ -83,13 +84,15 @@ typedef struct tag_cmd_pkt_set_configuration { } cmpk_set_cfg_t; /* 4. Both side : TX/RX query configuraton packet. The query structure is the - same as set configuration. */ + * same as set configuration. + */ #define cmpk_query_cfg_t cmpk_set_cfg_t /* 5. Multi packet feedback status. */ typedef struct tag_tx_stats_feedback { /* For endian transfer --> Driver will not the same as - firmware structure. */ + * firmware structure. + */ /* DW 0 */ u16 reserve1; u8 length; /* Command packet length */ diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 08302dfb0d90..35d1786703a7 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -10,7 +10,7 @@ * Returns: * NDIS_STATUS_FAILURE - the following initialization process should be terminated * NDIS_STATUS_SUCCESS - if firmware initialization process success -**************************************************************************************************/ + **************************************************************************************************/ #include "r8192U.h" #include "r8192U_hw.h" @@ -42,7 +42,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, rt_firmware *pfirmware = priv->pFirmware; struct sk_buff *skb; unsigned char *seg_ptr; - cb_desc *tcb_desc; + struct cb_desc *tcb_desc; u8 bLastIniPkt; u8 index; @@ -62,12 +62,12 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, /* Allocate skb buffer to contain firmware info and tx descriptor info * add 4 to avoid packet appending overflow. - * */ + */ skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); if (!skb) return false; memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; tcb_desc->bLastIniPkt = bLastIniPkt; @@ -277,7 +277,7 @@ bool init_firmware(struct net_device *dev) * 2. each packet segment will be put in the skb_buff packet. * 3. each skb_buff packet data content will already include the firmware info * and Tx descriptor info - * */ + */ rt_status = fw_download_code(dev, mapped_file, file_length); if (rst_opt == OPT_SYSTEM_RESET) release_firmware(fw_entry); diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 696df3440077..c99130fdb8ee 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -367,7 +367,8 @@ static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, /* Firmware RF Write control. * We can not execute the scheme in the initial step. * Otherwise, RF-R/W will waste much time. - * This is only for site survey. */ + * This is only for site survey. + */ /* 1. Read operation need not insert data. bit 0-11 */ /* 2. Write RF register address. bit 12-19 */ data |= ((offset&0xFF)<<12); @@ -380,7 +381,8 @@ static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, read_nic_dword(dev, QPNR, &tmp); while (tmp & 0x80000000) { /* If FW can not finish RF-R/W for more than ?? times. - We must reset FW. */ + * We must reset FW. + */ if (time++ < 100) { udelay(10); read_nic_dword(dev, QPNR, &tmp); @@ -394,7 +396,8 @@ static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath, read_nic_dword(dev, QPNR, &tmp); while (tmp & 0x80000000) { /* If FW can not finish RF-R/W for more than ?? times. - We must reset FW. */ + * We must reset FW. + */ if (time++ < 100) { udelay(10); read_nic_dword(dev, QPNR, &tmp); @@ -426,7 +429,8 @@ static void phy_FwRFSerialWrite(struct net_device *dev, /* Firmware RF Write control. * We can not execute the scheme in the initial step. * Otherwise, RF-R/W will waste much time. - * This is only for site survey. */ + * This is only for site survey. + */ /* 1. Set driver write bit and 12 bit data. bit 0-11 */ /* 2. Write RF register address. bit 12-19 */ @@ -442,7 +446,8 @@ static void phy_FwRFSerialWrite(struct net_device *dev, read_nic_dword(dev, QPNR, &tmp); while (tmp & 0x80000000) { /* If FW can not finish RF-R/W for more than ?? times. - We must reset FW. */ + * We must reset FW. + */ if (time++ < 100) { udelay(10); read_nic_dword(dev, QPNR, &tmp); @@ -451,10 +456,12 @@ static void phy_FwRFSerialWrite(struct net_device *dev, } } /* 7. No matter check bit. We always force the write. - Because FW will not accept the command. */ + * Because FW will not accept the command. + */ write_nic_dword(dev, QPNR, data); /* According to test, we must delay 20us to wait firmware - to finish RF write operation. */ + * to finish RF write operation. + */ /* We support delay in firmware side now. */ } @@ -723,7 +730,8 @@ u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, HW90_BLOCK_E CheckBlock, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]); /* TODO: we should not delay for such a long time. - Ask SD3 */ + * Ask SD3 + */ usleep_range(1000, 1000); reg = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], @@ -820,7 +828,8 @@ static void rtl8192_BB_Config_ParaFile(struct net_device *dev) } /* Check if the CCK HighPower is turned ON. - This is used to calculate PWDB. */ + * This is used to calculate PWDB. + */ priv->bCckHighPower = (u8)rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200); @@ -839,7 +848,8 @@ void rtl8192_BBConfig(struct net_device *dev) rtl8192_InitBBRFRegDef(dev); /* config BB&RF. As hardCode based initialization has not been well * implemented, so use file first. - * FIXME: should implement it for hardcode? */ + * FIXME: should implement it for hardcode? + */ rtl8192_BB_Config_ParaFile(dev); } @@ -1158,7 +1168,8 @@ bool rtl8192_SetRFPowerState(struct net_device *dev, switch (pHalData->eRFPowerState) { case eRfOff: /* If Rf off reason is from IPS, - LED should blink with no link */ + * LED should blink with no link + */ if (pMgntInfo->RfOffReason == RF_CHANGE_BY_IPS) Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK); else @@ -1168,7 +1179,7 @@ bool rtl8192_SetRFPowerState(struct net_device *dev, case eRfOn: /* Turn on RF we are still linked, which might - happen when we quickly turn off and on HW RF. + * happen when we quickly turn off and on HW RF. */ if (pMgntInfo->bMediaConnect) Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK); @@ -1263,7 +1274,8 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, if (!IsLegalChannel(priv->ieee80211, channel)) { RT_TRACE(COMP_ERR, "set to illegal channel: %d\n", channel); /* return true to tell upper caller function this channel - setting is finished! Or it will in while loop. */ + * setting is finished! Or it will in while loop. + */ return true; } /* FIXME: need to check whether channel is legal or not here */ @@ -1609,7 +1621,8 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) } /* Skip over setting of J-mode in BB register here. - Default value is "None J mode". */ + * Default value is "None J mode". + */ /* <3> Set RF related register */ switch (priv->rf_chip) { diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 0dd458d1402c..c83d7ebb164f 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -117,16 +117,16 @@ static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw) { - pfwhdr->signature = le16_to_cpu(*(u16 *)pmappedfw); - pfwhdr->version = le16_to_cpu(*(u16 *)(pmappedfw + 2)); + pfwhdr->signature = le16_to_cpu(*(__le16 *)pmappedfw); + pfwhdr->version = le16_to_cpu(*(__le16 *)(pmappedfw + 2)); /* define the size of boot loader */ - pfwhdr->dmem_size = le32_to_cpu(*(uint *)(pmappedfw + 4)); + pfwhdr->dmem_size = le32_to_cpu(*(__le32 *)(pmappedfw + 4)); /* define the size of FW in IMEM */ - pfwhdr->img_IMEM_size = le32_to_cpu(*(uint *)(pmappedfw + 8)); + pfwhdr->img_IMEM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 8)); /* define the size of FW in SRAM */ - pfwhdr->img_SRAM_size = le32_to_cpu(*(uint *)(pmappedfw + 12)); + pfwhdr->img_SRAM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 12)); /* define the size of DMEM variable */ - pfwhdr->fw_priv_sz = le32_to_cpu(*(uint *)(pmappedfw + 16)); + pfwhdr->fw_priv_sz = le32_to_cpu(*(__le32 *)(pmappedfw + 16)); } static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength) diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index 5dc3b5b9bfff..d84da2b6d6b3 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -174,16 +174,16 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv) sz += 8; ie += sz; /*beacon interval : 2bytes*/ - *(u16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod); + *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod); sz += 2; ie += 2; /*capability info*/ *(u16 *)ie = 0; - *(u16 *)ie |= cpu_to_le16(cap_IBSS); + *(__le16 *)ie |= cpu_to_le16(cap_IBSS); if (pregistrypriv->preamble == PREAMBLE_SHORT) - *(u16 *)ie |= cpu_to_le16(cap_ShortPremble); + *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble); if (pdev_network->Privacy) - *(u16 *)ie |= cpu_to_le16(cap_Privacy); + *(__le16 *)ie |= cpu_to_le16(cap_Privacy); sz += 2; ie += 2; /*SSID*/ @@ -202,10 +202,10 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv) rateLen, pdev_network->rates, &sz); /*DS parameter set*/ ie = r8712_set_ie(ie, _DSSET_IE_, 1, - (u8 *)&(pdev_network->Configuration.DSConfig), &sz); + (u8 *)&pdev_network->Configuration.DSConfig, &sz); /*IBSS Parameter Set*/ ie = r8712_set_ie(ie, _IBSS_PARA_IE_, 2, - (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz); + (u8 *)&pdev_network->Configuration.ATIMWindow, &sz); return sz; } @@ -224,7 +224,7 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) goto check_next_ie; /*check version...*/ memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16)); - val16 = le16_to_cpu(val16); + le16_to_cpus(&val16); if (val16 != 0x0001) goto check_next_ie; *wpa_ie_len = *(pbuf + 1); @@ -304,7 +304,7 @@ int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, } /*pairwise_cipher*/ if (left >= 2) { - count = le16_to_cpu(*(u16 *)pos); + count = le16_to_cpu(*(__le16 *)pos); pos += 2; left -= 2; if (count == 0 || left < count * WPA_SELECTOR_LEN) @@ -347,7 +347,7 @@ int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, } /*pairwise_cipher*/ if (left >= 2) { - count = le16_to_cpu(*(u16 *)pos); + count = le16_to_cpu(*(__le16 *)pos); pos += 2; left -= 2; if (count == 0 || left < count * RSN_SELECTOR_LEN) diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h index 67ab58084e8a..68fd65e80906 100644 --- a/drivers/staging/rtl8712/ieee80211.h +++ b/drivers/staging/rtl8712/ieee80211.h @@ -138,51 +138,51 @@ struct ieee_ibss_seq { }; struct ieee80211_hdr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 addr4[ETH_ALEN]; -} __packed; +} __packed __aligned(2); struct ieee80211_hdr_3addr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; -} __packed; + __le16 seq_ctl; +} __packed __aligned(2); struct ieee80211_hdr_qos { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 addr4[ETH_ALEN]; - u16 qc; -} __packed; + __le16 qc; +} __packed __aligned(2); struct ieee80211_hdr_3addr_qos { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; - u16 qc; + __le16 seq_ctl; + __le16 qc; } __packed; struct eapol { u8 snap[6]; - u16 ethertype; + __be16 ethertype; u8 version; u8 type; - u16 length; + __le16 length; } __packed; enum eap_type { @@ -514,13 +514,13 @@ struct ieee80211_security { */ struct ieee80211_header_data { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[6]; u8 addr2[6]; u8 addr3[6]; - u16 seq_ctrl; -}; + __le16 seq_ctrl; +} __packed __aligned(2); #define BEACON_PROBE_SSID_ID_POSITION 12 @@ -552,18 +552,18 @@ struct ieee80211_info_element { /* * These are the data types that can make up management packets * - u16 auth_algorithm; - u16 auth_sequence; - u16 beacon_interval; - u16 capability; + __le16 auth_algorithm; + __le16 auth_sequence; + __le16 beacon_interval; + __le16 capability; u8 current_ap[ETH_ALEN]; - u16 listen_interval; + __le16 listen_interval; struct { u16 association_id:14, reserved:2; } __packed; - u32 time_stamp[2]; - u16 reason; - u16 status; + __le32 time_stamp[2]; + __le16 reason; + __le16 status; */ #define IEEE80211_DEFAULT_TX_ESSID "Penguin" @@ -571,16 +571,16 @@ struct ieee80211_info_element { struct ieee80211_authentication { struct ieee80211_header_data header; - u16 algorithm; - u16 transaction; - u16 status; + __le16 algorithm; + __le16 transaction; + __le16 status; } __packed; struct ieee80211_probe_response { struct ieee80211_header_data header; - u32 time_stamp[2]; - u16 beacon_interval; - u16 capability; + __le32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; struct ieee80211_info_element info_element; } __packed; @@ -590,16 +590,16 @@ struct ieee80211_probe_request { struct ieee80211_assoc_request_frame { struct ieee80211_hdr_3addr header; - u16 capability; - u16 listen_interval; + __le16 capability; + __le16 listen_interval; struct ieee80211_info_element_hdr info_element; } __packed; struct ieee80211_assoc_response_frame { struct ieee80211_hdr_3addr header; - u16 capability; - u16 status; - u16 aid; + __le16 capability; + __le16 status; + __le16 aid; } __packed; struct ieee80211_txb { diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c index af7c4a47738a..999c16d9c6c1 100644 --- a/drivers/staging/rtl8712/mlme_linux.c +++ b/drivers/staging/rtl8712/mlme_linux.c @@ -117,7 +117,7 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter) backupTKIPCountermeasure = adapter->securitypriv. btkip_countermeasure; memset((unsigned char *)&adapter->securitypriv, 0, - sizeof(struct security_priv)); + sizeof(struct security_priv)); setup_timer(&adapter->securitypriv.tkip_timer, r8712_use_tkipkey_handler, (unsigned long)adapter); @@ -125,8 +125,8 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter) * for the following connection. */ memcpy(&adapter->securitypriv.PMKIDList[0], - &backupPMKIDList[0], - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); + &backupPMKIDList[0], + sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure; diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 9f61583af150..f19b6b27aa71 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -314,7 +314,8 @@ void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag) int r8712_cmd_thread(void *context) { struct cmd_obj *pcmd; - unsigned int cmdsz, wr_sz, *pcmdbuf; + unsigned int cmdsz, wr_sz; + __le32 *pcmdbuf; struct tx_desc *pdesc; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); struct _adapter *padapter = context; @@ -334,7 +335,7 @@ _next: r8712_unregister_cmd_alive(padapter); continue; } - pcmdbuf = (unsigned int *)pcmdpriv->cmd_buf; + pcmdbuf = (__le32 *)pcmdpriv->cmd_buf; pdesc = (struct tx_desc *)pcmdbuf; memset(pdesc, 0, TXDESC_SIZE); pcmd = cmd_hdl_filter(padapter, pcmd); @@ -424,7 +425,7 @@ _next: thread_exit(); } -void r8712_event_handle(struct _adapter *padapter, uint *peventbuf) +void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf) { u8 evt_code, evt_seq; u16 evt_sz; diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h index 29a4c23a0d23..b38374025c93 100644 --- a/drivers/staging/rtl8712/rtl8712_event.h +++ b/drivers/staging/rtl8712/rtl8712_event.h @@ -26,7 +26,7 @@ #ifndef _RTL8712_EVENT_H_ #define _RTL8712_EVENT_H_ -void r8712_event_handle(struct _adapter *padapter, uint *peventbuf); +void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf); void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf); enum rtl8712_c2h_event { diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 66f0e0a35167..20fe45a43e53 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -408,7 +408,7 @@ static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); } else { - u16 len; + __be16 len; /* Leave Ethernet header part of hdr and full payload */ len = htons(sub_skb->len); memcpy(skb_push(sub_skb, 2), &len, 2); @@ -439,21 +439,21 @@ exit: void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) { - uint voffset; + __le32 voffset; u8 *poffset; u16 cmd_len, drvinfo_sz; struct recv_stat *prxstat; poffset = (u8 *)prxcmdbuf; - voffset = *(uint *)poffset; + voffset = *(__le32 *)poffset; prxstat = (struct recv_stat *)prxcmdbuf; drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; drvinfo_sz <<= 3; poffset += RXDESC_SIZE + drvinfo_sz; do { - voffset = *(uint *)poffset; + voffset = *(__le32 *)poffset; cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff); - r8712_event_handle(padapter, (uint *)poffset); + r8712_event_handle(padapter, (__le32 *)poffset); poffset += (cmd_len + 8);/*8 bytes alignment*/ } while (le32_to_cpu(voffset) & BIT(31)); @@ -758,7 +758,7 @@ static void query_rx_phy_status(struct _adapter *padapter, /* CCK Driver info Structure is not the same as OFDM packet.*/ pcck_buf = (struct phy_cck_rx_status *)pphy_stat; /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by hardware + * (2)PWDB, Average PWDB calculated by hardware * (for rate adaptive) */ if (!cck_highpwr) { @@ -853,7 +853,7 @@ static void query_rx_phy_status(struct _adapter *padapter, rssi = query_rx_pwr_percentage(rx_pwr[i]); total_rssi += rssi; } - /* (2)PWDB, Average PWDB cacluated by hardware (for + /* (2)PWDB, Average PWDB calculated by hardware (for * rate adaptive) */ rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f) diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h index 0b0c2730aac5..0352e6fafd90 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ b/drivers/staging/rtl8712/rtl8712_recv.h @@ -50,12 +50,12 @@ #define REORDER_WAIT_TIME 30 /* (ms)*/ struct recv_stat { - unsigned int rxdw0; - unsigned int rxdw1; - unsigned int rxdw2; - unsigned int rxdw3; - unsigned int rxdw4; - unsigned int rxdw5; + __le32 rxdw0; + __le32 rxdw1; + __le32 rxdw2; + __le32 rxdw3; + __le32 rxdw4; + __le32 rxdw5; }; struct phy_cck_rx_status { @@ -69,14 +69,14 @@ struct phy_cck_rx_status { }; struct phy_stat { - unsigned int phydw0; - unsigned int phydw1; - unsigned int phydw2; - unsigned int phydw3; - unsigned int phydw4; - unsigned int phydw5; - unsigned int phydw6; - unsigned int phydw7; + __le32 phydw0; + __le32 phydw1; + __le32 phydw2; + __le32 phydw3; + __le32 phydw4; + __le32 phydw5; + __le32 phydw6; + __le32 phydw7; }; #define PHY_STAT_GAIN_TRSW_SHT 0 #define PHY_STAT_PWDB_ALL_SHT 4 diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index c4f03a602a2e..7fe626583c8a 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -302,7 +302,7 @@ u8 r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, int last_txcmdsz = 0; int padding_sz = 0; - /* 802.3->802.11 convertor */ + /* 802.3->802.11 converter */ r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); /* free skb struct */ r8712_xmit_complete(padapter, pxmitframe); @@ -561,19 +561,19 @@ static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz) ptxdesc_mp = &txdesc_mp; /* offset 8 */ - ptxdesc->txdw2 = cpu_to_le32(ptxdesc_mp->txdw2); + ptxdesc->txdw2 = ptxdesc_mp->txdw2; if (bmcst) ptxdesc->txdw2 |= cpu_to_le32(BMC); ptxdesc->txdw2 |= cpu_to_le32(BK); /* offset 16 */ - ptxdesc->txdw4 = cpu_to_le32(ptxdesc_mp->txdw4); + ptxdesc->txdw4 = ptxdesc_mp->txdw4; /* offset 20 */ - ptxdesc->txdw5 = cpu_to_le32(ptxdesc_mp->txdw5); + ptxdesc->txdw5 = ptxdesc_mp->txdw5; pattrib->pctrl = 0;/* reset to zero; */ } } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { /* offset 4 */ - ptxdesc->txdw1 |= (0x05) & 0x1f;/*CAM_ID(MAC_ID), default=5;*/ + ptxdesc->txdw1 |= cpu_to_le32((0x05) & 0x1f);/*CAM_ID(MAC_ID), default=5;*/ qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */ diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h index b50e7a1f3a42..02b1593ada01 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.h +++ b/drivers/staging/rtl8712/rtl8712_xmit.h @@ -91,14 +91,14 @@ struct tx_desc { /*DWORD 0*/ - unsigned int txdw0; - unsigned int txdw1; - unsigned int txdw2; - unsigned int txdw3; - unsigned int txdw4; - unsigned int txdw5; - unsigned int txdw6; - unsigned int txdw7; + __le32 txdw0; + __le32 txdw1; + __le32 txdw2; + __le32 txdw3; + __le32 txdw4; + __le32 txdw5; + __le32 txdw6; + __le32 txdw7; }; diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h index 3284dcf2f1a9..4734ca856aa2 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ b/drivers/staging/rtl8712/rtl871x_cmd.h @@ -156,9 +156,9 @@ struct setopmode_parm { * Command-Event Mode */ struct sitesurvey_parm { - sint passive_mode; /*active: 1, passive: 0 */ - sint bsslimit; /* 1 ~ 48 */ - sint ss_ssidlen; + __le32 passive_mode; /*active: 1, passive: 0 */ + __le32 bsslimit; /* 1 ~ 48 */ + __le32 ss_ssidlen; u8 ss_ssid[IW_ESSID_MAX_SIZE + 1]; }; diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h index 697c8d735150..5db8620980e5 100644 --- a/drivers/staging/rtl8712/rtl871x_event.h +++ b/drivers/staging/rtl8712/rtl871x_event.h @@ -66,7 +66,7 @@ struct joinbss_event { struct stassoc_event { unsigned char macaddr[6]; unsigned char rsvd[2]; - int cam_id; + __le32 cam_id; }; struct stadel_event { diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 590acb5aea3d..f4167f14af70 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -199,7 +199,7 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter, iwe.cmd = SIOCGIWMODE; memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs), 2); - cap = le16_to_cpu(cap); + le16_to_cpus(&cap); if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) { if (cap & WLAN_CAPABILITY_BSS) iwe.u.mode = (u32)IW_MODE_MASTER; @@ -1419,9 +1419,9 @@ static int r8711_wx_get_rate(struct net_device *dev, ht_cap = true; pht_capie = (struct ieee80211_ht_cap *)(p + 2); memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2); - bw_40MHz = (pht_capie->cap_info & + bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0; - short_GI = (pht_capie->cap_info & + short_GI = (le16_to_cpu(pht_capie->cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; } @@ -2322,7 +2322,7 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) piwstats->qual.level = 0; piwstats->qual.noise = 0; } else { - /* show percentage, we need transfer dbm to orignal value. */ + /* show percentage, we need transfer dbm to original value. */ tmp_level = padapter->recvpriv.fw_rssi; tmp_qual = padapter->recvpriv.signal; tmp_noise = padapter->recvpriv.noise; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 35cbdc71cad4..bf1ac22bae1c 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -257,10 +257,10 @@ int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) struct security_priv *psecuritypriv = &adapter->securitypriv; if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && - (pnetwork->network.Privacy == 0)) + (pnetwork->network.Privacy == cpu_to_le32(0))) ret = false; else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) && - (pnetwork->network.Privacy == 1)) + (pnetwork->network.Privacy == cpu_to_le32(1))) ret = false; else ret = true; @@ -933,7 +933,7 @@ void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) return; /* to do : init sta_info variable */ psta->qos_option = 0; - psta->mac_id = le32_to_cpu((uint)pstassoc->cam_id); + psta->mac_id = le32_to_cpu(pstassoc->cam_id); /* psta->aid = (uint)pstassoc->cam_id; */ if (adapter->securitypriv.AuthAlgrthm == 2) @@ -1637,25 +1637,23 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter) pdev_network->Rssi = 0; switch (pregistrypriv->wireless_mode) { case WIRELESS_11B: - pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11DS); + pdev_network->NetworkTypeInUse = Ndis802_11DS; break; case WIRELESS_11G: case WIRELESS_11BG: - pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM24); + pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; break; case WIRELESS_11A: - pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM5); + pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; break; default: /* TODO */ break; } - pdev_network->Configuration.DSConfig = cpu_to_le32( - pregistrypriv->channel); + pdev_network->Configuration.DSConfig = pregistrypriv->channel; if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) - pdev_network->Configuration.ATIMWindow = cpu_to_le32(3); - pdev_network->InfrastructureMode = cpu_to_le32( - cur_network->network.InfrastructureMode); + pdev_network->Configuration.ATIMWindow = 3; + pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode; /* 1. Supported rates * 2. IE */ @@ -1710,12 +1708,12 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, } out_len = *pout_len; memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); - ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH | + ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_MAX_AMSDU | - IEEE80211_HT_CAP_DSSSCCK40; + IEEE80211_HT_CAP_DSSSCCK40); ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_, diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c index b98a596757f5..6e264a8d0087 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c @@ -202,7 +202,7 @@ static int mp_start_test(struct _adapter *padapter) res = _FAIL; goto end_of_mp_start_test; } - /* 3 3. join psudo AdHoc */ + /* 3 3. join pseudo AdHoc */ tgt_network->join_res = 1; tgt_network->aid = psta->aid = 1; memcpy(&tgt_network->network, &bssid, length); @@ -227,7 +227,7 @@ static int mp_stop_test(struct _adapter *padapter) spin_lock_irqsave(&pmlmepriv->lock, irqL); if (!check_fwstate(pmlmepriv, WIFI_MP_STATE)) goto end_of_mp_stop_test; - /* 3 1. disconnect psudo AdHoc */ + /* 3 1. disconnect pseudo AdHoc */ r8712_os_indicate_disconnect(padapter); /* 3 2. clear psta used in mp test mode. */ psta = r8712_get_stainfo(&padapter->stapriv, diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 35c721a50598..2ef31a4e9a6b 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -258,7 +258,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, /* get ether_type */ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; memcpy(ðer_type, ptr, 2); - ether_type = ntohs((unsigned short)ether_type); + be16_to_cpus(ðer_type); if ((psta != NULL) && (psta->ieee8021x_blocked)) { /* blocked @@ -640,17 +640,23 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) /* append rx status for mp test packets */ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); + if (!ptr) + return _FAIL; memcpy(ptr, get_rxmem(precvframe), 24); ptr += 24; - } else + } else { ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); + if (!ptr) + return _FAIL; + } memcpy(ptr, pattrib->dst, ETH_ALEN); memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); if (!bsnaphdr) { - len = htons(len); - memcpy(ptr + 12, &len, 2); + __be16 be_tmp = htons(len); + + memcpy(ptr + 12, &be_tmp, 2); } return _SUCCESS; } diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index a7f04a4b089d..bd83fb492c45 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -192,7 +192,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) length = pattrib->last_txcmdsz - pattrib-> hdrlen - pattrib->iv_len - pattrib->icv_len; - *((u32 *)crc) = cpu_to_le32(getcrc32( + *((__le32 *)crc) = cpu_to_le32(getcrc32( payload, length)); arcfour_init(&mycontext, wepkey, 3 + keylength); arcfour_encrypt(&mycontext, payload, payload, @@ -203,7 +203,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - *((u32 *)crc) = cpu_to_le32(getcrc32( + *((__le32 *)crc) = cpu_to_le32(getcrc32( payload, length)); arcfour_init(&mycontext, wepkey, 3 + keylength); arcfour_encrypt(&mycontext, payload, payload, @@ -248,7 +248,7 @@ void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe) arcfour_init(&mycontext, wepkey, 3 + keylength); arcfour_encrypt(&mycontext, payload, payload, length); /* calculate icv and compare the icv */ - *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); + *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); } } @@ -616,7 +616,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - *((u32 *)crc) = cpu_to_le32( + *((__le32 *)crc) = cpu_to_le32( getcrc32(payload, length)); arcfour_init(&mycontext, rc4key, 16); arcfour_encrypt(&mycontext, payload, @@ -628,7 +628,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - *((u32 *)crc) = cpu_to_le32(getcrc32( + *((__le32 *)crc) = cpu_to_le32(getcrc32( payload, length)); arcfour_init(&mycontext, rc4key, 16); arcfour_encrypt(&mycontext, payload, @@ -696,7 +696,7 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) /* 4 decrypt payload include icv */ arcfour_init(&mycontext, rc4key, 16); arcfour_encrypt(&mycontext, payload, payload, length); - *((u32 *)crc) = cpu_to_le32(getcrc32(payload, + *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); if (crc[3] != payload[length - 1] || crc[2] != payload[length - 2] || @@ -833,7 +833,7 @@ static void mix_column(u8 *in, u8 *out) u8 add1b[4]; u8 add1bf7[4]; u8 rotl[4]; - u8 swap_halfs[4]; + u8 swap_halves[4]; u8 andf7[4]; u8 rotr[4]; u8 temp[4]; @@ -845,10 +845,10 @@ static void mix_column(u8 *in, u8 *out) else add1b[i] = 0x00; } - swap_halfs[0] = in[2]; /* Swap halves */ - swap_halfs[1] = in[3]; - swap_halfs[2] = in[0]; - swap_halfs[3] = in[1]; + swap_halves[0] = in[2]; /* Swap halves */ + swap_halves[1] = in[3]; + swap_halves[2] = in[0]; + swap_halves[3] = in[1]; rotl[0] = in[3]; /* Rotate left 8 bits */ rotl[1] = in[0]; rotl[2] = in[1]; @@ -872,7 +872,7 @@ static void mix_column(u8 *in, u8 *out) rotr[2] = rotr[3]; rotr[3] = temp[0]; xor_32(add1bf7, rotr, temp); - xor_32(swap_halfs, rotl, tempb); + xor_32(swap_halves, rotl, tempb); xor_32(temp, tempb, out); } @@ -1047,8 +1047,8 @@ static sint aes_cipher(u8 *key, uint hdrlen, u8 aes_out[16]; u8 padded_buffer[16]; u8 mic[8]; - uint frtype = GetFrameType(pframe); - uint frsubtype = GetFrameSubType(pframe); + u16 frtype = GetFrameType(pframe); + u16 frsubtype = GetFrameSubType(pframe); frsubtype >>= 4; memset((void *)mic_iv, 0, 16); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 4ab82ba9bb3f..de88819faf05 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -347,7 +347,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, * some settings above. */ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - pattrib->priority = (txdesc.txdw1 >> QSEL_SHT) & 0x1f; + pattrib->priority = + (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f; return _SUCCESS; } @@ -488,7 +489,7 @@ static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr, struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv = &pmlmepriv->qospriv; - u16 *fctrl = &pwlanhdr->frame_ctl; + __le16 *fctrl = &pwlanhdr->frame_ctl; memset(hdr, 0, WLANHDR_OFFSET); SetFrameSubType(fctrl, pattrib->subtype); @@ -577,7 +578,7 @@ static sint r8712_put_snap(u8 *data, u16 h_proto) snap->oui[0] = oui[0]; snap->oui[1] = oui[1]; snap->oui[2] = oui[2]; - *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); return SNAP_SIZE + sizeof(u16); } diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c index 9172400efe9a..332e2e51d778 100644 --- a/drivers/staging/rtl8712/usb_ops.c +++ b/drivers/staging/rtl8712/usb_ops.c @@ -41,7 +41,7 @@ static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; @@ -61,7 +61,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; @@ -81,7 +81,7 @@ static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; @@ -101,7 +101,7 @@ static void usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; @@ -109,8 +109,7 @@ static void usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) index = 0; wvalue = (u16)(addr & 0x0000ffff); len = 1; - data = val; - data = cpu_to_le32(data & 0x000000ff); + data = cpu_to_le32((u32)val & 0x000000ff); r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len, requesttype); } @@ -122,7 +121,7 @@ static void usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; @@ -130,8 +129,7 @@ static void usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) index = 0; wvalue = (u16)(addr & 0x0000ffff); len = 2; - data = val; - data = cpu_to_le32(data & 0x0000ffff); + data = cpu_to_le32((u32)val & 0x0000ffff); r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len, requesttype); } @@ -143,7 +141,7 @@ static void usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) u16 wvalue; u16 index; u16 len; - u32 data; + __le32 data; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; request = 0x05; diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index fc6bb0be2a28..441e76b8959d 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -192,7 +192,8 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) static void r8712_usb_read_port_complete(struct urb *purb) { - uint isevt, *pbuf; + uint isevt; + __le32 *pbuf; struct recv_buf *precvbuf = (struct recv_buf *)purb->context; struct _adapter *padapter = (struct _adapter *)precvbuf->adapter; struct recv_priv *precvpriv = &padapter->recvpriv; @@ -208,7 +209,7 @@ static void r8712_usb_read_port_complete(struct urb *purb) _pkt *pskb = precvbuf->pskb; precvbuf->transfer_len = purb->actual_length; - pbuf = (uint *)precvbuf->pbuf; + pbuf = (__le32 *)precvbuf->pbuf; isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff; if ((isevt & 0x1ff) == 0x1ff) { r8712_rxcmd_event_hdl(padapter, pbuf); diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index b8af9656e6da..74dfc9b0e494 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -151,138 +151,133 @@ enum WIFI_REG_DOMAIN { #define _ORDER_ BIT(15) #define SetToDs(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_TO_DS_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_TO_DS_); \ }) -#define GetToDs(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_TO_DS_)) != 0) +#define GetToDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_TO_DS_)) != 0) #define ClearToDs(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \ }) #define SetFrDs(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_FROM_DS_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_FROM_DS_); \ }) -#define GetFrDs(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_FROM_DS_)) != 0) +#define GetFrDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_FROM_DS_)) != 0) #define ClearFrDs(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ }) #define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) #define SetMFrag(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \ }) -#define GetMFrag(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_MORE_FRAG_)) != 0) +#define GetMFrag(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_MORE_FRAG_)) != 0) #define ClearMFrag(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \ }) #define SetRetry(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_RETRY_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_RETRY_); \ }) -#define GetRetry(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_RETRY_)) != 0) +#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_RETRY_)) != 0) #define ClearRetry(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \ }) #define SetPwrMgt(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_PWRMGT_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_PWRMGT_); \ }) -#define GetPwrMgt(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_PWRMGT_)) != 0) +#define GetPwrMgt(pbuf) (((*(__le16 *)(pbuf)) & \ + cpu_to_le16(_PWRMGT_)) != 0) #define ClearPwrMgt(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \ }) #define SetMData(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \ }) -#define GetMData(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_MORE_DATA_)) != 0) +#define GetMData(pbuf) (((*(__le16 *)(pbuf)) & \ + cpu_to_le16(_MORE_DATA_)) != 0) #define ClearMData(pbuf) ({ \ - *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \ + *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \ }) #define SetPrivacy(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_PRIVACY_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_PRIVACY_); \ }) -#define GetPrivacy(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_PRIVACY_)) != 0) +#define GetPrivacy(pbuf) (((*(__le16 *)(pbuf)) & \ + cpu_to_le16(_PRIVACY_)) != 0) -#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & \ - le16_to_cpu(_ORDER_)) != 0) +#define GetOrder(pbuf) (((*(__le16 *)(pbuf)) & \ + cpu_to_le16(_ORDER_)) != 0) -#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & \ +#define GetFrameType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ (BIT(3) | BIT(2))) #define SetFrameType(pbuf, type) \ do { \ - *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(3) | \ + *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(3) | \ BIT(2))); \ - *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + *(__le16 *)(pbuf) |= cpu_to_le16(type); \ } while (0) -#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & \ +#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | \ BIT(2))) #define SetFrameSubType(pbuf, type) \ do { \ - *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ + *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ - *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + *(__le16 *)(pbuf) |= cpu_to_le16(type); \ } while (0) -#define GetSequence(pbuf) (cpu_to_le16(*(unsigned short *)\ +#define GetSequence(pbuf) (le16_to_cpu(*(__le16 *)\ ((addr_t)(pbuf) + 22)) >> 4) -#define GetFragNum(pbuf) (cpu_to_le16(*(unsigned short *)((addr_t)\ +#define GetFragNum(pbuf) (le16_to_cpu(*(__le16 *)((addr_t)\ (pbuf) + 22)) & 0x0f) #define SetSeqNum(pbuf, num) ({ \ - *(unsigned short *)((addr_t)(pbuf) + 22) = \ - ((*(unsigned short *)((addr_t)(pbuf) + 22)) & \ - le16_to_cpu((unsigned short)0x000f)) | \ - le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \ + *(__le16 *)((addr_t)(pbuf) + 22) = \ + cpu_to_le16((le16_to_cpu(*(__le16 *)((addr_t)(pbuf) + 22)) & \ + 0x000f) | (0xfff0 & (num << 4))); \ }) #define SetDuration(pbuf, dur) ({ \ - *(unsigned short *)((addr_t)(pbuf) + 2) |= \ + *(__le16 *)((addr_t)(pbuf) + 2) |= \ cpu_to_le16(0xffff & (dur)); \ }) #define SetPriority(pbuf, tid) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf); \ + *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf); \ }) -#define GetPriority(pbuf) ((le16_to_cpu(*(unsigned short *)(pbuf))) & 0xf) +#define GetPriority(pbuf) ((le16_to_cpu(*(__le16 *)(pbuf))) & 0xf) #define SetAckpolicy(pbuf, ack) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16((ack & 3) << 5); \ + *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5); \ }) -#define GetAckpolicy(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 5) & 0x3) +#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3) -#define GetAMsdu(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 7) & 0x1) +#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) -#define GetAid(pbuf) (cpu_to_le16(*(unsigned short *)((addr_t)(pbuf) + 2)) \ +#define GetAid(pbuf) (cpu_to_le16(*(__le16 *)((addr_t)(pbuf) + 2)) \ & 0x3fff) #define GetAddr1Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 4)) @@ -476,10 +471,10 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 #define SetOrderBit(pbuf) ({ \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ + *(__le16 *)(pbuf) |= cpu_to_le16(_ORDER_); \ }) -#define GetOrderBit(pbuf) (((*(unsigned short *)(pbuf)) & \ +#define GetOrderBit(pbuf) (((*(__le16 *)(pbuf)) & \ le16_to_cpu(_ORDER_)) != 0) @@ -490,12 +485,12 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) * described in 802.11n draft section 7.2.1.7.1 */ struct ieee80211_bar { - unsigned short frame_control; - unsigned short duration; + __le16 frame_control; + __le16 duration; unsigned char ra[6]; unsigned char ta[6]; - unsigned short control; - unsigned short start_seq_num; + __le16 control; + __le16 start_seq_num; } __packed; /* 802.11 BAR control masks */ @@ -511,11 +506,11 @@ struct ieee80211_bar { */ struct ieee80211_ht_cap { - unsigned short cap_info; + __le16 cap_info; unsigned char ampdu_params_info; unsigned char supp_mcs_set[16]; - unsigned short extended_ht_cap_info; - unsigned int tx_BF_cap_info; + __le16 extended_ht_cap_info; + __le32 tx_BF_cap_info; unsigned char antenna_selection_info; } __packed; @@ -528,8 +523,8 @@ struct ieee80211_ht_cap { struct ieee80211_ht_addt_info { unsigned char control_chan; unsigned char ht_param; - unsigned short operation_mode; - unsigned short stbc_param; + __le16 operation_mode; + __le16 stbc_param; unsigned char basic_set[16]; } __packed; diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h index 86a88b493a43..c0654ae4d70d 100644 --- a/drivers/staging/rtl8712/wlan_bssdef.h +++ b/drivers/staging/rtl8712/wlan_bssdef.h @@ -83,7 +83,7 @@ struct wlan_bssid_ex { unsigned char MacAddress[6]; u8 Reserved[2]; struct ndis_802_11_ssid Ssid; - u32 Privacy; + __le32 Privacy; s32 Rssi; enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; struct NDIS_802_11_CONFIGURATION Configuration; diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 28d56c5d1449..806c12180714 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -1108,12 +1108,6 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) i++; } while (i < 1024); - if (retval != STATUS_SUCCESS) { - kfree(buf); - rtsx_trace(chip); - return STATUS_FAIL; - } - if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { /* Signature code is wrong */ kfree(buf); diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 68d75d0d5efd..b8177f50fabc 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -198,23 +198,21 @@ static int command_abort(struct scsi_cmnd *srb) */ static int device_reset(struct scsi_cmnd *srb) { - int result = 0; struct rtsx_dev *dev = host_to_rtsx(srb->device->host); dev_info(&dev->pci->dev, "%s called\n", __func__); - return result < 0 ? FAILED : SUCCESS; + return SUCCESS; } /* Simulate a SCSI bus reset by resetting the device's USB port. */ static int bus_reset(struct scsi_cmnd *srb) { - int result = 0; struct rtsx_dev *dev = host_to_rtsx(srb->device->host); dev_info(&dev->pci->dev, "%s called\n", __func__); - return result < 0 ? FAILED : SUCCESS; + return SUCCESS; } /* diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 4d8e7c5c26d5..23799013c432 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -207,7 +207,7 @@ handle_errors: void rtsx_add_cmd(struct rtsx_chip *chip, u8 cmd_type, u16 reg_addr, u8 mask, u8 data) { - u32 *cb = (u32 *)(chip->host_cmds_ptr); + __le32 *cb = (__le32 *)(chip->host_cmds_ptr); u32 val = 0; val |= (u32)(cmd_type & 0x03) << 30; @@ -300,7 +300,7 @@ finish_send_cmd: static inline void rtsx_add_sg_tbl( struct rtsx_chip *chip, u32 addr, u32 len, u8 option) { - u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr); + __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr); u64 val = 0; u32 temp_len = 0; u8 temp_opt = 0; diff --git a/drivers/staging/skein/skein_base.c b/drivers/staging/skein/skein_base.c index c24a57396483..8db858a11875 100644 --- a/drivers/staging/skein/skein_base.c +++ b/drivers/staging/skein/skein_base.c @@ -1,12 +1,12 @@ /*********************************************************************** -** -** Implementation of the Skein hash function. -** -** Source code author: Doug Whiting, 2008. -** -** This algorithm and source code is released to the public domain. -** -************************************************************************/ + ** + ** Implementation of the Skein hash function. + ** + ** Source code author: Doug Whiting, 2008. + ** + ** This algorithm and source code is released to the public domain. + ** + ************************************************************************/ #include <linux/string.h> /* get the memcpy/memset functions */ #include <linux/export.h> diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index dc464f334a58..cd794c1bc1bb 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -1,28 +1,30 @@ #ifndef _SKEIN_H_ #define _SKEIN_H_ 1 -/************************************************************************** -** -** Interface declarations and internal definitions for Skein hashing. -** -** Source code author: Doug Whiting, 2008. -** -** This algorithm and source code is released to the public domain. -** -*************************************************************************** -** -** The following compile-time switches may be defined to control some -** tradeoffs between speed, code size, error checking, and security. -** -** The "default" note explains what happens when the switch is not defined. -** -** SKEIN_ERR_CHECK -- how error checking is handled inside Skein -** code. If not defined, most error checking -** is disabled (for performance). Otherwise, -** the switch value is interpreted as: -** 0: use assert() to flag errors -** 1: return SKEIN_FAIL to flag errors -** -***************************************************************************/ +/* + ************************************************************************** + * + * Interface declarations and internal definitions for Skein hashing. + * + * Source code author: Doug Whiting, 2008. + * + * This algorithm and source code is released to the public domain. + * + ************************************************************************** + * + * The following compile-time switches may be defined to control some + * tradeoffs between speed, code size, error checking, and security. + * + * The "default" note explains what happens when the switch is not defined. + * + * SKEIN_ERR_CHECK -- how error checking is handled inside Skein + * code. If not defined, most error checking + * is disabled (for performance). Otherwise, + * the switch value is interpreted as: + * 0: use assert() to flag errors + * 1: return SKEIN_FAIL to flag errors + * + ************************************************************************** + */ /*Skein digest sizes for crypto api*/ #define SKEIN256_DIGEST_BIT_SIZE 256 @@ -101,19 +103,19 @@ int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val); int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val); /* -** Skein APIs for "extended" initialization: MAC keys, tree hashing. -** After an init_ext() call, just use update/final calls as with init(). -** -** Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes. -** When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL, -** the results of init_ext() are identical to calling init(). -** The function init() may be called once to "precompute" the IV for -** a given hash_bit_len value, then by saving a copy of the context -** the IV computation may be avoided in later calls. -** Similarly, the function init_ext() may be called once per MAC key -** to precompute the MAC IV, then a copy of the context saved and -** reused for each new MAC computation. -**/ + * Skein APIs for "extended" initialization: MAC keys, tree hashing. + * After an init_ext() call, just use update/final calls as with init(). + * + * Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes. + * When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL, + * the results of init_ext() are identical to calling init(). + * The function init() may be called once to "precompute" the IV for + * a given hash_bit_len value, then by saving a copy of the context + * the IV computation may be avoided in later calls. + * Similarly, the function init_ext() may be called once per MAC key + * to precompute the MAC IV, then a copy of the context saved and + * reused for each new MAC computation. + */ int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len, u64 tree_info, const u8 *key, size_t key_bytes); int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len, @@ -122,10 +124,10 @@ int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len, u64 tree_info, const u8 *key, size_t key_bytes); /* -** Skein APIs for MAC and tree hash: -** final_pad: pad, do final block, but no OUTPUT type -** output: do just the output stage -*/ + * Skein APIs for MAC and tree hash: + * final_pad: pad, do final block, but no OUTPUT type + * output: do just the output stage + */ int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val); int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val); int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val); @@ -139,13 +141,15 @@ int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val); int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val); #endif -/***************************************************************** -** "Internal" Skein definitions -** -- not needed for sequential hashing API, but will be -** helpful for other uses of Skein (e.g., tree hash mode). -** -- included here so that they can be shared between -** reference and optimized code. -******************************************************************/ +/* + ***************************************************************** + * "Internal" Skein definitions + * -- not needed for sequential hashing API, but will be + * helpful for other uses of Skein (e.g., tree hash mode). + * -- included here so that they can be shared between + * reference and optimized code. + ***************************************************************** + */ /* tweak word tweak[1]: bit field starting positions */ #define SKEIN_T1_BIT(BIT) ((BIT) - 64) /* second word */ @@ -226,9 +230,9 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val); #define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0, 0, 0) /* -** Skein macros for getting/setting tweak words, etc. -** These are useful for partial input bytes, hash tree init/update, etc. -**/ + * Skein macros for getting/setting tweak words, etc. + * These are useful for partial input bytes, hash tree init/update, etc. + */ #define skein_get_tweak(ctx_ptr, TWK_NUM) ((ctx_ptr)->h.tweak[TWK_NUM]) #define skein_set_tweak(ctx_ptr, TWK_NUM, t_val) { \ (ctx_ptr)->h.tweak[TWK_NUM] = (t_val); \ @@ -274,9 +278,11 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val); #define skein_assert_ret(x, ret_code) #define skein_assert(x) -/***************************************************************** -** Skein block function constants (shared across Ref and Opt code) -******************************************************************/ +/* + ***************************************************************** + * Skein block function constants (shared across Ref and Opt code) + ***************************************************************** + */ enum { /* SKEIN_256 round rotation constants */ R_256_0_0 = 14, R_256_0_1 = 16, diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 59a0a8a82118..256657077a46 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -1,18 +1,20 @@ -/*********************************************************************** -** -** Implementation of the Skein block functions. -** -** Source code author: Doug Whiting, 2008. -** -** This algorithm and source code is released to the public domain. -** -** Compile-time switches: -** -** SKEIN_USE_ASM -- set bits (256/512/1024) to select which -** versions use ASM code for block processing -** [default: use C for all block sizes] -** -************************************************************************/ +/* + *********************************************************************** + * + * Implementation of the Skein block functions. + * + * Source code author: Doug Whiting, 2008. + * + * This algorithm and source code is released to the public domain. + * + * Compile-time switches: + * + * SKEIN_USE_ASM -- set bits (256/512/1024) to select which + * versions use ASM code for block processing + * [default: use C for all block sizes] + * + *********************************************************************** + */ #include <linux/string.h> #include <linux/bitops.h> diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h index 9d40f4a5267b..ec1baea25c9e 100644 --- a/drivers/staging/skein/skein_block.h +++ b/drivers/staging/skein/skein_block.h @@ -1,12 +1,14 @@ -/*********************************************************************** -** -** Implementation of the Skein hash function. -** -** Source code author: Doug Whiting, 2008. -** -** This algorithm and source code is released to the public domain. -** -************************************************************************/ +/* + *********************************************************************** + * + * Implementation of the Skein hash function. + * + * Source code author: Doug Whiting, 2008. + * + * This algorithm and source code is released to the public domain. + * + *********************************************************************** + */ #ifndef _SKEIN_BLOCK_H_ #define _SKEIN_BLOCK_H_ diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h index 8a06314d0ed4..509d464c65a3 100644 --- a/drivers/staging/skein/skein_iv.h +++ b/drivers/staging/skein/skein_iv.h @@ -4,18 +4,18 @@ #include "skein_base.h" /* get Skein macros and types */ /* -***************** Pre-computed Skein IVs ******************* -** -** NOTE: these values are not "magic" constants, but -** are generated using the Threefish block function. -** They are pre-computed here only for speed; i.e., to -** avoid the need for a Threefish call during Init(). -** -** The IV for any fixed hash length may be pre-computed. -** Only the most common values are included here. -** -************************************************************ -**/ + **************** Pre-computed Skein IVs ******************* + * + * NOTE: these values are not "magic" constants, but + * are generated using the Threefish block function. + * They are pre-computed here only for speed; i.e., to + * avoid the need for a Threefish call during Init(). + * + * The IV for any fixed hash length may be pre-computed. + * Only the most common values are included here. + * + *********************************************************** + */ #define MK_64 SKEIN_MK_64 diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c index f59ce5c0867d..10cf7295dc6c 100644 --- a/drivers/staging/sm750fb/ddk750_chip.c +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -25,8 +25,9 @@ void sm750_set_chip_type(unsigned short devId, u8 revId) chip = SM750LE; pr_info("found sm750le\n"); } - } else + } else { chip = SM_UNKNOWN; + } } static unsigned int get_mxclk_freq(void) @@ -37,7 +38,7 @@ static unsigned int get_mxclk_freq(void) if (sm750_get_chip_type() == SM750LE) return MHz(130); - pll_reg = PEEK32(MXCLK_PLL_CTRL); + pll_reg = peek32(MXCLK_PLL_CTRL); M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT; N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT; OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT; @@ -77,7 +78,7 @@ static void set_chip_clock(unsigned int frequency) ulActualMxClk = sm750_calc_pll_value(frequency, &pll); /* Master Clock Control: MXCLK_PLL */ - POKE32(MXCLK_PLL_CTRL, sm750_format_pll_reg(&pll)); + poke32(MXCLK_PLL_CTRL, sm750_format_pll_reg(&pll)); } } @@ -104,7 +105,7 @@ static void set_memory_clock(unsigned int frequency) divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); /* Set the corresponding divisor in the register. */ - reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK; + reg = peek32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK; switch (divisor) { default: case 1: @@ -156,7 +157,7 @@ static void set_master_clock(unsigned int frequency) divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); /* Set the corresponding divisor in the register. */ - reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK; + reg = peek32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK; switch (divisor) { default: case 3: @@ -187,12 +188,12 @@ unsigned int ddk750_get_vm_size(void) return SZ_64M; /* for 750,always use power mode0*/ - reg = PEEK32(MODE0_GATE); + reg = peek32(MODE0_GATE); reg |= MODE0_GATE_GPIO; - POKE32(MODE0_GATE, reg); + poke32(MODE0_GATE, reg); /* get frame buffer size from GPIO */ - reg = PEEK32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK; + reg = peek32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK; switch (reg) { case MISC_CTRL_LOCALMEM_SIZE_8M: data = SZ_8M; break; /* 8 Mega byte */ @@ -218,15 +219,15 @@ int ddk750_init_hw(struct initchip_param *pInitParam) sm750_set_power_mode(pInitParam->powerMode); /* Enable display power gate & LOCALMEM power gate*/ - reg = PEEK32(CURRENT_GATE); + reg = peek32(CURRENT_GATE); reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM); sm750_set_current_gate(reg); if (sm750_get_chip_type() != SM750LE) { /* set panel pll and graphic mode via mmio_88 */ - reg = PEEK32(VGA_CONFIGURATION); + reg = peek32(VGA_CONFIGURATION); reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE); - POKE32(VGA_CONFIGURATION, reg); + poke32(VGA_CONFIGURATION, reg); } else { #if defined(__i386__) || defined(__x86_64__) /* set graphic mode via IO method */ @@ -244,7 +245,6 @@ int ddk750_init_hw(struct initchip_param *pInitParam) /* Set up master clock */ set_master_clock(MHz(pInitParam->masterClock)); - /* * Reset the memory controller. * If the memory controller is not reset in SM750, @@ -252,36 +252,36 @@ int ddk750_init_hw(struct initchip_param *pInitParam) * The memory should be resetted after changing the MXCLK. */ if (pInitParam->resetMemory == 1) { - reg = PEEK32(MISC_CTRL); + reg = peek32(MISC_CTRL); reg &= ~MISC_CTRL_LOCALMEM_RESET; - POKE32(MISC_CTRL, reg); + poke32(MISC_CTRL, reg); reg |= MISC_CTRL_LOCALMEM_RESET; - POKE32(MISC_CTRL, reg); + poke32(MISC_CTRL, reg); } if (pInitParam->setAllEngOff == 1) { sm750_enable_2d_engine(0); /* Disable Overlay, if a former application left it on */ - reg = PEEK32(VIDEO_DISPLAY_CTRL); + reg = peek32(VIDEO_DISPLAY_CTRL); reg &= ~DISPLAY_CTRL_PLANE; - POKE32(VIDEO_DISPLAY_CTRL, reg); + poke32(VIDEO_DISPLAY_CTRL, reg); /* Disable video alpha, if a former application left it on */ - reg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); + reg = peek32(VIDEO_ALPHA_DISPLAY_CTRL); reg &= ~DISPLAY_CTRL_PLANE; - POKE32(VIDEO_ALPHA_DISPLAY_CTRL, reg); + poke32(VIDEO_ALPHA_DISPLAY_CTRL, reg); /* Disable alpha plane, if a former application left it on */ - reg = PEEK32(ALPHA_DISPLAY_CTRL); + reg = peek32(ALPHA_DISPLAY_CTRL); reg &= ~DISPLAY_CTRL_PLANE; - POKE32(ALPHA_DISPLAY_CTRL, reg); + poke32(ALPHA_DISPLAY_CTRL, reg); /* Disable DMA Channel, if a former application left it on */ - reg = PEEK32(DMA_ABORT_INTERRUPT); + reg = peek32(DMA_ABORT_INTERRUPT); reg |= DMA_ABORT_INTERRUPT_ABORT_1; - POKE32(DMA_ABORT_INTERRUPT, reg); + poke32(DMA_ABORT_INTERRUPT, reg); /* Disable DMA Power, if a former application left it on */ sm750_enable_dma(0); @@ -407,5 +407,3 @@ unsigned int sm750_format_pll_reg(struct pll_value *pPLL) return reg; } - - diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h index e63b8b293816..fbeb615aa432 100644 --- a/drivers/staging/sm750fb/ddk750_chip.h +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -9,11 +9,18 @@ #include <linux/ioport.h> #include <linux/uaccess.h> +extern void __iomem *mmio750; + /* software control endianness */ -#define PEEK32(addr) readl(addr + mmio750) -#define POKE32(addr, data) writel(data, addr + mmio750) +static inline u32 peek32(u32 addr) +{ + return readl(addr + mmio750); +} -extern void __iomem *mmio750; +static inline void poke32(u32 data, u32 addr) +{ + writel(data, addr + mmio750); +} /* This is all the chips recognized by this library */ typedef enum _logical_chip_type_t { diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index c347803f7e19..e4724a660d07 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -18,7 +18,7 @@ static void setDisplayControl(int ctrl, int disp_state) reserved = CRT_DISPLAY_CTRL_RESERVED_MASK; } - val = PEEK32(reg); + val = peek32(reg); if (disp_state) { /* * Timing should be enabled first before enabling the @@ -27,7 +27,7 @@ static void setDisplayControl(int ctrl, int disp_state) * disabled. */ val |= DISPLAY_CTRL_TIMING; - POKE32(reg, val); + poke32(reg, val); val |= DISPLAY_CTRL_PLANE; @@ -38,8 +38,8 @@ static void setDisplayControl(int ctrl, int disp_state) */ do { cnt++; - POKE32(reg, val); - } while ((PEEK32(reg) & ~reserved) != (val & ~reserved)); + poke32(reg, val); + } while ((peek32(reg) & ~reserved) != (val & ~reserved)); pr_debug("Set Plane enbit:after tried %d times\n", cnt); } else { /* @@ -52,10 +52,10 @@ static void setDisplayControl(int ctrl, int disp_state) * before modifying the timing enable bit. */ val &= ~DISPLAY_CTRL_PLANE; - POKE32(reg, val); + poke32(reg, val); val &= ~DISPLAY_CTRL_TIMING; - POKE32(reg, val); + poke32(reg, val); } } @@ -67,19 +67,19 @@ static void primary_wait_vertical_sync(int delay) * Do not wait when the Primary PLL is off or display control is * already off. This will prevent the software to wait forever. */ - if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) || - !(PEEK32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) + if (!(peek32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) || + !(peek32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) return; while (delay-- > 0) { /* Wait for end of vsync. */ do { - status = PEEK32(SYSTEM_CTRL); + status = peek32(SYSTEM_CTRL); } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); /* Wait for start of vsync. */ do { - status = PEEK32(SYSTEM_CTRL); + status = peek32(SYSTEM_CTRL); } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE)); } } @@ -89,24 +89,24 @@ static void swPanelPowerSequence(int disp, int delay) unsigned int reg; /* disp should be 1 to open sequence */ - reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = peek32(PANEL_DISPLAY_CTRL); reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0); - POKE32(PANEL_DISPLAY_CTRL, reg); + poke32(PANEL_DISPLAY_CTRL, reg); primary_wait_vertical_sync(delay); - reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = peek32(PANEL_DISPLAY_CTRL); reg |= (disp ? PANEL_DISPLAY_CTRL_DATA : 0); - POKE32(PANEL_DISPLAY_CTRL, reg); + poke32(PANEL_DISPLAY_CTRL, reg); primary_wait_vertical_sync(delay); - reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = peek32(PANEL_DISPLAY_CTRL); reg |= (disp ? PANEL_DISPLAY_CTRL_VBIASEN : 0); - POKE32(PANEL_DISPLAY_CTRL, reg); + poke32(PANEL_DISPLAY_CTRL, reg); primary_wait_vertical_sync(delay); - reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = peek32(PANEL_DISPLAY_CTRL); reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0); - POKE32(PANEL_DISPLAY_CTRL, reg); + poke32(PANEL_DISPLAY_CTRL, reg); primary_wait_vertical_sync(delay); } @@ -116,22 +116,22 @@ void ddk750_setLogicalDispOut(disp_output_t output) if (output & PNL_2_USAGE) { /* set panel path controller select */ - reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = peek32(PANEL_DISPLAY_CTRL); reg &= ~PANEL_DISPLAY_CTRL_SELECT_MASK; reg |= (((output & PNL_2_MASK) >> PNL_2_OFFSET) << PANEL_DISPLAY_CTRL_SELECT_SHIFT); - POKE32(PANEL_DISPLAY_CTRL, reg); + poke32(PANEL_DISPLAY_CTRL, reg); } if (output & CRT_2_USAGE) { /* set crt path controller select */ - reg = PEEK32(CRT_DISPLAY_CTRL); + reg = peek32(CRT_DISPLAY_CTRL); reg &= ~CRT_DISPLAY_CTRL_SELECT_MASK; reg |= (((output & CRT_2_MASK) >> CRT_2_OFFSET) << CRT_DISPLAY_CTRL_SELECT_SHIFT); /*se blank off */ reg &= ~CRT_DISPLAY_CTRL_BLANK; - POKE32(CRT_DISPLAY_CTRL, reg); + poke32(CRT_DISPLAY_CTRL, reg); } if (output & PRI_TP_USAGE) { diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c index 05d4a73aa1d4..68716ef7cb06 100644 --- a/drivers/staging/sm750fb/ddk750_hwi2c.c +++ b/drivers/staging/sm750fb/ddk750_hwi2c.c @@ -15,10 +15,10 @@ unsigned char bus_speed_mode unsigned int value; /* Enable GPIO 30 & 31 as IIC clock & data */ - value = PEEK32(GPIO_MUX); + value = peek32(GPIO_MUX); value |= (GPIO_MUX_30 | GPIO_MUX_31); - POKE32(GPIO_MUX, value); + poke32(GPIO_MUX, value); /* * Enable Hardware I2C power. @@ -27,11 +27,11 @@ unsigned char bus_speed_mode sm750_enable_i2c(1); /* Enable the I2C Controller and set the bus speed mode */ - value = PEEK32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN); + value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN); if (bus_speed_mode) value |= I2C_CTRL_MODE; value |= I2C_CTRL_EN; - POKE32(I2C_CTRL, value); + poke32(I2C_CTRL, value); return 0; } @@ -41,17 +41,17 @@ void sm750_hw_i2c_close(void) unsigned int value; /* Disable I2C controller */ - value = PEEK32(I2C_CTRL) & ~I2C_CTRL_EN; - POKE32(I2C_CTRL, value); + value = peek32(I2C_CTRL) & ~I2C_CTRL_EN; + poke32(I2C_CTRL, value); /* Disable I2C Power */ sm750_enable_i2c(0); /* Set GPIO 30 & 31 back as GPIO pins */ - value = PEEK32(GPIO_MUX); + value = peek32(GPIO_MUX); value &= ~GPIO_MUX_30; value &= ~GPIO_MUX_31; - POKE32(GPIO_MUX, value); + poke32(GPIO_MUX, value); } static long hw_i2c_wait_tx_done(void) @@ -60,7 +60,7 @@ static long hw_i2c_wait_tx_done(void) /* Wait until the transfer is completed. */ timeout = HWI2C_WAIT_TIMEOUT; - while (!(PEEK32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0)) + while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0)) timeout--; if (timeout == 0) @@ -91,7 +91,7 @@ static unsigned int hw_i2c_write_data( unsigned int total_bytes = 0; /* Set the Device Address */ - POKE32(I2C_SLAVE_ADDRESS, addr & ~0x01); + poke32(I2C_SLAVE_ADDRESS, addr & ~0x01); /* * Write data. @@ -103,21 +103,21 @@ static unsigned int hw_i2c_write_data( * Reset I2C by writing 0 to I2C_RESET register to * clear the previous status. */ - POKE32(I2C_RESET, 0); + poke32(I2C_RESET, 0); /* Set the number of bytes to be written */ if (length < MAX_HWI2C_FIFO) count = length - 1; else count = MAX_HWI2C_FIFO - 1; - POKE32(I2C_BYTE_COUNT, count); + poke32(I2C_BYTE_COUNT, count); /* Move the data to the I2C data register */ for (i = 0; i <= count; i++) - POKE32(I2C_DATA0 + i, *buf++); + poke32(I2C_DATA0 + i, *buf++); /* Start the I2C */ - POKE32(I2C_CTRL, PEEK32(I2C_CTRL) | I2C_CTRL_CTRL); + poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); /* Wait until the transfer is completed. */ if (hw_i2c_wait_tx_done() != 0) @@ -158,7 +158,7 @@ static unsigned int hw_i2c_read_data( unsigned int total_bytes = 0; /* Set the Device Address */ - POKE32(I2C_SLAVE_ADDRESS, addr | 0x01); + poke32(I2C_SLAVE_ADDRESS, addr | 0x01); /* * Read data and save them to the buffer. @@ -170,17 +170,17 @@ static unsigned int hw_i2c_read_data( * Reset I2C by writing 0 to I2C_RESET register to * clear all the status. */ - POKE32(I2C_RESET, 0); + poke32(I2C_RESET, 0); /* Set the number of bytes to be read */ if (length <= MAX_HWI2C_FIFO) count = length - 1; else count = MAX_HWI2C_FIFO - 1; - POKE32(I2C_BYTE_COUNT, count); + poke32(I2C_BYTE_COUNT, count); /* Start the I2C */ - POKE32(I2C_CTRL, PEEK32(I2C_CTRL) | I2C_CTRL_CTRL); + poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); /* Wait until transaction done. */ if (hw_i2c_wait_tx_done() != 0) @@ -188,7 +188,7 @@ static unsigned int hw_i2c_read_data( /* Save the data to the given buffer */ for (i = 0; i <= count; i++) - *buf++ = PEEK32(I2C_DATA0 + i); + *buf++ = peek32(I2C_DATA0 + i); /* Subtract length by 16 */ length -= (count + 1); diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c index 4a4b1de97a87..1df7d57dea6d 100644 --- a/drivers/staging/sm750fb/ddk750_mode.c +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -25,9 +25,9 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, * Note that normal SM750/SM718 only use those two register for * auto-centering mode. */ - POKE32(CRT_AUTO_CENTERING_TL, 0); + poke32(CRT_AUTO_CENTERING_TL, 0); - POKE32(CRT_AUTO_CENTERING_BR, + poke32(CRT_AUTO_CENTERING_BR, (((y - 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT) & CRT_AUTO_CENTERING_BR_BOTTOM_MASK) | ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK)); @@ -66,7 +66,7 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, /* Set bit 14 of display controller */ dispControl |= DISPLAY_CTRL_CLOCK_PHASE; - POKE32(CRT_DISPLAY_CTRL, dispControl); + poke32(CRT_DISPLAY_CTRL, dispControl); return dispControl; } @@ -83,29 +83,29 @@ static int programModeRegisters(mode_parameter_t *pModeParam, if (pll->clockType == SECONDARY_PLL) { /* programe secondary pixel clock */ - POKE32(CRT_PLL_CTRL, sm750_format_pll_reg(pll)); - POKE32(CRT_HORIZONTAL_TOTAL, + poke32(CRT_PLL_CTRL, sm750_format_pll_reg(pll)); + poke32(CRT_HORIZONTAL_TOTAL, (((pModeParam->horizontal_total - 1) << CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) & CRT_HORIZONTAL_TOTAL_TOTAL_MASK) | ((pModeParam->horizontal_display_end - 1) & CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK)); - POKE32(CRT_HORIZONTAL_SYNC, + poke32(CRT_HORIZONTAL_SYNC, ((pModeParam->horizontal_sync_width << CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) & CRT_HORIZONTAL_SYNC_WIDTH_MASK) | ((pModeParam->horizontal_sync_start - 1) & CRT_HORIZONTAL_SYNC_START_MASK)); - POKE32(CRT_VERTICAL_TOTAL, + poke32(CRT_VERTICAL_TOTAL, (((pModeParam->vertical_total - 1) << CRT_VERTICAL_TOTAL_TOTAL_SHIFT) & CRT_VERTICAL_TOTAL_TOTAL_MASK) | ((pModeParam->vertical_display_end - 1) & CRT_VERTICAL_TOTAL_DISPLAY_END_MASK)); - POKE32(CRT_VERTICAL_SYNC, + poke32(CRT_VERTICAL_SYNC, ((pModeParam->vertical_sync_height << CRT_VERTICAL_SYNC_HEIGHT_SHIFT) & CRT_VERTICAL_SYNC_HEIGHT_MASK) | @@ -122,41 +122,41 @@ static int programModeRegisters(mode_parameter_t *pModeParam, if (sm750_get_chip_type() == SM750LE) { displayControlAdjust_SM750LE(pModeParam, tmp); } else { - reg = PEEK32(CRT_DISPLAY_CTRL) & + reg = peek32(CRT_DISPLAY_CTRL) & ~(DISPLAY_CTRL_VSYNC_PHASE | DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE); - POKE32(CRT_DISPLAY_CTRL, tmp | reg); + poke32(CRT_DISPLAY_CTRL, tmp | reg); } } else if (pll->clockType == PRIMARY_PLL) { unsigned int reserved; - POKE32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll)); + poke32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll)); reg = ((pModeParam->horizontal_total - 1) << PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) & PANEL_HORIZONTAL_TOTAL_TOTAL_MASK; reg |= ((pModeParam->horizontal_display_end - 1) & PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK); - POKE32(PANEL_HORIZONTAL_TOTAL, reg); + poke32(PANEL_HORIZONTAL_TOTAL, reg); - POKE32(PANEL_HORIZONTAL_SYNC, + poke32(PANEL_HORIZONTAL_SYNC, ((pModeParam->horizontal_sync_width << PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) & PANEL_HORIZONTAL_SYNC_WIDTH_MASK) | ((pModeParam->horizontal_sync_start - 1) & PANEL_HORIZONTAL_SYNC_START_MASK)); - POKE32(PANEL_VERTICAL_TOTAL, + poke32(PANEL_VERTICAL_TOTAL, (((pModeParam->vertical_total - 1) << PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) & PANEL_VERTICAL_TOTAL_TOTAL_MASK) | ((pModeParam->vertical_display_end - 1) & PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK)); - POKE32(PANEL_VERTICAL_SYNC, + poke32(PANEL_VERTICAL_SYNC, ((pModeParam->vertical_sync_height << PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) & PANEL_VERTICAL_SYNC_HEIGHT_MASK) | @@ -174,7 +174,7 @@ static int programModeRegisters(mode_parameter_t *pModeParam, reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK | PANEL_DISPLAY_CTRL_VSYNC; - reg = (PEEK32(PANEL_DISPLAY_CTRL) & ~reserved) & + reg = (peek32(PANEL_DISPLAY_CTRL) & ~reserved) & ~(DISPLAY_CTRL_CLOCK_PHASE | DISPLAY_CTRL_VSYNC_PHASE | DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE); @@ -187,14 +187,14 @@ static int programModeRegisters(mode_parameter_t *pModeParam, * Note: This problem happens by design. The hardware will wait * for the next vertical sync to turn on/off the plane. */ - POKE32(PANEL_DISPLAY_CTRL, tmp | reg); + poke32(PANEL_DISPLAY_CTRL, tmp | reg); - while ((PEEK32(PANEL_DISPLAY_CTRL) & ~reserved) != + while ((peek32(PANEL_DISPLAY_CTRL) & ~reserved) != (tmp | reg)) { cnt++; if (cnt > 1000) break; - POKE32(PANEL_DISPLAY_CTRL, tmp | reg); + poke32(PANEL_DISPLAY_CTRL, tmp | reg); } } else { ret = -1; diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c index 6167e30e8e01..02ff6204ee1e 100644 --- a/drivers/staging/sm750fb/ddk750_power.c +++ b/drivers/staging/sm750fb/ddk750_power.c @@ -7,13 +7,13 @@ void ddk750_set_dpms(DPMS_t state) unsigned int value; if (sm750_get_chip_type() == SM750LE) { - value = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK; + value = peek32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK; value |= (state << CRT_DISPLAY_CTRL_DPMS_SHIFT); - POKE32(CRT_DISPLAY_CTRL, value); + poke32(CRT_DISPLAY_CTRL, value); } else { - value = PEEK32(SYSTEM_CTRL); + value = peek32(SYSTEM_CTRL); value = (value & ~SYSTEM_CTRL_DPMS_MASK) | state; - POKE32(SYSTEM_CTRL, value); + poke32(SYSTEM_CTRL, value); } } @@ -21,7 +21,7 @@ static unsigned int get_power_mode(void) { if (sm750_get_chip_type() == SM750LE) return 0; - return PEEK32(POWER_MODE_CTRL) & POWER_MODE_CTRL_MODE_MASK; + return peek32(POWER_MODE_CTRL) & POWER_MODE_CTRL_MODE_MASK; } @@ -33,7 +33,7 @@ void sm750_set_power_mode(unsigned int mode) { unsigned int ctrl = 0; - ctrl = PEEK32(POWER_MODE_CTRL) & ~POWER_MODE_CTRL_MODE_MASK; + ctrl = peek32(POWER_MODE_CTRL) & ~POWER_MODE_CTRL_MODE_MASK; if (sm750_get_chip_type() == SM750LE) return; @@ -69,15 +69,15 @@ void sm750_set_power_mode(unsigned int mode) } /* Program new power mode. */ - POKE32(POWER_MODE_CTRL, ctrl); + poke32(POWER_MODE_CTRL, ctrl); } void sm750_set_current_gate(unsigned int gate) { if (get_power_mode() == POWER_MODE_CTRL_MODE_MODE1) - POKE32(MODE1_GATE, gate); + poke32(MODE1_GATE, gate); else - POKE32(MODE0_GATE, gate); + poke32(MODE0_GATE, gate); } @@ -89,7 +89,7 @@ void sm750_enable_2d_engine(unsigned int enable) { u32 gate; - gate = PEEK32(CURRENT_GATE); + gate = peek32(CURRENT_GATE); if (enable) gate |= (CURRENT_GATE_DE | CURRENT_GATE_CSC); else @@ -103,7 +103,7 @@ void sm750_enable_dma(unsigned int enable) u32 gate; /* Enable DMA Gate */ - gate = PEEK32(CURRENT_GATE); + gate = peek32(CURRENT_GATE); if (enable) gate |= CURRENT_GATE_DMA; else @@ -120,7 +120,7 @@ void sm750_enable_gpio(unsigned int enable) u32 gate; /* Enable GPIO Gate */ - gate = PEEK32(CURRENT_GATE); + gate = peek32(CURRENT_GATE); if (enable) gate |= CURRENT_GATE_GPIO; else @@ -137,7 +137,7 @@ void sm750_enable_i2c(unsigned int enable) u32 gate; /* Enable I2C Gate */ - gate = PEEK32(CURRENT_GATE); + gate = peek32(CURRENT_GATE); if (enable) gate |= CURRENT_GATE_I2C; else diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h index eb088b0d805f..4274d74d47c1 100644 --- a/drivers/staging/sm750fb/ddk750_power.h +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -10,8 +10,8 @@ typedef enum _DPMS_t { DPMS_t; #define setDAC(off) { \ - POKE32(MISC_CTRL, \ - (PEEK32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF) | (off)); \ + poke32(MISC_CTRL, \ + (peek32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF) | (off)); \ } void ddk750_set_dpms(DPMS_t); diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c index b8a4e44359af..a4ac07cd50cb 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -119,23 +119,23 @@ static void sw_i2c_scl(unsigned char value) unsigned long gpio_data; unsigned long gpio_dir; - gpio_dir = PEEK32(sw_i2c_clk_gpio_data_dir_reg); + gpio_dir = peek32(sw_i2c_clk_gpio_data_dir_reg); if (value) { /* High */ /* * Set direction as input. This will automatically * pull the signal up. */ gpio_dir &= ~(1 << sw_i2c_clk_gpio); - POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); + poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); } else { /* Low */ /* Set the signal down */ - gpio_data = PEEK32(sw_i2c_clk_gpio_data_reg); + gpio_data = peek32(sw_i2c_clk_gpio_data_reg); gpio_data &= ~(1 << sw_i2c_clk_gpio); - POKE32(sw_i2c_clk_gpio_data_reg, gpio_data); + poke32(sw_i2c_clk_gpio_data_reg, gpio_data); /* Set direction as output */ gpio_dir |= (1 << sw_i2c_clk_gpio); - POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); + poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); } } @@ -156,23 +156,23 @@ static void sw_i2c_sda(unsigned char value) unsigned long gpio_data; unsigned long gpio_dir; - gpio_dir = PEEK32(sw_i2c_data_gpio_data_dir_reg); + gpio_dir = peek32(sw_i2c_data_gpio_data_dir_reg); if (value) { /* High */ /* * Set direction as input. This will automatically * pull the signal up. */ gpio_dir &= ~(1 << sw_i2c_data_gpio); - POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); } else { /* Low */ /* Set the signal down */ - gpio_data = PEEK32(sw_i2c_data_gpio_data_reg); + gpio_data = peek32(sw_i2c_data_gpio_data_reg); gpio_data &= ~(1 << sw_i2c_data_gpio); - POKE32(sw_i2c_data_gpio_data_reg, gpio_data); + poke32(sw_i2c_data_gpio_data_reg, gpio_data); /* Set direction as output */ gpio_dir |= (1 << sw_i2c_data_gpio); - POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); } } @@ -189,14 +189,14 @@ static unsigned char sw_i2c_read_sda(void) unsigned long dir_mask = 1 << sw_i2c_data_gpio; /* Make sure that the direction is input (High) */ - gpio_dir = PEEK32(sw_i2c_data_gpio_data_dir_reg); + gpio_dir = peek32(sw_i2c_data_gpio_data_dir_reg); if ((gpio_dir & dir_mask) != ~dir_mask) { gpio_dir &= ~(1 << sw_i2c_data_gpio); - POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); + poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); } /* Now read the SDA line */ - gpio_data = PEEK32(sw_i2c_data_gpio_data_reg); + gpio_data = peek32(sw_i2c_data_gpio_data_reg); if (gpio_data & (1 << sw_i2c_data_gpio)) return 1; else @@ -422,10 +422,10 @@ long sm750_sw_i2c_init( sw_i2c_data_gpio = data_gpio; /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ - POKE32(sw_i2c_clk_gpio_mux_reg, - PEEK32(sw_i2c_clk_gpio_mux_reg) & ~(1 << sw_i2c_clk_gpio)); - POKE32(sw_i2c_data_gpio_mux_reg, - PEEK32(sw_i2c_data_gpio_mux_reg) & ~(1 << sw_i2c_data_gpio)); + poke32(sw_i2c_clk_gpio_mux_reg, + peek32(sw_i2c_clk_gpio_mux_reg) & ~(1 << sw_i2c_clk_gpio)); + poke32(sw_i2c_data_gpio_mux_reg, + peek32(sw_i2c_data_gpio_mux_reg) & ~(1 << sw_i2c_data_gpio)); /* Enable GPIO power */ sm750_enable_gpio(1); diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index e9632f162f99..e49f8845f923 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -100,7 +100,6 @@ static const struct fb_videomode lynx750_ext[] = { FB_VMODE_NONINTERLACED}, }; - /* no hardware cursor supported under version 2.6.10, kernel bug */ static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor) { @@ -974,10 +973,12 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) else { if (!g_fbmode[0]) { g_fbmode[0] = opt; - dev_info(&sm750_dev->pdev->dev, "find fbmode0 : %s\n", g_fbmode[0]); + dev_info(&sm750_dev->pdev->dev, + "find fbmode0 : %s\n", g_fbmode[0]); } else if (!g_fbmode[1]) { g_fbmode[1] = opt; - dev_info(&sm750_dev->pdev->dev, "find fbmode1 : %s\n", g_fbmode[1]); + dev_info(&sm750_dev->pdev->dev, + "find fbmode1 : %s\n", g_fbmode[1]); } else { dev_warn(&sm750_dev->pdev->dev, "How many view you wann set?\n"); } @@ -1228,7 +1229,7 @@ static void __exit lynxfb_exit(void) } module_exit(lynxfb_exit); -module_param(g_option, charp, S_IRUGO); +module_param(g_option, charp, 0444); MODULE_PARM_DESC(g_option, "\n\t\tCommon options:\n" diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index 2a13353fc492..b1651b0d2034 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -20,7 +20,7 @@ -#define POKE32(addr, data) \ +#define poke32(addr, data) \ writel((data), cursor->mmio + (addr)) /* cursor control for voyager and 718/750*/ @@ -52,11 +52,11 @@ void sm750_hw_cursor_enable(struct lynx_cursor *cursor) u32 reg; reg = (cursor->offset & HWC_ADDRESS_ADDRESS_MASK) | HWC_ADDRESS_ENABLE; - POKE32(HWC_ADDRESS, reg); + poke32(HWC_ADDRESS, reg); } void sm750_hw_cursor_disable(struct lynx_cursor *cursor) { - POKE32(HWC_ADDRESS, 0); + poke32(HWC_ADDRESS, 0); } void sm750_hw_cursor_setSize(struct lynx_cursor *cursor, @@ -72,7 +72,7 @@ void sm750_hw_cursor_setPos(struct lynx_cursor *cursor, reg = (((y << HWC_LOCATION_Y_SHIFT) & HWC_LOCATION_Y_MASK) | (x & HWC_LOCATION_X_MASK)); - POKE32(HWC_LOCATION, reg); + poke32(HWC_LOCATION, reg); } void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 fg, u32 bg) @@ -80,8 +80,8 @@ void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 reg = (fg << HWC_COLOR_12_2_RGB565_SHIFT) & HWC_COLOR_12_2_RGB565_MASK; - POKE32(HWC_COLOR_12, reg | (bg & HWC_COLOR_12_1_RGB565_MASK)); - POKE32(HWC_COLOR_3, 0xffe0); + poke32(HWC_COLOR_12, reg | (bg & HWC_COLOR_12_1_RGB565_MASK)); + poke32(HWC_COLOR_3, 0xffe0); } void sm750_hw_cursor_setData(struct lynx_cursor *cursor, diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index b6af3b53076b..fab3fc9c8330 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -108,30 +108,30 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) ddk750_init_hw((struct initchip_param *)&sm750_dev->initParm); /* for sm718, open pci burst */ if (sm750_dev->devid == 0x718) { - POKE32(SYSTEM_CTRL, - PEEK32(SYSTEM_CTRL) | SYSTEM_CTRL_PCI_BURST); + poke32(SYSTEM_CTRL, + peek32(SYSTEM_CTRL) | SYSTEM_CTRL_PCI_BURST); } if (sm750_get_chip_type() != SM750LE) { unsigned int val; /* does user need CRT? */ if (sm750_dev->nocrt) { - POKE32(MISC_CTRL, - PEEK32(MISC_CTRL) | MISC_CTRL_DAC_POWER_OFF); + poke32(MISC_CTRL, + peek32(MISC_CTRL) | MISC_CTRL_DAC_POWER_OFF); /* shut off dpms */ - val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; + val = peek32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; val |= SYSTEM_CTRL_DPMS_VPHN; - POKE32(SYSTEM_CTRL, val); + poke32(SYSTEM_CTRL, val); } else { - POKE32(MISC_CTRL, - PEEK32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF); + poke32(MISC_CTRL, + peek32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF); /* turn on dpms */ - val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; + val = peek32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; val |= SYSTEM_CTRL_DPMS_VPHP; - POKE32(SYSTEM_CTRL, val); + poke32(SYSTEM_CTRL, val); } - val = PEEK32(PANEL_DISPLAY_CTRL) & + val = peek32(PANEL_DISPLAY_CTRL) & ~(PANEL_DISPLAY_CTRL_DUAL_DISPLAY | PANEL_DISPLAY_CTRL_DOUBLE_PIXEL); switch (sm750_dev->pnltype) { @@ -144,7 +144,7 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) val |= PANEL_DISPLAY_CTRL_DUAL_DISPLAY; break; } - POKE32(PANEL_DISPLAY_CTRL, val); + poke32(PANEL_DISPLAY_CTRL, val); } else { /* * for 750LE, no DVI chip initialization @@ -211,9 +211,9 @@ int hw_sm750_output_setMode(struct lynxfb_output *output, /* just open DISPLAY_CONTROL_750LE register bit 3:0 */ u32 reg; - reg = PEEK32(DISPLAY_CONTROL_750LE); + reg = peek32(DISPLAY_CONTROL_750LE); reg |= 0xf; - POKE32(DISPLAY_CONTROL_750LE, reg); + poke32(DISPLAY_CONTROL_750LE, reg); } pr_info("ddk setlogicdispout done\n"); @@ -312,7 +312,7 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, if (crtc->channel != sm750_secondary) { /* set pitch, offset, width, start address, etc... */ - POKE32(PANEL_FB_ADDRESS, + poke32(PANEL_FB_ADDRESS, crtc->oScreen & PANEL_FB_ADDRESS_ADDRESS_MASK); reg = var->xres * (var->bits_per_pixel >> 3); @@ -324,32 +324,32 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, reg = (reg << PANEL_FB_WIDTH_WIDTH_SHIFT) & PANEL_FB_WIDTH_WIDTH_MASK; reg |= (fix->line_length & PANEL_FB_WIDTH_OFFSET_MASK); - POKE32(PANEL_FB_WIDTH, reg); + poke32(PANEL_FB_WIDTH, reg); reg = ((var->xres - 1) << PANEL_WINDOW_WIDTH_WIDTH_SHIFT) & PANEL_WINDOW_WIDTH_WIDTH_MASK; reg |= (var->xoffset & PANEL_WINDOW_WIDTH_X_MASK); - POKE32(PANEL_WINDOW_WIDTH, reg); + poke32(PANEL_WINDOW_WIDTH, reg); reg = (var->yres_virtual - 1) << PANEL_WINDOW_HEIGHT_HEIGHT_SHIFT; reg &= PANEL_WINDOW_HEIGHT_HEIGHT_MASK; reg |= (var->yoffset & PANEL_WINDOW_HEIGHT_Y_MASK); - POKE32(PANEL_WINDOW_HEIGHT, reg); + poke32(PANEL_WINDOW_HEIGHT, reg); - POKE32(PANEL_PLANE_TL, 0); + poke32(PANEL_PLANE_TL, 0); reg = ((var->yres - 1) << PANEL_PLANE_BR_BOTTOM_SHIFT) & PANEL_PLANE_BR_BOTTOM_MASK; reg |= ((var->xres - 1) & PANEL_PLANE_BR_RIGHT_MASK); - POKE32(PANEL_PLANE_BR, reg); + poke32(PANEL_PLANE_BR, reg); /* set pixel format */ - reg = PEEK32(PANEL_DISPLAY_CTRL); - POKE32(PANEL_DISPLAY_CTRL, reg | (var->bits_per_pixel >> 4)); + reg = peek32(PANEL_DISPLAY_CTRL); + poke32(PANEL_DISPLAY_CTRL, reg | (var->bits_per_pixel >> 4)); } else { /* not implemented now */ - POKE32(CRT_FB_ADDRESS, crtc->oScreen); + poke32(CRT_FB_ADDRESS, crtc->oScreen); reg = var->xres * (var->bits_per_pixel >> 3); /* * crtc->channel is not equal to par->index on numeric, @@ -358,13 +358,13 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, reg = ALIGN(reg, crtc->line_pad) << CRT_FB_WIDTH_WIDTH_SHIFT; reg &= CRT_FB_WIDTH_WIDTH_MASK; reg |= (fix->line_length & CRT_FB_WIDTH_OFFSET_MASK); - POKE32(CRT_FB_WIDTH, reg); + poke32(CRT_FB_WIDTH, reg); /* SET PIXEL FORMAT */ - reg = PEEK32(CRT_DISPLAY_CTRL); + reg = peek32(CRT_DISPLAY_CTRL); reg |= ((var->bits_per_pixel >> 4) & CRT_DISPLAY_CTRL_FORMAT_MASK); - POKE32(CRT_DISPLAY_CTRL, reg); + poke32(CRT_DISPLAY_CTRL, reg); } exit: @@ -376,7 +376,7 @@ int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index, { static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM}; - POKE32(add[crtc->channel] + index * 4, + poke32(add[crtc->channel] + index * 4, (red << 16) | (green << 8) | blue); return 0; } @@ -413,11 +413,11 @@ int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank) if (output->paths & sm750_crt) { unsigned int val; - val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK; - POKE32(CRT_DISPLAY_CTRL, val | dpms); + val = peek32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK; + poke32(CRT_DISPLAY_CTRL, val | dpms); - val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK; - POKE32(CRT_DISPLAY_CTRL, val | crtdb); + val = peek32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK; + poke32(CRT_DISPLAY_CTRL, val | crtdb); } return 0; } @@ -456,20 +456,20 @@ int hw_sm750_setBLANK(struct lynxfb_output *output, int blank) } if (output->paths & sm750_crt) { - unsigned int val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; + unsigned int val = peek32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK; - POKE32(SYSTEM_CTRL, val | dpms); + poke32(SYSTEM_CTRL, val | dpms); - val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK; - POKE32(CRT_DISPLAY_CTRL, val | crtdb); + val = peek32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK; + poke32(CRT_DISPLAY_CTRL, val | crtdb); } if (output->paths & sm750_panel) { - unsigned int val = PEEK32(PANEL_DISPLAY_CTRL); + unsigned int val = peek32(PANEL_DISPLAY_CTRL); val &= ~PANEL_DISPLAY_CTRL_DATA; val |= pps; - POKE32(PANEL_DISPLAY_CTRL, val); + poke32(PANEL_DISPLAY_CTRL, val); } return 0; @@ -482,23 +482,23 @@ void hw_sm750_initAccel(struct sm750_dev *sm750_dev) sm750_enable_2d_engine(1); if (sm750_get_chip_type() == SM750LE) { - reg = PEEK32(DE_STATE1); + reg = peek32(DE_STATE1); reg |= DE_STATE1_DE_ABORT; - POKE32(DE_STATE1, reg); + poke32(DE_STATE1, reg); - reg = PEEK32(DE_STATE1); + reg = peek32(DE_STATE1); reg &= ~DE_STATE1_DE_ABORT; - POKE32(DE_STATE1, reg); + poke32(DE_STATE1, reg); } else { /* engine reset */ - reg = PEEK32(SYSTEM_CTRL); + reg = peek32(SYSTEM_CTRL); reg |= SYSTEM_CTRL_DE_ABORT; - POKE32(SYSTEM_CTRL, reg); + poke32(SYSTEM_CTRL, reg); - reg = PEEK32(SYSTEM_CTRL); + reg = peek32(SYSTEM_CTRL); reg &= ~SYSTEM_CTRL_DE_ABORT; - POKE32(SYSTEM_CTRL, reg); + poke32(SYSTEM_CTRL, reg); } /* call 2d init */ @@ -512,7 +512,7 @@ int hw_sm750le_deWait(void) DE_STATE2_DE_MEM_FIFO_EMPTY; while (i--) { - unsigned int val = PEEK32(DE_STATE2); + unsigned int val = peek32(DE_STATE2); if ((val & mask) == (DE_STATE2_DE_FIFO_EMPTY | DE_STATE2_DE_MEM_FIFO_EMPTY)) @@ -530,7 +530,7 @@ int hw_sm750_deWait(void) SYSTEM_CTRL_DE_MEM_FIFO_EMPTY; while (i--) { - unsigned int val = PEEK32(SYSTEM_CTRL); + unsigned int val = peek32(SYSTEM_CTRL); if ((val & mask) == (SYSTEM_CTRL_DE_FIFO_EMPTY | SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) @@ -555,12 +555,12 @@ int hw_sm750_pan_display(struct lynxfb_crtc *crtc, ((var->xoffset * var->bits_per_pixel) >> 3); total += crtc->oScreen; if (crtc->channel == sm750_primary) { - POKE32(PANEL_FB_ADDRESS, - PEEK32(PANEL_FB_ADDRESS) | + poke32(PANEL_FB_ADDRESS, + peek32(PANEL_FB_ADDRESS) | (total & PANEL_FB_ADDRESS_ADDRESS_MASK)); } else { - POKE32(CRT_FB_ADDRESS, - PEEK32(CRT_FB_ADDRESS) | + poke32(CRT_FB_ADDRESS, + peek32(CRT_FB_ADDRESS) | (total & CRT_FB_ADDRESS_ADDRESS_MASK)); } return 0; diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c index 8f058b42f68d..d76da0a1382c 100644 --- a/drivers/staging/speakup/fakekey.c +++ b/drivers/staging/speakup/fakekey.c @@ -63,8 +63,8 @@ void speakup_remove_virtual_keyboard(void) } /* - * Send a simulated down-arrow to the application. - */ + * Send a simulated down-arrow to the application. + */ void speakup_fake_down_arrow(void) { unsigned long flags; @@ -87,9 +87,9 @@ void speakup_fake_down_arrow(void) } /* - * Are we handling a simulated keypress on the current CPU? - * Returns a boolean. - */ + * Are we handling a simulated keypress on the current CPU? + * Returns a boolean. + */ bool speakup_fake_key_pressed(void) { return this_cpu_read(reporting_keystroke); diff --git a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c index 8960079e4d60..2f9b3df7f78d 100644 --- a/drivers/staging/speakup/i18n.c +++ b/drivers/staging/speakup/i18n.c @@ -401,7 +401,7 @@ char *spk_msg_get(enum msg_index_t index) * Finds the start of the next format specifier in the argument string. * Return value: pointer to start of format * specifier, or NULL if no specifier exists. -*/ + */ static char *next_specifier(char *input) { int found = 0; @@ -450,7 +450,7 @@ static char *skip_width(char *input) * Note that this code only accepts a handful of conversion specifiers: * c d s x and ld. Not accidental; these are exactly the ones used in * the default group of formatted messages. -*/ + */ static char *skip_conversion(char *input) { if ((input[0] == 'l') && (input[1] == 'd')) @@ -463,7 +463,7 @@ static char *skip_conversion(char *input) /* * Function: find_specifier_end * Return a pointer to the end of the format specifier. -*/ + */ static char *find_specifier_end(char *input) { input++; /* Advance over %. */ @@ -478,7 +478,7 @@ static char *find_specifier_end(char *input) * Compare the format specifiers pointed to by *input1 and *input2. * Return 1 if they are the same, 0 otherwise. Advance *input1 and *input2 * so that they point to the character following the end of the specifier. -*/ + */ static int compare_specifiers(char **input1, char **input2) { int same = 0; @@ -500,7 +500,7 @@ static int compare_specifiers(char **input1, char **input2) * Check that two format strings contain the same number of format specifiers, * and that the order of specifiers is the same in both strings. * Return 1 if the condition holds, 0 if it doesn't. -*/ + */ static int fmt_validate(char *template, char *user) { int valid = 1; @@ -537,7 +537,7 @@ static int fmt_validate(char *template, char *user) * Failure conditions: * -EINVAL - Invalid format specifiers in formatted message or illegal index. * -ENOMEM - Unable to allocate memory. -*/ + */ ssize_t spk_msg_set(enum msg_index_t index, char *text, size_t length) { int rc = 0; @@ -573,7 +573,7 @@ ssize_t spk_msg_set(enum msg_index_t index, char *text, size_t length) /* * Find a message group, given its name. Return a pointer to the structure * if found, or NULL otherwise. -*/ + */ struct msg_group_t *spk_find_msg_group(const char *group_name) { struct msg_group_t *group = NULL; diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index e744aa9730ff..4e7ebc306488 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -865,66 +865,66 @@ static struct kobj_attribute version_attribute = __ATTR_RO(version); static struct kobj_attribute delimiters_attribute = - __ATTR(delimiters, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(delimiters, 0644, punc_show, punc_store); static struct kobj_attribute ex_num_attribute = - __ATTR(ex_num, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(ex_num, 0644, punc_show, punc_store); static struct kobj_attribute punc_all_attribute = - __ATTR(punc_all, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(punc_all, 0644, punc_show, punc_store); static struct kobj_attribute punc_most_attribute = - __ATTR(punc_most, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(punc_most, 0644, punc_show, punc_store); static struct kobj_attribute punc_some_attribute = - __ATTR(punc_some, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(punc_some, 0644, punc_show, punc_store); static struct kobj_attribute repeats_attribute = - __ATTR(repeats, S_IWUSR | S_IRUGO, punc_show, punc_store); + __ATTR(repeats, 0644, punc_show, punc_store); static struct kobj_attribute attrib_bleep_attribute = - __ATTR(attrib_bleep, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(attrib_bleep, 0644, spk_var_show, spk_var_store); static struct kobj_attribute bell_pos_attribute = - __ATTR(bell_pos, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(bell_pos, 0644, spk_var_show, spk_var_store); static struct kobj_attribute bleep_time_attribute = - __ATTR(bleep_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(bleep_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute bleeps_attribute = - __ATTR(bleeps, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(bleeps, 0644, spk_var_show, spk_var_store); static struct kobj_attribute cursor_time_attribute = - __ATTR(cursor_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(cursor_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute key_echo_attribute = - __ATTR(key_echo, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(key_echo, 0644, spk_var_show, spk_var_store); static struct kobj_attribute no_interrupt_attribute = - __ATTR(no_interrupt, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(no_interrupt, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punc_level_attribute = - __ATTR(punc_level, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punc_level, 0644, spk_var_show, spk_var_store); static struct kobj_attribute reading_punc_attribute = - __ATTR(reading_punc, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(reading_punc, 0644, spk_var_show, spk_var_store); static struct kobj_attribute say_control_attribute = - __ATTR(say_control, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(say_control, 0644, spk_var_show, spk_var_store); static struct kobj_attribute say_word_ctl_attribute = - __ATTR(say_word_ctl, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(say_word_ctl, 0644, spk_var_show, spk_var_store); static struct kobj_attribute spell_delay_attribute = - __ATTR(spell_delay, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(spell_delay, 0644, spk_var_show, spk_var_store); /* * These attributes are i18n related. */ static struct kobj_attribute announcements_attribute = - __ATTR(announcements, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(announcements, 0644, message_show, message_store); static struct kobj_attribute characters_attribute = - __ATTR(characters, S_IWUSR | S_IRUGO, chars_chartab_show, + __ATTR(characters, 0644, chars_chartab_show, chars_chartab_store); static struct kobj_attribute chartab_attribute = - __ATTR(chartab, S_IWUSR | S_IRUGO, chars_chartab_show, + __ATTR(chartab, 0644, chars_chartab_show, chars_chartab_store); static struct kobj_attribute ctl_keys_attribute = - __ATTR(ctl_keys, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(ctl_keys, 0644, message_show, message_store); static struct kobj_attribute colors_attribute = - __ATTR(colors, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(colors, 0644, message_show, message_store); static struct kobj_attribute formatted_attribute = - __ATTR(formatted, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(formatted, 0644, message_show, message_store); static struct kobj_attribute function_names_attribute = - __ATTR(function_names, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(function_names, 0644, message_show, message_store); static struct kobj_attribute key_names_attribute = - __ATTR(key_names, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(key_names, 0644, message_show, message_store); static struct kobj_attribute states_attribute = - __ATTR(states, S_IWUSR | S_IRUGO, message_show, message_store); + __ATTR(states, 0644, message_show, message_store); /* * Create groups of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 5c192042eeac..c2f70ef5b9b3 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -16,7 +16,7 @@ * 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/kernel.h> #include <linux/vt.h> @@ -58,8 +58,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(SPEAKUP_VERSION); char *synth_name; -module_param_named(synth, synth_name, charp, S_IRUGO); -module_param_named(quiet, spk_quiet_boot, bool, S_IRUGO); +module_param_named(synth, synth_name, charp, 0444); +module_param_named(quiet, spk_quiet_boot, bool, 0444); MODULE_PARM_DESC(synth, "Synth to start if speakup is built in."); MODULE_PARM_DESC(quiet, "Do not announce when the synthesizer is found."); diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index df74c912da72..b203f0f883a9 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h @@ -9,10 +9,6 @@ #define SHIFT_TBL_SIZE 64 #define MAX_DESC_LEN 72 -/* proc permissions */ -#define USER_R (S_IFREG|S_IRUGO) -#define USER_W (S_IFREG|S_IWUGO) - #define TOGGLE_0 .u.n = {NULL, 0, 0, 1, 0, 0, NULL } #define TOGGLE_1 .u.n = {NULL, 1, 0, 1, 0, 0, NULL } #define MAXVARLEN 15 diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c index efb791bb642b..c7fab261d860 100644 --- a/drivers/staging/speakup/speakup_acntpc.c +++ b/drivers/staging/speakup/speakup_acntpc.c @@ -57,28 +57,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/acntpc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -307,8 +307,8 @@ static void accent_release(void) speakup_info.port_tts = 0; } -module_param_named(port, port_forced, int, S_IRUGO); -module_param_named(start, synth_acntpc.startup, short, S_IRUGO); +module_param_named(port, port_forced, int, 0444); +module_param_named(start, synth_acntpc.startup, short, 0444); MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c index 34f45d3549b2..b2e352712766 100644 --- a/drivers/staging/speakup/speakup_acntsa.c +++ b/drivers/staging/speakup/speakup_acntsa.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -43,28 +43,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/acntsa. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -133,8 +133,8 @@ static int synth_probe(struct spk_synth *synth) return failed; } -module_param_named(ser, synth_acntsa.ser, int, S_IRUGO); -module_param_named(start, synth_acntsa.startup, short, S_IRUGO); +module_param_named(ser, synth_acntsa.ser, int, 0444); +module_param_named(start, synth_acntsa.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c index 3cbc8a7ad1ef..3f43f8105bc0 100644 --- a/drivers/staging/speakup/speakup_apollo.c +++ b/drivers/staging/speakup/speakup_apollo.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -49,30 +49,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/apollo. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute lang_attribute = - __ATTR(lang, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(lang, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -197,8 +197,8 @@ static void do_catch_up(struct spk_synth *synth) spk_serial_out(PROCSPEECH); } -module_param_named(ser, synth_apollo.ser, int, S_IRUGO); -module_param_named(start, synth_apollo.startup, short, S_IRUGO); +module_param_named(ser, synth_apollo.ser, int, 0444); +module_param_named(start, synth_apollo.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c index 7a12b8408b67..e696b87bf515 100644 --- a/drivers/staging/speakup/speakup_audptr.c +++ b/drivers/staging/speakup/speakup_audptr.c @@ -45,30 +45,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/audptr. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -167,8 +167,8 @@ static int synth_probe(struct spk_synth *synth) return 0; } -module_param_named(ser, synth_audptr.ser, int, S_IRUGO); -module_param_named(start, synth_audptr.startup, short, S_IRUGO); +module_param_named(ser, synth_audptr.ser, int, 0444); +module_param_named(start, synth_audptr.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_bns.c b/drivers/staging/speakup/speakup_bns.c index 570f0c21745e..da158c968e7c 100644 --- a/drivers/staging/speakup/speakup_bns.c +++ b/drivers/staging/speakup/speakup_bns.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -40,28 +40,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/bns. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -117,8 +117,8 @@ static struct spk_synth synth_bns = { }, }; -module_param_named(ser, synth_bns.ser, int, S_IRUGO); -module_param_named(start, synth_bns.startup, short, S_IRUGO); +module_param_named(ser, synth_bns.ser, int, 0444); +module_param_named(start, synth_bns.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index 1a5cf3d0a559..6b74a97385da 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -67,30 +67,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/decext. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -226,8 +226,8 @@ static void synth_flush(struct spk_synth *synth) spk_synth_immediate(synth, "\033P;10z\033\\"); } -module_param_named(ser, synth_decext.ser, int, S_IRUGO); -module_param_named(start, synth_decext.startup, short, S_IRUGO); +module_param_named(ser, synth_decext.ser, int, 0444); +module_param_named(start, synth_decext.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_decpc.c b/drivers/staging/speakup/speakup_decpc.c index d6479bd2163b..6bf38e49a96d 100644 --- a/drivers/staging/speakup/speakup_decpc.c +++ b/drivers/staging/speakup/speakup_decpc.c @@ -85,8 +85,8 @@ #define CTRL_io_priority 0x0c00 /* change i/o priority */ #define CTRL_free_mem 0x0d00 /* get free paragraphs on module */ #define CTRL_get_lang 0x0e00 /* return bit mask of loaded - * languages - */ + * languages + */ #define CMD_test 0x2000 /* self-test request */ #define TEST_mask 0x0F00 /* isolate test field */ #define TEST_null 0x0000 /* no test requested */ @@ -161,30 +161,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/decpc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -486,7 +486,7 @@ static void dtpc_release(void) speakup_info.port_tts = 0; } -module_param_named(start, synth_dec_pc.startup, short, S_IRUGO); +module_param_named(start, synth_dec_pc.startup, short, 0444); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index 764656759fbf..26036050cdb2 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -66,30 +66,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dectlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -295,8 +295,8 @@ static void synth_flush(struct spk_synth *synth) spk_serial_out(SYNTH_CLEAR); } -module_param_named(ser, synth_dectlk.ser, int, S_IRUGO); -module_param_named(start, synth_dectlk.startup, short, S_IRUGO); +module_param_named(ser, synth_dectlk.ser, int, 0444); +module_param_named(start, synth_dectlk.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index 38aa4013bf62..e2bf20806d8d 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -63,34 +63,34 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dtlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(freq, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -378,8 +378,8 @@ static void dtlk_release(void) speakup_info.port_tts = 0; } -module_param_named(port, port_forced, int, S_IRUGO); -module_param_named(start, synth_dtlk.startup, short, S_IRUGO); +module_param_named(port, port_forced, int, 0444); +module_param_named(start, synth_dtlk.startup, short, 0444); MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_dtlk.h b/drivers/staging/speakup/speakup_dtlk.h index 46d885fcfb20..b3b3cfc3db07 100644 --- a/drivers/staging/speakup/speakup_dtlk.h +++ b/drivers/staging/speakup/speakup_dtlk.h @@ -24,11 +24,11 @@ * usec later. */ #define TTS_ALMOST_FULL 0x08 /* mask for AF bit: When set to 1, - * indicates that less than 300 bytes - * are available in the TTS input - * buffer. AF is always 0 in the PCM, - * TGN and CVSD modes. - */ + * indicates that less than 300 bytes + * are available in the TTS input + * buffer. AF is always 0 in the PCM, + * TGN and CVSD modes. + */ #define TTS_ALMOST_EMPTY 0x04 /* mask for AE bit: When set to 1, * indicates that less than 300 bytes * are remaining in DoubleTalk's input diff --git a/drivers/staging/speakup/speakup_dummy.c b/drivers/staging/speakup/speakup_dummy.c index 87d2a8002b47..cb7cef30c124 100644 --- a/drivers/staging/speakup/speakup_dummy.c +++ b/drivers/staging/speakup/speakup_dummy.c @@ -42,28 +42,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dummy. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -119,8 +119,8 @@ static struct spk_synth synth_dummy = { }, }; -module_param_named(ser, synth_dummy.ser, int, S_IRUGO); -module_param_named(start, synth_dummy.startup, short, S_IRUGO); +module_param_named(ser, synth_dummy.ser, int, 0444); +module_param_named(start, synth_dummy.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index 5e2170bf4a8b..10f4964782e2 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -55,24 +55,24 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/keypc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -309,8 +309,8 @@ static void keynote_release(void) synth_port = 0; } -module_param_named(port, port_forced, int, S_IRUGO); -module_param_named(start, synth_keypc.startup, short, S_IRUGO); +module_param_named(port, port_forced, int, 0444); +module_param_named(start, synth_keypc.startup, short, 0444); MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_ltlk.c b/drivers/staging/speakup/speakup_ltlk.c index b474e8b65f9a..9d22198a0339 100644 --- a/drivers/staging/speakup/speakup_ltlk.c +++ b/drivers/staging/speakup/speakup_ltlk.c @@ -1,6 +1,6 @@ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> -* this version considerably modified by David Borowski, david575@rogers.com + * this version considerably modified by David Borowski, david575@rogers.com * * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. @@ -46,34 +46,34 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/ltlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(freq, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -165,8 +165,8 @@ static int synth_probe(struct spk_synth *synth) return failed; } -module_param_named(ser, synth_ltlk.ser, int, S_IRUGO); -module_param_named(start, synth_ltlk.startup, short, S_IRUGO); +module_param_named(ser, synth_ltlk.ser, int, 0444); +module_param_named(start, synth_ltlk.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index ed3e4282f41c..ff68a384f9c2 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -58,41 +58,41 @@ static struct var_t vars[] = { /* These attributes will appear in /sys/accessibility/speakup/soft. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(freq, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(voice, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); /* * We should uncomment the following definition, when we agree on a * method of passing a language designation to the software synthesizer. * static struct kobj_attribute lang_attribute = - * __ATTR(lang, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); + * __ATTR(lang, 0644, spk_var_show, spk_var_store); */ static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -340,7 +340,7 @@ static int softsynth_is_alive(struct spk_synth *synth) return 0; } -module_param_named(start, synth_soft.startup, short, S_IRUGO); +module_param_named(start, synth_soft.startup, short, 0444); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c index 586890908826..143fadabfe6c 100644 --- a/drivers/staging/speakup/speakup_spkout.c +++ b/drivers/staging/speakup/speakup_spkout.c @@ -43,30 +43,30 @@ static struct var_t vars[] = { /* These attributes will appear in /sys/accessibility/speakup/spkout. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(punct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -135,8 +135,8 @@ static void synth_flush(struct spk_synth *synth) outb(SYNTH_CLEAR, speakup_info.port_tts); } -module_param_named(ser, synth_spkout.ser, int, S_IRUGO); -module_param_named(start, synth_spkout.startup, short, S_IRUGO); +module_param_named(ser, synth_spkout.ser, int, 0444); +module_param_named(start, synth_spkout.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/speakup_txprt.c b/drivers/staging/speakup/speakup_txprt.c index b3d2cfd20ac8..aa2f338d15d8 100644 --- a/drivers/staging/speakup/speakup_txprt.c +++ b/drivers/staging/speakup/speakup_txprt.c @@ -39,28 +39,28 @@ static struct var_t vars[] = { /* These attributes will appear in /sys/accessibility/speakup/txprt. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_start, 0644, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(caps_stop, 0644, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(pitch, 0644, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(rate, 0644, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(tone, 0644, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(vol, 0644, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(delay_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(direct, 0644, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(full_time, 0644, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, 0644, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store); + __ATTR(trigger_time, 0644, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -116,8 +116,8 @@ static struct spk_synth synth_txprt = { }, }; -module_param_named(ser, synth_txprt.ser, int, S_IRUGO); -module_param_named(start, synth_txprt.startup, short, S_IRUGO); +module_param_named(ser, synth_txprt.ser, int, 0444); +module_param_named(start, synth_txprt.startup, short, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h index 98c4b6f0344a..d5aa41d82122 100644 --- a/drivers/staging/speakup/spk_priv.h +++ b/drivers/staging/speakup/spk_priv.h @@ -64,8 +64,8 @@ void spk_synth_flush(struct spk_synth *synth); int spk_synth_is_alive_nop(struct spk_synth *synth); int spk_synth_is_alive_restart(struct spk_synth *synth); void synth_printf(const char *buf, ...); -int synth_request_region(u_long, u_long); -int synth_release_region(u_long, u_long); +int synth_request_region(unsigned long start, unsigned long n); +int synth_release_region(unsigned long start, unsigned long n); int synth_add(struct spk_synth *in_synth); void synth_remove(struct spk_synth *in_synth); diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index 259ef6487959..1c95302f7f1b 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -21,11 +21,11 @@ #include <linux/uuid.h> /* -* Whenever this file is changed a corresponding change must be made in -* the Console/ServicePart/visordiag_early/supervisor_channel.h file -* which is needed for Linux kernel compiles. These two files must be -* in sync. -*/ + * Whenever this file is changed a corresponding change must be made in + * the Console/ServicePart/visordiag_early/supervisor_channel.h file + * which is needed for Linux kernel compiles. These two files must be + * in sync. + */ /* define the following to prevent include nesting in kernel header * files of similar abbreviated content @@ -310,82 +310,82 @@ static inline int spar_check_channel_server(uuid_le typeuuid, char *name, } /* -* Routine Description: -* Tries to insert the prebuilt signal pointed to by pSignal into the nth -* Queue of the Channel pointed to by pChannel -* -* Parameters: -* pChannel: (IN) points to the IO Channel -* Queue: (IN) nth Queue of the IO Channel -* pSignal: (IN) pointer to the signal -* -* Assumptions: -* - pChannel, Queue and pSignal are valid. -* - If insertion fails due to a full queue, the caller will determine the -* retry policy (e.g. wait & try again, report an error, etc.). -* -* Return value: 1 if the insertion succeeds, 0 if the queue was -* full. -*/ + * Routine Description: + * Tries to insert the prebuilt signal pointed to by pSignal into the nth + * Queue of the Channel pointed to by pChannel + * + * Parameters: + * pChannel: (IN) points to the IO Channel + * Queue: (IN) nth Queue of the IO Channel + * pSignal: (IN) pointer to the signal + * + * Assumptions: + * - pChannel, Queue and pSignal are valid. + * - If insertion fails due to a full queue, the caller will determine the + * retry policy (e.g. wait & try again, report an error, etc.). + * + * Return value: 1 if the insertion succeeds, 0 if the queue was + * full. + */ unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, void *sig); /* -* Routine Description: -* Removes one signal from Channel pChannel's nth Queue at the -* time of the call and copies it into the memory pointed to by -* pSignal. -* -* Parameters: -* pChannel: (IN) points to the IO Channel -* Queue: (IN) nth Queue of the IO Channel -* pSignal: (IN) pointer to where the signals are to be copied -* -* Assumptions: -* - pChannel and Queue are valid. -* - pSignal points to a memory area large enough to hold queue's SignalSize -* -* Return value: 1 if the removal succeeds, 0 if the queue was -* empty. -*/ + * Routine Description: + * Removes one signal from Channel pChannel's nth Queue at the + * time of the call and copies it into the memory pointed to by + * pSignal. + * + * Parameters: + * pChannel: (IN) points to the IO Channel + * Queue: (IN) nth Queue of the IO Channel + * pSignal: (IN) pointer to where the signals are to be copied + * + * Assumptions: + * - pChannel and Queue are valid. + * - pSignal points to a memory area large enough to hold queue's SignalSize + * + * Return value: 1 if the removal succeeds, 0 if the queue was + * empty. + */ unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig); /* -* Routine Description: -* Removes all signals present in Channel pChannel's nth Queue at the -* time of the call and copies them into the memory pointed to by -* pSignal. Returns the # of signals copied as the value of the routine. -* -* Parameters: -* pChannel: (IN) points to the IO Channel -* Queue: (IN) nth Queue of the IO Channel -* pSignal: (IN) pointer to where the signals are to be copied -* -* Assumptions: -* - pChannel and Queue are valid. -* - pSignal points to a memory area large enough to hold Queue's MaxSignals -* # of signals, each of which is Queue's SignalSize. -* -* Return value: -* # of signals copied. -*/ + * Routine Description: + * Removes all signals present in Channel pChannel's nth Queue at the + * time of the call and copies them into the memory pointed to by + * pSignal. Returns the # of signals copied as the value of the routine. + * + * Parameters: + * pChannel: (IN) points to the IO Channel + * Queue: (IN) nth Queue of the IO Channel + * pSignal: (IN) pointer to where the signals are to be copied + * + * Assumptions: + * - pChannel and Queue are valid. + * - pSignal points to a memory area large enough to hold Queue's MaxSignals + * # of signals, each of which is Queue's SignalSize. + * + * Return value: + * # of signals copied. + */ unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, void *sig); /* -* Routine Description: -* Determine whether a signal queue is empty. -* -* Parameters: -* pChannel: (IN) points to the IO Channel -* Queue: (IN) nth Queue of the IO Channel -* -* Return value: -* 1 if the signal queue is empty, 0 otherwise. -*/ + * Routine Description: + * Determine whether a signal queue is empty. + * + * Parameters: + * pChannel: (IN) points to the IO Channel + * Queue: (IN) nth Queue of the IO Channel + * + * Return value: + * 1 if the signal queue is empty, 0 otherwise. + */ unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, u32 queue); diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h index f0bfc4ded892..859345243afe 100644 --- a/drivers/staging/unisys/visorbus/controlvmchannel.h +++ b/drivers/staging/unisys/visorbus/controlvmchannel.h @@ -43,8 +43,6 @@ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE) -#define MAX_SERIAL_NUM 32 - /* Defines for various channel queues */ #define CONTROLVM_QUEUE_REQUEST 0 #define CONTROLVM_QUEUE_RESPONSE 1 @@ -436,26 +434,6 @@ struct spar_controlvm_channel_protocol { struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; }; -/* Offsets for VM channel attributes */ -#define VM_CH_REQ_QUEUE_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, request_queue) -#define VM_CH_RESP_QUEUE_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, response_queue) -#define VM_CH_EVENT_QUEUE_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, event_queue) -#define VM_CH_ACK_QUEUE_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, event_ack_queue) -#define VM_CH_REQ_MSG_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, request_msg) -#define VM_CH_RESP_MSG_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, response_msg) -#define VM_CH_EVENT_MSG_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, event_msg) -#define VM_CH_ACK_MSG_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, event_ack_msg) -#define VM_CH_CRASH_MSG_OFFSET \ - offsetof(struct spar_controlvm_channel_protocol, saved_crash_msg) - /* The following header will be located at the beginning of PayloadVmOffset for * various ControlVm commands. The receiver of a ControlVm command with a * PayloadVmOffset will dereference this address and then use connection_offset, @@ -484,56 +462,55 @@ struct spar_controlvm_parameters_header { /* General Errors------------------------------------------------------[0-99] */ #define CONTROLVM_RESP_SUCCESS 0 -#define CONTROLVM_RESP_ERROR_ALREADY_DONE 1 -#define CONTROLVM_RESP_ERROR_IOREMAP_FAILED 2 -#define CONTROLVM_RESP_ERROR_KMALLOC_FAILED 3 -#define CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN 4 -#define CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT 5 +#define CONTROLVM_RESP_ALREADY_DONE 1 +#define CONTROLVM_RESP_IOREMAP_FAILED 2 +#define CONTROLVM_RESP_KMALLOC_FAILED 3 +#define CONTROLVM_RESP_ID_UNKNOWN 4 +#define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 /* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ -#define CONTROLVM_RESP_ERROR_CLIENT_SWITCHCOUNT_NONZERO 100 -#define CONTROLVM_RESP_ERROR_EXPECTED_CHIPSET_INIT 101 +#define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 +#define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 /* Maximum Limit----------------------------------------------------[200-299] */ #define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */ #define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */ /* Payload and Parameter Related------------------------------------[400-499] */ -#define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, +#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, * DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ -#define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ +#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ /* Specified[Packet Structure] Value-------------------------------[500-599] */ -#define CONTROLVM_RESP_ERROR_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT, +#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT, * BUS_CONFIGURE, * DEVICE_CREATE, * DEVICE_CONFIG * DEVICE_DESTROY */ -#define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */ +#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */ /* DEVICE_CREATE, * DEVICE_CONFIGURE, * DEVICE_DESTROY */ -#define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE, +#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE, * DEVICE_CONFIGURE */ /* Partition Driver Callback Interface----------------------[600-699] */ -#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, + * BUS_DESTROY, + * DEVICE_CREATE, + * DEVICE_DESTROY + */ /* Unable to invoke VIRTPCI callback */ -#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605 - /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, + * BUS_DESTROY, + * DEVICE_CREATE, + * DEVICE_DESTROY + */ /* VIRTPCI Callback returned error */ -#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606 +#define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 /* SWITCH_ATTACHEXTPORT, * SWITCH_DETACHEXTPORT * DEVICE_CONFIGURE @@ -543,19 +520,19 @@ struct spar_controlvm_parameters_header { /* Bus Related------------------------------------------------------[700-799] */ #define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */ /* Channel Related--------------------------------------------------[800-899] */ -#define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, +#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, * DEVICE_DESTROY */ -#define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ +#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ /* Chipset Shutdown Related---------------------------------------[1000-1099] */ -#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000 -#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 +#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 +#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 /* Chipset Stop Related-------------------------------------------[1100-1199] */ -#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS 1100 -#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_SWITCH 1101 +#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 +#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 /* Device Related-------------------------------------------------[1400-1499] */ -#define CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT 1400 +#define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 #endif /* __CONTROLVMCHANNEL_H__ */ diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 3457ef338e1e..55f29ae8e015 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -49,7 +49,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, vdev = to_visor_device(dev); guid = visorchannel_get_uuid(vdev->visorchannel); - return snprintf(buf, PAGE_SIZE, "visorbus:%pUl\n", &guid); + return sprintf(buf, "visorbus:%pUl\n", &guid); } static DEVICE_ATTR_RO(modalias); @@ -187,8 +187,8 @@ static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr, if (!vdev->visorchannel) return 0; - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - visorchannel_get_physaddr(vdev->visorchannel)); + return sprintf(buf, "0x%llx\n", + visorchannel_get_physaddr(vdev->visorchannel)); } static DEVICE_ATTR_RO(physaddr); @@ -199,7 +199,7 @@ static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr, if (!vdev->visorchannel) return 0; - return snprintf(buf, PAGE_SIZE, "0x%lx\n", + return sprintf(buf, "0x%lx\n", visorchannel_get_nbytes(vdev->visorchannel)); } static DEVICE_ATTR_RO(nbytes); @@ -211,8 +211,8 @@ static ssize_t clientpartition_show(struct device *dev, if (!vdev->visorchannel) return 0; - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - visorchannel_get_clientpartition(vdev->visorchannel)); + return sprintf(buf, "0x%llx\n", + visorchannel_get_clientpartition(vdev->visorchannel)); } static DEVICE_ATTR_RO(clientpartition); @@ -224,8 +224,8 @@ static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, if (!vdev->visorchannel) return 0; - return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_id(vdev->visorchannel, typeid)); + return sprintf(buf, "%s\n", + visorchannel_id(vdev->visorchannel, typeid)); } static DEVICE_ATTR_RO(typeguid); @@ -237,8 +237,8 @@ static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, if (!vdev->visorchannel) return 0; - return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_zoneid(vdev->visorchannel, zoneid)); + return sprintf(buf, "%s\n", + visorchannel_zoneid(vdev->visorchannel, zoneid)); } static DEVICE_ATTR_RO(zoneguid); @@ -257,7 +257,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, if (!i) return 0; drv = to_visor_driver(xdrv); - return snprintf(buf, PAGE_SIZE, "%s\n", drv->channel_types[i - 1].name); + return sprintf(buf, "%s\n", drv->channel_types[i - 1].name); } static DEVICE_ATTR_RO(typename); @@ -296,7 +296,7 @@ static ssize_t partition_handle_show(struct device *dev, struct visor_device *vdev = to_visor_device(dev); u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); - return snprintf(buf, PAGE_SIZE, "0x%llx\n", handle); + return sprintf(buf, "0x%llx\n", handle); } static DEVICE_ATTR_RO(partition_handle); @@ -305,7 +305,7 @@ static ssize_t partition_guid_show(struct device *dev, char *buf) { struct visor_device *vdev = to_visor_device(dev); - return snprintf(buf, PAGE_SIZE, "{%pUb}\n", &vdev->partition_uuid); + return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid); } static DEVICE_ATTR_RO(partition_guid); @@ -314,7 +314,7 @@ static ssize_t partition_name_show(struct device *dev, char *buf) { struct visor_device *vdev = to_visor_device(dev); - return snprintf(buf, PAGE_SIZE, "%s\n", vdev->name); + return sprintf(buf, "%s\n", vdev->name); } static DEVICE_ATTR_RO(partition_name); @@ -324,7 +324,7 @@ static ssize_t channel_addr_show(struct device *dev, struct visor_device *vdev = to_visor_device(dev); u64 addr = visorchannel_get_physaddr(vdev->visorchannel); - return snprintf(buf, PAGE_SIZE, "0x%llx\n", addr); + return sprintf(buf, "0x%llx\n", addr); } static DEVICE_ATTR_RO(channel_addr); @@ -334,7 +334,7 @@ static ssize_t channel_bytes_show(struct device *dev, struct visor_device *vdev = to_visor_device(dev); u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); - return snprintf(buf, PAGE_SIZE, "0x%llx\n", nbytes); + return sprintf(buf, "0x%llx\n", nbytes); } static DEVICE_ATTR_RO(channel_bytes); @@ -438,8 +438,7 @@ dev_periodic_work(unsigned long __opaque) struct visor_device *dev = (struct visor_device *)__opaque; struct visor_driver *drv = to_visor_driver(dev->device.driver); - if (drv->channel_interrupt) - drv->channel_interrupt(dev); + drv->channel_interrupt(dev); mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL); } @@ -561,6 +560,13 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel); void visorbus_enable_channel_interrupts(struct visor_device *dev) { + struct visor_driver *drv = to_visor_driver(dev->device.driver); + + if (!drv->channel_interrupt) { + dev_err(&dev->device, "%s no interrupt function!\n", __func__); + return; + } + dev_start_periodic_work(dev); } EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts); @@ -617,9 +623,7 @@ create_visor_device(struct visor_device *dev) dev->device.release = visorbus_release_device; /* keep a reference just for us (now 2) */ get_device(&dev->device); - init_timer(&dev->timer); - dev->timer.data = (unsigned long)(dev); - dev->timer.function = dev_periodic_work; + setup_timer(&dev->timer, dev_periodic_work, (unsigned long)dev); /* * bus_id must be a unique name with respect to this bus TYPE @@ -984,7 +988,7 @@ create_bus_instance(struct visor_device *dev) goto err_hdr_info; } dev->debugfs_client_bus_info = - debugfs_create_file("client_bus_info", S_IRUSR | S_IRGRP, + debugfs_create_file("client_bus_info", 0440, dev->debugfs_dir, dev, &client_bus_info_debugfs_fops); if (!dev->debugfs_client_bus_info) { @@ -1337,10 +1341,10 @@ visorbus_exit(void) debugfs_remove_recursive(visorbus_debugfs_dir); } -module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO); +module_param_named(forcematch, visorbus_forcematch, int, 0444); MODULE_PARM_DESC(visorbus_forcematch, "1 to force a successful dev <--> drv match"); -module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO); +module_param_named(forcenomatch, visorbus_forcenomatch, int, 0444); MODULE_PARM_DESC(visorbus_forcenomatch, "1 to force an UNsuccessful dev <--> drv match"); diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index f51a7258bef0..e91febcc6c1e 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -45,12 +45,6 @@ struct visorchannel { spinlock_t insert_lock; /* protect head writes in chan_hdr */ spinlock_t remove_lock; /* protect tail writes in chan_hdr */ - struct { - struct signal_queue_header req_queue; - struct signal_queue_header rsp_queue; - struct signal_queue_header event_queue; - struct signal_queue_header ack_queue; - } safe_uis_queue; uuid_le type; uuid_le inst; }; diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index d7148c351d3f..97778d733e1e 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -91,18 +91,6 @@ static struct cdev file_cdev; static struct visorchannel **file_controlvm_channel; static struct visorchannel *controlvm_channel; - -/* Manages the request payload in the controlvm channel */ -struct visor_controlvm_payload_info { - u8 *ptr; /* pointer to base address of payload pool */ - u64 offset; /* - * offset from beginning of controlvm - * channel to beginning of payload * pool - */ - u32 bytes; /* number of bytes in payload pool */ -}; - -static struct visor_controlvm_payload_info controlvm_payload_info; static unsigned long controlvm_payload_bytes_buffered; /* @@ -114,60 +102,6 @@ static unsigned long controlvm_payload_bytes_buffered; static struct controlvm_message controlvm_pending_msg; static bool controlvm_pending_msg_valid; -/* - * This describes a buffer and its current state of transfer (e.g., how many - * bytes have already been supplied as putfile data, and how many bytes are - * remaining) for a putfile_request. - */ -struct putfile_active_buffer { - /* a payload from a controlvm message, containing a file data buffer */ - struct parser_context *parser_ctx; - /* points within data area of parser_ctx to next byte of data */ - size_t bytes_remaining; -}; - -#define PUTFILE_REQUEST_SIG 0x0906101302281211 -/* - * This identifies a single remote --> local CONTROLVM_TRANSMIT_FILE - * conversation. Structs of this type are dynamically linked into - * <Putfile_request_list>. - */ -struct putfile_request { - u64 sig; /* PUTFILE_REQUEST_SIG */ - - /* header from original TransmitFile request */ - struct controlvm_message_header controlvm_header; - - /* link to next struct putfile_request */ - struct list_head next_putfile_request; - - /* - * head of putfile_buffer_entry list, which describes the data to be - * supplied as putfile data; - * - this list is added to when controlvm messages come in that supply - * file data - * - this list is removed from via the hotplug program that is actually - * consuming these buffers to write as file data - */ - struct list_head input_buffer_list; - spinlock_t req_list_lock; /* lock for input_buffer_list */ - - /* waiters for input_buffer_list to go non-empty */ - wait_queue_head_t input_buffer_wq; - - /* data not yet read within current putfile_buffer_entry */ - struct putfile_active_buffer active_buf; - - /* - * <0 = failed, 0 = in-progress, >0 = successful; - * note that this must be set with req_list_lock, and if you set <0, - * it is your responsibility to also free up all of the other objects - * in this struct (like input_buffer_list, active_buf.parser_ctx) - * before releasing the lock - */ - int completion_status; -}; - struct parahotplug_request { struct list_head list; int id; @@ -188,7 +122,7 @@ static ssize_t toolaction_show(struct device *dev, visorchannel_read(controlvm_channel, offsetof(struct spar_controlvm_channel_protocol, tool_action), &tool_action, sizeof(u8)); - return scnprintf(buf, PAGE_SIZE, "%u\n", tool_action); + return sprintf(buf, "%u\n", tool_action); } static ssize_t toolaction_store(struct device *dev, @@ -223,8 +157,7 @@ static ssize_t boottotool_show(struct device *dev, offsetof(struct spar_controlvm_channel_protocol, efi_spar_ind), &efi_spar_indication, sizeof(struct efi_spar_indication)); - return scnprintf(buf, PAGE_SIZE, "%u\n", - efi_spar_indication.boot_to_tool); + return sprintf(buf, "%u\n", efi_spar_indication.boot_to_tool); } static ssize_t boottotool_store(struct device *dev, @@ -259,7 +192,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, offsetof(struct spar_controlvm_channel_protocol, installation_error), &error, sizeof(u32)); - return scnprintf(buf, PAGE_SIZE, "%i\n", error); + return sprintf(buf, "%i\n", error); } static ssize_t error_store(struct device *dev, struct device_attribute *attr, @@ -292,7 +225,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, offsetof(struct spar_controlvm_channel_protocol, installation_text_id), &text_id, sizeof(u32)); - return scnprintf(buf, PAGE_SIZE, "%i\n", text_id); + return sprintf(buf, "%i\n", text_id); } static ssize_t textid_store(struct device *dev, struct device_attribute *attr, @@ -324,7 +257,7 @@ static ssize_t remaining_steps_show(struct device *dev, offsetof(struct spar_controlvm_channel_protocol, installation_remaining_steps), &remaining_steps, sizeof(u16)); - return scnprintf(buf, PAGE_SIZE, "%hu\n", remaining_steps); + return sprintf(buf, "%hu\n", remaining_steps); } static ssize_t remaining_steps_store(struct device *dev, @@ -353,60 +286,12 @@ parser_id_get(struct parser_context *ctx) { struct spar_controlvm_parameters_header *phdr = NULL; - if (!ctx) - return NULL_UUID_LE; phdr = (struct spar_controlvm_parameters_header *)(ctx->data); return phdr->id; } -/* - * Describes the state from the perspective of which controlvm messages have - * been received for a bus or device. - */ - -enum PARSER_WHICH_STRING { - PARSERSTRING_INITIATOR, - PARSERSTRING_TARGET, - PARSERSTRING_CONNECTION, - PARSERSTRING_NAME, /* TODO: only PARSERSTRING_NAME is used ? */ -}; - -static void -parser_param_start(struct parser_context *ctx, - enum PARSER_WHICH_STRING which_string) -{ - struct spar_controlvm_parameters_header *phdr = NULL; - - if (!ctx) - return; - - phdr = (struct spar_controlvm_parameters_header *)(ctx->data); - switch (which_string) { - case PARSERSTRING_INITIATOR: - ctx->curr = ctx->data + phdr->initiator_offset; - ctx->bytes_remaining = phdr->initiator_length; - break; - case PARSERSTRING_TARGET: - ctx->curr = ctx->data + phdr->target_offset; - ctx->bytes_remaining = phdr->target_length; - break; - case PARSERSTRING_CONNECTION: - ctx->curr = ctx->data + phdr->connection_offset; - ctx->bytes_remaining = phdr->connection_length; - break; - case PARSERSTRING_NAME: - ctx->curr = ctx->data + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - break; - default: - break; - } -} - static void parser_done(struct parser_context *ctx) { - if (!ctx) - return; controlvm_payload_bytes_buffered -= ctx->param_bytes; kfree(ctx); } @@ -420,8 +305,6 @@ parser_string_get(struct parser_context *ctx) void *value = NULL; int i; - if (!ctx) - return NULL; pscan = ctx->curr; nscan = ctx->bytes_remaining; if (nscan == 0) @@ -444,6 +327,21 @@ parser_string_get(struct parser_context *ctx) return value; } +static void * +parser_name_get(struct parser_context *ctx) +{ + struct spar_controlvm_parameters_header *phdr = NULL; + + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + + if (phdr->name_offset + phdr->name_length > ctx->param_bytes) + return NULL; + + ctx->curr = ctx->data + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; + return parser_string_get(ctx); +} + struct visor_busdev { u32 bus_no; u32 dev_no; @@ -521,7 +419,7 @@ chipset_init(struct controlvm_message *inmsg) POSTCODE_LINUX(CHIPSET_INIT_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); if (chipset_inited) { - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + rc = -CONTROLVM_RESP_ALREADY_DONE; res = -EIO; goto out_respond; } @@ -613,27 +511,33 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) return err; } - if (typ == CRASH_BUS) { + switch (typ) { + case CRASH_DEV: + local_crash_msg_offset += sizeof(struct controlvm_message); err = visorchannel_write(controlvm_channel, local_crash_msg_offset, msg, - sizeof(struct controlvm_message)); + sizeof(struct controlvm_message)); if (err) { - POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, + POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0, DIAG_SEVERITY_ERR); return err; } - } else { - local_crash_msg_offset += sizeof(struct controlvm_message); + break; + case CRASH_BUS: err = visorchannel_write(controlvm_channel, local_crash_msg_offset, msg, sizeof(struct controlvm_message)); if (err) { - POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0, + POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, DIAG_SEVERITY_ERR); return err; } + break; + default: + pr_info("Invalid crash_obj_type\n"); + break; } return 0; } @@ -722,8 +626,11 @@ bus_create(struct controlvm_message *inmsg) POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, bus_no, DIAG_SEVERITY_PRINT); - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) - save_crash_message(inmsg, CRASH_BUS); + if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) { + err = save_crash_message(inmsg, CRASH_BUS); + if (err) + goto err_free_bus_info; + } if (inmsg->hdr.flags.response_expected == 1) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), @@ -857,9 +764,10 @@ bus_configure(struct controlvm_message *inmsg, if (err) goto err_respond; - bus_info->partition_uuid = parser_id_get(parser_ctx); - parser_param_start(parser_ctx, PARSERSTRING_NAME); - bus_info->name = parser_string_get(parser_ctx); + if (parser_ctx) { + bus_info->partition_uuid = parser_id_get(parser_ctx); + bus_info->name = parser_name_get(parser_ctx); + } POSTCODE_LINUX(BUS_CONFIGURE_EXIT_PC, 0, bus_no, DIAG_SEVERITY_PRINT); @@ -874,7 +782,7 @@ err_respond: return err; } -static void +static int my_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -884,37 +792,37 @@ my_device_create(struct controlvm_message *inmsg) struct visor_device *dev_info = NULL; struct visor_device *bus_info; struct visorchannel *visorchannel; - int rc = CONTROLVM_RESP_SUCCESS; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto out_respond; + err = -ENODEV; + goto err_respond; } if (bus_info->state.created == 0) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto out_respond; + err = -EINVAL; + goto err_respond; } dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (dev_info && (dev_info->state.created == 1)) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto out_respond; + err = -EEXIST; + goto err_respond; } dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_respond; + err = -ENOMEM; + goto err_respond; } dev_info->chipset_bus_no = bus_no; @@ -936,20 +844,23 @@ my_device_create(struct controlvm_message *inmsg) if (!visorchannel) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_free_dev_info; + err = -ENOMEM; + goto err_free_dev_info; } dev_info->visorchannel = visorchannel; dev_info->channel_type_guid = cmd->create_device.data_type_uuid; if (uuid_le_cmp(cmd->create_device.data_type_uuid, - spar_vhba_channel_protocol_uuid) == 0) - save_crash_message(inmsg, CRASH_DEV); + spar_vhba_channel_protocol_uuid) == 0) { + err = save_crash_message(inmsg, CRASH_DEV); + if (err) + goto err_free_dev_info; + } if (inmsg->hdr.flags.response_expected == 1) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); if (!pmsg_hdr) { - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_free_dev_info; + err = -ENOMEM; + goto err_free_dev_info; } memcpy(pmsg_hdr, &inmsg->hdr, @@ -960,17 +871,18 @@ my_device_create(struct controlvm_message *inmsg) chipset_device_create(dev_info); POSTCODE_LINUX(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, DIAG_SEVERITY_PRINT); - return; + return 0; -out_free_dev_info: +err_free_dev_info: kfree(dev_info); -out_respond: +err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int my_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -979,30 +891,30 @@ my_device_changestate(struct controlvm_message *inmsg) u32 dev_no = cmd->device_change_state.dev_no; struct spar_segment_state state = cmd->device_change_state.state; struct visor_device *dev_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + err = -ENODEV; goto err_respond; } if (dev_info->state.created == 0) { POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + err = -EINVAL; goto err_respond; } if (dev_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ - rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + err = -EIO; goto err_respond; } if (inmsg->hdr.flags.response_expected == 1) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); if (!pmsg_hdr) { - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + err = -ENOMEM; goto err_respond; } @@ -1023,15 +935,15 @@ my_device_changestate(struct controlvm_message *inmsg) * Response will be sent from chipset_device_pause. */ chipset_device_pause(dev_info); - - return; + return 0; err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int my_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -1039,27 +951,27 @@ my_device_destroy(struct controlvm_message *inmsg) u32 bus_no = cmd->destroy_device.bus_no; u32 dev_no = cmd->destroy_device.dev_no; struct visor_device *dev_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { - rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + err = -ENODEV; goto err_respond; } if (dev_info->state.created == 0) { - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + err = -EINVAL; goto err_respond; } if (dev_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ - rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + err = -EIO; goto err_respond; } if (inmsg->hdr.flags.response_expected == 1) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); if (!pmsg_hdr) { - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + err = -ENOMEM; goto err_respond; } @@ -1069,107 +981,33 @@ my_device_destroy(struct controlvm_message *inmsg) } chipset_device_destroy(dev_info); - return; + return 0; err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); -} - -/** - * initialize_controlvm_payload_info() - init controlvm_payload_info struct - * @phys_addr: the physical address of controlvm channel - * @offset: the offset to payload - * @bytes: the size of the payload in bytes - * @info: the returning valid struct - * - * When provided with the physical address of the controlvm channel - * (phys_addr), the offset to the payload area we need to manage - * (offset), and the size of this payload area (bytes), fills in the - * controlvm_payload_info struct. - * - * Return: CONTROLVM_RESP_SUCCESS for success or a negative for failure - */ -static int -initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, - struct visor_controlvm_payload_info *info) -{ - u8 *payload = NULL; - - if (!info) - return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - - if ((offset == 0) || (bytes == 0)) - return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - - payload = memremap(phys_addr + offset, bytes, MEMREMAP_WB); - if (!payload) - return -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; - - memset(info, 0, sizeof(struct visor_controlvm_payload_info)); - info->offset = offset; - info->bytes = bytes; - info->ptr = payload; - - return CONTROLVM_RESP_SUCCESS; -} - -static void -destroy_controlvm_payload_info(struct visor_controlvm_payload_info *info) -{ - if (info->ptr) { - memunmap(info->ptr); - info->ptr = NULL; - } - memset(info, 0, sizeof(struct visor_controlvm_payload_info)); -} - -static void -initialize_controlvm_payload(void) -{ - u64 phys_addr = visorchannel_get_physaddr(controlvm_channel); - u64 payload_offset = 0; - u32 payload_bytes = 0; - - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - request_payload_offset), - &payload_offset, sizeof(payload_offset)) < 0) { - POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, - DIAG_SEVERITY_ERR); - return; - } - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - request_payload_bytes), - &payload_bytes, sizeof(payload_bytes)) < 0) { - POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, - DIAG_SEVERITY_ERR); - return; - } - initialize_controlvm_payload_info(phys_addr, - payload_offset, payload_bytes, - &controlvm_payload_info); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } /* - * The general parahotplug flow works as follows. The visorchipset - * driver receives a DEVICE_CHANGESTATE message from Command - * specifying a physical device to enable or disable. The CONTROLVM - * message handler calls parahotplug_process_message, which then adds - * the message to a global list and kicks off a udev event which - * causes a user level script to enable or disable the specified - * device. The udev script then writes to - * /proc/visorchipset/parahotplug, which causes parahotplug_proc_write - * to get called, at which point the appropriate CONTROLVM message is - * retrieved from the list and responded to. + * The general parahotplug flow works as follows. The visorchipset receives + * a DEVICE_CHANGESTATE message from Command specifying a physical device + * to enable or disable. The CONTROLVM message handler calls + * parahotplug_process_message, which then adds the message to a global list + * and kicks off a udev event which causes a user level script to enable or + * disable the specified device. The udev script then writes to + * /sys/devices/platform/visorchipset/parahotplug, which causes the + * parahotplug store functions to get called, at which point the + * appropriate CONTROLVM message is retrieved from the list and responded + * to. */ #define PARAHOTPLUG_TIMEOUT_MS 2000 /** - * parahotplug_next_id() - generate unique int to match an outstanding CONTROLVM - * message with a udev script /proc response + * parahotplug_next_id() - generate unique int to match an outstanding + * CONTROLVM message with a udev script /sys + * response * * Return: a unique integer value */ @@ -1236,7 +1074,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ * @id: the id of the request * @active: indicates whether the request is assigned to active partition * - * Called from the /proc handler, which means the user script has + * Called from the /sys handler, which means the user script has * finished the enable/disable. Find the matching identifier, and * respond to the CONTROLVM message with success. * @@ -1433,7 +1271,7 @@ parahotplug_process_message(struct controlvm_message *inmsg) * * devices are automatically enabled at * initialization. - */ + */ parahotplug_request_kickoff(req); controlvm_respond_physdev_changestate (&inmsg->hdr, @@ -1455,22 +1293,33 @@ parahotplug_process_message(struct controlvm_message *inmsg) } } -/** - * visorchipset_chipset_ready() - sends chipset_ready action +/* + * chipset_ready_uevent() - sends chipset_ready action * * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. * - * Return: CONTROLVM_RESP_SUCCESS + * Return: 0 on success, negative on failure */ static int -visorchipset_chipset_ready(void) +chipset_ready_uevent(struct controlvm_message_header *msg_hdr) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_ONLINE); - return CONTROLVM_RESP_SUCCESS; + + if (msg_hdr->flags.response_expected) + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); + + return 0; } +/* + * chipset_selftest_uevent() - sends chipset_selftest action + * + * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. + * + * Return: 0 on success, negative on failure + */ static int -visorchipset_chipset_selftest(void) +chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) { char env_selftest[20]; char *envp[] = { env_selftest, NULL }; @@ -1478,54 +1327,29 @@ visorchipset_chipset_selftest(void) sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1); kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE, envp); - return CONTROLVM_RESP_SUCCESS; + + if (msg_hdr->flags.response_expected) + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); + + return 0; } -/** - * visorchipset_chipset_notready() - sends chipset_notready action +/* + * chipset_notready_uevent() - sends chipset_notready action * * Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset. * - * Return: CONTROLVM_RESP_SUCCESS + * Return: 0 on success, negative on failure */ static int -visorchipset_chipset_notready(void) +chipset_notready_uevent(struct controlvm_message_header *msg_hdr) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE); - return CONTROLVM_RESP_SUCCESS; -} - -static void -chipset_ready(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_ready(); - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); -} - -static void -chipset_selftest(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_selftest(); + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); -} - -static void -chipset_notready(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_notready(); - - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); + return 0; } static inline unsigned int @@ -1846,8 +1670,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) int allocbytes = sizeof(struct parser_context) + bytes; struct parser_context *ctx; - if (retry) - *retry = false; + *retry = false; /* * alloc an 0 extra byte to ensure payload is @@ -1856,14 +1679,12 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) allocbytes++; if ((controlvm_payload_bytes_buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { - if (retry) - *retry = true; + *retry = true; return NULL; } ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY); if (!ctx) { - if (retry) - *retry = true; + *retry = true; return NULL; } @@ -1990,19 +1811,18 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); break; case CONTROLVM_CHIPSET_READY: - chipset_ready(&inmsg.hdr); + chipset_ready_uevent(&inmsg.hdr); break; case CONTROLVM_CHIPSET_SELFTEST: - chipset_selftest(&inmsg.hdr); + chipset_selftest_uevent(&inmsg.hdr); break; case CONTROLVM_CHIPSET_STOP: - chipset_notready(&inmsg.hdr); + chipset_notready_uevent(&inmsg.hdr); break; default: if (inmsg.hdr.flags.response_expected) controlvm_respond - (&inmsg.hdr, - -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN); + (&inmsg.hdr, -CONTROLVM_RESP_ID_UNKNOWN); break; } @@ -2057,7 +1877,7 @@ parahotplug_process_list(void) if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, - CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT, + CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT, req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); } @@ -2148,17 +1968,14 @@ visorchipset_init(struct acpi_device *acpi_device) if (!controlvm_channel) goto error; - if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) { - initialize_controlvm_payload(); - } else { + if (!SPAR_CONTROLVM_CHANNEL_OK_CLIENT( + visorchannel_get_header(controlvm_channel))) goto error_destroy_channel; - } major_dev = MKDEV(visorchipset_major, 0); err = visorchipset_file_init(major_dev, &controlvm_channel); if (err < 0) - goto error_destroy_payload; + goto error_destroy_channel; /* if booting in a crash kernel */ if (is_kdump_kernel()) @@ -2194,9 +2011,6 @@ error_cancel_work: cancel_delayed_work_sync(&periodic_controlvm_work); visorchipset_file_cleanup(major_dev); -error_destroy_payload: - destroy_controlvm_payload_info(&controlvm_payload_info); - error_destroy_channel: visorchannel_destroy(controlvm_channel); @@ -2213,7 +2027,6 @@ visorchipset_exit(struct acpi_device *acpi_device) visorbus_exit(); cancel_delayed_work_sync(&periodic_controlvm_work); - destroy_controlvm_payload_info(&controlvm_payload_info); visorchannel_destroy(controlvm_channel); @@ -2277,7 +2090,7 @@ static void exit_unisys(void) acpi_bus_unregister_driver(&unisys_acpi_driver); } -module_param_named(major, visorchipset_major, int, S_IRUGO); +module_param_named(major, visorchipset_major, int, 0444); MODULE_PARM_DESC(visorchipset_major, "major device number to use for the device node"); diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h index 674a88b657d3..d1d72c184e29 100644 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ b/drivers/staging/unisys/visorbus/vmcallinterface.h @@ -16,10 +16,10 @@ #define __IOMONINTF_H__ /* -* This file contains all structures needed to support the VMCALLs for IO -* Virtualization. The VMCALLs are provided by Monitor and used by IO code -* running on IO Partitions. -*/ + * This file contains all structures needed to support the VMCALLs for IO + * Virtualization. The VMCALLs are provided by Monitor and used by IO code + * running on IO Partitions. + */ static inline unsigned long __unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx, unsigned long reg_ecx) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 5a7a87efed27..0ce92c85157c 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -29,10 +29,6 @@ /* The Send and Receive Buffers of the IO Queue may both be full */ #define IOS_ERROR_THRESHOLD 1000 -/* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters - * = 4800 bytes ~ 2^13 = 8192 bytes - */ -#define MAX_BUF 8192 #define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS * 2) #define VISORHBA_ERROR_COUNT 30 diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index ca3743d273e0..73a01a70b106 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -423,7 +423,7 @@ send_enbdis(struct net_device *netdev, int state, /** * visornic_disable_with_timeout - Disable network adapter - * @netdev: netdevice to disale + * @netdev: netdevice to disable * @timeout: timeout to wait for disable * * Disable the network adapter and inform the IO Partition that we @@ -461,10 +461,9 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) if (devdata->enab_dis_acked) break; if (devdata->server_down || devdata->server_change_state) { - spin_unlock_irqrestore(&devdata->priv_lock, flags); dev_dbg(&netdev->dev, "%s server went away\n", __func__); - return -EIO; + break; } set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&devdata->priv_lock, flags); @@ -533,7 +532,7 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) return -ENOMEM; count = i; - /* Ensure we can alloc 2/3rd of the requeested number of buffers. + /* Ensure we can alloc 2/3rd of the requested number of buffers. * 2/3 is an arbitrary choice; used also in ndis init.c */ if (count < ((2 * devdata->num_rcv_bufs) / 3)) { @@ -562,7 +561,7 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) * * Sends enable to IOVM, inits, and posts receive buffers to IOVM * timeout is defined in msecs (timeout of 0 specifies infinite wait) - * Return 0 for success, negavite for failure. + * Return 0 for success, negative for failure. */ static int visornic_enable_with_timeout(struct net_device *netdev, const int timeout) @@ -572,6 +571,8 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) unsigned long flags; int wait = 0; + napi_enable(&devdata->napi); + /* NOTE: the other end automatically unposts the rcv buffers when it * gets a disable. */ @@ -595,7 +596,6 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) /* send enable and wait for ack -- don't hold lock when sending enable * because if the queue is full, insert might sleep. */ - napi_enable(&devdata->napi); send_enbdis(netdev, 1, devdata); spin_lock_irqsave(&devdata->priv_lock, flags); @@ -604,10 +604,9 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) if (devdata->enab_dis_acked) break; if (devdata->server_down || devdata->server_change_state) { - spin_unlock_irqrestore(&devdata->priv_lock, flags); dev_dbg(&netdev->dev, "%s server went away\n", __func__); - return -EIO; + break; } set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&devdata->priv_lock, flags); @@ -751,7 +750,7 @@ static inline bool vnic_hit_low_watermark(struct visornic_devdata *devdata, * @skb: Packet to be sent * @netdev: net device the packet is being sent from * - * Convert the skb to a cmdrsp so the IO Partition can undersand it. + * Convert the skb to a cmdrsp so the IO Partition can understand it. * Send the XMIT command to the IO Partition for processing. This * function is protected from concurrent calls by a spinlock xmit_lock * in the net_device struct, but as soon as the function returns it @@ -1098,7 +1097,7 @@ repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, * * Got a receive packet back from the IO Part, handle it and send * it up the stack. - * Returns 1 iff an skb was receieved, otherwise 0 + * Returns 1 iff an skb was received, otherwise 0 */ static int visornic_rx(struct uiscmdrsp *cmdrsp) @@ -1228,7 +1227,7 @@ visornic_rx(struct uiscmdrsp *cmdrsp) } } - /* set up packet's protocl type using ethernet header - this + /* set up packet's protocol type using ethernet header - this * sets up skb->pkt_type & it also PULLS out the eth header */ skb->protocol = eth_type_trans(skb, netdev); @@ -1550,7 +1549,7 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) * @cmdrsp: io channel command response message * @devdata: visornic device to drain * - * Drain the respones queue of any responses from the IO partition. + * Drain the response queue of any responses from the IO partition. * Process the responses as we get them. * Returns when response queue is empty or when the thread stops. */ @@ -1666,7 +1665,7 @@ static int visornic_poll(struct napi_struct *napi, int budget) * poll_for_irq - Checks the status of the response queue. * @v: void pointer to the visronic devdata * - * Main function of the vnic_incoming thread. Peridocially check the + * Main function of the vnic_incoming thread. Periodically check the * response queue and drain it if needed. * Returns when thread has stopped. */ @@ -1712,7 +1711,7 @@ static int visornic_probe(struct visor_device *dev) netdev->watchdog_timeo = 5 * HZ; SET_NETDEV_DEV(netdev, &dev->device); - /* Get MAC adddress from channel and read it into the device. */ + /* Get MAC address from channel and read it into the device. */ netdev->addr_len = ETH_ALEN; channel_offset = offsetof(struct spar_io_channel_protocol, vnic.macaddr); @@ -1803,7 +1802,7 @@ static int visornic_probe(struct visor_device *dev) /* TODO: Setup Interrupt information */ /* Let's start our threads to get responses */ - netif_napi_add(netdev, &devdata->napi, visornic_poll, 64); + netif_napi_add(netdev, &devdata->napi, visornic_poll, NAPI_WEIGHT); setup_timer(&devdata->irq_poll_timer, poll_for_irq, (unsigned long)devdata); @@ -1833,10 +1832,7 @@ static int visornic_probe(struct visor_device *dev) goto cleanup_napi_add; } - /* Let's start our threads to get responses */ - netif_napi_add(netdev, &devdata->napi, visornic_poll, NAPI_WEIGHT); - - /* Note: Interupts have to be enable before the while + /* Note: Interrupts have to be enable before the while * loop below because the napi routine is responsible for * setting enab_dis_acked */ @@ -1849,7 +1845,7 @@ static int visornic_probe(struct visor_device *dev) goto cleanup_napi_add; } - /* create debgug/sysfs directories */ + /* create debug/sysfs directories */ devdata->eth_debugfs_dir = debugfs_create_dir(netdev->name, visornic_debugfs_dir); if (!devdata->eth_debugfs_dir) { @@ -2017,8 +2013,6 @@ static int visornic_resume(struct visor_device *dev, */ mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); - init_rcv_bufs(netdev, devdata); - rtnl_lock(); dev_open(netdev); rtnl_unlock(); diff --git a/drivers/staging/vc04_services/interface/vchi/connections/connection.h b/drivers/staging/vc04_services/interface/vchi/connections/connection.h index fef6ac34c6d2..e793cdf2847c 100644 --- a/drivers/staging/vc04_services/interface/vchi/connections/connection.h +++ b/drivers/staging/vc04_services/interface/vchi/connections/connection.h @@ -217,8 +217,7 @@ typedef void (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_hand System driver struct *****************************************************************************/ -struct opaque_vchi_connection_api_t -{ +struct opaque_vchi_connection_api_t { // Routine to init the connection VCHI_CONNECTION_INIT_T init; diff --git a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h index 8b3f76735bd4..a7740a425388 100644 --- a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h +++ b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h @@ -53,14 +53,12 @@ typedef enum message_event_type { MESSAGE_EVENT_MSG_DISCARDED } MESSAGE_EVENT_TYPE_T; -typedef enum vchi_msg_flags -{ +typedef enum vchi_msg_flags { VCHI_MSG_FLAGS_NONE = 0x0, VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1 } VCHI_MSG_FLAGS_T; -typedef enum message_tx_channel -{ +typedef enum message_tx_channel { MESSAGE_TX_CHANNEL_MESSAGE = 0, MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards } MESSAGE_TX_CHANNEL_T; @@ -69,8 +67,7 @@ typedef enum message_tx_channel #define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) #define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) -typedef enum message_rx_channel -{ +typedef enum message_rx_channel { MESSAGE_RX_CHANNEL_MESSAGE = 0, MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards } MESSAGE_RX_CHANNEL_T; diff --git a/drivers/staging/vc04_services/interface/vchi/vchi.h b/drivers/staging/vc04_services/interface/vchi/vchi.h index d6937288210c..addb7b00b688 100644 --- a/drivers/staging/vc04_services/interface/vchi/vchi.h +++ b/drivers/staging/vc04_services/interface/vchi/vchi.h @@ -61,8 +61,7 @@ struct vchi_version { #define VCHI_VERSION(v_) { v_, v_ } #define VCHI_VERSION_EX(v_, m_) { v_, m_ } -typedef enum -{ +typedef enum { VCHI_VEC_POINTER, VCHI_VEC_HANDLE, VCHI_VEC_LIST @@ -71,26 +70,22 @@ typedef enum typedef struct vchi_msg_vector_ex { VCHI_MSG_VECTOR_TYPE_T type; - union - { + union { // a memory handle - struct - { + struct { VCHI_MEM_HANDLE_T handle; uint32_t offset; int32_t vec_len; } handle; // an ordinary data pointer - struct - { + struct { const void *vec_base; int32_t vec_len; } ptr; // a nested vector list - struct - { + struct { struct vchi_msg_vector_ex *vec; uint32_t vec_len; } list; @@ -114,8 +109,7 @@ struct opaque_vchi_service_t; // Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold, // vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only. -typedef struct -{ +typedef struct { struct opaque_vchi_service_t *service; void *message; } VCHI_HELD_MSG_T; @@ -225,13 +219,17 @@ extern int32_t vchi_service_set_option( const VCHI_SERVICE_HANDLE_T handle, VCHI_SERVICE_OPTION_T option, int value); -// Routine to send a message across a service -extern int32_t - vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, - ssize_t (*copy_callback)(void *context, void *dest, - size_t offset, size_t maxsize), - void *context, - uint32_t data_size); +/* Routine to send a message from kernel memory across a service */ +extern int +vchi_queue_kernel_message(VCHI_SERVICE_HANDLE_T handle, + void *data, + unsigned int size); + +/* Routine to send a message from user memory across a service */ +extern int +vchi_queue_user_message(VCHI_SERVICE_HANDLE_T handle, + void __user *data, + unsigned int size); // Routine to receive a msg from a service // Dequeue is equivalent to hold, copy into client buffer, release diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_common.h b/drivers/staging/vc04_services/interface/vchi/vchi_common.h index d535a72970d3..45c2070d46b0 100644 --- a/drivers/staging/vc04_services/interface/vchi/vchi_common.h +++ b/drivers/staging/vc04_services/interface/vchi/vchi_common.h @@ -36,8 +36,7 @@ //flags used when sending messages (must be bitmapped) -typedef enum -{ +typedef enum { VCHI_FLAGS_NONE = 0x0, VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE = 0x1, // waits for message to be received, or sent (NB. not the same as being seen on other side) VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE = 0x2, // run a callback when message sent @@ -62,8 +61,7 @@ typedef enum { } VCHI_CRC_CONTROL_T; //callback reasons when an event occurs on a service -typedef enum -{ +typedef enum { VCHI_CALLBACK_REASON_MIN, //This indicates that there is data available @@ -111,8 +109,7 @@ typedef enum } VCHI_CALLBACK_REASON_T; // service control options -typedef enum -{ +typedef enum { VCHI_SERVICE_OPTION_MIN, VCHI_SERVICE_OPTION_TRACE, @@ -123,9 +120,9 @@ typedef enum //Callback used by all services / bulk transfers -typedef void (*VCHI_CALLBACK_T)( void *callback_param, //my service local param - VCHI_CALLBACK_REASON_T reason, - void *handle ); //for transmitting msg's only +typedef void (*VCHI_CALLBACK_T)(void *callback_param, //my service local param + VCHI_CALLBACK_REASON_T reason, + void *handle); //for transmitting msg's only diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h deleted file mode 100644 index 7ea5c64d5343..000000000000 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) 2010-2012 Broadcom. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the above-listed copyright holders may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2, as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef VCHIQ_2835_H -#define VCHIQ_2835_H - -#include "vchiq_pagelist.h" - -#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0 -#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1 - -#endif /* VCHIQ_2835_H */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 2b500d85cebc..e6241fb5cfa6 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -48,18 +48,21 @@ #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) #include "vchiq_arm.h" -#include "vchiq_2835.h" #include "vchiq_connected.h" #include "vchiq_killable.h" +#include "vchiq_pagelist.h" #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) +#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0 +#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1 + #define BELL0 0x00 #define BELL2 0x08 typedef struct vchiq_2835_state_struct { - int inited; - VCHIQ_ARM_STATE_T arm_state; + int inited; + VCHIQ_ARM_STATE_T arm_state; } VCHIQ_2835_ARM_STATE_T; struct vchiq_pagelist_info { @@ -192,31 +195,31 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) vchiq_call_connected_callbacks(); - return 0; + return 0; } VCHIQ_STATUS_T vchiq_platform_init_state(VCHIQ_STATE_T *state) { - VCHIQ_STATUS_T status = VCHIQ_SUCCESS; - state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL); - ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 1; - status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state); - if(status != VCHIQ_SUCCESS) - { - ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 0; - } - return status; + VCHIQ_STATUS_T status = VCHIQ_SUCCESS; + state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL); + ((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited = 1; + status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->arm_state); + if (status != VCHIQ_SUCCESS) + { + ((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited = 0; + } + return status; } VCHIQ_ARM_STATE_T* vchiq_platform_get_arm_state(VCHIQ_STATE_T *state) { - if(!((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited) - { - BUG(); - } - return &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state; + if (!((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited) + { + BUG(); + } + return &((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->arm_state; } void @@ -292,13 +295,13 @@ vchiq_dump_platform_state(void *dump_context) VCHIQ_STATUS_T vchiq_platform_suspend(VCHIQ_STATE_T *state) { - return VCHIQ_ERROR; + return VCHIQ_ERROR; } VCHIQ_STATUS_T vchiq_platform_resume(VCHIQ_STATE_T *state) { - return VCHIQ_SUCCESS; + return VCHIQ_SUCCESS; } void @@ -312,15 +315,15 @@ vchiq_platform_resumed(VCHIQ_STATE_T *state) } int -vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state) +vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state) { - return 1; // autosuspend not supported - videocore always wanted + return 1; // autosuspend not supported - videocore always wanted } int vchiq_platform_use_suspend_timer(void) { - return 0; + return 0; } void vchiq_dump_platform_use_state(VCHIQ_STATE_T *state) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 0d987898b4f8..1dc8627e65b0 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -64,10 +64,10 @@ #define VCHIQ_MINOR 0 /* Some per-instance constants */ -#define MAX_COMPLETIONS 16 +#define MAX_COMPLETIONS 128 #define MAX_SERVICES 64 #define MAX_ELEMENTS 8 -#define MSG_QUEUE_SIZE 64 +#define MSG_QUEUE_SIZE 128 #define KEEPALIVE_VER 1 #define KEEPALIVE_VER_MIN KEEPALIVE_VER @@ -194,7 +194,7 @@ vchiq_static_assert(ARRAY_SIZE(ioctl_names) == (VCHIQ_IOC_MAX + 1)); static void -dump_phys_mem(void *virt_addr, uint32_t num_bytes); +dump_phys_mem(void *virt_addr, u32 num_bytes); /**************************************************************************** * @@ -208,10 +208,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, void *bulk_userdata) { VCHIQ_COMPLETION_DATA_T *completion; + int insert; DEBUG_INITIALISE(g_state.local) - while (instance->completion_insert == - (instance->completion_remove + MAX_COMPLETIONS)) { + insert = instance->completion_insert; + while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) { /* Out of space - wait for the client */ DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_log_trace(vchiq_arm_log_level, @@ -224,14 +225,12 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, } else if (instance->closing) { vchiq_log_info(vchiq_arm_log_level, "service_callback closing"); - return VCHIQ_ERROR; + return VCHIQ_SUCCESS; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); } - completion = - &instance->completions[instance->completion_insert & - (MAX_COMPLETIONS - 1)]; + completion = &instance->completions[insert & (MAX_COMPLETIONS - 1)]; completion->header = header; completion->reason = reason; @@ -252,9 +251,10 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, wmb(); if (reason == VCHIQ_MESSAGE_AVAILABLE) - user_service->message_available_pos = - instance->completion_insert; - instance->completion_insert++; + user_service->message_available_pos = insert; + + insert++; + instance->completion_insert = insert; up(&instance->insert_event); @@ -279,6 +279,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, USER_SERVICE_T *user_service; VCHIQ_SERVICE_T *service; VCHIQ_INSTANCE_T instance; + bool skip_completion = false; DEBUG_INITIALISE(g_state.local) DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, user_service->msg_queue[user_service->msg_insert & (MSG_QUEUE_SIZE - 1)] = header; user_service->msg_insert++; - spin_unlock(&msg_queue_spinlock); - - up(&user_service->insert_event); /* If there is a thread waiting in DEQUEUE_MESSAGE, or if ** there is a MESSAGE_AVAILABLE in the completion queue then @@ -356,15 +354,20 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, if (((user_service->message_available_pos - instance->completion_remove) >= 0) || user_service->dequeue_pending) { - DEBUG_TRACE(SERVICE_CALLBACK_LINE); user_service->dequeue_pending = 0; - return VCHIQ_SUCCESS; + skip_completion = true; } + spin_unlock(&msg_queue_spinlock); + up(&user_service->insert_event); + header = NULL; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); + if (skip_completion) + return VCHIQ_SUCCESS; + return add_completion(instance, reason, header, user_service, bulk_userdata); } @@ -665,7 +668,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; /* close_pending is false on first entry, and when the - wait in vchiq_close_service has been interrupted. */ + wait in vchiq_close_service has been interrupted. */ if (!user_service->close_pending) { status = vchiq_close_service(service->handle); if (status != VCHIQ_SUCCESS) @@ -691,7 +694,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; /* close_pending is false on first entry, and when the - wait in vchiq_close_service has been interrupted. */ + wait in vchiq_close_service has been interrupted. */ if (!user_service->close_pending) { status = vchiq_remove_service(service->handle); if (status != VCHIQ_SUCCESS) @@ -892,24 +895,27 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } DEBUG_TRACE(AWAIT_COMPLETION_LINE); - /* A read memory barrier is needed to stop prefetch of a stale - ** completion record - */ - rmb(); - if (ret == 0) { int msgbufcount = args.msgbufcount; + int remove = instance->completion_remove; + for (ret = 0; ret < args.count; ret++) { VCHIQ_COMPLETION_DATA_T *completion; VCHIQ_SERVICE_T *service; USER_SERVICE_T *user_service; VCHIQ_HEADER_T *header; - if (instance->completion_remove == - instance->completion_insert) + + if (remove == instance->completion_insert) break; + completion = &instance->completions[ - instance->completion_remove & - (MAX_COMPLETIONS - 1)]; + remove & (MAX_COMPLETIONS - 1)]; + + /* + * A read memory barrier is needed to stop + * prefetch of a stale completion record + */ + rmb(); service = completion->service_userdata; user_service = service->base.userdata; @@ -984,7 +990,13 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } - instance->completion_remove++; + /* + * Ensure that the above copy has completed + * before advancing the remove pointer. + */ + mb(); + remove++; + instance->completion_remove = remove; } if (msgbufcount != args.msgbufcount) { @@ -1535,10 +1547,10 @@ vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service) ***************************************************************************/ static void -dump_phys_mem(void *virt_addr, uint32_t num_bytes) +dump_phys_mem(void *virt_addr, u32 num_bytes) { int rc; - uint8_t *end_virt_addr = virt_addr + num_bytes; + u8 *end_virt_addr = virt_addr + num_bytes; int num_pages; int offset; int end_offset; @@ -1546,7 +1558,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) int prev_idx; struct page *page; struct page **pages; - uint8_t *kmapped_virt_ptr; + u8 *kmapped_virt_ptr; /* Align virtAddr and endVirtAddr to 16 byte boundaries. */ @@ -1602,7 +1614,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) if (vchiq_arm_log_level >= VCHIQ_LOG_TRACE) vchiq_log_dump_mem("ph", - (uint32_t)(unsigned long)&kmapped_virt_ptr[ + (u32)(unsigned long)&kmapped_virt_ptr[ page_offset], &kmapped_virt_ptr[page_offset], 16); @@ -1996,7 +2008,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state) &arm_state->blocked_blocker, timeout_val) <= 0) { vchiq_log_error(vchiq_susp_log_level, "%s wait for " - "previously blocked clients failed" , __func__); + "previously blocked clients failed", __func__); status = VCHIQ_ERROR; write_lock_bh(&arm_state->susp_res_lock); goto out; @@ -2012,7 +2024,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state) if (resume_count > 1) { status = VCHIQ_ERROR; vchiq_log_error(vchiq_susp_log_level, "%s waited too " - "many times for resume" , __func__); + "many times for resume", __func__); goto out; } write_unlock_bh(&arm_state->susp_res_lock); @@ -2372,52 +2384,6 @@ out: return resume; } -void -vchiq_platform_check_resume(VCHIQ_STATE_T *state) -{ - VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); - int res = 0; - - if (!arm_state) - goto out; - - vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); - - write_lock_bh(&arm_state->susp_res_lock); - if (arm_state->wake_address == 0) { - vchiq_log_info(vchiq_susp_log_level, - "%s: already awake", __func__); - goto unlock; - } - if (arm_state->vc_resume_state == VC_RESUME_IN_PROGRESS) { - vchiq_log_info(vchiq_susp_log_level, - "%s: already resuming", __func__); - goto unlock; - } - - if (arm_state->vc_resume_state == VC_RESUME_REQUESTED) { - set_resume_state(arm_state, VC_RESUME_IN_PROGRESS); - res = 1; - } else - vchiq_log_trace(vchiq_susp_log_level, - "%s: not resuming (resume state %s)", __func__, - resume_state_names[arm_state->vc_resume_state + - VC_RESUME_NUM_OFFSET]); - -unlock: - write_unlock_bh(&arm_state->susp_res_lock); - - if (res) - vchiq_platform_resume(state); - -out: - vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__); - return; - -} - - - VCHIQ_STATUS_T vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, enum USE_TYPE_E use_type) @@ -2870,10 +2836,10 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) { write_lock_bh(&arm_state->susp_res_lock); if (!arm_state->first_connect) { - char threadname[10]; + char threadname[16]; arm_state->first_connect = 1; write_unlock_bh(&arm_state->susp_res_lock); - snprintf(threadname, sizeof(threadname), "VCHIQka-%d", + snprintf(threadname, sizeof(threadname), "vchiq-keep/%d", state->id); arm_state->ka_thread = kthread_create( &vchiq_keepalive_thread_func, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 9740e1afbc9d..bfbd81d9db33 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -154,7 +154,7 @@ vchiq_check_resume(VCHIQ_STATE_T *state); extern void vchiq_check_suspend(VCHIQ_STATE_T *state); - VCHIQ_STATUS_T +VCHIQ_STATUS_T vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); extern VCHIQ_STATUS_T diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 028e90bc1cdc..d587097b261c 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -90,7 +90,7 @@ static atomic_t pause_bulks_count = ATOMIC_INIT(0); static DEFINE_SPINLOCK(service_spinlock); DEFINE_SPINLOCK(bulk_waiter_spinlock); -DEFINE_SPINLOCK(quota_spinlock); +static DEFINE_SPINLOCK(quota_spinlock); VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES]; static unsigned int handle_seq; @@ -517,7 +517,7 @@ get_connected_service(VCHIQ_STATE_T *state, unsigned int port) inline void request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type) { - uint32_t value; + u32 value; if (service) { do { @@ -607,15 +607,17 @@ process_free_queue(VCHIQ_STATE_T *state) BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)]; int slot_queue_available; - /* Use a read memory barrier to ensure that any state that may have - ** been modified by another thread is not masked by stale prefetched - ** values. */ - rmb(); - /* Find slots which have been freed by the other side, and return them ** to the available queue. */ slot_queue_available = state->slot_queue_available; + /* + * Use a memory barrier to ensure that any state that may have been + * modified by another thread is not masked by stale prefetched + * values. + */ + mb(); + while (slot_queue_available != local->slot_queue_recycle) { unsigned int pos; int slot_index = local->slot_queue[slot_queue_available++ & @@ -623,6 +625,12 @@ process_free_queue(VCHIQ_STATE_T *state) char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index); int data_found = 0; + /* + * Beware of the address dependency - data is calculated + * using an index written by the other side. + */ + rmb(); + vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%pK %x %x", state->id, slot_index, data, local->slot_queue_recycle, slot_queue_available); @@ -721,6 +729,12 @@ process_free_queue(VCHIQ_STATE_T *state) up(&state->data_quota_event); } + /* + * Don't allow the slot to be reused until we are no + * longer interested in it. + */ + mb(); + state->slot_queue_available = slot_queue_available; up(&state->slot_available_event); } @@ -920,7 +934,7 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, VCHIQ_LOG_INFO)) vchiq_log_dump_mem("Sent", 0, header->data, - min((size_t)64, + min((size_t)16, (size_t)callback_result)); spin_lock("a_spinlock); @@ -1073,7 +1087,7 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, VCHIQ_LOG_INFO)) vchiq_log_dump_mem("Sent", 0, header->data, - min((size_t)64, + min((size_t)16, (size_t)callback_result)); VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); @@ -1286,14 +1300,14 @@ poll_services(VCHIQ_STATE_T *state) int group, i; for (group = 0; group < BITSET_SIZE(state->unused_service); group++) { - uint32_t flags; + u32 flags; flags = atomic_xchg(&state->poll_services[group], 0); for (i = 0; flags; i++) { if (flags & (1 << i)) { VCHIQ_SERVICE_T *service = find_service_by_port(state, (group<<5) + i); - uint32_t service_flags; + u32 service_flags; flags &= ~(1 << i); if (!service) continue; @@ -1513,12 +1527,10 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) { VCHIQ_SERVICE_T *service = NULL; int msgid, size; - int type; unsigned int localport, remoteport; msgid = header->msgid; size = header->size; - type = VCHIQ_MSG_TYPE(msgid); localport = VCHIQ_MSG_DSTPORT(msgid); remoteport = VCHIQ_MSG_SRCPORT(msgid); if (size >= sizeof(struct vchiq_open_payload)) { @@ -1620,7 +1632,7 @@ fail_open: /* No available service, or an invalid request - send a CLOSE */ if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)), - NULL, 0, 0, 0) == VCHIQ_RETRY) + NULL, NULL, 0, 0) == VCHIQ_RETRY) goto bail_not_ready; return 1; @@ -1736,7 +1748,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) remoteport, localport, size); if (size > 0) vchiq_log_dump_mem("Rcvd", 0, header->data, - min(64, size)); + min(16, size)); } if (((unsigned long)header & VCHIQ_SLOT_MASK) + @@ -1973,7 +1985,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) /* Send a PAUSE in response */ if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), - NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK) + NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK) == VCHIQ_RETRY) goto bail_not_ready; if (state->is_master) @@ -2072,7 +2084,7 @@ slot_handler_func(void *v) pause_bulks(state); if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), - NULL, 0, 0, + NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK) != VCHIQ_RETRY) { vchiq_set_conn_state(state, @@ -2092,7 +2104,7 @@ slot_handler_func(void *v) case VCHIQ_CONNSTATE_RESUMING: if (queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0), - NULL, 0, 0, QMFLAGS_NO_MUTEX_LOCK) + NULL, NULL, 0, QMFLAGS_NO_MUTEX_LOCK) != VCHIQ_RETRY) { if (state->is_master) resume_bulks(state); @@ -2193,7 +2205,7 @@ sync_func(void *v) remoteport, localport, size); if (size > 0) vchiq_log_dump_mem("Rcvd", 0, header->data, - min(64, size)); + min(16, size)); } switch (type) { @@ -2317,7 +2329,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, VCHIQ_SHARED_STATE_T *local; VCHIQ_SHARED_STATE_T *remote; VCHIQ_STATUS_T status; - char threadname[10]; + char threadname[16]; static int id; int i; @@ -2485,7 +2497,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, /* bring up slot handler thread */ - snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id); + snprintf(threadname, sizeof(threadname), "vchiq-slot/%d", state->id); state->slot_handler_thread = kthread_create(&slot_handler_func, (void *)state, threadname); @@ -2499,7 +2511,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, set_user_nice(state->slot_handler_thread, -19); wake_up_process(state->slot_handler_thread); - snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id); + snprintf(threadname, sizeof(threadname), "vchiq-recy/%d", state->id); state->recycle_thread = kthread_create(&recycle_func, (void *)state, threadname); @@ -2512,7 +2524,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, set_user_nice(state->recycle_thread, -19); wake_up_process(state->recycle_thread); - snprintf(threadname, sizeof(threadname), "VCHIQs-%d", state->id); + snprintf(threadname, sizeof(threadname), "vchiq-sync/%d", state->id); state->sync_thread = kthread_create(&sync_func, (void *)state, threadname); @@ -2904,7 +2916,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd) (VCHIQ_MSG_CLOSE, service->localport, VCHIQ_MSG_DSTPORT(service->remoteport)), - NULL, 0, 0, 0); + NULL, NULL, 0, 0); } break; @@ -2926,7 +2938,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd) (VCHIQ_MSG_CLOSE, service->localport, VCHIQ_MSG_DSTPORT(service->remoteport)), - NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK); + NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK); if (status == VCHIQ_SUCCESS) { if (!close_recvd) { @@ -3056,7 +3068,7 @@ vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance) if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) { if (queue_message(state, NULL, - VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0, + VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, NULL, 0, QMFLAGS_IS_BLOCKING) == VCHIQ_RETRY) return VCHIQ_RETRY; @@ -3509,20 +3521,20 @@ release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) VCHIQ_STATUS_T vchiq_get_peer_version(VCHIQ_SERVICE_HANDLE_T handle, short *peer_version) { - VCHIQ_STATUS_T status = VCHIQ_ERROR; - VCHIQ_SERVICE_T *service = find_service_by_handle(handle); + VCHIQ_STATUS_T status = VCHIQ_ERROR; + VCHIQ_SERVICE_T *service = find_service_by_handle(handle); - if (!service || - (vchiq_check_service(service) != VCHIQ_SUCCESS) || - !peer_version) - goto exit; - *peer_version = service->peer_version; - status = VCHIQ_SUCCESS; + if (!service || + (vchiq_check_service(service) != VCHIQ_SUCCESS) || + !peer_version) + goto exit; + *peer_version = service->peer_version; + status = VCHIQ_SUCCESS; exit: - if (service) - unlock_service(service); - return status; + if (service) + unlock_service(service); + return status; } VCHIQ_STATUS_T @@ -3626,7 +3638,7 @@ vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle, return status; } -void +static void vchiq_dump_shared_state(void *dump_context, VCHIQ_STATE_T *state, VCHIQ_SHARED_STATE_T *shared, const char *label) { @@ -3816,7 +3828,7 @@ vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service) service->stats.bulk_stalls, service->stats.bulk_aborted_count, service->stats.error_count); - } + } } vchiq_dump(dump_context, buf, len + 1); @@ -3857,7 +3869,7 @@ VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T *state) if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0), - NULL, 0, 0, 0); + NULL, NULL, 0, 0); return status; } @@ -3867,7 +3879,7 @@ VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T *state) if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0), - NULL, 0, 0, 0); + NULL, NULL, 0, 0); return status; } @@ -3877,14 +3889,14 @@ VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T *state) if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0), - NULL, 0, 0, 0); + NULL, NULL, 0, 0); return status; } -void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *void_mem, +void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_t num_bytes) { - const uint8_t *mem = (const uint8_t *)void_mem; + const u8 *mem = (const u8 *)void_mem; size_t offset; char line_buf[100]; char *s; @@ -3901,7 +3913,7 @@ void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *void_mem, for (offset = 0; offset < 16; offset++) { if (offset < num_bytes) { - uint8_t ch = mem[offset]; + u8 ch = mem[offset]; if ((ch < ' ') || (ch > '~')) ch = '.'; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h index 4d6a3788e9c5..1d95e3d70621 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h @@ -36,8 +36,7 @@ #include "vchiq_core.h" -typedef struct vchiq_debugfs_node_struct -{ +typedef struct vchiq_debugfs_node_struct { struct dentry *dentry; } VCHIQ_DEBUGFS_NODE_T; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c index e93922a87263..4317c06943a6 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c @@ -75,23 +75,23 @@ VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out) VCHIQ_STATUS_T status = VCHIQ_ERROR; VCHIQ_STATE_T *state; VCHIQ_INSTANCE_T instance = NULL; - int i; + int i; vchiq_log_trace(vchiq_core_log_level, "%s called", __func__); - /* VideoCore may not be ready due to boot up timing. - It may never be ready if kernel and firmware are mismatched, so don't block forever. */ - for (i=0; i<VCHIQ_INIT_RETRIES; i++) { + /* VideoCore may not be ready due to boot up timing. + It may never be ready if kernel and firmware are mismatched, so don't block forever. */ + for (i = 0; i < VCHIQ_INIT_RETRIES; i++) { state = vchiq_get_state(); if (state) break; udelay(500); } - if (i==VCHIQ_INIT_RETRIES) { + if (i == VCHIQ_INIT_RETRIES) { vchiq_log_error(vchiq_core_log_level, "%s: videocore not initialized\n", __func__); goto failed; - } else if (i>0) { + } else if (i > 0) { vchiq_log_warning(vchiq_core_log_level, "%s: videocore initialized after %d retries\n", __func__, i); } @@ -172,7 +172,7 @@ EXPORT_SYMBOL(vchiq_shutdown); * ***************************************************************************/ -int vchiq_is_connected(VCHIQ_INSTANCE_T instance) +static int vchiq_is_connected(VCHIQ_INSTANCE_T instance) { return instance->connected; } diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c index d9771394a041..48984abc3854 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c @@ -39,8 +39,6 @@ #include "vchiq_util.h" -#include <stddef.h> - #define vchiq_status_to_vchi(status) ((int32_t)status) typedef struct { @@ -158,6 +156,7 @@ EXPORT_SYMBOL(vchi_msg_remove); * Returns: int32_t - success == 0 * ***********************************************************/ +static int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, ssize_t (*copy_callback)(void *context, void *dest, size_t offset, size_t maxsize), @@ -186,7 +185,62 @@ int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, return vchiq_status_to_vchi(status); } -EXPORT_SYMBOL(vchi_msg_queue); + +static ssize_t +vchi_queue_kernel_message_callback(void *context, + void *dest, + size_t offset, + size_t maxsize) +{ + memcpy(dest, context + offset, maxsize); + return maxsize; +} + +int +vchi_queue_kernel_message(VCHI_SERVICE_HANDLE_T handle, + void *data, + unsigned int size) +{ + return vchi_msg_queue(handle, + vchi_queue_kernel_message_callback, + data, + size); +} +EXPORT_SYMBOL(vchi_queue_kernel_message); + +struct vchi_queue_user_message_context { + void __user *data; +}; + +static ssize_t +vchi_queue_user_message_callback(void *context, + void *dest, + size_t offset, + size_t maxsize) +{ + struct vchi_queue_user_message_context *copycontext = context; + + if (copy_from_user(dest, copycontext->data + offset, maxsize)) + return -EFAULT; + + return maxsize; +} + +int +vchi_queue_user_message(VCHI_SERVICE_HANDLE_T handle, + void __user *data, + unsigned int size) +{ + struct vchi_queue_user_message_context copycontext = { + .data = data + }; + + return vchi_msg_queue(handle, + vchi_queue_user_message_callback, + ©context, + size); +} +EXPORT_SYMBOL(vchi_queue_user_message); /*********************************************************** * Name: vchi_bulk_queue_receive @@ -527,7 +581,7 @@ static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason, SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle); - if (!service->callback) + if (!service->callback) goto release; switch (reason) { @@ -577,7 +631,7 @@ static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason, } release: - vchiq_release_message(service->handle, header); + vchiq_release_message(service->handle, header); done: return VCHIQ_SUCCESS; } @@ -739,16 +793,18 @@ int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle, } EXPORT_SYMBOL(vchi_service_set_option); -int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version ) +int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_version) { - int32_t ret = -1; - SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle; - if(service) - { - VCHIQ_STATUS_T status = vchiq_get_peer_version(service->handle, peer_version); - ret = vchiq_status_to_vchi( status ); - } - return ret; + int32_t ret = -1; + SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle; + if (service) + { + VCHIQ_STATUS_T status; + + status = vchiq_get_peer_version(service->handle, peer_version); + ret = vchiq_status_to_vchi(status); + } + return ret; } EXPORT_SYMBOL(vchi_get_peer_version); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c index f76f4d790532..e0ba0ed704fd 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c @@ -80,9 +80,8 @@ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) return; while (queue->write == queue->read + queue->size) { - if (down_interruptible(&queue->pop) != 0) { + if (down_interruptible(&queue->pop) != 0) flush_signals(current); - } } /* @@ -107,9 +106,8 @@ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue) { while (queue->write == queue->read) { - if (down_interruptible(&queue->push) != 0) { + if (down_interruptible(&queue->push) != 0) flush_signals(current); - } } up(&queue->push); // We haven't removed anything from the queue. @@ -128,9 +126,8 @@ VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue) VCHIQ_HEADER_T *header; while (queue->write == queue->read) { - if (down_interruptible(&queue->push) != 0) { + if (down_interruptible(&queue->push) != 0) flush_signals(current); - } } /* diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 87aa5174df22..69e9a7705afb 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -47,7 +47,8 @@ static const char driver_name[] = "vme_user"; static int bus[VME_USER_BUS_MAX]; static unsigned int bus_num; -/* Currently Documentation/admin-guide/devices.rst defines the following for VME: +/* Currently Documentation/admin-guide/devices.rst defines the + * following for VME: * * 221 char VME bus * 0 = /dev/bus/vme/m0 First master image diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 8a567c9155b4..c351e03f6ad2 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -75,13 +75,13 @@ void BBvSetShortSlotTime(struct vnt_private *); void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); /* VT3253 Baseband */ -bool BBbVT3253Init(struct vnt_private *); -void BBvSoftwareReset(struct vnt_private *); -void BBvPowerSaveModeON(struct vnt_private *); -void BBvPowerSaveModeOFF(struct vnt_private *); -void BBvSetTxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); -void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); -void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID); -void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID); +bool BBbVT3253Init(struct vnt_private *priv); +void BBvSoftwareReset(struct vnt_private *priv); +void BBvPowerSaveModeON(struct vnt_private *priv); +void BBvPowerSaveModeOFF(struct vnt_private *priv); +void BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode); +void BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode); +void BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID); +void BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID); #endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index c2cde7e92c8f..7f08cda27e2c 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -35,21 +35,23 @@ struct vnt_private; -void vnt_set_channel(struct vnt_private *, u32); -void vnt_set_rspinf(struct vnt_private *, u8); -void vnt_update_ifs(struct vnt_private *); -void vnt_update_top_rates(struct vnt_private *); -int vnt_ofdm_min_rate(struct vnt_private *); -void vnt_adjust_tsf(struct vnt_private *, u8, u64, u64); -bool vnt_get_current_tsf(struct vnt_private *, u64 *); -bool vnt_clear_current_tsf(struct vnt_private *); -void vnt_reset_next_tbtt(struct vnt_private *, u16); -void vnt_update_next_tbtt(struct vnt_private *, u64, u16); -u64 vnt_get_next_tbtt(u64, u16); -u64 vnt_get_tsf_offset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2); -int vnt_radio_power_off(struct vnt_private *); -int vnt_radio_power_on(struct vnt_private *); -u8 vnt_get_pkt_type(struct vnt_private *); -void vnt_set_bss_mode(struct vnt_private *); +void vnt_set_channel(struct vnt_private *priv, u32 connection_channel); +void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type); +void vnt_update_ifs(struct vnt_private *priv); +void vnt_update_top_rates(struct vnt_private *priv); +int vnt_ofdm_min_rate(struct vnt_private *priv); +void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, + u64 time_stamp, u64 local_tsf); +bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf); +bool vnt_clear_current_tsf(struct vnt_private *priv); +void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval); +void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, + u16 beacon_interval); +u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval); +u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2); +int vnt_radio_power_off(struct vnt_private *priv); +int vnt_radio_power_on(struct vnt_private *priv); +u8 vnt_get_pkt_type(struct vnt_private *priv); +void vnt_set_bss_mode(struct vnt_private *priv); #endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index fcea6995fe26..62f18a959098 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -28,6 +28,6 @@ #include "device.h" -void vnt_init_bands(struct vnt_private *); +void vnt_init_bands(struct vnt_private *priv); #endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index ff1850c4a927..5d0454f3af0e 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -28,7 +28,7 @@ #include "device.h" -int vnt_rx_data(struct vnt_private *, struct vnt_rcb *, +int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb, unsigned long bytes_received); #endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 1b48f9c86f63..282f665aacfa 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -64,11 +64,11 @@ int vnt_download_firmware(struct vnt_private *priv) memcpy(buffer, fw->data + ii, length); status = vnt_control_out(priv, - 0, - 0x1200+ii, - 0x0000, - length, - buffer); + 0, + 0x1200+ii, + 0x0000, + length, + buffer); dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size); @@ -94,11 +94,11 @@ int vnt_firmware_branch_to_sram(struct vnt_private *priv) dev_dbg(&priv->usb->dev, "---->Branch to Sram\n"); status = vnt_control_out(priv, - 1, - 0x1200, - 0x0000, - 0, - NULL); + 1, + 0x1200, + 0x0000, + 0, + NULL); return status == STATUS_SUCCESS; } @@ -107,14 +107,14 @@ int vnt_check_firmware_version(struct vnt_private *priv) int status; status = vnt_control_in(priv, - MESSAGE_TYPE_READ, - 0, - MESSAGE_REQUEST_VERSION, - 2, - (u8 *)&priv->firmware_version); + MESSAGE_TYPE_READ, + 0, + MESSAGE_REQUEST_VERSION, + 2, + (u8 *)&priv->firmware_version); dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", - priv->firmware_version); + priv->firmware_version); if (status != STATUS_SUCCESS) { dev_dbg(&priv->usb->dev, "Firmware Invalid.\n"); @@ -126,7 +126,7 @@ int vnt_check_firmware_version(struct vnt_private *priv) } dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", - priv->firmware_version); + priv->firmware_version); if (priv->firmware_version < FIRMWARE_VERSION) { /* branch to loader for download new firmware */ diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index e2b54acb8fdb..f753019c94c9 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -28,8 +28,8 @@ #include "device.h" -int vnt_download_firmware(struct vnt_private *); -int vnt_firmware_branch_to_sram(struct vnt_private *); -int vnt_check_firmware_version(struct vnt_private *); +int vnt_download_firmware(struct vnt_private *priv); +int vnt_firmware_branch_to_sram(struct vnt_private *priv); +int vnt_check_firmware_version(struct vnt_private *priv); #endif /* __FIRMWARE_H__ */ diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 73538fb4e4e2..c6ffbe0e2728 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -142,7 +142,7 @@ void vnt_int_process_data(struct vnt_private *priv) if (int_data->isr0 != 0) { if (int_data->isr0 & ISR_BNTX && - priv->op_mode == NL80211_IFTYPE_AP) + priv->op_mode == NL80211_IFTYPE_AP) vnt_schedule_command(priv, WLAN_CMD_BECON_SEND); if (int_data->isr0 & ISR_TBTT && diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 97e55bacbb7c..b5f1b4b02ce4 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -51,7 +51,7 @@ struct vnt_interrupt_data { u8 sw[2]; } __packed; -void vnt_int_start_interrupt(struct vnt_private *); -void vnt_int_process_data(struct vnt_private *); +void vnt_int_start_interrupt(struct vnt_private *priv); +void vnt_int_process_data(struct vnt_private *priv); #endif /* __INT_H__ */ diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 0246a8fc47fe..cc18cb141bff 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -44,8 +44,8 @@ int vnt_key_init_table(struct vnt_private *priv) } static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, - struct ieee80211_key_conf *key, u32 key_type, u32 mode, - bool onfly_latch) + struct ieee80211_key_conf *key, u32 key_type, + u32 mode, bool onfly_latch) { struct vnt_private *priv = hw->priv; u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -115,7 +115,7 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, } int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key) + struct ieee80211_vif *vif, struct ieee80211_key_conf *key) { struct ieee80211_bss_conf *conf = &vif->bss_conf; struct vnt_private *priv = hw->priv; @@ -138,7 +138,7 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, vnt_mac_disable_keyentry(priv, u); vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, - KEY_CTL_WEP, true); + KEY_CTL_WEP, true); key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -161,13 +161,13 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE, - key_dec_mode, true); + key_dec_mode, true); } else { vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, - key_dec_mode, true); + key_dec_mode, true); vnt_set_keymode(hw, (u8 *)conf->bssid, key, - VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); + VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); } return 0; diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 7861faf5138f..906d3454591d 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -43,9 +43,9 @@ #define VNT_KEY_ONFLY 0x8000 #define VNT_KEY_ONFLY_ALL 0x4000 -int vnt_key_init_table(struct vnt_private *); +int vnt_key_init_table(struct vnt_private *priv); int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key); + struct ieee80211_vif *vif, struct ieee80211_key_conf *key); #endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 611da4929ddc..417fdad1f9ae 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -50,7 +50,7 @@ void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter) __le64 le_mc = cpu_to_le64(mc_filter); vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0, - MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc); + MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc); } /* @@ -77,7 +77,7 @@ void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) data[1] = EnCFG_BBType_MASK; vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } /* @@ -97,7 +97,7 @@ void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) { vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0, - sizeof(entry_idx), &entry_idx); + sizeof(entry_idx), &entry_idx); } /* @@ -115,7 +115,7 @@ void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) * */ void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, - u32 key_idx, u8 *addr, u8 *key) + u32 key_idx, u8 *addr, u8 *key) { struct vnt_mac_set_key set_key; u16 offset; @@ -132,10 +132,11 @@ void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP); dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n", - offset, key_ctl, (u8 *)&set_key); + offset, key_ctl, (u8 *)&set_key); vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset, - (u16)key_idx, sizeof(struct vnt_mac_set_key), (u8 *)&set_key); + (u16)key_idx, sizeof(struct vnt_mac_set_key), + (u8 *)&set_key); } void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits) @@ -146,7 +147,8 @@ void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits) data[1] = bits; vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), + data); } void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits) @@ -156,8 +158,8 @@ void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits) data[0] = bits; data[1] = bits; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) @@ -167,14 +169,14 @@ void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) data[0] = (u8)(word & 0xff); data[1] = (u8)(word >> 8); - vnt_control_out(priv, MESSAGE_TYPE_WRITE, - reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr) { vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0, - MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); + MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); } void vnt_mac_enable_protect_mode(struct vnt_private *priv) @@ -184,8 +186,8 @@ void vnt_mac_enable_protect_mode(struct vnt_private *priv) data[0] = EnCFG_ProtectMd; data[1] = EnCFG_ProtectMd; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_disable_protect_mode(struct vnt_private *priv) @@ -195,8 +197,8 @@ void vnt_mac_disable_protect_mode(struct vnt_private *priv) data[0] = 0; data[1] = EnCFG_ProtectMd; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) @@ -206,8 +208,8 @@ void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) data[0] = EnCFG_BarkerPream; data[1] = EnCFG_BarkerPream; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) @@ -217,8 +219,8 @@ void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) data[0] = 0; data[1] = EnCFG_BarkerPream; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, - MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) @@ -228,8 +230,8 @@ void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) data[0] = (u8)(interval & 0xff); data[1] = (u8)(interval >> 8); - vnt_control_out(priv, MESSAGE_TYPE_WRITE, - MAC_REG_BI, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } void vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led) diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 4c6e610f1bc1..29f37a0ff156 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -364,20 +364,21 @@ struct vnt_mac_set_key { u8 key[WLAN_KEY_LEN_CCMP]; } __packed; -void vnt_mac_set_filter(struct vnt_private *, u64); -void vnt_mac_shutdown(struct vnt_private *); -void vnt_mac_set_bb_type(struct vnt_private *, u8); -void vnt_mac_disable_keyentry(struct vnt_private *, u8); -void vnt_mac_set_keyentry(struct vnt_private *, u16, u32, u32, u8 *, u8 *); -void vnt_mac_reg_bits_off(struct vnt_private *, u8, u8); -void vnt_mac_reg_bits_on(struct vnt_private *, u8, u8); -void vnt_mac_write_word(struct vnt_private *, u8, u16); -void vnt_mac_set_bssid_addr(struct vnt_private *, u8 *); -void vnt_mac_enable_protect_mode(struct vnt_private *); -void vnt_mac_disable_protect_mode(struct vnt_private *); -void vnt_mac_enable_barker_preamble_mode(struct vnt_private *); -void vnt_mac_disable_barker_preamble_mode(struct vnt_private *); -void vnt_mac_set_beacon_interval(struct vnt_private *, u16); -void vnt_mac_set_led(struct vnt_private *priv, u8, u8); +void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter); +void vnt_mac_shutdown(struct vnt_private *priv); +void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type); +void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx); +void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, + u32 key_idx, u8 *addr, u8 *key); +void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits); +void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits); +void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word); +void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr); +void vnt_mac_enable_protect_mode(struct vnt_private *priv); +void vnt_mac_disable_protect_mode(struct vnt_private *priv); +void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv); +void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv); +void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval); +void vnt_mac_set_led(struct vnt_private *privpriv, u8 state, u8 led); #endif /* __MAC_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 50d02d9aa535..9e074e9daf4e 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -128,7 +128,7 @@ static int vnt_init_registers(struct vnt_private *priv) u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0; dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n", - DEVICE_INIT_COLD, priv->packet_type); + DEVICE_INIT_COLD, priv->packet_type); if (!vnt_check_firmware_version(priv)) { if (vnt_download_firmware(priv) == true) { @@ -156,16 +156,17 @@ static int vnt_init_registers(struct vnt_private *priv) init_cmd->long_retry_limit = priv->long_retry_limit; /* issue card_init command to device */ - status = vnt_control_out(priv, - MESSAGE_TYPE_CARDINIT, 0, 0, - sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd); + status = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0, + sizeof(struct vnt_cmd_card_init), + (u8 *)init_cmd); if (status != STATUS_SUCCESS) { dev_dbg(&priv->usb->dev, "Issue Card init fail\n"); return false; } status = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0, - sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp); + sizeof(struct vnt_rsp_card_init), + (u8 *)init_rsp); if (status != STATUS_SUCCESS) { dev_dbg(&priv->usb->dev, "Cardinit request in status fail!\n"); @@ -173,9 +174,8 @@ static int vnt_init_registers(struct vnt_private *priv) } /* local ID for AES functions */ - status = vnt_control_in(priv, MESSAGE_TYPE_READ, - MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1, - &priv->local_id); + status = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_LOCALID, + MESSAGE_REQUEST_MACREG, 1, &priv->local_id); if (status != STATUS_SUCCESS) return false; @@ -278,7 +278,6 @@ static int vnt_init_registers(struct vnt_private *priv) if (priv->rf_type == RF_VT3226D0) { if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) && (priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) { - calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ]; calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC]; calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ]; @@ -340,17 +339,18 @@ static int vnt_init_registers(struct vnt_private *priv) if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) { status = vnt_control_in(priv, MESSAGE_TYPE_READ, - MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &tmp); + MAC_REG_GPIOCTL1, + MESSAGE_REQUEST_MACREG, 1, &tmp); if (status != STATUS_SUCCESS) return false; if ((tmp & GPIO3_DATA) == 0) vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, - GPIO3_INTMD); + GPIO3_INTMD); else vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, - GPIO3_INTMD); + GPIO3_INTMD); } vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38); @@ -430,7 +430,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(struct vnt_usb_send_context), - GFP_KERNEL); + GFP_KERNEL); if (!tx_context) goto free_tx; @@ -450,7 +450,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL); if (!priv->rcb[ii]) { dev_err(&priv->usb->dev, - "failed to allocate rcb no %d\n", ii); + "failed to allocate rcb no %d\n", ii); goto free_rx_tx; } @@ -496,7 +496,8 @@ free_tx: } static void vnt_tx_80211(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, struct sk_buff *skb) + struct ieee80211_tx_control *control, + struct sk_buff *skb) { struct vnt_private *priv = hw->priv; @@ -610,7 +611,7 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) } static void vnt_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif) { struct vnt_private *priv = hw->priv; @@ -653,7 +654,7 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed) } if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || - (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { + (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { vnt_set_channel(priv, conf->chandef.chan->hw_value); if (conf->chandef.chan->band == NL80211_BAND_5GHZ) @@ -682,8 +683,8 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed) } static void vnt_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf, - u32 changed) + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf, u32 changed) { struct vnt_private *priv = hw->priv; @@ -692,7 +693,6 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID && conf->bssid) vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid); - if (changed & BSS_CHANGED_BASIC_RATES) { priv->basic_rates = conf->basic_rates; @@ -731,11 +731,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_TXPOWER) vnt_rf_setpower(priv, priv->current_rate, - conf->chandef.chan->hw_value); + conf->chandef.chan->hw_value); if (changed & BSS_CHANGED_BEACON_ENABLED) { dev_dbg(&priv->usb->dev, - "Beacon enable %d\n", conf->enable_beacon); + "Beacon enable %d\n", conf->enable_beacon); if (conf->enable_beacon) { vnt_beacon_enable(priv, vif, conf); @@ -768,7 +768,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, } static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) + struct netdev_hw_addr_list *mc_list) { struct vnt_private *priv = hw->priv; struct netdev_hw_addr *ha; @@ -787,7 +787,8 @@ static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, } static void vnt_configure(struct ieee80211_hw *hw, - unsigned int changed_flags, unsigned int *total_flags, u64 multicast) + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) { struct vnt_private *priv = hw->priv; u8 rx_mode = 0; @@ -796,7 +797,7 @@ static void vnt_configure(struct ieee80211_hw *hw, *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC; rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR, - MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode); + MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode); if (!rc) rx_mode = RCR_MULTICAST | RCR_BROADCAST; @@ -814,7 +815,6 @@ static void vnt_configure(struct ieee80211_hw *hw, } else { rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); } - } if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) { @@ -830,8 +830,8 @@ static void vnt_configure(struct ieee80211_hw *hw, } static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) { struct vnt_private *priv = hw->priv; @@ -871,7 +871,7 @@ static void vnt_sw_scan_complete(struct ieee80211_hw *hw, } static int vnt_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) + struct ieee80211_low_level_stats *stats) { struct vnt_private *priv = hw->priv; @@ -925,7 +925,6 @@ static const struct ieee80211_ops vnt_mac_ops = { int vnt_init(struct vnt_private *priv) { - if (!(vnt_init_registers(priv))) return -EAGAIN; @@ -955,9 +954,9 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) udev = usb_get_dev(interface_to_usbdev(intf)); dev_notice(&udev->dev, "%s Ver. %s\n", - DEVICE_FULL_DRV_NAM, DEVICE_VERSION); + DEVICE_FULL_DRV_NAM, DEVICE_VERSION); dev_notice(&udev->dev, - "Copyright (c) 2004 VIA Networking Technologies, Inc.\n"); + "Copyright (c) 2004 VIA Networking Technologies, Inc.\n"); hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops); if (!hw) { diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index 9d1ebb695f9d..859e75fc77ac 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -28,8 +28,8 @@ #define C_PWBT 1000 /* micro sec. power up before TBTT */ -void vnt_disable_power_saving(struct vnt_private *); -void vnt_enable_power_saving(struct vnt_private *, u16); -int vnt_next_tbtt_wakeup(struct vnt_private *); +void vnt_disable_power_saving(struct vnt_private *priv); +void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval); +int vnt_next_tbtt_wakeup(struct vnt_private *priv); #endif /* __POWER_H__ */ diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 6101a35582b6..068c1c89f653 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -771,7 +771,7 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate) ret &= vnt_rf_write_embedded(priv, 0x015C0800); } else { dev_dbg(&priv->usb->dev, - "@@@@ vnt_rf_set_txpower> 11G mode\n"); + "@@@@ vnt_rf_set_txpower> 11G mode\n"); power_setting = ((0x3f - power) << 20) | (0x7 << 8); @@ -876,7 +876,7 @@ void vnt_rf_table_download(struct vnt_private *priv) memcpy(array, addr1, length1); vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, - MESSAGE_REQUEST_RF_INIT, length1, array); + MESSAGE_REQUEST_RF_INIT, length1, array); /* Channel Table 0 */ value = 0; @@ -889,7 +889,7 @@ void vnt_rf_table_download(struct vnt_private *priv) memcpy(array, addr2, length); vnt_control_out(priv, MESSAGE_TYPE_WRITE, - value, MESSAGE_REQUEST_RF_CH0, length, array); + value, MESSAGE_REQUEST_RF_CH0, length, array); length2 -= length; value += length; @@ -907,7 +907,7 @@ void vnt_rf_table_download(struct vnt_private *priv) memcpy(array, addr3, length); vnt_control_out(priv, MESSAGE_TYPE_WRITE, - value, MESSAGE_REQUEST_RF_CH1, length, array); + value, MESSAGE_REQUEST_RF_CH1, length, array); length3 -= length; value += length; @@ -924,7 +924,7 @@ void vnt_rf_table_download(struct vnt_private *priv) /* Init Table 2 */ vnt_control_out(priv, MESSAGE_TYPE_WRITE, - 0, MESSAGE_REQUEST_RF_INIT2, length1, array); + 0, MESSAGE_REQUEST_RF_INIT2, length1, array); /* Channel Table 0 */ value = 0; @@ -937,7 +937,7 @@ void vnt_rf_table_download(struct vnt_private *priv) memcpy(array, addr2, length); vnt_control_out(priv, MESSAGE_TYPE_WRITE, - value, MESSAGE_REQUEST_RF_CH2, length, array); + value, MESSAGE_REQUEST_RF_CH2, length, array); length2 -= length; value += length; diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index c3d4f06d65f4..c907a18047d2 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -50,10 +50,10 @@ #define VNT_RF_MAX_POWER 0x3f #define VNT_RF_REG_LEN 0x17 /* 24 bit length */ -int vnt_rf_write_embedded(struct vnt_private *, u32); -int vnt_rf_setpower(struct vnt_private *, u32, u32); -int vnt_rf_set_txpower(struct vnt_private *, u8, u32); -void vnt_rf_rssi_to_dbm(struct vnt_private *, u8, long *); -void vnt_rf_table_download(struct vnt_private *); +int vnt_rf_write_embedded(struct vnt_private *priv, u32 data); +int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel); +int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate); +void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm); +void vnt_rf_table_download(struct vnt_private *priv); #endif /* __RF_H__ */ diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index aa59e7f14ab3..1835cd13ef49 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -90,7 +90,7 @@ static struct vnt_usb_send_context if (!context->in_use) { context->in_use = true; memset(context->data, 0, - MAX_TOTAL_SIZE_WITH_ALL_HEADERS); + MAX_TOTAL_SIZE_WITH_ALL_HEADERS); context->hdr = NULL; @@ -114,19 +114,19 @@ static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) } static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type, - u32 frame_length, u16 rate, int need_ack) + u32 frame_length, u16 rate, int need_ack) { u32 data_time, ack_time; data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - frame_length, rate); + frame_length, rate); if (pkt_type == PK_TYPE_11B) ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, (u16)priv->top_cck_basic_rate); + 14, (u16)priv->top_cck_basic_rate); else ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, (u16)priv->top_ofdm_basic_rate); + 14, (u16)priv->top_ofdm_basic_rate); if (need_ack) return data_time + priv->sifs + ack_time; @@ -135,21 +135,21 @@ static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type, } static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type, - u32 frame_length, u16 rate, int need_ack) + u32 frame_length, u16 rate, int need_ack) { return cpu_to_le16((u16)vnt_get_rsvtime(priv, pkt_type, frame_length, rate, need_ack)); } static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv, - u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate) + u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate) { u32 rrv_time, rts_time, cts_time, ack_time, data_time; rrv_time = rts_time = cts_time = ack_time = data_time = 0; data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - frame_length, current_rate); + frame_length, current_rate); if (rsv_type == 0) { rts_time = vnt_get_frame_time(priv->preamble_type, @@ -160,19 +160,19 @@ static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv, rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, 20, priv->top_cck_basic_rate); cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_cck_basic_rate); + 14, priv->top_cck_basic_rate); ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_ofdm_basic_rate); + 14, priv->top_ofdm_basic_rate); } else if (rsv_type == 2) { rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 20, priv->top_ofdm_basic_rate); + 20, priv->top_ofdm_basic_rate); cts_time = ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, 14, priv->top_ofdm_basic_rate); } else if (rsv_type == 3) { cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_cck_basic_rate); + 14, priv->top_cck_basic_rate); ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_ofdm_basic_rate); + 14, priv->top_ofdm_basic_rate); rrv_time = cts_time + ack_time + data_time + 2 * priv->sifs; @@ -185,7 +185,7 @@ static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv, } static __le16 vnt_get_duration_le(struct vnt_private *priv, - u8 pkt_type, int need_ack) + u8 pkt_type, int need_ack) { u32 ack_time = 0; @@ -220,17 +220,17 @@ static __le16 vnt_get_rtscts_duration_le(struct vnt_usb_send_context *context, pkt_type, 14, priv->top_cck_basic_rate); dur_time = cts_time + 2 * priv->sifs + vnt_get_rsvtime(priv, pkt_type, - frame_length, rate, need_ack); + frame_length, rate, need_ack); break; case RTSDUR_AA: case RTSDUR_AA_F0: case RTSDUR_AA_F1: cts_time = vnt_get_frame_time(priv->preamble_type, - pkt_type, 14, priv->top_ofdm_basic_rate); + pkt_type, 14, priv->top_ofdm_basic_rate); dur_time = cts_time + 2 * priv->sifs + vnt_get_rsvtime(priv, pkt_type, - frame_length, rate, need_ack); + frame_length, rate, need_ack); break; case CTSDUR_BA: @@ -410,7 +410,7 @@ static u16 vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, u16 current_rate = tx_context->tx_rate; vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, - PK_TYPE_11B, &buf->b); + PK_TYPE_11B, &buf->b); vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->a); @@ -437,7 +437,7 @@ static u16 vnt_rxtx_rts_g_fb_head(struct vnt_usb_send_context *tx_context, u16 rts_frame_len = 20; vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, - PK_TYPE_11B, &buf->b); + PK_TYPE_11B, &buf->b); vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->a); @@ -683,17 +683,17 @@ static u16 vnt_rxtx_ab(struct vnt_usb_send_context *tx_context, } static u16 vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context, - struct vnt_tx_buffer *tx_buffer, - struct vnt_mic_hdr **mic_hdr, u32 need_mic, - bool need_rts) + struct vnt_tx_buffer *tx_buffer, + struct vnt_mic_hdr **mic_hdr, u32 need_mic, + bool need_rts) { if (tx_context->pkt_type == PK_TYPE_11GB || tx_context->pkt_type == PK_TYPE_11GA) { if (need_rts) { if (need_mic) - *mic_hdr = &tx_buffer-> - tx_head.tx_rts.tx.mic.hdr; + *mic_hdr = + &tx_buffer->tx_head.tx_rts.tx.mic.hdr; return vnt_rxtx_rts(tx_context, &tx_buffer->tx_head, need_mic); @@ -732,7 +732,7 @@ static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context, if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { memcpy(key_buffer + 8, iv, 3); memcpy(key_buffer + 11, - tx_key->key, WLAN_KEY_LEN_WEP40); + tx_key->key, WLAN_KEY_LEN_WEP40); } break; @@ -1024,11 +1024,11 @@ static int vnt_beacon_xmit(struct vnt_private *priv, /* Get SignalField,ServiceField,Length */ vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11A, &short_head->ab); + PK_TYPE_11A, &short_head->ab); /* Get Duration and TimeStampOff */ short_head->duration = vnt_get_duration_le(priv, - PK_TYPE_11A, false); + PK_TYPE_11A, false); short_head->time_stamp_off = vnt_time_stamp_off(priv, current_rate); } else { @@ -1037,7 +1037,7 @@ static int vnt_beacon_xmit(struct vnt_private *priv, /* Get SignalField,ServiceField,Length */ vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11B, &short_head->ab); + PK_TYPE_11B, &short_head->ab); /* Get Duration and TimeStampOff */ short_head->duration = vnt_get_duration_le(priv, @@ -1101,7 +1101,7 @@ int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) } int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf) + struct ieee80211_bss_conf *conf) { vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 4a79c404275b..1ba8647bea86 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -249,9 +249,9 @@ struct vnt_beacon_buffer { struct ieee80211_mgmt mgmt_hdr; } __packed; -int vnt_tx_packet(struct vnt_private *, struct sk_buff *); -int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *); -int vnt_beacon_enable(struct vnt_private *, struct ieee80211_vif *, - struct ieee80211_bss_conf *); +int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb); +int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif); +int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); #endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index e9b6b21f7422..1ae6a64c7fd4 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -44,7 +44,7 @@ #define USB_CTL_WAIT 500 /* ms */ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status = 0; @@ -68,11 +68,11 @@ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) { vnt_control_out(priv, MESSAGE_TYPE_WRITE, - reg_off, reg, sizeof(u8), &data); + reg_off, reg, sizeof(u8), &data); } int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status; @@ -82,8 +82,8 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, mutex_lock(&priv->usb_lock); status = usb_control_msg(priv->usb, - usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value, - index, buffer, length, USB_CTL_WAIT); + usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value, + index, buffer, length, USB_CTL_WAIT); mutex_unlock(&priv->usb_lock); @@ -96,7 +96,7 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data) { vnt_control_in(priv, MESSAGE_TYPE_READ, - reg_off, reg, sizeof(u8), data); + reg_off, reg, sizeof(u8), data); } static void vnt_start_interrupt_urb_complete(struct urb *urb) diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index 8bafd9aee1fa..9fc5ac0ef6c1 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -28,14 +28,17 @@ #include "device.h" -int vnt_control_out(struct vnt_private *, u8, u16, u16, u16, u8 *); -int vnt_control_in(struct vnt_private *, u8, u16, u16, u16, u8 *); +int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer); +int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer); -void vnt_control_out_u8(struct vnt_private *, u8, u8, u8); -void vnt_control_in_u8(struct vnt_private *, u8, u8, u8 *); +void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); +void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data); -int vnt_start_interrupt_urb(struct vnt_private *); -int vnt_submit_rx_urb(struct vnt_private *, struct vnt_rcb *); -int vnt_tx_context(struct vnt_private *, struct vnt_usb_send_context *); +int vnt_start_interrupt_urb(struct vnt_private *priv); +int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); +int vnt_tx_context(struct vnt_private *priv, + struct vnt_usb_send_context *context); #endif /* __USBPIPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 95faaeb7432a..9f6cc2ef08dd 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -139,7 +139,7 @@ void vnt_run_command(struct work_struct *work) case WLAN_CMD_CHANGE_ANTENNA_START: dev_dbg(&priv->usb->dev, "Change from Antenna%d to", - priv->rx_antenna_sel); + priv->rx_antenna_sel); if (priv->rx_antenna_sel == 0) { priv->rx_antenna_sel = 1; diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 764c09ccd42d..727ec14380c4 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -51,9 +51,9 @@ enum vnt_cmd_state { struct vnt_private; -void vnt_reset_command_timer(struct vnt_private *); +void vnt_reset_command_timer(struct vnt_private *priv); -int vnt_schedule_command(struct vnt_private *, enum vnt_cmd); +int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd); void vnt_run_command(struct work_struct *work); diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b00ea75524e4..c307ccef790e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3998,8 +3998,9 @@ static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo) pNewJoinBssParam->rsn_found = true; index += pu8IEs[index + 1] + 2; continue; - } else + } else { index += pu8IEs[index + 1] + 2; + } } } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3775706578b2..9ab43935869e 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -364,7 +364,7 @@ static int linux_wlan_start_firmware(struct net_device *dev) return ret; if (!wait_for_completion_timeout(&wilc->sync_event, - msecs_to_jiffies(5000))) + msecs_to_jiffies(5000))) return -ETIME; return 0; @@ -992,7 +992,7 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) tx_data->skb = skb; eth_h = (struct ethhdr *)(skb->data); - if (eth_h->h_proto == 0x8e88) + if (eth_h->h_proto == cpu_to_be16(0x8e88)) netdev_dbg(ndev, "EAPOL transmitted\n"); ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c index 07260c497db4..7d32de930576 100644 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -17,7 +17,6 @@ #include "wilc_wlan_if.h" - static struct dentry *wilc_dir; /* @@ -36,7 +35,6 @@ EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL); * -------------------------------------------------------------------------------- */ - static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { char buf[128]; @@ -52,7 +50,7 @@ static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, si } static ssize_t wilc_debug_level_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { int flag = 0; int ret; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 3ad7cec4662d..cd6b8badc5f3 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -81,7 +81,6 @@ static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd) return ret; } - static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd) { struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev); @@ -127,7 +126,7 @@ static int linux_sdio_probe(struct sdio_func *func, dev_dbg(&func->dev, "Initializing netdev\n"); ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio, - &wilc_hif_sdio); + &wilc_hif_sdio); if (ret) { dev_err(&func->dev, "Couldn't initialize netdev\n"); return ret; @@ -915,7 +914,6 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) __LINE__); goto _fail_; } - } } else { if (g_sdio.irq_gpio) { @@ -945,7 +943,6 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) __LINE__); goto _fail_; } - } if (!ret) break; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index c1a24f7bc85f..f7ce47cac2aa 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, { s32 s32Error = 0; u32 i; + u32 sel_bssi_idx = UINT_MAX; u8 u8security = NO_ENCRYPT; enum AUTHTYPE tenuAuth_type = ANY; @@ -688,18 +689,24 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, memcmp(last_scanned_shadow[i].ssid, sme->ssid, sme->ssid_len) == 0) { - if (!sme->bssid) - break; - else + if (!sme->bssid) { + if (sel_bssi_idx == UINT_MAX || + last_scanned_shadow[i].rssi > + last_scanned_shadow[sel_bssi_idx].rssi) + sel_bssi_idx = i; + } else { if (memcmp(last_scanned_shadow[i].bssid, sme->bssid, - ETH_ALEN) == 0) + ETH_ALEN) == 0) { + sel_bssi_idx = i; break; + } + } } } - if (i < last_scanned_cnt) { - pstrNetworkInfo = &last_scanned_shadow[i]; + if (sel_bssi_idx < last_scanned_cnt) { + pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx]; } else { s32Error = -ENOENT; wilc_connecting = 0; @@ -2285,8 +2292,11 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types; wdev->wiphy->max_remain_on_channel_duration = 500; - 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->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; wdev->iftype = NL80211_IFTYPE_STATION; diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index aa0e5a3d4a89..11870cb3f254 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -483,8 +483,8 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev, msg_join.authtype.data = P80211ENUM_authalg_sharedkey; else netdev_warn(dev, - "Unhandled authorisation type for connect (%d)\n", - sme->auth_type); + "Unhandled authorisation type for connect (%d)\n", + sme->auth_type); /* Set the encryption - we only support wep */ if (is_wep) { @@ -667,7 +667,7 @@ void prism2_disconnected(struct wlandevice *wlandev) void prism2_roamed(struct wlandevice *wlandev) { cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid, - NULL, 0, NULL, 0, GFP_KERNEL); + NULL, 0, NULL, 0, GFP_KERNEL); } /* Structures for declaring wiphy interface */ diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 60caf9c37727..5f1851c85f12 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -1388,13 +1388,13 @@ static inline int hfa384x_drvr_getconfig16(struct hfa384x *hw, u16 rid, void *va result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); if (result == 0) - *((u16 *)val) = le16_to_cpu(*((u16 *)val)); + le16_to_cpus(val); return result; } static inline int hfa384x_drvr_setconfig16(struct hfa384x *hw, u16 rid, u16 val) { - u16 value = cpu_to_le16(val); + __le16 value = cpu_to_le16(val); return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); } diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 8387e6a3031a..8b0905e7c9be 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -387,7 +387,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, (((memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0) && (ethconv == WLAN_ETHCONV_8021h) && - (p80211_stt_findproto(le16_to_cpu(e_snap->type)))) || + (p80211_stt_findproto(be16_to_cpu(e_snap->type)))) || (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) != 0))) { pr_debug("SNAP+RFC1042 len: %d\n", payload_length); diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h index ed70d98e5cf1..04bac2ed0e8a 100644 --- a/drivers/staging/wlan-ng/p80211conv.h +++ b/drivers/staging/wlan-ng/p80211conv.h @@ -130,7 +130,7 @@ struct p80211_metawep { struct wlan_ethhdr { u8 daddr[ETH_ALEN]; u8 saddr[ETH_ALEN]; - u16 type; + __be16 type; } __packed; /* local llc header type */ @@ -143,7 +143,7 @@ struct wlan_llc { /* local snap header type */ struct wlan_snap { u8 oui[WLAN_IEEE_OUI_LEN]; - u16 type; + __be16 type; } __packed; /* Circular include trick */ diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 53dbbd69e552..021fb23ae9ba 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -237,7 +237,7 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev, struct p80211_hdr_a3 *hdr; hdr = (struct p80211_hdr_a3 *)skb->data; - if (p80211_rx_typedrop(wlandev, hdr->fc)) + if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc))) return CONV_TO_ETHER_SKIPPED; /* perform mcast filtering: allow my local address through but reject diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index c558ad656c49..0e671c3b308d 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -1303,14 +1303,13 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) /* Set the driver state */ /* Do we want the prism2 header? */ if ((msg->prismheader.status == - P80211ENUM_msgitem_status_data_ok) - && (msg->prismheader.data == P80211ENUM_truth_true)) { + P80211ENUM_msgitem_status_data_ok) && + (msg->prismheader.data == P80211ENUM_truth_true)) { hw->sniffhdr = 0; wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; - } else - if ((msg->wlanheader.status == - P80211ENUM_msgitem_status_data_ok) - && (msg->wlanheader.data == P80211ENUM_truth_true)) { + } else if ((msg->wlanheader.status == + P80211ENUM_msgitem_status_data_ok) && + (msg->wlanheader.data == P80211ENUM_truth_true)) { hw->sniffhdr = 1; wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; } else { diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 8ea6a647d037..28df1f3d6f4a 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -146,7 +146,6 @@ static int prism2mib_priv(struct mibrec *mib, struct p80211msg_dot11req_mibset *msg, void *data); static struct mibrec mibtab[] = { - /* dot11smt MIB's */ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1), F_STA | F_WRITE, @@ -624,7 +623,6 @@ static int prism2mib_excludeunencrypted(struct mibrec *mib, struct p80211msg_dot11req_mibset *msg, void *data) { - return prism2mib_flag(mib, isget, wlandev, hw, msg, data); } @@ -747,7 +745,7 @@ static int prism2mib_priv(struct mibrec *mib, * pstr wlan message data * * Returns: - * Nothing + * Nothing * */ diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 777cd6e11694..6930f7eb741b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -607,8 +607,12 @@ static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info, { switch (var->bits_per_pixel) { case 8: - var->red.offset = var->green.offset = var->blue.offset = 0; - var->red.length = var->green.length = var->blue.length = 6; + var->red.offset = 0; + var->green.offset = 0; + var->blue.offset = 0; + var->red.length = 6; + var->green.length = 6; + var->blue.length = 6; xgifb_info->video_cmap_len = 256; break; case 16: @@ -1015,7 +1019,8 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgifb_info->video_vheight = info->var.yres_virtual; xgifb_info->video_height = XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = xgifb_info->org_y = 0; + xgifb_info->org_x = 0; + xgifb_info->org_y = 0; xgifb_info->video_linelength = info->var.xres_virtual * (xgifb_info->video_bpp >> 3); switch (xgifb_info->video_bpp) { @@ -1311,10 +1316,12 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->yoffset = var->yres_virtual - var->yres - 1; /* Set everything else to 0 */ - var->red.msb_right = - var->green.msb_right = - var->blue.msb_right = - var->transp.offset = var->transp.length = var->transp.msb_right = 0; + var->red.msb_right = 0; + var->green.msb_right = 0; + var->blue.msb_right = 0; + var->transp.offset = 0; + var->transp.length = 0; + var->transp.msb_right = 0; return 0; } @@ -1468,7 +1475,8 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) { u8 cr32, temp = 0; - xgifb_info->TV_plug = xgifb_info->TV_type = 0; + xgifb_info->TV_plug = 0; + xgifb_info->TV_type = 0; cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32); @@ -1738,7 +1746,9 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto error_0; } - xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress = + xgifb_info->video_vbase = + ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); + hw_info->pjVideoMemoryAddress = ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); @@ -1897,7 +1907,8 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) xgifb_info->video_vheight = xgifb_info->video_height = XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = xgifb_info->org_y = 0; + xgifb_info->org_x = 0; + xgifb_info->org_y = 0; xgifb_info->video_linelength = xgifb_info->video_width * (xgifb_info->video_bpp >> 3); diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 14af157958cd..591a3c9babf5 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -579,8 +579,7 @@ static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) if ((data & 0x10) == 0) { data = xgifb_reg_get(pVBInfo->P3c4, 0x39); - data = (data & 0x02) >> 1; - return data; + return (data & 0x02) >> 1; } return data & 0x01; } diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h index 6f082a7a5a4a..c6317ab00474 100644 --- a/drivers/staging/xgifb/vb_setmode.h +++ b/drivers/staging/xgifb/vb_setmode.h @@ -1,14 +1,14 @@ #ifndef _VBSETMODE_ #define _VBSETMODE_ -void InitTo330Pointer(unsigned char, struct vb_device_info *); -void XGI_UnLockCRT2(struct vb_device_info *); -void XGI_LockCRT2(struct vb_device_info *); -void XGI_DisplayOff(struct xgifb_video_info *, - struct xgi_hw_device_info *, - struct vb_device_info *); -void XGI_GetVBType(struct vb_device_info *); -void XGI_SenseCRT1(struct vb_device_info *); +void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo); +void XGI_UnLockCRT2(struct vb_device_info *pVBInfo); +void XGI_LockCRT2(struct vb_device_info *pVBInfo); +void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, + struct xgi_hw_device_info *pXGIHWDE, + struct vb_device_info *pVBInfo); +void XGI_GetVBType(struct vb_device_info *pVBInfo); +void XGI_SenseCRT1(struct vb_device_info *pVBInfo); unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo); @@ -18,6 +18,6 @@ unsigned char XGI_SearchModeID(unsigned short ModeNo, unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *); + struct vb_device_info *pVBInfo); #endif diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index dd85f3503410..7ef111d3ecc5 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h @@ -232,6 +232,7 @@ struct hid_sensor_common { atomic_t data_ready; atomic_t user_requested_state; struct iio_trigger *trigger; + int timestamp_ns_scale; struct hid_sensor_hub_attribute_info poll; struct hid_sensor_hub_attribute_info report_state; struct hid_sensor_hub_attribute_info power_state; @@ -271,4 +272,7 @@ int hid_sensor_format_scale(u32 usage_id, s32 hid_sensor_read_poll_value(struct hid_sensor_common *st); +int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st, + int64_t raw_value); + #endif diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h index f2ee90aed0c2..30c7dc45e45f 100644 --- a/include/linux/hid-sensor-ids.h +++ b/include/linux/hid-sensor-ids.h @@ -52,6 +52,9 @@ #define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS 0x200458 #define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS 0x200459 +/* Gravity vector */ +#define HID_USAGE_SENSOR_GRAVITY_VECTOR 0x20007B + /* ORIENTATION: Compass 3D: (200083) */ #define HID_USAGE_SENSOR_COMPASS_3D 0x200083 #define HID_USAGE_SENSOR_DATA_ORIENTATION 0x200470 @@ -95,6 +98,7 @@ #define HID_USAGE_SENSOR_TIME_HOUR 0x200525 #define HID_USAGE_SENSOR_TIME_MINUTE 0x200526 #define HID_USAGE_SENSOR_TIME_SECOND 0x200527 +#define HID_USAGE_SENSOR_TIME_TIMESTAMP 0x200529 /* Units */ #define HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED 0x00 diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 70a5164f4728..48767c776119 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -11,139 +11,15 @@ #define _IIO_BUFFER_GENERIC_H_ #include <linux/sysfs.h> #include <linux/iio/iio.h> -#include <linux/kref.h> - -#ifdef CONFIG_IIO_BUFFER struct iio_buffer; -/** - * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be - * configured. It has a fixed value which will be buffer specific. - */ -#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0) - -/** - * struct iio_buffer_access_funcs - access functions for buffers. - * @store_to: actually store stuff to the buffer - * @read_first_n: try to get a specified number of bytes (must exist) - * @data_available: indicates how much data is available for reading from - * the buffer. - * @request_update: if a parameter change has been marked, update underlying - * storage. - * @set_bytes_per_datum:set number of bytes per datum - * @set_length: set number of datums in buffer - * @enable: called if the buffer is attached to a device and the - * device starts sampling. Calls are balanced with - * @disable. - * @disable: called if the buffer is attached to a device and the - * device stops sampling. Calles are balanced with @enable. - * @release: called when the last reference to the buffer is dropped, - * should free all resources allocated by the buffer. - * @modes: Supported operating modes by this buffer type - * @flags: A bitmask combination of INDIO_BUFFER_FLAG_* - * - * The purpose of this structure is to make the buffer element - * modular as event for a given driver, different usecases may require - * different buffer designs (space efficiency vs speed for example). - * - * It is worth noting that a given buffer implementation may only support a - * small proportion of these functions. The core code 'should' cope fine with - * any of them not existing. - **/ -struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, const void *data); - int (*read_first_n)(struct iio_buffer *buffer, - size_t n, - char __user *buf); - size_t (*data_available)(struct iio_buffer *buffer); - - int (*request_update)(struct iio_buffer *buffer); - - int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); - int (*set_length)(struct iio_buffer *buffer, int length); - - int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); - int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); - - void (*release)(struct iio_buffer *buffer); - - unsigned int modes; - unsigned int flags; -}; - -/** - * struct iio_buffer - general buffer structure - * @length: [DEVICE] number of datums in buffer - * @bytes_per_datum: [DEVICE] size of individual datum including timestamp - * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode - * control method is used - * @scan_mask: [INTERN] bitmask used in masking scan mode elements - * @scan_timestamp: [INTERN] does the scan mode include a timestamp - * @access: [DRIVER] buffer access functions associated with the - * implementation. - * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes. - * @buffer_group: [INTERN] attributes of the buffer group - * @scan_el_group: [DRIVER] attribute group for those attributes not - * created from the iio_chan_info array. - * @pollq: [INTERN] wait queue to allow for polling on the buffer. - * @stufftoread: [INTERN] flag to indicate new data. - * @attrs: [INTERN] standard attributes of the buffer - * @demux_list: [INTERN] list of operations required to demux the scan. - * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. - * @buffer_list: [INTERN] entry in the devices list of current buffers. - * @ref: [INTERN] reference count of the buffer. - * @watermark: [INTERN] number of datums to wait for poll/read. - */ -struct iio_buffer { - int length; - int bytes_per_datum; - struct attribute_group *scan_el_attrs; - long *scan_mask; - bool scan_timestamp; - const struct iio_buffer_access_funcs *access; - struct list_head scan_el_dev_attr_list; - struct attribute_group buffer_group; - struct attribute_group scan_el_group; - wait_queue_head_t pollq; - bool stufftoread; - const struct attribute **attrs; - struct list_head demux_list; - void *demux_bounce; - struct list_head buffer_list; - struct kref ref; - unsigned int watermark; -}; - -/** - * iio_update_buffers() - add or remove buffer from active list - * @indio_dev: device to add buffer to - * @insert_buffer: buffer to insert - * @remove_buffer: buffer_to_remove - * - * Note this will tear down the all buffering and build it up again - */ -int iio_update_buffers(struct iio_dev *indio_dev, - struct iio_buffer *insert_buffer, - struct iio_buffer *remove_buffer); - -/** - * iio_buffer_init() - Initialize the buffer structure - * @buffer: buffer to be initialized - **/ -void iio_buffer_init(struct iio_buffer *buffer); +void iio_buffer_set_attrs(struct iio_buffer *buffer, + const struct attribute **attrs); -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); - -/** - * iio_push_to_buffers() - push to a registered buffer. - * @indio_dev: iio_dev structure for device. - * @data: Full scan. - */ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data); -/* +/** * iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers * @indio_dev: iio_dev structure for device. * @data: sample data @@ -168,34 +44,10 @@ static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev, return iio_push_to_buffers(indio_dev, data); } -int iio_update_demux(struct iio_dev *indio_dev); - bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, - const unsigned long *mask); - -struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer); -void iio_buffer_put(struct iio_buffer *buffer); - -/** - * iio_device_attach_buffer - Attach a buffer to a IIO device - * @indio_dev: The device the buffer should be attached to - * @buffer: The buffer to attach to the device - * - * This function attaches a buffer to a IIO device. The buffer stays attached to - * the device until the device is freed. The function should only be called at - * most once per device. - */ -static inline void iio_device_attach_buffer(struct iio_dev *indio_dev, - struct iio_buffer *buffer) -{ - indio_dev->buffer = iio_buffer_get(buffer); -} - -#else /* CONFIG_IIO_BUFFER */ - -static inline void iio_buffer_get(struct iio_buffer *buffer) {} -static inline void iio_buffer_put(struct iio_buffer *buffer) {} + const unsigned long *mask); -#endif /* CONFIG_IIO_BUFFER */ +void iio_device_attach_buffer(struct iio_dev *indio_dev, + struct iio_buffer *buffer); #endif /* _IIO_BUFFER_GENERIC_H_ */ diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h new file mode 100644 index 000000000000..8daba198fafa --- /dev/null +++ b/include/linux/iio/buffer_impl.h @@ -0,0 +1,162 @@ +#ifndef _IIO_BUFFER_GENERIC_IMPL_H_ +#define _IIO_BUFFER_GENERIC_IMPL_H_ +#include <linux/sysfs.h> +#include <linux/kref.h> + +#ifdef CONFIG_IIO_BUFFER + +struct iio_dev; +struct iio_buffer; + +/** + * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be + * configured. It has a fixed value which will be buffer specific. + */ +#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0) + +/** + * struct iio_buffer_access_funcs - access functions for buffers. + * @store_to: actually store stuff to the buffer + * @read_first_n: try to get a specified number of bytes (must exist) + * @data_available: indicates how much data is available for reading from + * the buffer. + * @request_update: if a parameter change has been marked, update underlying + * storage. + * @set_bytes_per_datum:set number of bytes per datum + * @set_length: set number of datums in buffer + * @enable: called if the buffer is attached to a device and the + * device starts sampling. Calls are balanced with + * @disable. + * @disable: called if the buffer is attached to a device and the + * device stops sampling. Calles are balanced with @enable. + * @release: called when the last reference to the buffer is dropped, + * should free all resources allocated by the buffer. + * @modes: Supported operating modes by this buffer type + * @flags: A bitmask combination of INDIO_BUFFER_FLAG_* + * + * The purpose of this structure is to make the buffer element + * modular as event for a given driver, different usecases may require + * different buffer designs (space efficiency vs speed for example). + * + * It is worth noting that a given buffer implementation may only support a + * small proportion of these functions. The core code 'should' cope fine with + * any of them not existing. + **/ +struct iio_buffer_access_funcs { + int (*store_to)(struct iio_buffer *buffer, const void *data); + int (*read_first_n)(struct iio_buffer *buffer, + size_t n, + char __user *buf); + size_t (*data_available)(struct iio_buffer *buffer); + + int (*request_update)(struct iio_buffer *buffer); + + int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); + int (*set_length)(struct iio_buffer *buffer, int length); + + int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + + void (*release)(struct iio_buffer *buffer); + + unsigned int modes; + unsigned int flags; +}; + +/** + * struct iio_buffer - general buffer structure + * + * Note that the internals of this structure should only be of interest to + * those writing new buffer implementations. + */ +struct iio_buffer { + /** @length: Number of datums in buffer. */ + int length; + + /** @bytes_per_datum: Size of individual datum including timestamp. */ + int bytes_per_datum; + + /** + * @access: Buffer access functions associated with the + * implementation. + */ + const struct iio_buffer_access_funcs *access; + + /** @scan_mask: Bitmask used in masking scan mode elements. */ + long *scan_mask; + + /** @demux_list: List of operations required to demux the scan. */ + struct list_head demux_list; + + /** @pollq: Wait queue to allow for polling on the buffer. */ + wait_queue_head_t pollq; + + /** @watermark: Number of datums to wait for poll/read. */ + unsigned int watermark; + + /* private: */ + /* + * @scan_el_attrs: Control of scan elements if that scan mode + * control method is used. + */ + struct attribute_group *scan_el_attrs; + + /* @scan_timestamp: Does the scan mode include a timestamp. */ + bool scan_timestamp; + + /* @scan_el_dev_attr_list: List of scan element related attributes. */ + struct list_head scan_el_dev_attr_list; + + /* @buffer_group: Attributes of the buffer group. */ + struct attribute_group buffer_group; + + /* + * @scan_el_group: Attribute group for those attributes not + * created from the iio_chan_info array. + */ + struct attribute_group scan_el_group; + + /* @stufftoread: Flag to indicate new data. */ + bool stufftoread; + + /* @attrs: Standard attributes of the buffer. */ + const struct attribute **attrs; + + /* @demux_bounce: Buffer for doing gather from incoming scan. */ + void *demux_bounce; + + /* @buffer_list: Entry in the devices list of current buffers. */ + struct list_head buffer_list; + + /* @ref: Reference count of the buffer. */ + struct kref ref; +}; + +/** + * iio_update_buffers() - add or remove buffer from active list + * @indio_dev: device to add buffer to + * @insert_buffer: buffer to insert + * @remove_buffer: buffer_to_remove + * + * Note this will tear down the all buffering and build it up again + */ +int iio_update_buffers(struct iio_dev *indio_dev, + struct iio_buffer *insert_buffer, + struct iio_buffer *remove_buffer); + +/** + * iio_buffer_init() - Initialize the buffer structure + * @buffer: buffer to be initialized + **/ +void iio_buffer_init(struct iio_buffer *buffer); + +struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer); +void iio_buffer_put(struct iio_buffer *buffer); + +#else /* CONFIG_IIO_BUFFER */ + +static inline void iio_buffer_get(struct iio_buffer *buffer) {} +static inline void iio_buffer_put(struct iio_buffer *buffer) {} + +#endif /* CONFIG_IIO_BUFFER */ +#endif /* _IIO_BUFFER_GENERIC_IMPL_H_ */ diff --git a/include/linux/iio/common/st_sensors_i2c.h b/include/linux/iio/common/st_sensors_i2c.h index 1796af093368..254de3c7dde8 100644 --- a/include/linux/iio/common/st_sensors_i2c.h +++ b/include/linux/iio/common/st_sensors_i2c.h @@ -28,4 +28,13 @@ static inline void st_sensors_of_i2c_probe(struct i2c_client *client, } #endif +#ifdef CONFIG_ACPI +int st_sensors_match_acpi_device(struct device *dev); +#else +static inline int st_sensors_match_acpi_device(struct device *dev) +{ + return -ENODEV; +} +#endif + #endif /* ST_SENSORS_I2C_H */ diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 1683bc710d14..027cfa9c3703 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -1,9 +1,8 @@ #ifndef __LINUX_IIO_KFIFO_BUF_H__ #define __LINUX_IIO_KFIFO_BUF_H__ -#include <linux/kfifo.h> -#include <linux/iio/iio.h> -#include <linux/iio/buffer.h> +struct iio_buffer; +struct device; struct iio_buffer *iio_kfifo_allocate(void); void iio_kfifo_free(struct iio_buffer *r); diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h new file mode 100644 index 000000000000..55535aef2e6c --- /dev/null +++ b/include/linux/iio/timer/stm32-timer-trigger.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) STMicroelectronics 2016 + * + * Author: Benjamin Gaignard <benjamin.gaignard@st.com> + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef _STM32_TIMER_TRIGGER_H_ +#define _STM32_TIMER_TRIGGER_H_ + +#define TIM1_TRGO "tim1_trgo" +#define TIM1_CH1 "tim1_ch1" +#define TIM1_CH2 "tim1_ch2" +#define TIM1_CH3 "tim1_ch3" +#define TIM1_CH4 "tim1_ch4" + +#define TIM2_TRGO "tim2_trgo" +#define TIM2_CH1 "tim2_ch1" +#define TIM2_CH2 "tim2_ch2" +#define TIM2_CH3 "tim2_ch3" +#define TIM2_CH4 "tim2_ch4" + +#define TIM3_TRGO "tim3_trgo" +#define TIM3_CH1 "tim3_ch1" +#define TIM3_CH2 "tim3_ch2" +#define TIM3_CH3 "tim3_ch3" +#define TIM3_CH4 "tim3_ch4" + +#define TIM4_TRGO "tim4_trgo" +#define TIM4_CH1 "tim4_ch1" +#define TIM4_CH2 "tim4_ch2" +#define TIM4_CH3 "tim4_ch3" +#define TIM4_CH4 "tim4_ch4" + +#define TIM5_TRGO "tim5_trgo" +#define TIM5_CH1 "tim5_ch1" +#define TIM5_CH2 "tim5_ch2" +#define TIM5_CH3 "tim5_ch3" +#define TIM5_CH4 "tim5_ch4" + +#define TIM6_TRGO "tim6_trgo" + +#define TIM7_TRGO "tim7_trgo" + +#define TIM8_TRGO "tim8_trgo" +#define TIM8_CH1 "tim8_ch1" +#define TIM8_CH2 "tim8_ch2" +#define TIM8_CH3 "tim8_ch3" +#define TIM8_CH4 "tim8_ch4" + +#define TIM9_TRGO "tim9_trgo" +#define TIM9_CH1 "tim9_ch1" +#define TIM9_CH2 "tim9_ch2" + +#define TIM12_TRGO "tim12_trgo" +#define TIM12_CH1 "tim12_ch1" +#define TIM12_CH2 "tim12_ch2" + +bool is_stm32_timer_trigger(struct iio_trigger *trig); + +#endif diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index 1683003603f3..098c3501ad2c 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -1441,7 +1441,8 @@ enum motionsensor_type { MOTIONSENSE_TYPE_PROX = 3, MOTIONSENSE_TYPE_LIGHT = 4, MOTIONSENSE_TYPE_ACTIVITY = 5, - MOTIONSENSE_TYPE_MAX + MOTIONSENSE_TYPE_BARO = 6, + MOTIONSENSE_TYPE_MAX, }; /* List of motion sensor locations. */ diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h new file mode 100644 index 000000000000..d0300045f04a --- /dev/null +++ b/include/linux/mfd/stm32-timers.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) STMicroelectronics 2016 + * + * Author: Benjamin Gaignard <benjamin.gaignard@st.com> + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef _LINUX_STM32_GPTIMER_H_ +#define _LINUX_STM32_GPTIMER_H_ + +#include <linux/clk.h> +#include <linux/regmap.h> + +#define TIM_CR1 0x00 /* Control Register 1 */ +#define TIM_CR2 0x04 /* Control Register 2 */ +#define TIM_SMCR 0x08 /* Slave mode control reg */ +#define TIM_DIER 0x0C /* DMA/interrupt register */ +#define TIM_SR 0x10 /* Status register */ +#define TIM_EGR 0x14 /* Event Generation Reg */ +#define TIM_CCMR1 0x18 /* Capt/Comp 1 Mode Reg */ +#define TIM_CCMR2 0x1C /* Capt/Comp 2 Mode Reg */ +#define TIM_CCER 0x20 /* Capt/Comp Enable Reg */ +#define TIM_PSC 0x28 /* Prescaler */ +#define TIM_ARR 0x2c /* Auto-Reload Register */ +#define TIM_CCR1 0x34 /* Capt/Comp Register 1 */ +#define TIM_CCR2 0x38 /* Capt/Comp Register 2 */ +#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */ +#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */ +#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */ + +#define TIM_CR1_CEN BIT(0) /* Counter Enable */ +#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */ +#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */ +#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */ +#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */ +#define TIM_DIER_UIE BIT(0) /* Update interrupt */ +#define TIM_SR_UIF BIT(0) /* Update interrupt flag */ +#define TIM_EGR_UG BIT(0) /* Update Generation */ +#define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */ +#define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */ +#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */ +#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */ +#define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */ +#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */ +#define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */ +#define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */ +#define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */ +#define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12)) +#define TIM_BDTR_BKE BIT(12) /* Break input enable */ +#define TIM_BDTR_BKP BIT(13) /* Break input polarity */ +#define TIM_BDTR_AOE BIT(14) /* Automatic Output Enable */ +#define TIM_BDTR_MOE BIT(15) /* Main Output Enable */ +#define TIM_BDTR_BKF (BIT(16) | BIT(17) | BIT(18) | BIT(19)) +#define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23)) +#define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */ +#define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */ + +#define MAX_TIM_PSC 0xFFFF +#define TIM_CR2_MMS_SHIFT 4 +#define TIM_SMCR_TS_SHIFT 4 +#define TIM_BDTR_BKF_MASK 0xF +#define TIM_BDTR_BKF_SHIFT 16 +#define TIM_BDTR_BK2F_SHIFT 20 + +struct stm32_timers { + struct clk *clk; + struct regmap *regmap; + u32 max_arr; +}; +#endif diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index e54d14a7f876..ffafd6c25a48 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -42,6 +42,7 @@ enum iio_chan_type { IIO_ELECTRICALCONDUCTIVITY, IIO_COUNT, IIO_INDEX, + IIO_GRAVITY, }; enum iio_modifier { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index d9b7e0f306c6..b61245e1181d 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -57,6 +57,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_RESISTANCE] = "resistance", [IIO_PH] = "ph", [IIO_UVINDEX] = "uvindex", + [IIO_GRAVITY] = "gravity", }; static const char * const iio_ev_type_text[] = { @@ -149,6 +150,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_RESISTANCE: case IIO_PH: case IIO_UVINDEX: + case IIO_GRAVITY: break; default: return false; |