diff --git a/[refs] b/[refs] index 7ab49dd2a52a..1bab9f877f7a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: abf8792d0e1b203e303ed1c02437e0e10a39dcda +refs/heads/master: 92389ca8362c42952c7ebb8a0350ac522dcde0f4 diff --git a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone index 698b8081c473..063bda7fe707 100644 --- a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone +++ b/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone @@ -1,4 +1,4 @@ -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/actual_dpi +What: /sys/bus/usb/devices/-:./actual_dpi Date: March 2010 Contact: Stefan Achatz Description: It is possible to switch the dpi setting of the mouse with the @@ -17,13 +17,13 @@ Description: It is possible to switch the dpi setting of the mouse with the This file is readonly. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/actual_profile +What: /sys/bus/usb/devices/-:./actual_profile Date: March 2010 Contact: Stefan Achatz Description: When read, this file returns the number of the actual profile. This file is readonly. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/firmware_version +What: /sys/bus/usb/devices/-:./firmware_version Date: March 2010 Contact: Stefan Achatz Description: When read, this file returns the raw integer version number of the @@ -33,7 +33,7 @@ Description: When read, this file returns the raw integer version number of the left. E.g. a returned value of 138 means 1.38 This file is readonly. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/profile[1-5] +What: /sys/bus/usb/devices/-:./profile[1-5] Date: March 2010 Contact: Stefan Achatz Description: The mouse can store 5 profiles which can be switched by the @@ -48,7 +48,7 @@ Description: The mouse can store 5 profiles which can be switched by the stored in the profile doesn't need to fit the number of the store. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/settings +What: /sys/bus/usb/devices/-:./settings Date: March 2010 Contact: Stefan Achatz Description: When read, this file returns the settings stored in the mouse. @@ -58,7 +58,7 @@ Description: When read, this file returns the settings stored in the mouse. The data has to be 36 bytes long. The mouse will reject invalid data. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/startup_profile +What: /sys/bus/usb/devices/-:./startup_profile Date: March 2010 Contact: Stefan Achatz Description: The integer value of this attribute ranges from 1 to 5. @@ -67,7 +67,7 @@ Description: The integer value of this attribute ranges from 1 to 5. When written, this file sets the number of the startup profile and the mouse activates this profile immediately. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/tcu +What: /sys/bus/usb/devices/-:./tcu Date: March 2010 Contact: Stefan Achatz Description: The mouse has a "Tracking Control Unit" which lets the user @@ -78,7 +78,7 @@ Description: The mouse has a "Tracking Control Unit" which lets the user Writing 1 in this file will start the calibration which takes around 6 seconds to complete and activates the TCU. -What: /sys/bus/usb/devices/-:./::./kone/roccatkone/weight +What: /sys/bus/usb/devices/-:./weight Date: March 2010 Contact: Stefan Achatz Description: The mouse can be equipped with one of four supplied weights diff --git a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus deleted file mode 100644 index 0f9f30eb1742..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus +++ /dev/null @@ -1,108 +0,0 @@ -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/actual_profile -Date: October 2010 -Contact: Stefan Achatz -Description: When read, this file returns the number of the actual profile in - range 0-4. - This file is readonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/firmware_version -Date: October 2010 -Contact: Stefan Achatz -Description: When read, this file returns the raw integer version number of the - firmware reported by the mouse. Using the integer value eases - further usage in other programs. To receive the real version - number the decimal point has to be shifted 2 positions to the - left. E.g. a returned value of 121 means 1.21 - This file is readonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/macro -Date: October 2010 -Contact: Stefan Achatz -Description: The mouse can store a macro with max 500 key/button strokes - internally. - When written, this file lets one set the sequence for a specific - button for a specific profile. Button and profile numbers are - included in written data. The data has to be 2082 bytes long. - This file is writeonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/profile_buttons -Date: August 2010 -Contact: Stefan Achatz -Description: The mouse can store 5 profiles which can be switched by the - press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. - When written, this file lets one write the respective profile - buttons back to the mouse. The data has to be 77 bytes long. - The mouse will reject invalid data. - Which profile to write is determined by the profile number - contained in the data. - This file is writeonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/profile[1-5]_buttons -Date: August 2010 -Contact: Stefan Achatz -Description: The mouse can store 5 profiles which can be switched by the - press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. - When read, these files return the respective profile buttons. - The returned data is 77 bytes in size. - This file is readonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/profile_settings -Date: October 2010 -Contact: Stefan Achatz -Description: The mouse can store 5 profiles which can be switched by the - press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity - and light effects. - When written, this file lets one write the respective profile - settings back to the mouse. The data has to be 43 bytes long. - The mouse will reject invalid data. - Which profile to write is determined by the profile number - contained in the data. - This file is writeonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/profile[1-5]_settings -Date: August 2010 -Contact: Stefan Achatz -Description: The mouse can store 5 profiles which can be switched by the - press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity - and light effects. - When read, these files return the respective profile settings. - The returned data is 43 bytes in size. - This file is readonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/sensor -Date: October 2010 -Contact: Stefan Achatz -Description: The mouse has a tracking- and a distance-control-unit. These - can be activated/deactivated and the lift-off distance can be - set. The data has to be 6 bytes long. - This file is writeonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/startup_profile -Date: October 2010 -Contact: Stefan Achatz -Description: The integer value of this attribute ranges from 0-4. - When read, this attribute returns the number of the profile - that's active when the mouse is powered on. - When written, this file sets the number of the startup profile - and the mouse activates this profile immediately. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/tcu -Date: October 2010 -Contact: Stefan Achatz -Description: When written a calibration process for the tracking control unit - can be initiated/cancelled. - The data has to be 3 bytes long. - This file is writeonly. - -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/tcu_image -Date: October 2010 -Contact: Stefan Achatz -Description: When read the mouse returns a 30x30 pixel image of the - sampled underground. This works only in the course of a - calibration process initiated with tcu. - The returned data is 1028 bytes in size. - This file is readonly. diff --git a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra index 1c37b823f142..ad1125b02ff4 100644 --- a/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra +++ b/trunk/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra @@ -1,4 +1,4 @@ -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/actual_cpi +What: /sys/bus/usb/devices/-:./actual_cpi Date: August 2010 Contact: Stefan Achatz Description: It is possible to switch the cpi setting of the mouse with the @@ -14,14 +14,14 @@ Description: It is possible to switch the cpi setting of the mouse with the This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/actual_profile +What: /sys/bus/usb/devices/-:./actual_profile Date: August 2010 Contact: Stefan Achatz Description: When read, this file returns the number of the actual profile in range 0-4. This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/firmware_version +What: /sys/bus/usb/devices/-:./firmware_version Date: August 2010 Contact: Stefan Achatz Description: When read, this file returns the raw integer version number of the @@ -31,7 +31,7 @@ Description: When read, this file returns the raw integer version number of the left. E.g. a returned value of 138 means 1.38 This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/profile_settings +What: /sys/bus/usb/devices/-:./profile_settings Date: August 2010 Contact: Stefan Achatz Description: The mouse can store 5 profiles which can be switched by the @@ -45,7 +45,7 @@ Description: The mouse can store 5 profiles which can be switched by the contained in the data. This file is writeonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/profile[1-5]_settings +What: /sys/bus/usb/devices/-:./profile[1-5]_settings Date: August 2010 Contact: Stefan Achatz Description: The mouse can store 5 profiles which can be switched by the @@ -56,7 +56,7 @@ Description: The mouse can store 5 profiles which can be switched by the The returned data is 13 bytes in size. This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/profile_buttons +What: /sys/bus/usb/devices/-:./profile_buttons Date: August 2010 Contact: Stefan Achatz Description: The mouse can store 5 profiles which can be switched by the @@ -69,7 +69,7 @@ Description: The mouse can store 5 profiles which can be switched by the contained in the data. This file is writeonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/profile[1-5]_buttons +What: /sys/bus/usb/devices/-:./profile[1-5]_buttons Date: August 2010 Contact: Stefan Achatz Description: The mouse can store 5 profiles which can be switched by the @@ -79,7 +79,7 @@ Description: The mouse can store 5 profiles which can be switched by the The returned data is 19 bytes in size. This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/startup_profile +What: /sys/bus/usb/devices/-:./startup_profile Date: August 2010 Contact: Stefan Achatz Description: The integer value of this attribute ranges from 0-4. @@ -87,7 +87,7 @@ Description: The integer value of this attribute ranges from 0-4. that's active when the mouse is powered on. This file is readonly. -What: /sys/bus/usb/devices/-:./::./pyra/roccatpyra/settings +What: /sys/bus/usb/devices/-:./settings Date: August 2010 Contact: Stefan Achatz Description: When read, this file returns the settings stored in the mouse. diff --git a/trunk/Documentation/coccinelle.txt b/trunk/Documentation/coccinelle.txt index 96b690348ba1..4a276ea7001c 100644 --- a/trunk/Documentation/coccinelle.txt +++ b/trunk/Documentation/coccinelle.txt @@ -36,10 +36,6 @@ as a regular user, and install it with sudo make install -The semantic patches in the kernel will work best with Coccinelle version -0.2.4 or later. Using earlier versions may incur some parse errors in the -semantic patch code, but any results that are obtained should still be -correct. Using Coccinelle on the Linux kernel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/trunk/Documentation/hwmon/ds620 b/trunk/Documentation/hwmon/ds620 deleted file mode 100644 index 1fbe3cd916cc..000000000000 --- a/trunk/Documentation/hwmon/ds620 +++ /dev/null @@ -1,34 +0,0 @@ -Kernel driver ds620 -=================== - -Supported chips: - * Dallas Semiconductor DS620 - Prefix: 'ds620' - Datasheet: Publicly available at the Dallas Semiconductor website - http://www.dalsemi.com/ - -Authors: - Roland Stigge - based on ds1621.c by - Christian W. Zuckschwerdt - -Description ------------ - -The DS620 is a (one instance) digital thermometer and thermostat. It has both -high and low temperature limits which can be user defined (i.e. programmed -into non-volatile on-chip registers). Temperature range is -55 degree Celsius -to +125. Between 0 and 70 degree Celsius, accuracy is 0.5 Kelvin. The value -returned via sysfs displays post decimal positions. - -The thermostat function works as follows: When configured via platform_data -(struct ds620_platform_data) .pomode == 0 (default), the thermostat output pin -PO is always low. If .pomode == 1, the thermostat is in PO_LOW mode. I.e., the -output pin PO becomes active when the temperature falls below temp1_min and -stays active until the temperature goes above temp1_max. - -Likewise, with .pomode == 2, the thermostat is in PO_HIGH mode. I.e., the PO -output pin becomes active when the temperature goes above temp1_max and stays -active until the temperature falls below temp1_min. - -The PO output pin of the DS620 operates active-low. diff --git a/trunk/Documentation/hwmon/sht21 b/trunk/Documentation/hwmon/sht21 deleted file mode 100644 index db17fda45c3e..000000000000 --- a/trunk/Documentation/hwmon/sht21 +++ /dev/null @@ -1,49 +0,0 @@ -Kernel driver sht21 -=================== - -Supported chips: - * Sensirion SHT21 - Prefix: 'sht21' - Addresses scanned: none - Datasheet: Publicly available at the Sensirion website - http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-SHT21.pdf - - * Sensirion SHT25 - Prefix: 'sht21' - Addresses scanned: none - Datasheet: Publicly available at the Sensirion website - http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-SHT25.pdf - -Author: - Urs Fleisch - -Description ------------ - -The SHT21 and SHT25 are humidity and temperature sensors in a DFN package of -only 3 x 3 mm footprint and 1.1 mm height. The difference between the two -devices is the higher level of precision of the SHT25 (1.8% relative humidity, -0.2 degree Celsius) compared with the SHT21 (2.0% relative humidity, -0.3 degree Celsius). - -The devices communicate with the I2C protocol. All sensors are set to the same -I2C address 0x40, so an entry with I2C_BOARD_INFO("sht21", 0x40) can be used -in the board setup code. - -sysfs-Interface ---------------- - -temp1_input - temperature input -humidity1_input - humidity input - -Notes ------ - -The driver uses the default resolution settings of 12 bit for humidity and 14 -bit for temperature, which results in typical measurement times of 22 ms for -humidity and 66 ms for temperature. To keep self heating below 0.1 degree -Celsius, the device should not be active for more than 10% of the time, -e.g. maximum two measurements per second at the given resolution. - -Different resolutions, the on-chip heater, using the CRC checksum and reading -the serial number are not supported yet. diff --git a/trunk/Documentation/hwmon/sysfs-interface b/trunk/Documentation/hwmon/sysfs-interface index c6559f153589..645699010551 100644 --- a/trunk/Documentation/hwmon/sysfs-interface +++ b/trunk/Documentation/hwmon/sysfs-interface @@ -384,20 +384,10 @@ curr[1-*]_min Current min value. Unit: milliampere RW -curr[1-*]_lcrit Current critical low value - Unit: milliampere - RW - -curr[1-*]_crit Current critical high value. - Unit: milliampere - RW - curr[1-*]_input Current input value Unit: milliampere RO -Also see the Alarms section for status flags associated with currents. - ********* * Power * ********* @@ -460,6 +450,13 @@ power[1-*]_accuracy Accuracy of the power meter. Unit: Percent RO +power[1-*]_alarm 1 if the system is drawing more power than the + cap allows; 0 otherwise. A poll notification is + sent to this file when the power use exceeds the + cap. This file only appears if the cap is known + to be enforced by hardware. + RO + power[1-*]_cap If power use rises above this limit, the system should take action to reduce power use. A poll notification is sent to this file if the @@ -482,20 +479,6 @@ power[1-*]_cap_min Minimum cap that can be set. Unit: microWatt RO -power[1-*]_max Maximum power. - Unit: microWatt - RW - -power[1-*]_crit Critical maximum power. - If power rises to or above this limit, the - system is expected take drastic action to reduce - power consumption, such as a system shutdown or - a forced powerdown of some devices. - Unit: microWatt - RW - -Also see the Alarms section for status flags associated with power readings. - ********** * Energy * ********** @@ -505,15 +488,6 @@ energy[1-*]_input Cumulative energy use RO -************ -* Humidity * -************ - -humidity[1-*]_input Humidity - Unit: milli-percent (per cent mille, pcm) - RO - - ********** * Alarms * ********** @@ -527,7 +501,6 @@ implementation. in[0-*]_alarm curr[1-*]_alarm -power[1-*]_alarm fan[1-*]_alarm temp[1-*]_alarm Channel alarm @@ -539,20 +512,12 @@ OR in[0-*]_min_alarm in[0-*]_max_alarm -in[0-*]_lcrit_alarm -in[0-*]_crit_alarm curr[1-*]_min_alarm curr[1-*]_max_alarm -curr[1-*]_lcrit_alarm -curr[1-*]_crit_alarm -power[1-*]_cap_alarm -power[1-*]_max_alarm -power[1-*]_crit_alarm fan[1-*]_min_alarm fan[1-*]_max_alarm temp[1-*]_min_alarm temp[1-*]_max_alarm -temp[1-*]_lcrit_alarm temp[1-*]_crit_alarm temp[1-*]_emergency_alarm Limit alarm diff --git a/trunk/Documentation/kbuild/kbuild.txt b/trunk/Documentation/kbuild/kbuild.txt index 4a990317b84a..1e5165aa9e4e 100644 --- a/trunk/Documentation/kbuild/kbuild.txt +++ b/trunk/Documentation/kbuild/kbuild.txt @@ -73,14 +73,6 @@ Specify the output directory when building the kernel. The output directory can also be specified using "O=...". Setting "O=..." takes precedence over KBUILD_OUTPUT. -KBUILD_DEBARCH --------------------------------------------------- -For the deb-pkg target, allows overriding the normal heuristics deployed by -deb-pkg. Normally deb-pkg attempts to guess the right architecture based on -the UTS_MACHINE variable, and on some architectures also the kernel config. -The value of KBUILD_DEBARCH is assumed (not checked) to be a valid Debian -architecture. - ARCH -------------------------------------------------- Set ARCH to the architecture to be built. diff --git a/trunk/Documentation/kbuild/kconfig-language.txt b/trunk/Documentation/kbuild/kconfig-language.txt index b507d61fd41c..2fe93ca7c77c 100644 --- a/trunk/Documentation/kbuild/kconfig-language.txt +++ b/trunk/Documentation/kbuild/kconfig-language.txt @@ -112,6 +112,7 @@ applicable everywhere (see syntax). (no prompts anywhere) and for symbols with no dependencies. That will limit the usefulness but on the other hand avoid the illegal configurations all over. + kconfig should one day warn about such things. - numerical ranges: "range" ["if" ] This allows to limit the range of possible input values for int @@ -267,7 +268,7 @@ separate list of options. choices: - "choice" [symbol] + "choice" "endchoice" @@ -281,10 +282,6 @@ single driver can be compiled/loaded into the kernel, but all drivers can be compiled as modules. A choice accepts another option "optional", which allows to set the choice to 'n' and no entry needs to be selected. -If no [symbol] is associated with a choice, then you can not have multiple -definitions of that choice. If a [symbol] is associated to the choice, -then you may define the same choice (ie. with the same entries) in another -place. comment: diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index 86e3cd0d26a0..0ef00bd6e54d 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -1136,21 +1136,6 @@ When kbuild executes, the following steps are followed (roughly): resulting in the target file being recompiled for no obvious reason. - dtc - Create flattend device tree blob object suitable for linking - into vmlinux. Device tree blobs linked into vmlinux are placed - in an init section in the image. Platform code *must* copy the - blob to non-init memory prior to calling unflatten_device_tree(). - - Example: - #arch/x86/platform/ce4100/Makefile - clean-files := *dtb.S - - DTC_FLAGS := -p 1024 - obj-y += foo.dtb.o - - $(obj)/%.dtb: $(src)/%.dts - $(call cmd,dtc) --- 6.7 Custom kbuild commands diff --git a/trunk/Documentation/keys-trusted-encrypted.txt b/trunk/Documentation/keys-trusted-encrypted.txt deleted file mode 100644 index 8fb79bc1ac4b..000000000000 --- a/trunk/Documentation/keys-trusted-encrypted.txt +++ /dev/null @@ -1,145 +0,0 @@ - Trusted and Encrypted Keys - -Trusted and Encrypted Keys are two new key types added to the existing kernel -key ring service. Both of these new types are variable length symmetic keys, -and in both cases all keys are created in the kernel, and user space sees, -stores, and loads only encrypted blobs. Trusted Keys require the availability -of a Trusted Platform Module (TPM) chip for greater security, while Encrypted -Keys can be used on any system. All user level blobs, are displayed and loaded -in hex ascii for convenience, and are integrity verified. - -Trusted Keys use a TPM both to generate and to seal the keys. Keys are sealed -under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR -(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob -integrity verifications match. A loaded Trusted Key can be updated with new -(future) PCR values, so keys are easily migrated to new pcr values, such as -when the kernel and initramfs are updated. The same key can have many saved -blobs under different PCR values, so multiple boots are easily supported. - -By default, trusted keys are sealed under the SRK, which has the default -authorization value (20 zeros). This can be set at takeownership time with the -trouser's utility: "tpm_takeownership -u -z". - -Usage: - keyctl add trusted name "new keylen [options]" ring - keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring - keyctl update key "update [options]" - keyctl print keyid - - options: - keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) - keyauth= ascii hex auth for sealing key default 0x00...i - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) - pcrlock= pcr number to be extended to "lock" blob - migratable= 0|1 indicating permission to reseal to new PCR values, - default 1 (resealing allowed) - -"keyctl print" returns an ascii hex copy of the sealed key, which is in standard -TPM_STORED_DATA format. The key length for new keys are always in bytes. -Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit -within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding. - -Encrypted keys do not depend on a TPM, and are faster, as they use AES for -encryption/decryption. New keys are created from kernel generated random -numbers, and are encrypted/decrypted using a specified 'master' key. The -'master' key can either be a trusted-key or user-key type. The main -disadvantage of encrypted keys is that if they are not rooted in a trusted key, -they are only as secure as the user key encrypting them. The master user key -should therefore be loaded in as secure a way as possible, preferably early in -boot. - -Usage: - keyctl add encrypted name "new key-type:master-key-name keylen" ring - keyctl add encrypted name "load hex_blob" ring - keyctl update keyid "update key-type:master-key-name" - -where 'key-type' is either 'trusted' or 'user'. - -Examples of trusted and encrypted key usage: - -Create and save a trusted key named "kmk" of length 32 bytes: - - $ keyctl add trusted kmk "new 32" @u - 440502848 - - $ keyctl show - Session Keyring - -3 --alswrv 500 500 keyring: _ses - 97833714 --alswrv 500 -1 \_ keyring: _uid.500 - 440502848 --alswrv 500 500 \_ trusted: kmk - - $ keyctl print 440502848 - 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 - 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b - 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 - a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec - d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d - dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 - f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b - e4a8aea2b607ec96931e6f4d4fe563ba - - $ keyctl pipe 440502848 > kmk.blob - -Load a trusted key from the saved blob: - - $ keyctl add trusted kmk "load `cat kmk.blob`" @u - 268728824 - - $ keyctl print 268728824 - 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 - 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b - 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 - a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec - d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d - dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 - f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b - e4a8aea2b607ec96931e6f4d4fe563ba - -Reseal a trusted key under new pcr values: - - $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`" - $ keyctl print 268728824 - 010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805 - 77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73 - d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e - df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4 - 9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6 - e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610 - 94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9 - 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef - df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8 - -Create and save an encrypted key "evm" using the above trusted key "kmk": - - $ keyctl add encrypted evm "new trusted:kmk 32" @u - 159771175 - - $ keyctl print 159771175 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 - 5972dcb82ab2dde83376d82b2e3c09ffc - - $ keyctl pipe 159771175 > evm.blob - -Load an encrypted key "evm" from saved blob: - - $ keyctl add encrypted evm "load `cat evm.blob`" @u - 831684262 - - $ keyctl print 831684262 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 - 5972dcb82ab2dde83376d82b2e3c09ffc - - -The initial consumer of trusted keys is EVM, which at boot time needs a high -quality symmetric key for HMAC protection of file metadata. The use of a -trusted key provides strong guarantees that the EVM key has not been -compromised by a user level problem, and when sealed to specific boot PCR -values, protects against boot and offline attacks. Other uses for trusted and -encrypted keys, such as for disk and file encryption are anticipated. diff --git a/trunk/Documentation/make/headers_install.txt b/trunk/Documentation/make/headers_install.txt index 951eb9f1e040..f2481cabffcb 100644 --- a/trunk/Documentation/make/headers_install.txt +++ b/trunk/Documentation/make/headers_install.txt @@ -39,9 +39,8 @@ INSTALL_HDR_PATH indicates where to install the headers. It defaults to The command "make headers_install_all" exports headers for all architectures simultaneously. (This is mostly of interest to distribution maintainers, who create an architecture-independent tarball from the resulting include -directory.) You also can use HDR_ARCH_LIST to specify list of architectures. -Remember to provide the appropriate linux/asm directory via "mv" or "ln -s" -before building a C library with headers exported this way. +directory.) Remember to provide the appropriate linux/asm directory via "mv" +or "ln -s" before building a C library with headers exported this way. The kernel header export infrastructure is maintained by David Woodhouse . diff --git a/trunk/Documentation/power/drivers-testing.txt b/trunk/Documentation/power/drivers-testing.txt index 638afdf4d6b8..7f7a737f7f9f 100644 --- a/trunk/Documentation/power/drivers-testing.txt +++ b/trunk/Documentation/power/drivers-testing.txt @@ -23,10 +23,10 @@ Once you have resolved the suspend/resume-related problems with your test system without the new driver, you are ready to test it: a) Build the driver as a module, load it and try the test modes of hibernation - (see: Documentation/power/basic-pm-debugging.txt, 1). + (see: Documents/power/basic-pm-debugging.txt, 1). b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and - "platform" modes (see: Documentation/power/basic-pm-debugging.txt, 1). + "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). c) Compile the driver directly into the kernel and try the test modes of hibernation. @@ -34,12 +34,12 @@ c) Compile the driver directly into the kernel and try the test modes of d) Attempt to hibernate with the driver compiled directly into the kernel in the "reboot", "shutdown" and "platform" modes. -e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.txt, +e) Try the test modes of suspend (see: Documents/power/basic-pm-debugging.txt, 2). [As far as the STR tests are concerned, it should not matter whether or not the driver is built as a module.] f) Attempt to suspend to RAM using the s2ram tool with the driver loaded - (see: Documentation/power/basic-pm-debugging.txt, 2). + (see: Documents/power/basic-pm-debugging.txt, 2). Each of the above tests should be repeated several times and the STD tests should be mixed with the STR tests. If any of them fails, the driver cannot be diff --git a/trunk/Documentation/power/runtime_pm.txt b/trunk/Documentation/power/runtime_pm.txt index ffe55ffa540a..41cc7b30d7dd 100644 --- a/trunk/Documentation/power/runtime_pm.txt +++ b/trunk/Documentation/power/runtime_pm.txt @@ -50,15 +50,6 @@ type's callbacks are not defined) of given device. The bus type, device type and device class callbacks are referred to as subsystem-level callbacks in what follows. -By default, the callbacks are always invoked in process context with interrupts -enabled. However, subsystems can use the pm_runtime_irq_safe() helper function -to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume() -callbacks should be invoked in atomic context with interrupts disabled -(->runtime_idle() is still invoked the default way). This implies that these -callback routines must not block or sleep, but it also means that the -synchronous helper functions listed at the end of Section 4 can be used within -an interrupt handler or in an atomic context. - The subsystem-level suspend callback is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include executing the device driver's own ->runtime_suspend() callback (from the @@ -246,10 +237,6 @@ defined in include/linux/pm.h: Section 8); it may be modified only by the pm_runtime_no_callbacks() helper function - unsigned int irq_safe; - - indicates that the ->runtime_suspend() and ->runtime_resume() callbacks - will be invoked with the spinlock held and interrupts disabled - unsigned int use_autosuspend; - indicates that the device's driver supports delayed autosuspend (see Section 9); it may be modified only by the @@ -357,10 +344,6 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: - decrement the device's usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its result - int pm_runtime_put_sync_suspend(struct device *dev); - - decrement the device's usage counter; if the result is 0 then run - pm_runtime_suspend(dev) and return its result - int pm_runtime_put_sync_autosuspend(struct device *dev); - decrement the device's usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its result @@ -414,11 +397,6 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: PM attributes from /sys/devices/.../power (or prevent them from being added when the device is registered) - void pm_runtime_irq_safe(struct device *dev); - - set the power.irq_safe flag for the device, causing the runtime-PM - suspend and resume callbacks (but not the idle callback) to be invoked - with interrupts disabled - void pm_runtime_mark_last_busy(struct device *dev); - set the power.last_busy field to the current time @@ -460,15 +438,6 @@ pm_runtime_suspended() pm_runtime_mark_last_busy() pm_runtime_autosuspend_expiration() -If pm_runtime_irq_safe() has been called for a device then the following helper -functions may also be used in interrupt context: - -pm_runtime_suspend() -pm_runtime_autosuspend() -pm_runtime_resume() -pm_runtime_get_sync() -pm_runtime_put_sync_suspend() - 5. Run-time PM Initialization, Device Probing and Removal Initially, the run-time PM is disabled for all devices, which means that the diff --git a/trunk/Documentation/powerpc/dts-bindings/eeprom.txt b/trunk/Documentation/powerpc/dts-bindings/eeprom.txt deleted file mode 100644 index 4342c10de1bf..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/eeprom.txt +++ /dev/null @@ -1,28 +0,0 @@ -EEPROMs (I2C) - -Required properties: - - - compatible : should be "," - If there is no specific driver for , a generic - driver based on is selected. Possible types are: - 24c00, 24c01, 24c02, 24c04, 24c08, 24c16, 24c32, 24c64, - 24c128, 24c256, 24c512, 24c1024, spd - - - reg : the I2C address of the EEPROM - -Optional properties: - - - pagesize : the length of the pagesize for writing. Please consult the - manual of your device, that value varies a lot. A wrong value - may result in data loss! If not specified, a safety value of - '1' is used which will be very slow. - - - read-only: this parameterless property disables writes to the eeprom - -Example: - -eeprom@52 { - compatible = "atmel,24c32"; - reg = <0x52>; - pagesize = <32>; -}; diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 574067194f38..209e1584c3dc 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -219,7 +219,7 @@ dmesg_restrict: This toggle indicates whether unprivileged users are prevented from using dmesg(8) to view messages from the kernel's log buffer. When dmesg_restrict is set to (0) there are no restrictions. When -dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use +dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use dmesg(8). The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default diff --git a/trunk/Documentation/vm/Makefile b/trunk/Documentation/vm/Makefile index 3fa4d0668864..9dcff328b964 100644 --- a/trunk/Documentation/vm/Makefile +++ b/trunk/Documentation/vm/Makefile @@ -2,7 +2,7 @@ obj- := dummy.o # List of programs to build -hostprogs-y := page-types hugepage-mmap hugepage-shm map_hugetlb +hostprogs-y := slabinfo page-types hugepage-mmap hugepage-shm map_hugetlb # Tell kbuild to always build the programs always := $(hostprogs-y) diff --git a/trunk/tools/slub/slabinfo.c b/trunk/Documentation/vm/slabinfo.c similarity index 99% rename from trunk/tools/slub/slabinfo.c rename to trunk/Documentation/vm/slabinfo.c index 516551c9f172..92e729f4b676 100644 --- a/trunk/tools/slub/slabinfo.c +++ b/trunk/Documentation/vm/slabinfo.c @@ -607,7 +607,7 @@ static int debug_opt_scan(char *opt) } for ( ; *opt; opt++) - switch (*opt) { + switch (*opt) { case 'F' : case 'f': if (sanity) return 0; @@ -1127,7 +1127,7 @@ static void read_slab_dir(void) continue; switch (de->d_type) { case DT_LNK: - alias->name = strdup(de->d_name); + alias->name = strdup(de->d_name); count = readlink(de->d_name, buffer, sizeof(buffer)); if (count < 0) @@ -1143,7 +1143,7 @@ static void read_slab_dir(void) case DT_DIR: if (chdir(de->d_name)) fatal("Unable to access slab %s\n", slab->name); - slab->name = strdup(de->d_name); + slab->name = strdup(de->d_name); slab->alias = 0; slab->refs = 0; slab->aliases = get_obj("aliases"); diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 9e4d4ca690e2..23d04363a195 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4268,7 +4268,6 @@ NILFS2 FILESYSTEM M: KONISHI Ryusuke L: linux-nilfs@vger.kernel.org W: http://www.nilfs.org/en/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2.git S: Supported F: Documentation/filesystems/nilfs2.txt F: fs/nilfs2/ @@ -5930,8 +5929,7 @@ F: drivers/net/tlan.* TOMOYO SECURITY MODULE M: Kentaro Takeda M: Tetsuo Handa -L: tomoyo-dev-en@lists.sourceforge.jp (subscribers-only, for developers in English) -L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for users in English) +L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) W: http://tomoyo.sourceforge.jp/ diff --git a/trunk/Makefile b/trunk/Makefile index 6a457690d10b..74b25559f831 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -224,7 +224,6 @@ ifeq ($(ARCH),m68knommu) endif KCONFIG_CONFIG ?= .config -export KCONFIG_CONFIG # SHELL used by kbuild CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ diff --git a/trunk/arch/arm/mach-msm/Kconfig b/trunk/arch/arm/mach-msm/Kconfig index 5d3d9ade12fb..fae931ac2e56 100644 --- a/trunk/arch/arm/mach-msm/Kconfig +++ b/trunk/arch/arm/mach-msm/Kconfig @@ -40,13 +40,11 @@ config ARCH_MSM8X60 bool "MSM8X60" select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \ && !MACH_MSM8X60_FFA) - select ARCH_MSM_SCORPIONMP select ARM_GIC select CPU_V7 select MSM_V2_TLMM select MSM_GPIOMUX select IOMMU_API - select MSM_SCM if SMP endchoice @@ -174,7 +172,4 @@ config MSM_V2_TLMM config IOMMU_API bool - -config MSM_SCM - bool endif diff --git a/trunk/arch/arm/mach-msm/Makefile b/trunk/arch/arm/mach-msm/Makefile index 94195c190e13..59646bbd6195 100644 --- a/trunk/arch/arm/mach-msm/Makefile +++ b/trunk/arch/arm/mach-msm/Makefile @@ -18,10 +18,6 @@ obj-$(CONFIG_MSM_PROC_COMM) += clock.o obj-$(CONFIG_ARCH_QSD8X50) += sirc.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o -obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o - -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o diff --git a/trunk/arch/arm/mach-msm/headsmp.S b/trunk/arch/arm/mach-msm/headsmp.S deleted file mode 100644 index d0c214338df9..000000000000 --- a/trunk/arch/arm/mach-msm/headsmp.S +++ /dev/null @@ -1,40 +0,0 @@ -/* - * linux/arch/arm/mach-realview/headsmp.S - * - * Copyright (c) 2003 ARM Limited - * 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 as - * published by the Free Software Foundation. - */ -#include -#include - - __INIT - -/* - * MSM specific entry point for secondary CPUs. This provides - * a "holding pen" into which all secondary cores are held until we're - * ready for them to initialise. - */ -ENTRY(msm_secondary_startup) - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #15 - adr r4, 1f - ldmia r4, {r5, r6} - sub r4, r4, r5 - add r6, r6, r4 -pen: ldr r7, [r6] - cmp r7, r0 - bne pen - - /* - * we've been released from the holding pen: secondary_stack - * should now contain the SVC stack for this core - */ - b secondary_startup - - .align -1: .long . - .long pen_release diff --git a/trunk/arch/arm/mach-msm/hotplug.c b/trunk/arch/arm/mach-msm/hotplug.c deleted file mode 100644 index 5a31f70dfb8e..000000000000 --- a/trunk/arch/arm/mach-msm/hotplug.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2002 ARM Ltd. - * 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 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#include - -extern volatile int pen_release; - -static inline void cpu_enter_lowpower(void) -{ - /* Just flush the cache. Changing the coherency is not yet - * available on msm. */ - flush_cache_all(); -} - -static inline void cpu_leave_lowpower(void) -{ -} - -static inline void platform_do_lowpower(unsigned int cpu) -{ - /* Just enter wfi for now. TODO: Properly shut off the cpu. */ - for (;;) { - /* - * here's the WFI - */ - asm("wfi" - : - : - : "memory", "cc"); - - if (pen_release == cpu) { - /* - * OK, proper wakeup, we're done - */ - break; - } - - /* - * getting here, means that we have come out of WFI without - * having been woken up - this shouldn't happen - * - * The trouble is, letting people know about this is not really - * possible, since we are currently running incoherently, and - * therefore cannot safely call printk() or anything else - */ - pr_debug("CPU%u: spurious wakeup call\n", cpu); - } -} - -int platform_cpu_kill(unsigned int cpu) -{ - return 1; -} - -/* - * platform-specific code to shutdown a CPU - * - * Called with IRQs disabled - */ -void platform_cpu_die(unsigned int cpu) -{ - /* - * we're ready for shutdown now, so do it - */ - cpu_enter_lowpower(); - platform_do_lowpower(cpu); - - /* - * bring this CPU back into the world of cache - * coherency, and then restore interrupts - */ - cpu_leave_lowpower(); -} - -int platform_cpu_disable(unsigned int cpu) -{ - /* - * we don't allow CPU 0 to be shutdown (it is still too special - * e.g. clock tick interrupts) - */ - return cpu == 0 ? -EPERM : 0; -} diff --git a/trunk/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/trunk/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h index a54e33b0882e..7c43a9bff1a9 100644 --- a/trunk/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/trunk/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -60,11 +60,7 @@ #define MSM_TMR_BASE IOMEM(0xF0200000) #define MSM_TMR_PHYS 0x02000000 -#define MSM_TMR_SIZE SZ_4K - -#define MSM_TMR0_BASE IOMEM(0xF0201000) -#define MSM_TMR0_PHYS 0x02040000 -#define MSM_TMR0_SIZE SZ_4K +#define MSM_TMR_SIZE (SZ_1M) #define MSM_GPT_BASE (MSM_TMR_BASE + 0x4) #define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) diff --git a/trunk/arch/arm/mach-msm/io.c b/trunk/arch/arm/mach-msm/io.c index 800f327a7ecc..f912d7bf1889 100644 --- a/trunk/arch/arm/mach-msm/io.c +++ b/trunk/arch/arm/mach-msm/io.c @@ -105,7 +105,6 @@ static struct map_desc msm8x60_io_desc[] __initdata = { MSM_DEVICE(QGIC_DIST), MSM_DEVICE(QGIC_CPU), MSM_DEVICE(TMR), - MSM_DEVICE(TMR0), MSM_DEVICE(ACC), MSM_DEVICE(GCC), }; diff --git a/trunk/arch/arm/mach-msm/platsmp.c b/trunk/arch/arm/mach-msm/platsmp.c deleted file mode 100644 index 0f427bc94447..000000000000 --- a/trunk/arch/arm/mach-msm/platsmp.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * Copyright (c) 2010, Code Aurora Forum. 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 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "scm-boot.h" - -#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 -#define SCSS_CPU1CORE_RESET 0xD80 -#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 - -/* Mask for edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ -#define GIC_PPI_EDGE_MASK 0xFFFFD7FF - -extern void msm_secondary_startup(void); -/* - * control for which core is the next to come out of the secondary - * boot "holding pen". - */ -volatile int pen_release = -1; - -static DEFINE_SPINLOCK(boot_lock); - -void __cpuinit platform_secondary_init(unsigned int cpu) -{ - /* Configure edge-triggered PPIs */ - writel(GIC_PPI_EDGE_MASK, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); - - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - - /* - * let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - pen_release = -1; - smp_wmb(); - - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); -} - -static __cpuinit void prepare_cold_cpu(unsigned int cpu) -{ - int ret; - ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup), - SCM_FLAG_COLDBOOT_CPU1); - if (ret == 0) { - void *sc1_base_ptr; - sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); - if (sc1_base_ptr) { - writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); - writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET); - writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP); - iounmap(sc1_base_ptr); - } - } else - printk(KERN_DEBUG "Failed to set secondary core boot " - "address\n"); -} - -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - unsigned long timeout; - static int cold_boot_done; - - /* Only need to bring cpu out of reset this way once */ - if (cold_boot_done == false) { - prepare_cold_cpu(cpu); - cold_boot_done = true; - } - - /* - * set synchronisation state between this boot processor - * and the secondary one - */ - spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from - * the holding pen - release it, then wait for it to flag - * that it has been released by resetting pen_release. - * - * Note that "pen_release" is the hardware CPU ID, whereas - * "cpu" is Linux's internal ID. - */ - pen_release = cpu; - __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); - outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); - - /* - * Send the secondary CPU a soft interrupt, thereby causing - * the boot monitor to read the system wide flags register, - * and branch to the address found there. - */ - smp_cross_call(cpumask_of(cpu), 1); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - smp_rmb(); - if (pen_release == -1) - break; - - udelay(10); - } - - /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; -} - -/* - * Initialise the CPU possible map early - this describes the CPUs - * which may be present or become present in the system. The msm8x60 - * does not support the ARM SCU, so just set the possible cpu mask to - * NR_CPUS. - */ -void __init smp_init_cpus(void) -{ - unsigned int i; - - for (i = 0; i < NR_CPUS; i++) - set_cpu_possible(i, true); -} - -void __init platform_smp_prepare_cpus(unsigned int max_cpus) -{ - int i; - - /* - * Initialise the present map, which describes the set of CPUs - * actually populated at the present time. - */ - for (i = 0; i < max_cpus; i++) - set_cpu_present(i, true); -} diff --git a/trunk/arch/arm/mach-msm/scm-boot.c b/trunk/arch/arm/mach-msm/scm-boot.c deleted file mode 100644 index 45cee3e469a5..000000000000 --- a/trunk/arch/arm/mach-msm/scm-boot.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include - -#include "scm.h" -#include "scm-boot.h" - -/* - * Set the cold/warm boot address for one of the CPU cores. - */ -int scm_set_boot_addr(phys_addr_t addr, int flags) -{ - struct { - unsigned int flags; - phys_addr_t addr; - } cmd; - - cmd.addr = addr; - cmd.flags = flags; - return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR, - &cmd, sizeof(cmd), NULL, 0); -} -EXPORT_SYMBOL(scm_set_boot_addr); diff --git a/trunk/arch/arm/mach-msm/scm-boot.h b/trunk/arch/arm/mach-msm/scm-boot.h deleted file mode 100644 index 68f9b6153d74..000000000000 --- a/trunk/arch/arm/mach-msm/scm-boot.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Code Aurora Forum, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * 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 __MACH_SCM_BOOT_H -#define __MACH_SCM_BOOT_H - -#define SCM_BOOT_ADDR 0x1 -#define SCM_FLAG_COLDBOOT_CPU1 0x1 -#define SCM_FLAG_WARMBOOT_CPU1 0x2 -#define SCM_FLAG_WARMBOOT_CPU0 0x4 - -int scm_set_boot_addr(phys_addr_t addr, int flags); - -#endif diff --git a/trunk/arch/arm/mach-msm/scm.c b/trunk/arch/arm/mach-msm/scm.c deleted file mode 100644 index f4b9bc90d6a7..000000000000 --- a/trunk/arch/arm/mach-msm/scm.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "scm.h" - -/* Cache line size for msm8x60 */ -#define CACHELINESIZE 32 - -#define SCM_ENOMEM -5 -#define SCM_EOPNOTSUPP -4 -#define SCM_EINVAL_ADDR -3 -#define SCM_EINVAL_ARG -2 -#define SCM_ERROR -1 -#define SCM_INTERRUPTED 1 - -static DEFINE_MUTEX(scm_lock); - -/** - * struct scm_command - one SCM command buffer - * @len: total available memory for command and response - * @buf_offset: start of command buffer - * @resp_hdr_offset: start of response buffer - * @id: command to be executed - * @buf: buffer returned from scm_get_command_buffer() - * - * An SCM command is layed out in memory as follows: - * - * ------------------- <--- struct scm_command - * | command header | - * ------------------- <--- scm_get_command_buffer() - * | command buffer | - * ------------------- <--- struct scm_response and - * | response header | scm_command_to_response() - * ------------------- <--- scm_get_response_buffer() - * | response buffer | - * ------------------- - * - * There can be arbitrary padding between the headers and buffers so - * you should always use the appropriate scm_get_*_buffer() routines - * to access the buffers in a safe manner. - */ -struct scm_command { - u32 len; - u32 buf_offset; - u32 resp_hdr_offset; - u32 id; - u32 buf[0]; -}; - -/** - * struct scm_response - one SCM response buffer - * @len: total available memory for response - * @buf_offset: start of response data relative to start of scm_response - * @is_complete: indicates if the command has finished processing - */ -struct scm_response { - u32 len; - u32 buf_offset; - u32 is_complete; -}; - -/** - * alloc_scm_command() - Allocate an SCM command - * @cmd_size: size of the command buffer - * @resp_size: size of the response buffer - * - * Allocate an SCM command, including enough room for the command - * and response headers as well as the command and response buffers. - * - * Returns a valid &scm_command on success or %NULL if the allocation fails. - */ -static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size) -{ - struct scm_command *cmd; - size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size + - resp_size; - - cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL); - if (cmd) { - cmd->len = len; - cmd->buf_offset = offsetof(struct scm_command, buf); - cmd->resp_hdr_offset = cmd->buf_offset + cmd_size; - } - return cmd; -} - -/** - * free_scm_command() - Free an SCM command - * @cmd: command to free - * - * Free an SCM command. - */ -static inline void free_scm_command(struct scm_command *cmd) -{ - kfree(cmd); -} - -/** - * scm_command_to_response() - Get a pointer to a scm_response - * @cmd: command - * - * Returns a pointer to a response for a command. - */ -static inline struct scm_response *scm_command_to_response( - const struct scm_command *cmd) -{ - return (void *)cmd + cmd->resp_hdr_offset; -} - -/** - * scm_get_command_buffer() - Get a pointer to a command buffer - * @cmd: command - * - * Returns a pointer to the command buffer of a command. - */ -static inline void *scm_get_command_buffer(const struct scm_command *cmd) -{ - return (void *)cmd->buf; -} - -/** - * scm_get_response_buffer() - Get a pointer to a response buffer - * @rsp: response - * - * Returns a pointer to a response buffer of a response. - */ -static inline void *scm_get_response_buffer(const struct scm_response *rsp) -{ - return (void *)rsp + rsp->buf_offset; -} - -static int scm_remap_error(int err) -{ - switch (err) { - case SCM_ERROR: - return -EIO; - case SCM_EINVAL_ADDR: - case SCM_EINVAL_ARG: - return -EINVAL; - case SCM_EOPNOTSUPP: - return -EOPNOTSUPP; - case SCM_ENOMEM: - return -ENOMEM; - } - return -EINVAL; -} - -static u32 smc(u32 cmd_addr) -{ - int context_id; - register u32 r0 asm("r0") = 1; - register u32 r1 asm("r1") = (u32)&context_id; - register u32 r2 asm("r2") = cmd_addr; - asm( - __asmeq("%0", "r0") - __asmeq("%1", "r0") - __asmeq("%2", "r1") - __asmeq("%3", "r2") - "smc #0 @ switch to secure world\n" - : "=r" (r0) - : "r" (r0), "r" (r1), "r" (r2) - : "r3"); - return r0; -} - -static int __scm_call(const struct scm_command *cmd) -{ - int ret; - u32 cmd_addr = virt_to_phys(cmd); - - /* - * Flush the entire cache here so callers don't have to remember - * to flush the cache when passing physical addresses to the secure - * side in the buffer. - */ - flush_cache_all(); - do { - ret = smc(cmd_addr); - if (ret < 0) { - ret = scm_remap_error(ret); - break; - } - } while (ret == SCM_INTERRUPTED); - - return ret; -} - -/** - * scm_call() - Send an SCM command - * @svc_id: service identifier - * @cmd_id: command identifier - * @cmd_buf: command buffer - * @cmd_len: length of the command buffer - * @resp_buf: response buffer - * @resp_len: length of the response buffer - * - * Sends a command to the SCM and waits for the command to finish processing. - */ -int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, - void *resp_buf, size_t resp_len) -{ - int ret; - struct scm_command *cmd; - struct scm_response *rsp; - - cmd = alloc_scm_command(cmd_len, resp_len); - if (!cmd) - return -ENOMEM; - - cmd->id = (svc_id << 10) | cmd_id; - if (cmd_buf) - memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len); - - mutex_lock(&scm_lock); - ret = __scm_call(cmd); - mutex_unlock(&scm_lock); - if (ret) - goto out; - - rsp = scm_command_to_response(cmd); - do { - u32 start = (u32)rsp; - u32 end = (u32)scm_get_response_buffer(rsp) + resp_len; - start &= ~(CACHELINESIZE - 1); - while (start < end) { - asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start) - : "memory"); - start += CACHELINESIZE; - } - } while (!rsp->is_complete); - - if (resp_buf) - memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len); -out: - free_scm_command(cmd); - return ret; -} -EXPORT_SYMBOL(scm_call); - -u32 scm_get_version(void) -{ - int context_id; - static u32 version = -1; - register u32 r0 asm("r0") = 0x1 << 8; - register u32 r1 asm("r1") = (u32)&context_id; - - if (version != -1) - return version; - - mutex_lock(&scm_lock); - asm( - __asmeq("%0", "r1") - __asmeq("%1", "r0") - __asmeq("%2", "r1") - "smc #0 @ switch to secure world\n" - : "=r" (r1) - : "r" (r0), "r" (r1) - : "r2", "r3"); - version = r1; - mutex_unlock(&scm_lock); - - return version; -} -EXPORT_SYMBOL(scm_get_version); diff --git a/trunk/arch/arm/mach-msm/scm.h b/trunk/arch/arm/mach-msm/scm.h deleted file mode 100644 index 261786be11c5..000000000000 --- a/trunk/arch/arm/mach-msm/scm.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Code Aurora Forum, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * 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 __MACH_SCM_H -#define __MACH_SCM_H - -#define SCM_SVC_BOOT 0x1 -#define SCM_SVC_PIL 0x2 - -extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, - void *resp_buf, size_t resp_len); - -#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) - -extern u32 scm_get_version(void); - -#endif diff --git a/trunk/arch/arm/mach-msm/timer.c b/trunk/arch/arm/mach-msm/timer.c index c105d28b53e3..595be7fea31a 100644 --- a/trunk/arch/arm/mach-msm/timer.c +++ b/trunk/arch/arm/mach-msm/timer.c @@ -47,19 +47,6 @@ enum { #define GPT_HZ 32768 -enum timer_location { - LOCAL_TIMER = 0, - GLOBAL_TIMER = 1, -}; - -#ifdef MSM_TMR0_BASE -#define MSM_TMR_GLOBAL (MSM_TMR0_BASE - MSM_TMR_BASE) -#else -#define MSM_TMR_GLOBAL 0 -#endif - -#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT - #if defined(CONFIG_ARCH_QSD8X50) #define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ #define MSM_DGT_SHIFT (0) @@ -78,67 +65,49 @@ struct msm_clock { void __iomem *regbase; uint32_t freq; uint32_t shift; - void __iomem *global_counter; - void __iomem *local_counter; -}; - -enum { - MSM_CLOCK_GPT, - MSM_CLOCK_DGT, - NR_TIMERS, }; - -static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event; - static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; - if (smp_processor_id() != 0) - evt = local_clock_event; - if (evt->event_handler == NULL) - return IRQ_HANDLED; evt->event_handler(evt); return IRQ_HANDLED; } -static cycle_t msm_read_timer_count(struct clocksource *cs) +static cycle_t msm_gpt_read(struct clocksource *cs) { - struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource); - - return readl(clk->global_counter); + return readl(MSM_GPT_BASE + TIMER_COUNT_VAL); } -static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt) +static cycle_t msm_dgt_read(struct clocksource *cs) { -#ifdef CONFIG_SMP - int i; - for (i = 0; i < NR_TIMERS; i++) - if (evt == &(msm_clocks[i].clockevent)) - return &msm_clocks[i]; - return &msm_clocks[MSM_GLOBAL_TIMER]; -#else - return container_of(evt, struct msm_clock, clockevent); -#endif + return readl(MSM_DGT_BASE + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT; } static int msm_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - struct msm_clock *clock = clockevent_to_clock(evt); - uint32_t now = readl(clock->local_counter); + struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent); + uint32_t now = readl(clock->regbase + TIMER_COUNT_VAL); uint32_t alarm = now + (cycles << clock->shift); + int late; writel(alarm, clock->regbase + TIMER_MATCH_VAL); + now = readl(clock->regbase + TIMER_COUNT_VAL); + late = now - alarm; + if (late >= (-2 << clock->shift) && late < DGT_HZ*5) { + printk(KERN_NOTICE "msm_timer_set_next_event(%lu) clock %s, " + "alarm already expired, now %x, alarm %x, late %d\n", + cycles, clock->clockevent.name, now, alarm, late); + return -ETIME; + } return 0; } static void msm_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - struct msm_clock *clock = clockevent_to_clock(evt); - + struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent); switch (mode) { case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_PERIODIC: @@ -154,7 +123,7 @@ static void msm_timer_set_mode(enum clock_event_mode mode, } static struct msm_clock msm_clocks[] = { - [MSM_CLOCK_GPT] = { + { .clockevent = { .name = "gp_timer", .features = CLOCK_EVT_FEAT_ONESHOT, @@ -166,7 +135,7 @@ static struct msm_clock msm_clocks[] = { .clocksource = { .name = "gp_timer", .rating = 200, - .read = msm_read_timer_count, + .read = msm_gpt_read, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }, @@ -178,12 +147,9 @@ static struct msm_clock msm_clocks[] = { .irq = INT_GP_TIMER_EXP }, .regbase = MSM_GPT_BASE, - .freq = GPT_HZ, - .local_counter = MSM_GPT_BASE + TIMER_COUNT_VAL, - .global_counter = MSM_GPT_BASE + TIMER_COUNT_VAL + - MSM_TMR_GLOBAL, + .freq = GPT_HZ }, - [MSM_CLOCK_DGT] = { + { .clockevent = { .name = "dg_timer", .features = CLOCK_EVT_FEAT_ONESHOT, @@ -195,7 +161,7 @@ static struct msm_clock msm_clocks[] = { .clocksource = { .name = "dg_timer", .rating = 300, - .read = msm_read_timer_count, + .read = msm_dgt_read, .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }, @@ -208,10 +174,7 @@ static struct msm_clock msm_clocks[] = { }, .regbase = MSM_DGT_BASE, .freq = DGT_HZ >> MSM_DGT_SHIFT, - .shift = MSM_DGT_SHIFT, - .local_counter = MSM_DGT_BASE + TIMER_COUNT_VAL, - .global_counter = MSM_DGT_BASE + TIMER_COUNT_VAL + - MSM_TMR_GLOBAL, + .shift = MSM_DGT_SHIFT } }; @@ -220,7 +183,7 @@ static void __init msm_timer_init(void) int i; int res; -#ifdef CONFIG_ARCH_MSM_SCORPIONMP +#ifdef CONFIG_ARCH_MSM8X60 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); #endif @@ -254,48 +217,6 @@ static void __init msm_timer_init(void) } } -#ifdef CONFIG_SMP -void __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; - - /* Use existing clock_event for cpu 0 */ - if (!smp_processor_id()) - return; - - writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); - - if (!local_clock_event) { - writel(0, clock->regbase + TIMER_ENABLE); - writel(0, clock->regbase + TIMER_CLEAR); - writel(~0, clock->regbase + TIMER_MATCH_VAL); - } - evt->irq = clock->irq.irq; - evt->name = "local_timer"; - evt->features = CLOCK_EVT_FEAT_ONESHOT; - evt->rating = clock->clockevent.rating; - evt->set_mode = msm_timer_set_mode; - evt->set_next_event = msm_timer_set_next_event; - evt->shift = clock->clockevent.shift; - evt->mult = div_sc(clock->freq, NSEC_PER_SEC, evt->shift); - evt->max_delta_ns = - clockevent_delta2ns(0xf0000000 >> clock->shift, evt); - evt->min_delta_ns = clockevent_delta2ns(4, evt); - - local_clock_event = evt; - - gic_enable_ppi(clock->irq.irq); - - clockevents_register_device(evt); -} - -inline int local_timer_ack(void) -{ - return 1; -} - -#endif - struct sys_timer msm_timer = { .init = msm_timer_init }; diff --git a/trunk/arch/arm/mach-ux500/clock.c b/trunk/arch/arm/mach-ux500/clock.c index ccff2dae167f..b2b0a3b9be8f 100644 --- a/trunk/arch/arm/mach-ux500/clock.c +++ b/trunk/arch/arm/mach-ux500/clock.c @@ -136,8 +136,7 @@ EXPORT_SYMBOL(clk_disable); */ static unsigned long clk_mtu_get_rate(struct clk *clk) { - void __iomem *addr = __io_address(UX500_PRCMU_BASE) - + PRCM_TCR; + void __iomem *addr; u32 tcr; int mtu = (int) clk->data; /* @@ -149,13 +148,20 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) unsigned long mturate; unsigned long retclk; + if (cpu_is_u5500()) + addr = __io_address(U5500_PRCMU_BASE); + else if (cpu_is_u8500()) + addr = __io_address(U8500_PRCMU_BASE); + else + ux500_unknown_soc(); + /* * On a startup, always conifgure the TCR to the doze mode; * bootloaders do it for us. Do this in the kernel too. */ - writel(PRCM_TCR_DOZE_MODE, addr); + writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR); - tcr = readl(addr); + tcr = readl(addr + PRCM_TCR); /* Get the rate from the parent as a default */ if (clk->parent_periph) diff --git a/trunk/arch/arm/mach-ux500/cpu-db5500.c b/trunk/arch/arm/mach-ux500/cpu-db5500.c index acc841e48de4..7b0ab8336f3f 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db5500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db5500.c @@ -22,6 +22,16 @@ #include "devices-db5500.h" static struct map_desc u5500_io_desc[] __initdata = { + __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_UART2_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K), + __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K), + __IO_DEV_DESC(U5500_TWD_BASE, SZ_4K), + __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), + __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K), @@ -143,8 +153,6 @@ static void __init db5500_add_gpios(void) void __init u5500_map_io(void) { - ux500_map_io(); - iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); } diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index c0f34a404c53..1b2b81c0f27c 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -30,6 +30,22 @@ static struct platform_device *platform_devs[] __initdata = { /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), + __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), + __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), + __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), + __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), + __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), + + __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), + __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), @@ -117,8 +133,6 @@ bool cpu_is_u8500v20(void) void __init u8500_map_io(void) { - ux500_map_io(); - iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); if (cpu_is_u8500ed()) diff --git a/trunk/arch/arm/mach-ux500/cpu.c b/trunk/arch/arm/mach-ux500/cpu.c index 5730409c0f7d..35a3af13fb30 100644 --- a/trunk/arch/arm/mach-ux500/cpu.c +++ b/trunk/arch/arm/mach-ux500/cpu.c @@ -23,37 +23,29 @@ #include "clock.h" -static struct map_desc ux500_io_desc[] __initdata = { - __IO_DEV_DESC(UX500_UART0_BASE, SZ_4K), - __IO_DEV_DESC(UX500_UART2_BASE, SZ_4K), - - __IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K), - __IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K), - __IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K), - __IO_DEV_DESC(UX500_TWD_BASE, SZ_4K), - __IO_DEV_DESC(UX500_SCU_BASE, SZ_4K), - - __IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K), - __IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K), - __IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K), - __IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K), - __IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K), - - __IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K), - __IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K), - - __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), -}; +#ifdef CONFIG_CACHE_L2X0 +static void __iomem *l2x0_base; +#endif void __init ux500_map_io(void) { - iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); } void __init ux500_init_irq(void) { - gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE), - __io_address(UX500_GIC_CPU_BASE)); + void __iomem *dist_base; + void __iomem *cpu_base; + + if (cpu_is_u5500()) { + dist_base = __io_address(U5500_GIC_DIST_BASE); + cpu_base = __io_address(U5500_GIC_CPU_BASE); + } else if (cpu_is_u8500()) { + dist_base = __io_address(U8500_GIC_DIST_BASE); + cpu_base = __io_address(U8500_GIC_CPU_BASE); + } else + ux500_unknown_soc(); + + gic_init(0, 29, dist_base, cpu_base); /* * Init clocks here so that they are available for system timer @@ -74,7 +66,8 @@ static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) static inline void ux500_cache_sync(void) { - void __iomem *base = __io_address(UX500_L2CC_BASE); + void __iomem *base = l2x0_base; + writel_relaxed(0, base + L2X0_CACHE_SYNC); ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); } @@ -96,20 +89,23 @@ static void ux500_l2x0_disable(void) */ static void ux500_l2x0_inv_all(void) { - void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE); + void __iomem *base = l2x0_base; uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ /* invalidate all ways */ - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); - ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); + writel_relaxed(l2x0_way_mask, base + L2X0_INV_WAY); + ux500_cache_wait(base + L2X0_INV_WAY, l2x0_way_mask); ux500_cache_sync(); } static int ux500_l2x0_init(void) { - void __iomem *l2x0_base; - - l2x0_base = __io_address(UX500_L2CC_BASE); + if (cpu_is_u5500()) + l2x0_base = __io_address(U5500_L2CC_BASE); + else if (cpu_is_u8500()) + l2x0_base = __io_address(U8500_L2CC_BASE); + else + ux500_unknown_soc(); /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); @@ -127,13 +123,21 @@ static void __init ux500_timer_init(void) { #ifdef CONFIG_LOCAL_TIMERS /* Setup the local timer base */ - twd_base = __io_address(UX500_TWD_BASE); + if (cpu_is_u5500()) + twd_base = __io_address(U5500_TWD_BASE); + else if (cpu_is_u8500()) + twd_base = __io_address(U8500_TWD_BASE); + else + ux500_unknown_soc(); #endif - /* Setup the MTU base */ - if (cpu_is_u8500ed()) + if (cpu_is_u5500()) + mtu_base = __io_address(U5500_MTU0_BASE); + else if (cpu_is_u8500ed()) mtu_base = __io_address(U8500_MTU0_BASE_ED); + else if (cpu_is_u8500()) + mtu_base = __io_address(U8500_MTU0_BASE); else - mtu_base = __io_address(UX500_MTU0_BASE); + ux500_unknown_soc(); nmdk_timer_init(); } diff --git a/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S b/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S index be7c0f14e310..700fb05ee815 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-ux500/include/mach/debug-macro.S @@ -14,7 +14,24 @@ #error Invalid Ux500 debug UART #endif -#define __UX500_UART(n) UX500_UART##n##_BASE +/* + * DEBUG_LL only works if only one SOC is built in. We don't use #else below + * in order to get "__UX500_UART redefined" warnings if more than one SOC is + * built, so that there's some hint during the build that something is wrong. + */ + +#ifdef CONFIG_UX500_SOC_DB5500 +#define __UX500_UART(n) U5500_UART##n##_BASE +#endif + +#ifdef CONFIG_UX500_SOC_DB8500 +#define __UX500_UART(n) U8500_UART##n##_BASE +#endif + +#ifndef __UX500_UART +#error Unknown SOC +#endif + #define UX500_UART(n) __UX500_UART(n) #define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART) diff --git a/trunk/arch/arm/mach-ux500/include/mach/entry-macro.S b/trunk/arch/arm/mach-ux500/include/mach/entry-macro.S index a37f585a3ecb..071bba94f727 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-ux500/include/mach/entry-macro.S @@ -11,15 +11,10 @@ * warranty of any kind, whether express or implied. */ #include -#define HAVE_GET_IRQNR_PREAMBLE #include .macro disable_fiq .endm - .macro get_irqnr_preamble, base, tmp - ldr \base, =IO_ADDRESS(UX500_GIC_CPU_BASE) - .endm - .macro arch_ret_to_user, tmp1, tmp2 .endm diff --git a/trunk/arch/arm/mach-ux500/include/mach/hardware.h b/trunk/arch/arm/mach-ux500/include/mach/hardware.h index 6295cc581355..bced4a8e16ef 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/hardware.h +++ b/trunk/arch/arm/mach-ux500/include/mach/hardware.h @@ -29,65 +29,6 @@ #include #include -#ifdef CONFIG_UX500_SOC_DB8500 -#define UX500(periph) U8500_##periph##_BASE -#elif defined(CONFIG_UX500_SOC_DB5500) -#define UX500(periph) U5500_##periph##_BASE -#endif - -#define UX500_BACKUPRAM0_BASE UX500(BACKUPRAM0) -#define UX500_BACKUPRAM1_BASE UX500(BACKUPRAM1) -#define UX500_B2R2_BASE UX500(B2R2) - -#define UX500_CLKRST1_BASE UX500(CLKRST1) -#define UX500_CLKRST2_BASE UX500(CLKRST2) -#define UX500_CLKRST3_BASE UX500(CLKRST3) -#define UX500_CLKRST5_BASE UX500(CLKRST5) -#define UX500_CLKRST6_BASE UX500(CLKRST6) - -#define UX500_DMA_BASE UX500(DMA) -#define UX500_FSMC_BASE UX500(FSMC) - -#define UX500_GIC_CPU_BASE UX500(GIC_CPU) -#define UX500_GIC_DIST_BASE UX500(GIC_DIST) - -#define UX500_I2C1_BASE UX500(I2C1) -#define UX500_I2C2_BASE UX500(I2C2) -#define UX500_I2C3_BASE UX500(I2C3) - -#define UX500_L2CC_BASE UX500(L2CC) -#define UX500_MCDE_BASE UX500(MCDE) -#define UX500_MTU0_BASE UX500(MTU0) -#define UX500_MTU1_BASE UX500(MTU1) -#define UX500_PRCMU_BASE UX500(PRCMU) - -#define UX500_RNG_BASE UX500(RNG) -#define UX500_RTC_BASE UX500(RTC) - -#define UX500_SCU_BASE UX500(SCU) - -#define UX500_SDI0_BASE UX500(SDI0) -#define UX500_SDI1_BASE UX500(SDI1) -#define UX500_SDI2_BASE UX500(SDI2) -#define UX500_SDI3_BASE UX500(SDI3) -#define UX500_SDI4_BASE UX500(SDI4) - -#define UX500_SPI0_BASE UX500(SPI0) -#define UX500_SPI1_BASE UX500(SPI1) -#define UX500_SPI2_BASE UX500(SPI2) -#define UX500_SPI3_BASE UX500(SPI3) - -#define UX500_SIA_BASE UX500(SIA) -#define UX500_SVA_BASE UX500(SVA) - -#define UX500_TWD_BASE UX500(TWD) - -#define UX500_UART0_BASE UX500(UART0) -#define UX500_UART1_BASE UX500(UART1) -#define UX500_UART2_BASE UX500(UART2) - -#define UX500_USBOTG_BASE UX500(USBOTG) - /* ST-Ericsson modified pl022 id */ #define SSP_PER_ID 0x01080022 @@ -143,6 +84,7 @@ static inline bool cpu_is_u5500(void) } #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) +#define ux500_unknown_soc() BUG() #endif diff --git a/trunk/arch/arm/mach-ux500/include/mach/setup.h b/trunk/arch/arm/mach-ux500/include/mach/setup.h index 469877e0de90..5d8423294d41 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/setup.h +++ b/trunk/arch/arm/mach-ux500/include/mach/setup.h @@ -14,7 +14,6 @@ #include #include -extern void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index d77e76cb7edd..4fff4d408417 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * control for which core is the next to come out of the secondary @@ -40,6 +41,18 @@ static void write_pen_release(int val) outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); } +static void __iomem *scu_base_addr(void) +{ + if (cpu_is_u5500()) + return __io_address(U5500_SCU_BASE); + else if (cpu_is_u8500()) + return __io_address(U8500_SCU_BASE); + else + ux500_unknown_soc(); + + return NULL; +} + static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) @@ -100,21 +113,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init wakeup_secondary(void) { + void __iomem *backupram; + + if (cpu_is_u5500()) + backupram = __io_address(U5500_BACKUPRAM0_BASE); + else if (cpu_is_u8500()) + backupram = __io_address(U8500_BACKUPRAM0_BASE); + else + ux500_unknown_soc(); + /* * write the address of secondary startup into the backup ram register * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the * backup ram register at offset 0x1FF0, which is what boot rom code * is waiting for. This would wake up the secondary core from WFE */ -#define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4 +#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4 __raw_writel(virt_to_phys(u8500_secondary_startup), - __io_address(UX500_BACKUPRAM0_BASE) + - U8500_CPU1_JUMPADDR_OFFSET); + backupram + UX500_CPU1_JUMPADDR_OFFSET); -#define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 +#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 __raw_writel(0xA1FEED01, - __io_address(UX500_BACKUPRAM0_BASE) + - U8500_CPU1_WAKEMAGIC_OFFSET); + backupram + UX500_CPU1_WAKEMAGIC_OFFSET); /* make sure write buffer is drained */ mb(); @@ -126,9 +146,10 @@ static void __init wakeup_secondary(void) */ void __init smp_init_cpus(void) { + void __iomem *scu_base = scu_base_addr(); unsigned int i, ncores; - ncores = scu_get_core_count(__io_address(UX500_SCU_BASE)); + ncores = scu_base ? scu_get_core_count(scu_base) : 1; /* sanity check */ if (ncores > NR_CPUS) { @@ -154,6 +175,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) for (i = 0; i < max_cpus; i++) set_cpu_present(i, true); - scu_enable(__io_address(UX500_SCU_BASE)); + scu_enable(scu_base_addr()); wakeup_secondary(); } diff --git a/trunk/arch/arm/plat-s3c24xx/cpu-freq.c b/trunk/arch/arm/plat-s3c24xx/cpu-freq.c index 25a8fc7f512e..1ecc15bfe9d4 100644 --- a/trunk/arch/arm/plat-s3c24xx/cpu-freq.c +++ b/trunk/arch/arm/plat-s3c24xx/cpu-freq.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index 5f5018a71a3d..387d5ffdfd3a 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -14,7 +14,7 @@ config MICROBLAZE select HAVE_DMA_API_DEBUG select TRACING_SUPPORT select OF - select OF_EARLY_FLATTREE + select OF_FLATTREE config SWAP def_bool n diff --git a/trunk/arch/microblaze/boot/Makefile b/trunk/arch/microblaze/boot/Makefile index 4c4e58ef0cb6..be01d78750d9 100644 --- a/trunk/arch/microblaze/boot/Makefile +++ b/trunk/arch/microblaze/boot/Makefile @@ -10,6 +10,9 @@ targets := linux.bin linux.bin.gz simpleImage.% OBJCOPYFLAGS := -O binary +# Where the DTS files live +dtstree := $(srctree)/$(src)/dts + # Ensure system.dtb exists $(obj)/linked_dtb.o: $(obj)/system.dtb @@ -48,11 +51,14 @@ $(obj)/simpleImage.%: vmlinux FORCE $(call if_changed,strip) @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' +# Rule to build device tree blobs +DTC = $(objtree)/scripts/dtc/dtc # Rule to build device tree blobs -DTC_FLAGS := -p 1024 +quiet_cmd_dtc = DTC $@ + cmd_dtc = $(DTC) -O dtb -o $(obj)/$*.dtb -b 0 -p 1024 $(dtstree)/$*.dts -$(obj)/%.dtb: $(src)/dts/%.dts FORCE - $(call cmd,dtc) +$(obj)/%.dtb: $(dtstree)/%.dts FORCE + $(call if_changed,dtc) clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub diff --git a/trunk/arch/microblaze/include/asm/prom.h b/trunk/arch/microblaze/include/asm/prom.h index 2e72af078b05..bdc38312ae4a 100644 --- a/trunk/arch/microblaze/include/asm/prom.h +++ b/trunk/arch/microblaze/include/asm/prom.h @@ -64,6 +64,9 @@ extern void kdump_move_device_tree(void); /* CPU OF node matching */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); +/* Get the MAC address */ +extern const void *of_get_mac_address(struct device_node *np); + /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved diff --git a/trunk/arch/microblaze/kernel/prom_parse.c b/trunk/arch/microblaze/kernel/prom_parse.c index 9ae24f4b882b..99d9b61cccb5 100644 --- a/trunk/arch/microblaze/kernel/prom_parse.c +++ b/trunk/arch/microblaze/kernel/prom_parse.c @@ -110,3 +110,41 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, cells = prop ? *(u32 *)prop : of_n_size_cells(dn); *size = of_read_number(dma_window, cells); } + +/** + * Search the device tree for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the device tree, but were not set by U-Boot. For example, the + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC + * addresses. Some older U-Boots only initialized 'local-mac-address'. In + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists + * but is all zeros. +*/ +const void *of_get_mac_address(struct device_node *np) +{ + struct property *pp; + + pp = of_find_property(np, "mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "local-mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + return NULL; +} +EXPORT_SYMBOL(of_get_mac_address); diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index f489ec30e071..0a9b5b8b2a19 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -2218,7 +2218,7 @@ config SECCOMP config USE_OF bool "Flattened Device Tree support" select OF - select OF_EARLY_FLATTREE + select OF_FLATTREE help Include support for flattened device tree machine descriptions. diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 48fb4790bfec..e625e9e034ae 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -116,7 +116,7 @@ config PPC bool default y select OF - select OF_EARLY_FLATTREE + select OF_FLATTREE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 96deec63bcf3..fae8192c8fcc 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -35,7 +35,7 @@ endif BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -DTC_FLAGS ?= -p 1024 +DTS_FLAGS ?= -p 1024 $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 @@ -332,8 +332,10 @@ $(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb) # Rule to build device tree blobs -$(obj)/%.dtb: $(src)/dts/%.dts - $(call cmd,dtc) +DTC = $(objtree)/scripts/dtc/dtc + +$(obj)/%.dtb: $(dtstree)/%.dts + $(DTC) -O dtb -o $(obj)/$*.dtb -b 0 $(DTS_FLAGS) $(dtstree)/$*.dts # If there isn't a platform selected then just strip the vmlinux. ifeq (,$(image-y)) diff --git a/trunk/arch/powerpc/boot/dts/bluestone.dts b/trunk/arch/powerpc/boot/dts/bluestone.dts index 2a56a0dbd1f7..9bb3d72c0e5a 100644 --- a/trunk/arch/powerpc/boot/dts/bluestone.dts +++ b/trunk/arch/powerpc/boot/dts/bluestone.dts @@ -33,7 +33,7 @@ aliases { ethernet0 = &EMAC0; serial0 = &UART0; - //serial1 = &UART1; --gcl missing UART1 label + serial1 = &UART1; }; cpus { @@ -52,7 +52,7 @@ d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; - //next-level-cache = <&L2C0>; --gcl missing L2C0 label + next-level-cache = <&L2C0>; }; }; @@ -142,7 +142,7 @@ /*RXEOB*/ 0x7 0x4 /*SERR*/ 0x3 0x4 /*TXDE*/ 0x4 0x4 - /*RXDE*/ 0x5 0x4>; + /*RXDE*/ 0x5 0x4 }; POB0: opb { @@ -182,7 +182,7 @@ reg = <0x001a0000 0x00060000>; }; }; - }; + } UART0: serial@ef600300 { device_type = "serial"; diff --git a/trunk/arch/powerpc/boot/dts/cm5200.dts b/trunk/arch/powerpc/boot/dts/cm5200.dts index ad3a4f4a2b04..dd3860846f15 100644 --- a/trunk/arch/powerpc/boot/dts/cm5200.dts +++ b/trunk/arch/powerpc/boot/dts/cm5200.dts @@ -10,74 +10,220 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "schindler,cm5200"; compatible = "schindler,cm5200"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x04000000>; // 64MB + }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; - can@900 { - status = "disabled"; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; }; - can@980 { - status = "disabled"; + timer@620 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; }; - psc@2000 { // PSC1 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + timer@630 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; }; - psc@2200 { // PSC2 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + timer@640 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; + }; + + timer@650 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; + }; + + timer@660 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; + }; + + timer@670 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; + }; + + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; + }; + + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2400 { // PSC3 + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + serial@2000 { // PSC1 compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; - psc@2600 { // PSC4 - status = "disabled"; + serial@2200 { // PSC2 + compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2200 0x100>; + interrupts = <2 2 0>; }; - psc@2800 { // PSC5 - status = "disabled"; + serial@2400 { // PSC3 + compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2400 0x100>; + interrupts = <2 3 0>; }; - psc@2c00 { // PSC6 + serial@2c00 { // PSC6 compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; - ata@3a00 { - status = "disabled"; + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; }; - i2c@3d00 { - status = "disabled"; + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; }; - - }; - - pci@f0000d00 { - status = "disabled"; }; localbus { + compatible = "fsl,mpc5200b-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xfc000000 0x2000000>; + // 16-bit flash device at LocalPlus Bus CS0 flash@0,0 { compatible = "cfi-flash"; diff --git a/trunk/arch/powerpc/boot/dts/digsy_mtc.dts b/trunk/arch/powerpc/boot/dts/digsy_mtc.dts index 27bd267d631c..8e9be6bfe23e 100644 --- a/trunk/arch/powerpc/boot/dts/digsy_mtc.dts +++ b/trunk/arch/powerpc/boot/dts/digsy_mtc.dts @@ -11,68 +11,195 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "intercontrol,digsy-mtc"; compatible = "intercontrol,digsy-mtc"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; memory { + device_type = "memory"; reg = <0x00000000 0x02000000>; // 32MB }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; - rtc@800 { - status = "disabled"; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; }; - can@900 { - status = "disabled"; + timer@620 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; }; - can@980 { - status = "disabled"; + timer@630 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; }; - psc@2000 { // PSC1 - status = "disabled"; + timer@640 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; }; - psc@2200 { // PSC2 - status = "disabled"; + timer@650 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; }; - psc@2400 { // PSC3 - status = "disabled"; + timer@660 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; }; - psc@2600 { // PSC4 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + timer@670 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; + }; + + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; }; - psc@2800 { // PSC5 + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + serial@2600 { // PSC4 compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2600 0x100>; + interrupts = <2 11 0>; }; - psc@2c00 { // PSC6 - status = "disabled"; + serial@2800 { // PSC5 + compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2800 0x100>; + interrupts = <2 12 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + rtc@50 { compatible = "at,24c08"; reg = <0x50>; @@ -84,16 +211,16 @@ }; }; - i2c@3d40 { - status = "disabled"; + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; }; }; - pci@f0000d00 { - status = "disabled"; - }; - - localbus { + lpb { + compatible = "fsl,mpc5200b-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; ranges = <0 0 0xff000000 0x1000000>; // 16-bit flash device at LocalPlus Bus CS0 diff --git a/trunk/arch/powerpc/boot/dts/hotfoot.dts b/trunk/arch/powerpc/boot/dts/hotfoot.dts index 71d3bb4931dc..cad9c3840afc 100644 --- a/trunk/arch/powerpc/boot/dts/hotfoot.dts +++ b/trunk/arch/powerpc/boot/dts/hotfoot.dts @@ -117,8 +117,6 @@ }; IIC: i2c@ef600500 { - #address-cells = <1>; - #size-cells = <0>; compatible = "ibm,iic-405ep", "ibm,iic"; reg = <0xef600500 0x00000011>; interrupt-parent = <&UIC0>; diff --git a/trunk/arch/powerpc/boot/dts/lite5200b.dts b/trunk/arch/powerpc/boot/dts/lite5200b.dts index fb288bb882b6..59702ace900f 100644 --- a/trunk/arch/powerpc/boot/dts/lite5200b.dts +++ b/trunk/arch/powerpc/boot/dts/lite5200b.dts @@ -10,75 +10,256 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "fsl,lite5200b"; compatible = "fsl,lite5200b"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; memory { + device_type = "memory"; reg = <0x00000000 0x10000000>; // 256MB }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; - psc@2000 { // PSC1 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - cell-index = <0>; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; + }; + + timer@620 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; + }; + + timer@630 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; + }; + + timer@640 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; + }; + + timer@650 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; + }; + + timer@660 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; + }; + + timer@670 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; + }; + + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; }; - psc@2200 { // PSC2 - status = "disabled"; + can@900 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + reg = <0x900 0x80>; }; - psc@2400 { // PSC3 - status = "disabled"; + can@980 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; }; - psc@2600 { // PSC4 - status = "disabled"; + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2800 { // PSC5 - status = "disabled"; + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2c00 { // PSC6 - status = "disabled"; + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + serial@2000 { // PSC1 + compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <0>; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; // PSC2 in ac97 mode example //ac97@2200 { // PSC2 // compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97"; // cell-index = <1>; + // reg = <0x2200 0x100>; + // interrupts = <2 2 0>; //}; // PSC3 in CODEC mode example //i2s@2400 { // PSC3 // compatible = "fsl,mpc5200b-psc-i2s"; //not 5200 compatible // cell-index = <2>; + // reg = <0x2400 0x100>; + // interrupts = <2 3 0>; + //}; + + // PSC4 in uart mode example + //serial@2600 { // PSC4 + // compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + // cell-index = <3>; + // reg = <0x2600 0x100>; + // interrupts = <2 11 0>; + //}; + + // PSC5 in uart mode example + //serial@2800 { // PSC5 + // compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + // cell-index = <4>; + // reg = <0x2800 0x100>; + // interrupts = <2 12 0>; //}; // PSC6 in spi mode example //spi@2c00 { // PSC6 // compatible = "fsl,mpc5200b-psc-spi","fsl,mpc5200-psc-spi"; // cell-index = <5>; + // reg = <0x2c00 0x100>; + // interrupts = <2 4 0>; //}; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + }; + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; + eeprom@50 { compatible = "atmel,24c02"; reg = <0x50>; @@ -92,6 +273,12 @@ }; pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot 0xc000 0 0 2 &mpc5200_pic 1 1 3 @@ -111,6 +298,11 @@ }; localbus { + compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xfe000000 0x02000000>; flash@0,0 { diff --git a/trunk/arch/powerpc/boot/dts/media5200.dts b/trunk/arch/powerpc/boot/dts/media5200.dts index 48d72f38e5ed..0c3902bc5b6a 100644 --- a/trunk/arch/powerpc/boot/dts/media5200.dts +++ b/trunk/arch/powerpc/boot/dts/media5200.dts @@ -11,11 +11,14 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "fsl,media5200"; compatible = "fsl,media5200"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; aliases { console = &console; @@ -27,7 +30,16 @@ }; cpus { + #address-cells = <1>; + #size-cells = <0>; + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K timebase-frequency = <33000000>; // 33 MHz, these were configured by U-Boot bus-frequency = <132000000>; // 132 MHz clock-frequency = <396000000>; // 396 MHz @@ -35,57 +47,205 @@ }; memory { + device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB RAM }; - soc5200@f0000000 { + soc@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; bus-frequency = <132000000>;// 132 MHz + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; - psc@2000 { // PSC1 - status = "disabled"; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; + }; + + timer@620 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; + }; + + timer@630 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; + }; + + timer@640 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; + }; + + timer@650 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; + }; + + timer@660 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; + }; + + timer@670 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; + }; + + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; + }; + + can@900 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + reg = <0x900 0x80>; }; - psc@2200 { // PSC2 - status = "disabled"; + can@980 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; }; - psc@2400 { // PSC3 - status = "disabled"; + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2600 { // PSC4 - status = "disabled"; + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2800 { // PSC5 - status = "disabled"; + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0x100>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; }; // PSC6 in uart mode - console: psc@2c00 { // PSC6 + console: serial@2c00 { // PSC6 compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <5>; + port-number = <0>; // Logical port assignment + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; - ethernet@3000 { + eth0: ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; - usb@1000 { - reg = <0x1000 0x100>; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + }; + + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; + }; + + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; }; }; pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = <0xc000 0 0 1 &media5200_fpga 0 2 // 1st slot 0xc000 0 0 2 &media5200_fpga 0 3 @@ -102,29 +262,37 @@ 0xe000 0 0 1 &media5200_fpga 0 5 // CoralIP >; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 10 0>; + interrupt-parent = <&mpc5200_pic>; + bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; - interrupt-parent = <&mpc5200_pic>; }; localbus { + compatible = "fsl,mpc5200b-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges = < 0 0 0xfc000000 0x02000000 1 0 0xfe000000 0x02000000 2 0 0xf0010000 0x00010000 3 0 0xf0020000 0x00010000 >; + flash@0,0 { compatible = "amd,am29lv28ml", "cfi-flash"; - reg = <0 0x0 0x2000000>; // 32 MB - bank-width = <4>; // Width in bytes of the flash bank - device-width = <2>; // Two devices on each bank + reg = <0 0x0 0x2000000>; // 32 MB + bank-width = <4>; // Width in bytes of the flash bank + device-width = <2>; // Two devices on each bank }; flash@1,0 { compatible = "amd,am29lv28ml", "cfi-flash"; - reg = <1 0 0x2000000>; // 32 MB - bank-width = <4>; // Width in bytes of the flash bank - device-width = <2>; // Two devices on each bank + reg = <1 0 0x2000000>; // 32 MB + bank-width = <4>; // Width in bytes of the flash bank + device-width = <2>; // Two devices on each bank }; media5200_fpga: fpga@2,0 { diff --git a/trunk/arch/powerpc/boot/dts/motionpro.dts b/trunk/arch/powerpc/boot/dts/motionpro.dts index 0b78e89ac69b..6ca4fc144a33 100644 --- a/trunk/arch/powerpc/boot/dts/motionpro.dts +++ b/trunk/arch/powerpc/boot/dts/motionpro.dts @@ -10,73 +10,219 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "promess,motionpro"; compatible = "promess,motionpro"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x04000000>; // 64MB + }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; - timer@660 { // Motion-PRO status LED + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; + }; + + timer@620 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; + }; + + timer@630 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; + }; + + timer@640 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; + }; + + timer@650 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; + }; + + motionpro-led@660 { // Motion-PRO status LED compatible = "promess,motionpro-led"; label = "motionpro-statusled"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; blink-delay = <100>; // 100 msec }; - timer@670 { // Motion-PRO ready LED + motionpro-led@670 { // Motion-PRO ready LED compatible = "promess,motionpro-led"; label = "motionpro-readyled"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; }; - can@900 { - status = "disabled"; + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; }; - psc@2000 { // PSC1 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + can@980 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; }; - // PSC2 in spi master mode - psc@2200 { // PSC2 - compatible = "fsl,mpc5200b-psc-spi","fsl,mpc5200-psc-spi"; - cell-index = <1>; + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2400 { // PSC3 - status = "disabled"; + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; - psc@2600 { // PSC4 - status = "disabled"; + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; }; - psc@2800 { // PSC5 + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + serial@2000 { // PSC1 compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; + }; + + // PSC2 in spi master mode + spi@2200 { // PSC2 + compatible = "fsl,mpc5200b-psc-spi","fsl,mpc5200-psc-spi"; + cell-index = <1>; + reg = <0x2200 0x100>; + interrupts = <2 2 0>; }; - psc@2c00 { // PSC6 - status = "disabled"; + // PSC5 in uart mode + serial@2800 { // PSC5 + compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2800 0x100>; + interrupts = <2 12 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@2 { reg = <2>; }; }; - i2c@3d00 { - status = "disabled"; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; }; i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; + rtc@68 { compatible = "dallas,ds1339"; reg = <0x68>; @@ -89,11 +235,10 @@ }; }; - pci@f0000d00 { - status = "disabled"; - }; - localbus { + compatible = "fsl,mpc5200b-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; ranges = <0 0 0xff000000 0x01000000 1 0 0x50000000 0x00010000 2 0 0x50010000 0x00010000 @@ -135,6 +280,5 @@ #size-cells = <1>; #address-cells = <1>; }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi b/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi deleted file mode 100644 index bc27548e895d..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi +++ /dev/null @@ -1,275 +0,0 @@ -/* - * base MPC5200b Device Tree Source - * - * Copyright (C) 2010 SecretLab - * Grant Likely - * John Bonesio - * - * 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. - */ - -/dts-v1/; - -/ { - model = "fsl,mpc5200b"; - compatible = "fsl,mpc5200b"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - powerpc: PowerPC,5200@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <0x4000>; // L1, 16K - i-cache-size = <0x4000>; // L1, 16K - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader - }; - }; - - memory: memory { - device_type = "memory"; - reg = <0x00000000 0x04000000>; // 64MB - }; - - soc: soc5200@f0000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc5200b-immr"; - ranges = <0 0xf0000000 0x0000c000>; - reg = <0xf0000000 0x00000100>; - bus-frequency = <0>; // from bootloader - system-frequency = <0>; // from bootloader - - cdm@200 { - compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; - reg = <0x200 0x38>; - }; - - mpc5200_pic: interrupt-controller@500 { - // 5200 interrupts are encoded into two levels; - interrupt-controller; - #interrupt-cells = <3>; - compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; - reg = <0x500 0x80>; - }; - - timer@600 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x600 0x10>; - interrupts = <1 9 0>; - }; - - timer@610 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x610 0x10>; - interrupts = <1 10 0>; - }; - - timer@620 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x620 0x10>; - interrupts = <1 11 0>; - }; - - timer@630 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x630 0x10>; - interrupts = <1 12 0>; - }; - - timer@640 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x640 0x10>; - interrupts = <1 13 0>; - }; - - timer@650 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x650 0x10>; - interrupts = <1 14 0>; - }; - - timer@660 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x660 0x10>; - interrupts = <1 15 0>; - }; - - timer@670 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x670 0x10>; - interrupts = <1 16 0>; - }; - - rtc@800 { // Real time clock - compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; - reg = <0x800 0x100>; - interrupts = <1 5 0 1 6 0>; - }; - - can@900 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 17 0>; - reg = <0x900 0x80>; - }; - - can@980 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 18 0>; - reg = <0x980 0x80>; - }; - - gpio_simple: gpio@b00 { - compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; - reg = <0xb00 0x40>; - interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio_wkup: gpio@c00 { - compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; - reg = <0xc00 0x40>; - interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - spi@f00 { - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - }; - - usb: usb@1000 { - compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; - reg = <0x1000 0xff>; - interrupts = <2 6 0>; - }; - - dma-controller@1200 { - compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; - reg = <0x1200 0x80>; - interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 - 3 4 0 3 5 0 3 6 0 3 7 0 - 3 8 0 3 9 0 3 10 0 3 11 0 - 3 12 0 3 13 0 3 14 0 3 15 0>; - }; - - xlb@1f00 { - compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; - reg = <0x1f00 0x100>; - }; - - psc1: psc@2000 { // PSC1 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2000 0x100>; - interrupts = <2 1 0>; - }; - - psc2: psc@2200 { // PSC2 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2200 0x100>; - interrupts = <2 2 0>; - }; - - psc3: psc@2400 { // PSC3 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2400 0x100>; - interrupts = <2 3 0>; - }; - - psc4: psc@2600 { // PSC4 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2600 0x100>; - interrupts = <2 11 0>; - }; - - psc5: psc@2800 { // PSC5 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2800 0x100>; - interrupts = <2 12 0>; - }; - - psc6: psc@2c00 { // PSC6 - compatible = "fsl,mpc5200b-psc","fsl,mpc5200-psc"; - reg = <0x2c00 0x100>; - interrupts = <2 4 0>; - }; - - eth0: ethernet@3000 { - compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; - reg = <0x3000 0x400>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <2 5 0>; - }; - - mdio@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; - reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts - interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - }; - - ata@3a00 { - compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; - reg = <0x3a00 0x100>; - interrupts = <2 7 0>; - }; - - i2c@3d00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d00 0x40>; - interrupts = <2 15 0>; - }; - - i2c@3d40 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d40 0x40>; - interrupts = <2 16 0>; - }; - - sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; - reg = <0x8000 0x4000>; - }; - }; - - pci: pci@f0000d00 { - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; - reg = <0xf0000d00 0x100>; - // interrupt-map-mask = need to add - // interrupt-map = need to add - clock-frequency = <0>; // From boot loader - interrupts = <2 8 0 2 9 0 2 10 0>; - bus-range = <0 0>; - // ranges = need to add - }; - - localbus: localbus { - compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - ranges = <0 0 0xfc000000 0x2000000>; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mucmc52.dts b/trunk/arch/powerpc/boot/dts/mucmc52.dts index 21d34720fcc9..b72a7581d798 100644 --- a/trunk/arch/powerpc/boot/dts/mucmc52.dts +++ b/trunk/arch/powerpc/boot/dts/mucmc52.dts @@ -11,109 +11,172 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "manroland,mucmc52"; compatible = "manroland,mucmc52"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x04000000>; // 64MB + }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + gpt0: timer@600 { // GPT 0 in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; gpio-controller; #gpio-cells = <2>; }; gpt1: timer@610 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; gpio-controller; #gpio-cells = <2>; }; gpt2: timer@620 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; gpio-controller; #gpio-cells = <2>; }; gpt3: timer@630 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; gpio-controller; #gpio-cells = <2>; }; - timer@640 { - status = "disabled"; - }; - - timer@650 { - status = "disabled"; - }; - - timer@660 { - status = "disabled"; - }; - - timer@670 { - status = "disabled"; - }; - - rtc@800 { - status = "disabled"; - }; - - can@900 { - status = "disabled"; + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - can@980 { - status = "disabled"; + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; - spi@f00 { - status = "disabled"; + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; }; - usb@1000 { - status = "disabled"; + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; }; - psc@2000 { // PSC1 + serial@2000 { /* PSC1 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; - psc@2200 { // PSC2 + serial@2200 { /* PSC2 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2200 0x100>; + interrupts = <2 2 0>; }; - psc@2400 { // PSC3 - status = "disabled"; - }; - - psc@2600 { // PSC4 - status = "disabled"; - }; - - psc@2800 { // PSC5 - status = "disabled"; - }; - - psc@2c00 { // PSC6 + serial@2c00 { /* PSC6 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { compatible = "intel,lxt971"; reg = <0>; }; }; - i2c@3d00 { - status = "disabled"; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; }; i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; hwmon@2c { compatible = "ad,adm9240"; reg = <0x2c>; @@ -123,9 +186,20 @@ reg = <0x51>; }; }; + + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; + }; }; pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = < /* IDSEL 0x10 */ @@ -134,12 +208,20 @@ 0x8000 0 0 3 &mpc5200_pic 0 2 3 0x8000 0 0 4 &mpc5200_pic 0 1 3 >; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 10 0>; + bus-range = <0 0>; ranges = <0x42000000 0 0x60000000 0x60000000 0 0x10000000 0x02000000 0 0x90000000 0x90000000 0 0x10000000 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>; }; localbus { + compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xff800000 0x00800000 1 0 0x80000000 0x00800000 3 0 0x80000000 0x00800000>; diff --git a/trunk/arch/powerpc/boot/dts/pcm030.dts b/trunk/arch/powerpc/boot/dts/pcm030.dts index 9e354997eb7e..8a4ec30b21ae 100644 --- a/trunk/arch/powerpc/boot/dts/pcm030.dts +++ b/trunk/arch/powerpc/boot/dts/pcm030.dts @@ -12,92 +12,246 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "phytec,pcm030"; compatible = "phytec,pcm030"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x04000000>; // 64MB + }; soc5200@f0000000 { - timer@600 { // General Purpose Timer + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; + }; + gpt2: timer@620 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; gpio-controller; #gpio-cells = <2>; }; gpt3: timer@630 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; gpio-controller; #gpio-cells = <2>; }; gpt4: timer@640 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; gpio-controller; #gpio-cells = <2>; }; gpt5: timer@650 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; gpio-controller; #gpio-cells = <2>; }; gpt6: timer@660 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; gpio-controller; #gpio-cells = <2>; }; gpt7: timer@670 { // General Purpose Timer in GPIO mode compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; + }; + + can@900 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + reg = <0x900 0x80>; + }; + + can@980 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; + }; + + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; gpio-controller; #gpio-cells = <2>; }; - psc@2000 { /* PSC1 in ac97 mode */ + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + ac97@2000 { /* PSC1 in ac97 mode */ compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; /* PSC2 port is used by CAN1/2 */ - psc@2200 { - status = "disabled"; - }; - psc@2400 { /* PSC3 in UART mode */ + serial@2400 { /* PSC3 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <2>; + reg = <0x2400 0x100>; + interrupts = <2 3 0>; }; /* PSC4 is ??? */ - psc@2600 { - status = "disabled"; - }; /* PSC5 is ??? */ - psc@2800 { - status = "disabled"; - }; - psc@2c00 { /* PSC6 in UART mode */ + serial@2c00 { /* PSC6 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <5>; + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + }; + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; @@ -105,7 +259,6 @@ eeprom@52 { compatible = "catalyst,24c32"; reg = <0x52>; - pagesize = <32>; }; }; @@ -116,6 +269,12 @@ }; pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot 0xc000 0 0 2 &mpc5200_pic 1 1 3 @@ -126,12 +285,11 @@ 0xc800 0 0 2 &mpc5200_pic 1 2 3 0xc800 0 0 3 &mpc5200_pic 1 3 3 0xc800 0 0 4 &mpc5200_pic 0 0 3>; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 10 0>; + bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; }; - - localbus { - status = "disabled"; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/pcm032.dts b/trunk/arch/powerpc/boot/dts/pcm032.dts index 1dd478bfff96..85d857a5d46e 100644 --- a/trunk/arch/powerpc/boot/dts/pcm032.dts +++ b/trunk/arch/powerpc/boot/dts/pcm032.dts @@ -12,37 +12,99 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "phytec,pcm032"; compatible = "phytec,pcm032"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; memory { + device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB }; soc5200@f0000000 { - timer@600 { // General Purpose Timer + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; fsl,has-wdt; }; + timer@610 { // General Purpose Timer + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; + }; + gpt2: timer@620 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; gpio-controller; #gpio-cells = <2>; }; gpt3: timer@630 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x630 0x10>; + interrupts = <1 12 0>; gpio-controller; #gpio-cells = <2>; }; gpt4: timer@640 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; gpio-controller; #gpio-cells = <2>; }; gpt5: timer@650 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; gpio-controller; #gpio-cells = <2>; }; @@ -56,62 +118,163 @@ }; gpt7: timer@670 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; gpio-controller; #gpio-cells = <2>; }; - psc@2000 { /* PSC1 is ac97 */ + rtc@800 { // Real time clock + compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; + reg = <0x800 0x100>; + interrupts = <1 5 0 1 6 0>; + }; + + can@900 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + reg = <0x900 0x80>; + }; + + can@980 { + compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; + }; + + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + spi@f00 { + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + }; + + usb@1000 { + compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + ac97@2000 { /* PSC1 is ac97 */ compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97"; cell-index = <0>; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; /* PSC2 port is used by CAN1/2 */ - psc@2200 { - status = "disabled"; - }; - psc@2400 { /* PSC3 in UART mode */ + serial@2400 { /* PSC3 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <2>; + reg = <0x2400 0x100>; + interrupts = <2 3 0>; }; /* PSC4 is ??? */ - psc@2600 { - status = "disabled"; - }; /* PSC5 is ??? */ - psc@2800 { - status = "disabled"; - }; - psc@2c00 { /* PSC6 in UART mode */ + serial@2c00 { /* PSC6 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + cell-index = <5>; + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { reg = <0>; }; }; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + }; + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; eeprom@52 { - compatible = "catalyst,24c32"; + compatible = "at24,24c32"; reg = <0x52>; - pagesize = <32>; }; }; + + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; + }; }; pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot 0xc000 0 0 2 &mpc5200_pic 1 1 3 @@ -122,12 +285,20 @@ 0xc800 0 0 2 &mpc5200_pic 1 2 3 0xc800 0 0 3 &mpc5200_pic 1 3 3 0xc800 0 0 4 &mpc5200_pic 0 0 3>; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 10 0>; + bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; }; localbus { + compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xfe000000 0x02000000 1 0 0xfc000000 0x02000000 2 0 0xfbe00000 0x00200000 @@ -180,39 +351,40 @@ bank-width = <2>; }; - /* + /* * example snippets for FPGA * * fpga@3,0 { - * compatible = "fpga_driver"; - * reg = <3 0 0x02000000>; - * bank-width = <4>; + * compatible = "fpga_driver"; + * reg = <3 0 0x02000000>; + * bank-width = <4>; * }; * * fpga@4,0 { - * compatible = "fpga_driver"; - * reg = <4 0 0x02000000>; - * bank-width = <4>; + * compatible = "fpga_driver"; + * reg = <4 0 0x02000000>; + * bank-width = <4>; * }; - */ + */ - /* + /* * example snippets for free chipselects - * + * * device@5,0 { - * compatible = "custom_driver"; - * reg = <5 0 0x02000000>; + * compatible = "custom_driver"; + * reg = <5 0 0x02000000>; * }; - * + * * device@6,0 { - * compatible = "custom_driver"; - * reg = <6 0 0x02000000>; + * compatible = "custom_driver"; + * reg = <6 0 0x02000000>; * }; - * + * * device@7,0 { - * compatible = "custom_driver"; - * reg = <7 0 0x02000000>; + * compatible = "custom_driver"; + * reg = <7 0 0x02000000>; * }; - */ + */ }; }; + diff --git a/trunk/arch/powerpc/boot/dts/uc101.dts b/trunk/arch/powerpc/boot/dts/uc101.dts index ba83d5488ec6..019264c62904 100644 --- a/trunk/arch/powerpc/boot/dts/uc101.dts +++ b/trunk/arch/powerpc/boot/dts/uc101.dts @@ -11,24 +11,79 @@ * option) any later version. */ -/include/ "mpc5200b.dtsi" +/dts-v1/; / { model = "manroland,uc101"; compatible = "manroland,uc101"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x04000000>; // 64MB + }; soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200b-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + gpt0: timer@600 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; gpio-controller; #gpio-cells = <2>; }; gpt1: timer@610 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x610 0x10>; + interrupts = <1 10 0>; gpio-controller; #gpio-cells = <2>; }; gpt2: timer@620 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x620 0x10>; + interrupts = <1 11 0>; gpio-controller; #gpio-cells = <2>; }; @@ -42,85 +97,118 @@ }; gpt4: timer@640 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x640 0x10>; + interrupts = <1 13 0>; gpio-controller; #gpio-cells = <2>; }; gpt5: timer@650 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x650 0x10>; + interrupts = <1 14 0>; gpio-controller; #gpio-cells = <2>; }; gpt6: timer@660 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x660 0x10>; + interrupts = <1 15 0>; gpio-controller; #gpio-cells = <2>; }; gpt7: timer@670 { // General Purpose Timer in GPIO mode + compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + reg = <0x670 0x10>; + interrupts = <1 16 0>; gpio-controller; #gpio-cells = <2>; }; - rtc@800 { - status = "disabled"; - }; - - can@900 { - status = "disabled"; + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; - can@980 { - status = "disabled"; + gpio_wkup: gpio@c00 { + compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; + reg = <0xc00 0x40>; + interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; - spi@f00 { - status = "disabled"; + dma-controller@1200 { + compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; }; - usb@1000 { - status = "disabled"; + xlb@1f00 { + compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; }; - psc@2000 { // PSC1 + serial@2000 { /* PSC1 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; }; - psc@2200 { // PSC2 + serial@2200 { /* PSC2 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2200 0x100>; + interrupts = <2 2 0>; }; - psc@2400 { // PSC3 - status = "disabled"; - }; - - psc@2600 { // PSC4 - status = "disabled"; - }; - - psc@2800 { // PSC5 - status = "disabled"; - }; - - psc@2c00 { // PSC6 + serial@2c00 { /* PSC6 in UART mode */ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + reg = <0x2c00 0x100>; + interrupts = <2 4 0>; }; ethernet@3000 { + compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; phy-handle = <&phy0>; }; mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + phy0: ethernet-phy@0 { compatible = "intel,lxt971"; reg = <0>; }; }; - i2c@3d00 { - status = "disabled"; + ata@3a00 { + compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; }; i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; fsl,preserve-clocking; clock-frequency = <400000>; @@ -133,13 +221,19 @@ reg = <0x51>; }; }; - }; - pci@f0000d00 { - status = "disabled"; + sram@8000 { + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; + }; }; localbus { + compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xff800000 0x00800000 1 0 0x80000000 0x00800000 3 0 0x80000000 0x00800000>; diff --git a/trunk/arch/powerpc/include/asm/prom.h b/trunk/arch/powerpc/include/asm/prom.h index d72757585595..ae26f2efd089 100644 --- a/trunk/arch/powerpc/include/asm/prom.h +++ b/trunk/arch/powerpc/include/asm/prom.h @@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void); /* Translate a DMA address from device space to CPU space */ extern u64 of_translate_dma_address(struct device_node *dev, - const __be32 *in_addr); + const u32 *in_addr); #ifdef CONFIG_PCI extern unsigned long pci_address_to_pio(phys_addr_t address); @@ -63,6 +63,9 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); /* cache lookup */ struct device_node *of_find_next_cache_node(struct device_node *np); +/* Get the MAC address */ +extern const void *of_get_mac_address(struct device_node *np); + #ifdef CONFIG_NUMA extern int of_node_to_nid(struct device_node *device); #else diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c index c2b7a07cc3d3..88334af038e5 100644 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ b/trunk/arch/powerpc/kernel/prom_parse.c @@ -117,3 +117,41 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, cells = prop ? *(u32 *)prop : of_n_size_cells(dn); *size = of_read_number(dma_window, cells); } + +/** + * Search the device tree for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the device tree, but were not set by U-Boot. For example, the + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC + * addresses. Some older U-Boots only initialized 'local-mac-address'. In + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists + * but is all zeros. +*/ +const void *of_get_mac_address(struct device_node *np) +{ + struct property *pp; + + pp = of_find_property(np, "mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "local-mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + return NULL; +} +EXPORT_SYMBOL(of_get_mac_address); diff --git a/trunk/arch/powerpc/platforms/40x/ppc40x_simple.c b/trunk/arch/powerpc/platforms/40x/ppc40x_simple.c index 2521d93ef136..546bbc229d19 100644 --- a/trunk/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/trunk/arch/powerpc/platforms/40x/ppc40x_simple.c @@ -50,7 +50,7 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe); * Again, if your board needs to do things differently then create a * board.c file for it rather than adding it to this list. */ -static const char *board[] __initdata = { +static char *board[] __initdata = { "amcc,acadia", "amcc,haleakala", "amcc,kilauea", @@ -60,9 +60,14 @@ static const char *board[] __initdata = { static int __init ppc40x_probe(void) { - if (of_flat_dt_match(of_get_flat_dt_root(), board)) { - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); - return 1; + unsigned long root = of_get_flat_dt_root(); + int i = 0; + + for (i = 0; i < ARRAY_SIZE(board); i++) { + if (of_flat_dt_is_compatible(root, board[i])) { + ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + return 1; + } } return 0; diff --git a/trunk/arch/powerpc/platforms/512x/mpc5121_generic.c b/trunk/arch/powerpc/platforms/512x/mpc5121_generic.c index 926731f1ff01..e487eb06ec6b 100644 --- a/trunk/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/trunk/arch/powerpc/platforms/512x/mpc5121_generic.c @@ -26,7 +26,7 @@ /* * list of supported boards */ -static const char *board[] __initdata = { +static char *board[] __initdata = { "prt,prtlvt", NULL }; @@ -36,7 +36,16 @@ static const char *board[] __initdata = { */ static int __init mpc5121_generic_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long node = of_get_flat_dt_root(); + int i = 0; + + while (board[i]) { + if (of_flat_dt_is_compatible(node, board[i])) + break; + i++; + } + + return board[i] != NULL; } define_machine(mpc5121_generic) { diff --git a/trunk/arch/powerpc/platforms/52xx/lite5200.c b/trunk/arch/powerpc/platforms/52xx/lite5200.c index 01ffa64d2aa7..de55bc0584b5 100644 --- a/trunk/arch/powerpc/platforms/52xx/lite5200.c +++ b/trunk/arch/powerpc/platforms/52xx/lite5200.c @@ -172,18 +172,20 @@ static void __init lite5200_setup_arch(void) mpc52xx_setup_pci(); } -static const char *board[] __initdata = { - "fsl,lite5200", - "fsl,lite5200b", - NULL, -}; - /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init lite5200_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long node = of_get_flat_dt_root(); + const char *model = of_get_flat_dt_prop(node, "model", NULL); + + if (!of_flat_dt_is_compatible(node, "fsl,lite5200") && + !of_flat_dt_is_compatible(node, "fsl,lite5200b")) + return 0; + pr_debug("%s board found\n", model ? model : "unknown"); + + return 1; } define_machine(lite5200) { diff --git a/trunk/arch/powerpc/platforms/52xx/media5200.c b/trunk/arch/powerpc/platforms/52xx/media5200.c index 2c7780cb68e5..0bac3a3dbecf 100644 --- a/trunk/arch/powerpc/platforms/52xx/media5200.c +++ b/trunk/arch/powerpc/platforms/52xx/media5200.c @@ -239,7 +239,7 @@ static void __init media5200_setup_arch(void) } /* list of the supported boards */ -static const char *board[] __initdata = { +static char *board[] __initdata = { "fsl,media5200", NULL }; @@ -249,7 +249,16 @@ static const char *board[] __initdata = { */ static int __init media5200_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long node = of_get_flat_dt_root(); + int i = 0; + + while (board[i]) { + if (of_flat_dt_is_compatible(node, board[i])) + break; + i++; + } + + return (board[i] != NULL); } define_machine(media5200_platform) { diff --git a/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c b/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c index e36d6e232ae6..d45be5b5ad49 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c @@ -49,7 +49,7 @@ static void __init mpc5200_simple_setup_arch(void) } /* list of the supported boards */ -static const char *board[] __initdata = { +static char *board[] __initdata = { "intercontrol,digsy-mtc", "manroland,mucmc52", "manroland,uc101", @@ -66,7 +66,16 @@ static const char *board[] __initdata = { */ static int __init mpc5200_simple_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long node = of_get_flat_dt_root(); + int i = 0; + + while (board[i]) { + if (of_flat_dt_is_compatible(node, board[i])) + break; + i++; + } + + return (board[i] != NULL); } define_machine(mpc5200_simple_platform) { diff --git a/trunk/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc830x_rdb.c index 661d354e4ff2..846831d495b5 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc830x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc830x_rdb.c @@ -57,19 +57,16 @@ static void __init mpc830x_rdb_init_IRQ(void) ipic_set_default_priority(); } -struct const char *board[] __initdata = { - "MPC8308RDB", - "fsl,mpc8308rdb", - "denx,mpc8308_p1m", - NULL -} - /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init mpc830x_rdb_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "MPC8308RDB") || + of_flat_dt_is_compatible(root, "fsl,mpc8308rdb") || + of_flat_dt_is_compatible(root, "denx,mpc8308_p1m"); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c index b54cd736a895..ae525e4745d2 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -60,18 +60,15 @@ static void __init mpc831x_rdb_init_IRQ(void) ipic_set_default_priority(); } -struct const char *board[] __initdata = { - "MPC8313ERDB", - "fsl,mpc8315erdb", - NULL -} - /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init mpc831x_rdb_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "MPC8313ERDB") || + of_flat_dt_is_compatible(root, "fsl,mpc8315erdb"); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 7bafbf2ec0f9..910caa6b5810 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -101,20 +101,17 @@ static void __init mpc837x_rdb_init_IRQ(void) ipic_set_default_priority(); } -static const char *board[] __initdata = { - "fsl,mpc8377rdb", - "fsl,mpc8378rdb", - "fsl,mpc8379rdb", - "fsl,mpc8377wlan", - NULL -}; - /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init mpc837x_rdb_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,mpc8377rdb") || + of_flat_dt_is_compatible(root, "fsl,mpc8378rdb") || + of_flat_dt_is_compatible(root, "fsl,mpc8379rdb") || + of_flat_dt_is_compatible(root, "fsl,mpc8377wlan"); } define_machine(mpc837x_rdb) { diff --git a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c index 5e847d0b47c8..8f29bbce5360 100644 --- a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c @@ -186,21 +186,21 @@ static int __init declare_of_platform_devices(void) } machine_device_initcall(tqm85xx, declare_of_platform_devices); -static const char *board[] __initdata = { - "tqc,tqm8540", - "tqc,tqm8541", - "tqc,tqm8548", - "tqc,tqm8555", - "tqc,tqm8560", - NULL -}; - /* * Called very early, device-tree isn't unflattened */ static int __init tqm85xx_probe(void) { - return of_flat_dt_match(of_get_flat_dt_root(), board); + unsigned long root = of_get_flat_dt_root(); + + if ((of_flat_dt_is_compatible(root, "tqc,tqm8540")) || + (of_flat_dt_is_compatible(root, "tqc,tqm8541")) || + (of_flat_dt_is_compatible(root, "tqc,tqm8548")) || + (of_flat_dt_is_compatible(root, "tqc,tqm8555")) || + (of_flat_dt_is_compatible(root, "tqc,tqm8560"))) + return 1; + + return 0; } define_machine(tqm85xx) { diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c b/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c index 23982c7892d2..15e13b568904 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c @@ -25,6 +25,7 @@ #include #include #include +#include /** * EEH_SHOW_ATTR -- create sysfs entry for eeh statistic diff --git a/trunk/arch/powerpc/sysdev/mv64x60_dev.c b/trunk/arch/powerpc/sysdev/mv64x60_dev.c index feaee402e2d6..1398bc454999 100644 --- a/trunk/arch/powerpc/sysdev/mv64x60_dev.c +++ b/trunk/arch/powerpc/sysdev/mv64x60_dev.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/sysdev/tsi108_dev.c b/trunk/arch/powerpc/sysdev/tsi108_dev.c index c2d675b6392c..d4d15aaf18fa 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_dev.c +++ b/trunk/arch/powerpc/sysdev/tsi108_dev.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/sparc/kernel/auxio_32.c b/trunk/arch/sparc/kernel/auxio_32.c index 8505e0ac78ba..35f48837871a 100644 --- a/trunk/arch/sparc/kernel/auxio_32.c +++ b/trunk/arch/sparc/kernel/auxio_32.c @@ -121,7 +121,7 @@ void __init auxio_power_probe(void) node = prom_searchsiblings(node, "obio"); node = prom_getchild(node); node = prom_searchsiblings(node, "power"); - if (node == 0 || (s32)node == -1) + if (node == 0 || node == -1) return; /* Map the power control register. */ diff --git a/trunk/arch/sparc/kernel/starfire.c b/trunk/arch/sparc/kernel/starfire.c index 82281a566bb8..a4446c0fb7a1 100644 --- a/trunk/arch/sparc/kernel/starfire.c +++ b/trunk/arch/sparc/kernel/starfire.c @@ -24,7 +24,7 @@ int this_is_starfire = 0; void check_if_starfire(void) { phandle ssnode = prom_finddevice("/ssp-serial"); - if (ssnode != 0 && (s32)ssnode != -1) + if (ssnode != 0 && ssnode != -1) this_is_starfire = 1; } diff --git a/trunk/arch/sparc/prom/init_32.c b/trunk/arch/sparc/prom/init_32.c index 0a601b300639..d342dba4dd54 100644 --- a/trunk/arch/sparc/prom/init_32.c +++ b/trunk/arch/sparc/prom/init_32.c @@ -60,7 +60,7 @@ void __init prom_init(struct linux_romvec *rp) prom_nodeops = romvec->pv_nodeops; prom_root_node = prom_getsibling(0); - if ((prom_root_node == 0) || ((s32)prom_root_node == -1)) + if((prom_root_node == 0) || (prom_root_node == -1)) prom_halt(); if((((unsigned long) prom_nodeops) == 0) || diff --git a/trunk/arch/sparc/prom/init_64.c b/trunk/arch/sparc/prom/init_64.c index 5016c5e20575..9c6ac4b81ded 100644 --- a/trunk/arch/sparc/prom/init_64.c +++ b/trunk/arch/sparc/prom/init_64.c @@ -35,13 +35,13 @@ void __init prom_init(void *cif_handler, void *cif_stack) prom_cif_init(cif_handler, cif_stack); prom_chosen_node = prom_finddevice(prom_chosen_path); - if (!prom_chosen_node || (s32)prom_chosen_node == -1) + if (!prom_chosen_node || prom_chosen_node == -1) prom_halt(); prom_stdout = prom_getint(prom_chosen_node, "stdout"); node = prom_finddevice("/openprom"); - if (!node || (s32)node == -1) + if (!node || node == -1) prom_halt(); prom_getstring(node, "version", prom_version, sizeof(prom_version)); diff --git a/trunk/arch/sparc/prom/tree_32.c b/trunk/arch/sparc/prom/tree_32.c index f30e8d038f01..bc8e4cb87a68 100644 --- a/trunk/arch/sparc/prom/tree_32.c +++ b/trunk/arch/sparc/prom/tree_32.c @@ -40,11 +40,11 @@ phandle prom_getchild(phandle node) { phandle cnode; - if ((s32)node == -1) + if (node == -1) return 0; cnode = __prom_getchild(node); - if (cnode == 0 || (s32)cnode == -1) + if (cnode == 0 || cnode == -1) return 0; return cnode; @@ -72,11 +72,11 @@ phandle prom_getsibling(phandle node) { phandle sibnode; - if ((s32)node == -1) + if (node == -1) return 0; sibnode = __prom_getsibling(node); - if (sibnode == 0 || (s32)sibnode == -1) + if (sibnode == 0 || sibnode == -1) return 0; return sibnode; @@ -219,7 +219,7 @@ static char *__prom_nextprop(phandle node, char * oprop) */ char *prom_nextprop(phandle node, char *oprop, char *buffer) { - if (node == 0 || (s32)node == -1) + if (node == 0 || node == -1) return ""; return __prom_nextprop(node, oprop); @@ -253,7 +253,7 @@ phandle prom_finddevice(char *name) if (d != s + 3 && (!*d || *d == '/') && d <= s + 3 + 8) { node2 = node; - while (node2 && (s32)node2 != -1) { + while (node2 && node2 != -1) { if (prom_getproperty (node2, "reg", (char *)reg, sizeof (reg)) > 0) { if (which_io == reg[0].which_io && phys_addr == reg[0].phys_addr) { node = node2; @@ -261,7 +261,7 @@ phandle prom_finddevice(char *name) } } node2 = prom_getsibling(node2); - if (!node2 || (s32)node2 == -1) + if (!node2 || node2 == -1) break; node2 = prom_searchsiblings(prom_getsibling(node2), nbuf); } @@ -303,7 +303,6 @@ phandle prom_inst2pkg(int inst) node = (*romvec->pv_v2devops.v2_inst2pkg)(inst); restore_current(); spin_unlock_irqrestore(&prom_lock, flags); - if ((s32)node == -1) - return 0; + if (node == -1) return 0; return node; } diff --git a/trunk/arch/sparc/prom/tree_64.c b/trunk/arch/sparc/prom/tree_64.c index 92204c3800b5..d93660048376 100644 --- a/trunk/arch/sparc/prom/tree_64.c +++ b/trunk/arch/sparc/prom/tree_64.c @@ -43,10 +43,10 @@ inline phandle prom_getchild(phandle node) { phandle cnode; - if ((s32)node == -1) + if (node == -1) return 0; cnode = __prom_getchild(node); - if ((s32)cnode == -1) + if (cnode == -1) return 0; return cnode; } @@ -56,10 +56,10 @@ inline phandle prom_getparent(phandle node) { phandle cnode; - if ((s32)node == -1) + if (node == -1) return 0; cnode = prom_node_to_node("parent", node); - if ((s32)cnode == -1) + if (cnode == -1) return 0; return cnode; } @@ -76,10 +76,10 @@ inline phandle prom_getsibling(phandle node) { phandle sibnode; - if ((s32)node == -1) + if (node == -1) return 0; sibnode = __prom_getsibling(node); - if ((s32)sibnode == -1) + if (sibnode == -1) return 0; return sibnode; @@ -240,7 +240,7 @@ inline char *prom_firstprop(phandle node, char *buffer) unsigned long args[7]; *buffer = 0; - if ((s32)node == -1) + if (node == -1) return buffer; args[0] = (unsigned long) prom_nextprop_name; @@ -266,7 +266,7 @@ inline char *prom_nextprop(phandle node, const char *oprop, char *buffer) unsigned long args[7]; char buf[32]; - if ((s32)node == -1) { + if (node == -1) { *buffer = 0; return buffer; } @@ -369,7 +369,7 @@ inline phandle prom_inst2pkg(int inst) p1275_cmd_direct(args); node = (int) args[4]; - if ((s32)node == -1) + if (node == -1) return 0; return node; } diff --git a/trunk/arch/x86/include/asm/hypervisor.h b/trunk/arch/x86/include/asm/hypervisor.h index 7a15153c675d..ff2546ce7178 100644 --- a/trunk/arch/x86/include/asm/hypervisor.h +++ b/trunk/arch/x86/include/asm/hypervisor.h @@ -20,9 +20,6 @@ #ifndef _ASM_X86_HYPERVISOR_H #define _ASM_X86_HYPERVISOR_H -#include -#include - extern void init_hypervisor(struct cpuinfo_x86 *c); extern void init_hypervisor_platform(void); @@ -50,13 +47,4 @@ extern const struct hypervisor_x86 x86_hyper_vmware; extern const struct hypervisor_x86 x86_hyper_ms_hyperv; extern const struct hypervisor_x86 x86_hyper_xen_hvm; -static inline bool hypervisor_x2apic_available(void) -{ - if (kvm_para_available()) - return true; - if (xen_x2apic_para_available()) - return true; - return false; -} - #endif diff --git a/trunk/arch/x86/include/asm/xen/hypervisor.h b/trunk/arch/x86/include/asm/xen/hypervisor.h index 66d0fff1ee84..396ff4cc8ed4 100644 --- a/trunk/arch/x86/include/asm/xen/hypervisor.h +++ b/trunk/arch/x86/include/asm/xen/hypervisor.h @@ -37,39 +37,4 @@ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; -#include - -static inline uint32_t xen_cpuid_base(void) -{ - uint32_t base, eax, ebx, ecx, edx; - char signature[13]; - - for (base = 0x40000000; base < 0x40010000; base += 0x100) { - cpuid(base, &eax, &ebx, &ecx, &edx); - *(uint32_t *)(signature + 0) = ebx; - *(uint32_t *)(signature + 4) = ecx; - *(uint32_t *)(signature + 8) = edx; - signature[12] = 0; - - if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2)) - return base; - } - - return 0; -} - -#ifdef CONFIG_XEN -extern bool xen_hvm_need_lapic(void); - -static inline bool xen_x2apic_para_available(void) -{ - return xen_hvm_need_lapic(); -} -#else -static inline bool xen_x2apic_para_available(void) -{ - return (xen_cpuid_base() != 0); -} -#endif - #endif /* _ASM_X86_XEN_HYPERVISOR_H */ diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index a51345ba449e..79e6baa8aa0a 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -49,8 +49,8 @@ #include #include #include +#include #include -#include unsigned int num_processors; @@ -1476,8 +1476,7 @@ void __init enable_IR_x2apic(void) /* IR is required if there is APIC ID > 255 even when running * under KVM */ - if (max_physical_apicid > 255 || - !hypervisor_x2apic_available()) + if (max_physical_apicid > 255 || !kvm_para_available()) goto nox2apic; /* * without IR all CPUs can be addressed by IOAPIC/MSI diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index 7e8d3bc80af6..aa8c89ae54cf 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -1174,15 +1174,6 @@ asmlinkage void __init xen_start_kernel(void) xen_smp_init(); -#ifdef CONFIG_ACPI_NUMA - /* - * The pages we from Xen are not related to machine pages, so - * any NUMA information the kernel tries to get from ACPI will - * be meaningless. Prevent it from trying. - */ - acpi_numa = -1; -#endif - pgd = (pgd_t *)xen_start_info->pt_base; if (!xen_initial_domain()) @@ -1265,6 +1256,25 @@ asmlinkage void __init xen_start_kernel(void) #endif } +static uint32_t xen_cpuid_base(void) +{ + uint32_t base, eax, ebx, ecx, edx; + char signature[13]; + + for (base = 0x40000000; base < 0x40010000; base += 0x100) { + cpuid(base, &eax, &ebx, &ecx, &edx); + *(uint32_t *)(signature + 0) = ebx; + *(uint32_t *)(signature + 4) = ecx; + *(uint32_t *)(signature + 8) = edx; + signature[12] = 0; + + if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2)) + return base; + } + + return 0; +} + static int init_hvm_pv_info(int *major, int *minor) { uint32_t eax, ebx, ecx, edx, pages, msr, base; @@ -1374,18 +1384,6 @@ static bool __init xen_hvm_platform(void) return true; } -bool xen_hvm_need_lapic(void) -{ - if (xen_pv_domain()) - return false; - if (!xen_hvm_domain()) - return false; - if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback) - return false; - return true; -} -EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); - const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = { .name = "Xen HVM", .detect = xen_hvm_platform, diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index c6b298d4c136..36e2319264bd 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -2,14 +2,6 @@ # SATA/PATA driver configuration # -config HAVE_PATA_PLATFORM - bool - help - This is an internal configuration node for any machine that - uses pata-platform driver to enable the relevant driver in the - configuration structure without having to submit endless patches - to update the PATA_PLATFORM entry. - menuconfig ATA tristate "Serial ATA and Parallel ATA drivers" depends on HAS_IOMEM @@ -98,14 +90,6 @@ config SATA_INIC162X help This option enables support for Initio 162x Serial ATA. -config SATA_ACARD_AHCI - tristate "ACard AHCI variant (ATP 8620)" - depends on PCI - help - This option enables support for Acard. - - If unsure, say N. - config SATA_SIL24 tristate "Silicon Image 3124/3132 SATA support" depends on PCI @@ -416,11 +400,11 @@ config PATA_HPT37X If unsure, say N. config PATA_HPT3X2N - tristate "HPT 371N/372N/302N PATA support" + tristate "HPT 372N/302N PATA support" depends on PCI help This option enables support for the N variant HPT PATA - controllers via the new ATA layer. + controllers via the new ATA layer If unsure, say N. @@ -781,6 +765,14 @@ config PATA_PCMCIA If unsure, say N. +config HAVE_PATA_PLATFORM + bool + help + This is an internal configuration node for any machine that + uses pata-platform driver to enable the relevant driver in the + configuration structure without having to submit endless patches + to update the PATA_PLATFORM entry. + config PATA_PLATFORM tristate "Generic platform device PATA support" depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index 27291aad6ca7..2b67c900a459 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_ATA) += libata.o # non-SFF interface obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o -obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o diff --git a/trunk/drivers/ata/acard-ahci.c b/trunk/drivers/ata/acard-ahci.c deleted file mode 100644 index 339c210f03a6..000000000000 --- a/trunk/drivers/ata/acard-ahci.c +++ /dev/null @@ -1,528 +0,0 @@ - -/* - * acard-ahci.c - ACard AHCI SATA support - * - * Maintained by: Jeff Garzik - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * - * Copyright 2010 Red Hat, Inc. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - * libata documentation is available via 'make {ps|pdf}docs', - * as Documentation/DocBook/libata.* - * - * AHCI hardware documentation: - * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf - * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ahci.h" - -#define DRV_NAME "acard-ahci" -#define DRV_VERSION "1.0" - -/* - Received FIS structure limited to 80h. -*/ - -#define ACARD_AHCI_RX_FIS_SZ 128 - -enum { - AHCI_PCI_BAR = 5, -}; - -enum board_ids { - board_acard_ahci, -}; - -struct acard_sg { - __le32 addr; - __le32 addr_hi; - __le32 reserved; - __le32 size; /* bit 31 (EOT) max==0x10000 (64k) */ -}; - -static void acard_ahci_qc_prep(struct ata_queued_cmd *qc); -static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc); -static int acard_ahci_port_start(struct ata_port *ap); -static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); - -#ifdef CONFIG_PM -static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -static int acard_ahci_pci_device_resume(struct pci_dev *pdev); -#endif - -static struct scsi_host_template acard_ahci_sht = { - AHCI_SHT("acard-ahci"), -}; - -static struct ata_port_operations acard_ops = { - .inherits = &ahci_ops, - .qc_prep = acard_ahci_qc_prep, - .qc_fill_rtf = acard_ahci_qc_fill_rtf, - .port_start = acard_ahci_port_start, -}; - -#define AHCI_HFLAGS(flags) .private_data = (void *)(flags) - -static const struct ata_port_info acard_ahci_port_info[] = { - [board_acard_ahci] = - { - AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), - .flags = AHCI_FLAG_COMMON, - .pio_mask = ATA_PIO4, - .udma_mask = ATA_UDMA6, - .port_ops = &acard_ops, - }, -}; - -static const struct pci_device_id acard_ahci_pci_tbl[] = { - /* ACard */ - { PCI_VDEVICE(ARTOP, 0x000d), board_acard_ahci }, /* ATP8620 */ - - { } /* terminate list */ -}; - -static struct pci_driver acard_ahci_pci_driver = { - .name = DRV_NAME, - .id_table = acard_ahci_pci_tbl, - .probe = acard_ahci_init_one, - .remove = ata_pci_remove_one, -#ifdef CONFIG_PM - .suspend = acard_ahci_pci_device_suspend, - .resume = acard_ahci_pci_device_resume, -#endif -}; - -#ifdef CONFIG_PM -static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) -{ - struct ata_host *host = dev_get_drvdata(&pdev->dev); - struct ahci_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->mmio; - u32 ctl; - - if (mesg.event & PM_EVENT_SUSPEND && - hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { - dev_printk(KERN_ERR, &pdev->dev, - "BIOS update required for suspend/resume\n"); - return -EIO; - } - - if (mesg.event & PM_EVENT_SLEEP) { - /* AHCI spec rev1.1 section 8.3.3: - * Software must disable interrupts prior to requesting a - * transition of the HBA to D3 state. - */ - ctl = readl(mmio + HOST_CTL); - ctl &= ~HOST_IRQ_EN; - writel(ctl, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - } - - return ata_pci_device_suspend(pdev, mesg); -} - -static int acard_ahci_pci_device_resume(struct pci_dev *pdev) -{ - struct ata_host *host = dev_get_drvdata(&pdev->dev); - int rc; - - rc = ata_pci_device_do_resume(pdev); - if (rc) - return rc; - - if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = ahci_reset_controller(host); - if (rc) - return rc; - - ahci_init_controller(host); - } - - ata_host_resume(host); - - return 0; -} -#endif - -static int acard_ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) -{ - int rc; - - if (using_dac && - !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - if (rc) { - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "64-bit DMA enable failed\n"); - return rc; - } - } - } else { - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "32-bit DMA enable failed\n"); - return rc; - } - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "32-bit consistent DMA enable failed\n"); - return rc; - } - } - return 0; -} - -static void acard_ahci_pci_print_info(struct ata_host *host) -{ - struct pci_dev *pdev = to_pci_dev(host->dev); - u16 cc; - const char *scc_s; - - pci_read_config_word(pdev, 0x0a, &cc); - if (cc == PCI_CLASS_STORAGE_IDE) - scc_s = "IDE"; - else if (cc == PCI_CLASS_STORAGE_SATA) - scc_s = "SATA"; - else if (cc == PCI_CLASS_STORAGE_RAID) - scc_s = "RAID"; - else - scc_s = "unknown"; - - ahci_print_info(host, scc_s); -} - -static unsigned int acard_ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) -{ - struct scatterlist *sg; - struct acard_sg *acard_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; - unsigned int si, last_si = 0; - - VPRINTK("ENTER\n"); - - /* - * Next, the S/G list. - */ - for_each_sg(qc->sg, sg, qc->n_elem, si) { - dma_addr_t addr = sg_dma_address(sg); - u32 sg_len = sg_dma_len(sg); - - /* - * ACard note: - * We must set an end-of-table (EOT) bit, - * and the segment cannot exceed 64k (0x10000) - */ - acard_sg[si].addr = cpu_to_le32(addr & 0xffffffff); - acard_sg[si].addr_hi = cpu_to_le32((addr >> 16) >> 16); - acard_sg[si].size = cpu_to_le32(sg_len); - last_si = si; - } - - acard_sg[last_si].size |= cpu_to_le32(1 << 31); /* set EOT */ - - return si; -} - -static void acard_ahci_qc_prep(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct ahci_port_priv *pp = ap->private_data; - int is_atapi = ata_is_atapi(qc->tf.protocol); - void *cmd_tbl; - u32 opts; - const u32 cmd_fis_len = 5; /* five dwords */ - unsigned int n_elem; - - /* - * Fill in command table information. First, the header, - * a SATA Register - Host to Device command FIS. - */ - cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; - - ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl); - if (is_atapi) { - memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); - memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); - } - - n_elem = 0; - if (qc->flags & ATA_QCFLAG_DMAMAP) - n_elem = acard_ahci_fill_sg(qc, cmd_tbl); - - /* - * Fill in command slot information. - * - * ACard note: prd table length not filled in - */ - opts = cmd_fis_len | (qc->dev->link->pmp << 12); - if (qc->tf.flags & ATA_TFLAG_WRITE) - opts |= AHCI_CMD_WRITE; - if (is_atapi) - opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; - - ahci_fill_cmd_slot(pp, qc->tag, opts); -} - -static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc) -{ - struct ahci_port_priv *pp = qc->ap->private_data; - u8 *rx_fis = pp->rx_fis; - - if (pp->fbs_enabled) - rx_fis += qc->dev->link->pmp * ACARD_AHCI_RX_FIS_SZ; - - /* - * After a successful execution of an ATA PIO data-in command, - * the device doesn't send D2H Reg FIS to update the TF and - * the host should take TF and E_Status from the preceding PIO - * Setup FIS. - */ - if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE && - !(qc->flags & ATA_QCFLAG_FAILED)) { - ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); - qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15]; - } else - ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); - - return true; -} - -static int acard_ahci_port_start(struct ata_port *ap) -{ - struct ahci_host_priv *hpriv = ap->host->private_data; - struct device *dev = ap->host->dev; - struct ahci_port_priv *pp; - void *mem; - dma_addr_t mem_dma; - size_t dma_sz, rx_fis_sz; - - pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); - if (!pp) - return -ENOMEM; - - /* check FBS capability */ - if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) { - void __iomem *port_mmio = ahci_port_base(ap); - u32 cmd = readl(port_mmio + PORT_CMD); - if (cmd & PORT_CMD_FBSCP) - pp->fbs_supported = true; - else if (hpriv->flags & AHCI_HFLAG_YES_FBS) { - dev_printk(KERN_INFO, dev, - "port %d can do FBS, forcing FBSCP\n", - ap->port_no); - pp->fbs_supported = true; - } else - dev_printk(KERN_WARNING, dev, - "port %d is not capable of FBS\n", - ap->port_no); - } - - if (pp->fbs_supported) { - dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ; - rx_fis_sz = ACARD_AHCI_RX_FIS_SZ * 16; - } else { - dma_sz = AHCI_PORT_PRIV_DMA_SZ; - rx_fis_sz = ACARD_AHCI_RX_FIS_SZ; - } - - mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL); - if (!mem) - return -ENOMEM; - memset(mem, 0, dma_sz); - - /* - * First item in chunk of DMA memory: 32-slot command table, - * 32 bytes each in size - */ - pp->cmd_slot = mem; - pp->cmd_slot_dma = mem_dma; - - mem += AHCI_CMD_SLOT_SZ; - mem_dma += AHCI_CMD_SLOT_SZ; - - /* - * Second item: Received-FIS area - */ - pp->rx_fis = mem; - pp->rx_fis_dma = mem_dma; - - mem += rx_fis_sz; - mem_dma += rx_fis_sz; - - /* - * Third item: data area for storing a single command - * and its scatter-gather table - */ - pp->cmd_tbl = mem; - pp->cmd_tbl_dma = mem_dma; - - /* - * Save off initial list of interrupts to be enabled. - * This could be changed later - */ - pp->intr_mask = DEF_PORT_IRQ; - - ap->private_data = pp; - - /* engage engines, captain */ - return ahci_port_resume(ap); -} - -static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static int printed_version; - unsigned int board_id = ent->driver_data; - struct ata_port_info pi = acard_ahci_port_info[board_id]; - const struct ata_port_info *ppi[] = { &pi, NULL }; - struct device *dev = &pdev->dev; - struct ahci_host_priv *hpriv; - struct ata_host *host; - int n_ports, i, rc; - - VPRINTK("ENTER\n"); - - WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); - - if (!printed_version++) - dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - - /* acquire resources */ - rc = pcim_enable_device(pdev); - if (rc) - return rc; - - /* AHCI controllers often implement SFF compatible interface. - * Grab all PCI BARs just in case. - */ - rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); - if (rc == -EBUSY) - pcim_pin_device(pdev); - if (rc) - return rc; - - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); - if (!hpriv) - return -ENOMEM; - hpriv->flags |= (unsigned long)pi.private_data; - - if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) - pci_enable_msi(pdev); - - hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; - - /* save initial config */ - ahci_save_initial_config(&pdev->dev, hpriv, 0, 0); - - /* prepare host */ - if (hpriv->cap & HOST_CAP_NCQ) - pi.flags |= ATA_FLAG_NCQ; - - if (hpriv->cap & HOST_CAP_PMP) - pi.flags |= ATA_FLAG_PMP; - - ahci_set_em_messages(hpriv, &pi); - - /* CAP.NP sometimes indicate the index of the last enabled - * port, at other times, that of the last possible port, so - * determining the maximum port number requires looking at - * both CAP.NP and port_map. - */ - n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); - - host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); - if (!host) - return -ENOMEM; - host->private_data = hpriv; - - if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) - host->flags |= ATA_HOST_PARALLEL_SCAN; - else - printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar"); - ata_port_pbar_desc(ap, AHCI_PCI_BAR, - 0x100 + ap->port_no * 0x80, "port"); - - /* set initial link pm policy */ - /* - ap->pm_policy = NOT_AVAILABLE; - */ - /* disabled/not-implemented port */ - if (!(hpriv->port_map & (1 << i))) - ap->ops = &ata_dummy_port_ops; - } - - /* initialize adapter */ - rc = acard_ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); - if (rc) - return rc; - - rc = ahci_reset_controller(host); - if (rc) - return rc; - - ahci_init_controller(host); - acard_ahci_pci_print_info(host); - - pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED, - &acard_ahci_sht); -} - -static int __init acard_ahci_init(void) -{ - return pci_register_driver(&acard_ahci_pci_driver); -} - -static void __exit acard_ahci_exit(void) -{ - pci_unregister_driver(&acard_ahci_pci_driver); -} - -MODULE_AUTHOR("Jeff Garzik"); -MODULE_DESCRIPTION("ACard AHCI SATA low-level driver"); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(pci, acard_ahci_pci_tbl); -MODULE_VERSION(DRV_VERSION); - -module_init(acard_ahci_init); -module_exit(acard_ahci_exit); diff --git a/trunk/drivers/ata/ahci.h b/trunk/drivers/ata/ahci.h index 3e606c34f57b..329cbbb91284 100644 --- a/trunk/drivers/ata/ahci.h +++ b/trunk/drivers/ata/ahci.h @@ -311,8 +311,6 @@ extern struct device_attribute *ahci_sdev_attrs[]; extern struct ata_port_operations ahci_ops; -void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, - u32 opts); void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv, unsigned int force_port_map, @@ -328,7 +326,6 @@ int ahci_stop_engine(struct ata_port *ap); void ahci_start_engine(struct ata_port *ap); int ahci_check_ready(struct ata_link *link); int ahci_kick_engine(struct ata_port *ap); -int ahci_port_resume(struct ata_port *ap); void ahci_set_em_messages(struct ahci_host_priv *hpriv, struct ata_port_info *pi); int ahci_reset_em(struct ata_host *host); diff --git a/trunk/drivers/ata/libahci.c b/trunk/drivers/ata/libahci.c index 26d452339e98..ebc08d65b3dd 100644 --- a/trunk/drivers/ata/libahci.c +++ b/trunk/drivers/ata/libahci.c @@ -87,7 +87,10 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, static void ahci_postreset(struct ata_link *link, unsigned int *class); static void ahci_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); +static int ahci_port_resume(struct ata_port *ap); static void ahci_dev_config(struct ata_device *dev); +static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, + u32 opts); #ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); #endif @@ -1130,8 +1133,8 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) return ata_dev_classify(&tf); } -void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, - u32 opts) +static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, + u32 opts) { dma_addr_t cmd_tbl_dma; @@ -1142,7 +1145,6 @@ void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); } -EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot); int ahci_kick_engine(struct ata_port *ap) { @@ -1916,7 +1918,7 @@ static void ahci_pmp_detach(struct ata_port *ap) writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); } -int ahci_port_resume(struct ata_port *ap) +static int ahci_port_resume(struct ata_port *ap) { ahci_power_up(ap); ahci_start_port(ap); @@ -1928,7 +1930,6 @@ int ahci_port_resume(struct ata_port *ap) return 0; } -EXPORT_SYMBOL_GPL(ahci_port_resume); #ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 5defc74973d7..66aa4bee80a6 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -346,11 +346,12 @@ struct device_attribute *ata_common_sdev_attrs[] = { }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -static void ata_scsi_invalid_field(struct scsi_cmnd *cmd) +static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) { ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ - cmd->scsi_done(cmd); + done(cmd); } /** @@ -718,6 +719,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl); * ata_scsi_qc_new - acquire new ata_queued_cmd reference * @dev: ATA device to which the new command is attached * @cmd: SCSI command that originated this ATA command + * @done: SCSI command completion function * * Obtain a reference to an unused ata_queued_cmd structure, * which is the basic libata structure representing a single @@ -734,20 +736,21 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl); * Command allocated, or %NULL if none available. */ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, - struct scsi_cmnd *cmd) + struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) { struct ata_queued_cmd *qc; qc = ata_qc_new_init(dev); if (qc) { qc->scsicmd = cmd; - qc->scsidone = cmd->scsi_done; + qc->scsidone = done; qc->sg = scsi_sglist(cmd); qc->n_elem = scsi_sg_count(cmd); } else { cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1); - cmd->scsi_done(cmd); + done(cmd); } return qc; @@ -1732,6 +1735,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * ata_scsi_translate - Translate then issue SCSI command to ATA device * @dev: ATA device to which the command is addressed * @cmd: SCSI command to execute + * @done: SCSI command completion function * @xlat_func: Actor which translates @cmd to an ATA taskfile * * Our ->queuecommand() function has decided that the SCSI @@ -1755,6 +1759,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * needs to be deferred. */ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *), ata_xlat_func_t xlat_func) { struct ata_port *ap = dev->link->ap; @@ -1763,7 +1768,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, VPRINTK("ENTER\n"); - qc = ata_scsi_qc_new(dev, cmd); + qc = ata_scsi_qc_new(dev, cmd, done); if (!qc) goto err_mem; @@ -1799,14 +1804,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, early_finish: ata_qc_free(qc); - cmd->scsi_done(cmd); + qc->scsidone(cmd); DPRINTK("EXIT - early finish (good or error)\n"); return 0; err_did: ata_qc_free(qc); cmd->result = (DID_ERROR << 16); - cmd->scsi_done(cmd); + qc->scsidone(cmd); err_mem: DPRINTK("EXIT - internal\n"); return 0; @@ -3111,6 +3116,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, } static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, + void (*done)(struct scsi_cmnd *), struct ata_device *dev) { u8 scsi_op = scmd->cmnd[0]; @@ -3144,9 +3150,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, } if (xlat_func) - rc = ata_scsi_translate(dev, scmd, xlat_func); + rc = ata_scsi_translate(dev, scmd, done, xlat_func); else - ata_scsi_simulate(dev, scmd); + ata_scsi_simulate(dev, scmd, done); return rc; @@ -3154,7 +3160,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n", scmd->cmd_len, scsi_op, dev->cdb_len); scmd->result = DID_ERROR << 16; - scmd->scsi_done(scmd); + done(scmd); return 0; } @@ -3193,7 +3199,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) dev = ata_scsi_find_dev(ap, scsidev); if (likely(dev)) - rc = __ata_scsi_queuecmd(cmd, dev); + rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev); else { cmd->result = (DID_BAD_TARGET << 16); cmd->scsi_done(cmd); @@ -3208,6 +3214,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) * ata_scsi_simulate - simulate SCSI command on ATA device * @dev: the target device * @cmd: SCSI command being sent to device. + * @done: SCSI command completion function. * * Interprets and directly executes a select list of SCSI commands * that can be handled internally. @@ -3216,7 +3223,8 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) * spin_lock_irqsave(host lock) */ -void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) +void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) { struct ata_scsi_args args; const u8 *scsicmd = cmd->cmnd; @@ -3225,17 +3233,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) args.dev = dev; args.id = dev->id; args.cmd = cmd; - args.done = cmd->scsi_done; + args.done = done; switch(scsicmd[0]) { /* TODO: worth improving? */ case FORMAT_UNIT: - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); break; case INQUIRY: if (scsicmd[1] & 2) /* is CmdDt set? */ - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); else switch (scsicmd[2]) { @@ -3261,7 +3269,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); break; default: - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); break; } break; @@ -3273,7 +3281,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) case MODE_SELECT: /* unconditionally return */ case MODE_SELECT_10: /* bad-field-in-cdb */ - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); break; case READ_CAPACITY: @@ -3284,7 +3292,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); break; case REPORT_LUNS: @@ -3294,7 +3302,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) case REQUEST_SENSE: ata_scsi_set_sense(cmd, 0, 0, 0); cmd->result = (DRIVER_SENSE << 24); - cmd->scsi_done(cmd); + done(cmd); break; /* if we reach this, then writeback caching is disabled, @@ -3316,14 +3324,14 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) ata_scsi_rbuf_fill(&args, ata_scsiop_noop); else - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(cmd, done); break; /* all other commands */ default: ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); /* "Invalid command operation code" */ - cmd->scsi_done(cmd); + done(cmd); break; } } @@ -3850,6 +3858,7 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); /** * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device * @cmd: SCSI command to be sent + * @done: Completion function, called when command is complete * @ap: ATA port to which the command is being sent * * RETURNS: @@ -3857,17 +3866,18 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); * 0 otherwise. */ -int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) +int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), + struct ata_port *ap) { int rc = 0; ata_scsi_dump_cdb(ap, cmd); if (likely(ata_dev_enabled(ap->link.device))) - rc = __ata_scsi_queuecmd(cmd, ap->link.device); + rc = __ata_scsi_queuecmd(cmd, done, ap->link.device); else { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + done(cmd); } return rc; } diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index d7e57db36bc8..7688868557b9 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.9" +#define DRV_VERSION "0.6.8" struct hpt_clock { u8 xfer_mode; @@ -110,23 +110,18 @@ static const struct hpt_clock hpt366_25[] = { { 0, 0x01208585 } }; -static const char * const bad_ata33[] = { - "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", - "Maxtor 90845U3", "Maxtor 90650U2", - "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", - "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", - "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", - "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", +static const char *bad_ata33[] = { + "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", + "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", + "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", "Maxtor 90510D4", "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", - "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", - "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", - "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", - "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", + "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", + "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", NULL }; -static const char * const bad_ata66_4[] = { +static const char *bad_ata66_4[] = { "IBM-DTLA-307075", "IBM-DTLA-307060", "IBM-DTLA-307045", @@ -145,13 +140,12 @@ static const char * const bad_ata66_4[] = { NULL }; -static const char * const bad_ata66_3[] = { +static const char *bad_ata66_3[] = { "WDC AC310200R", NULL }; -static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, - const char * const list[]) +static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; int i = 0; @@ -294,7 +288,6 @@ static struct ata_port_operations hpt366_port_ops = { static void hpt36x_init_chipset(struct pci_dev *dev) { u8 drive_fast; - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); @@ -356,16 +349,16 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* PCI clocking determines the ATA timing values to use */ /* info_hpt366 is safe against re-entry so we can scribble on it */ - switch ((reg1 & 0x700) >> 8) { - case 9: - hpriv = &hpt366_40; - break; - case 5: - hpriv = &hpt366_25; - break; - default: - hpriv = &hpt366_33; - break; + switch((reg1 & 0x700) >> 8) { + case 9: + hpriv = &hpt366_40; + break; + case 5: + hpriv = &hpt366_25; + break; + default: + hpriv = &hpt366_33; + break; } /* Now kick off ATA set up */ return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); @@ -392,9 +385,9 @@ static const struct pci_device_id hpt36x[] = { }; static struct pci_driver hpt36x_pci_driver = { - .name = DRV_NAME, + .name = DRV_NAME, .id_table = hpt36x, - .probe = hpt36x_init_one, + .probe = hpt36x_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index efdd18bc8663..9ae4c0830577 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * * TODO * Look into engine reset on timeout errors. Should not be required. @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.18" +#define DRV_VERSION "0.6.15" struct hpt_clock { u8 xfer_speed; @@ -210,7 +210,7 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed) { struct hpt_clock *clocks = ap->host->private_data; - while (clocks->xfer_speed) { + while(clocks->xfer_speed) { if (clocks->xfer_speed == speed) return clocks->timing; clocks++; @@ -219,8 +219,7 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed) return 0xffffffffU; /* silence compiler warning */ } -static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, - const char * const list[]) +static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; int i = 0; @@ -238,23 +237,18 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, return 0; } -static const char * const bad_ata33[] = { - "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", - "Maxtor 90845U3", "Maxtor 90650U2", - "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", - "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", - "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", - "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", +static const char *bad_ata33[] = { + "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", + "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", + "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", "Maxtor 90510D4", "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", - "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", - "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", - "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", - "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", + "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", + "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", NULL }; -static const char * const bad_ata100_5[] = { +static const char *bad_ata100_5[] = { "IBM-DTLA-307075", "IBM-DTLA-307060", "IBM-DTLA-307045", @@ -307,22 +301,6 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) return mask; } -/** - * hpt372_filter - mode selection filter - * @adev: ATA device - * @mask: mode mask - * - * The Marvell bridge chips used on the HighPoint SATA cards do not seem - * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... - */ -static unsigned long hpt372_filter(struct ata_device *adev, unsigned long mask) -{ - if (ata_id_is_sata(adev->id)) - mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); - - return mask; -} - /** * hpt37x_cable_detect - Detect the cable type * @ap: ATA port to detect on @@ -395,7 +373,6 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) { 0x50, 1, 0x04, 0x04 }, { 0x54, 1, 0x04, 0x04 } }; - if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) return -ENOENT; @@ -609,11 +586,11 @@ static struct ata_port_operations hpt370a_port_ops = { }; /* - * Configuration for HPT371 and HPT302. Slightly different PIO and DMA - * mode setting functionality. + * Configuration for HPT372, HPT371, HPT302. Slightly different PIO + * and DMA mode setting functionality. */ -static struct ata_port_operations hpt302_port_ops = { +static struct ata_port_operations hpt372_port_ops = { .inherits = &ata_bmdma_port_ops, .bmdma_stop = hpt37x_bmdma_stop, @@ -625,17 +602,7 @@ static struct ata_port_operations hpt302_port_ops = { }; /* - * Configuration for HPT372. Mode setting works like 371 and 302 - * but we have a mode filter. - */ - -static struct ata_port_operations hpt372_port_ops = { - .inherits = &hpt302_port_ops, - .mode_filter = hpt372_filter, -}; - -/* - * Configuration for HPT374. Mode setting and filtering works like 372 + * Configuration for HPT374. Mode setting works like 372 and friends * but we have a different cable detection procedure for function 1. */ @@ -680,12 +647,12 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) u32 reg5c; int tries; - for (tries = 0; tries < 0x5000; tries++) { + for(tries = 0; tries < 0x5000; tries++) { udelay(50); pci_read_config_byte(dev, 0x5b, ®5b); if (reg5b & 0x80) { /* See if it stays set */ - for (tries = 0; tries < 0x1000; tries++) { + for(tries = 0; tries < 0x1000; tries ++) { pci_read_config_byte(dev, 0x5b, ®5b); /* Failed ? */ if ((reg5b & 0x80) == 0) @@ -693,7 +660,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) } /* Turn off tuning, we have the DPLL set */ pci_read_config_dword(dev, 0x5c, ®5c); - pci_write_config_dword(dev, 0x5c, reg5c & ~0x100); + pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); return 1; } } @@ -705,7 +672,6 @@ static u32 hpt374_read_freq(struct pci_dev *pdev) { u32 freq; unsigned long io_base = pci_resource_start(pdev, 4); - if (PCI_FUNC(pdev->devfn) & 1) { struct pci_dev *pdev_0; @@ -771,23 +737,23 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = ATA_UDMA5, .port_ops = &hpt370a_port_ops }; - /* HPT370 - UDMA66 */ + /* HPT370 - UDMA100 */ static const struct ata_port_info info_hpt370_33 = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, + .udma_mask = ATA_UDMA5, .port_ops = &hpt370_port_ops }; - /* HPT370A - UDMA66 */ + /* HPT370A - UDMA100 */ static const struct ata_port_info info_hpt370a_33 = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, + .udma_mask = ATA_UDMA5, .port_ops = &hpt370a_port_ops }; - /* HPT372 - UDMA133 */ + /* HPT371, 372 and friends - UDMA133 */ static const struct ata_port_info info_hpt372 = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, @@ -795,14 +761,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = ATA_UDMA6, .port_ops = &hpt372_port_ops }; - /* HPT371, 302 - UDMA133 */ - static const struct ata_port_info info_hpt302 = { - .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &hpt302_port_ops - }; /* HPT374 - UDMA100, function 1 uses different prereset method */ static const struct ata_port_info info_hpt374_fn0 = { .flags = ATA_FLAG_SLAVE_POSS, @@ -847,68 +805,64 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (rev == 6) return -ENODEV; - switch (rev) { - case 3: - ppi[0] = &info_hpt370; - chip_table = &hpt370; - prefer_dpll = 0; - break; - case 4: - ppi[0] = &info_hpt370a; - chip_table = &hpt370a; - prefer_dpll = 0; - break; - case 5: - ppi[0] = &info_hpt372; - chip_table = &hpt372; - break; - default: - printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype, " - "please report (%d).\n", rev); - return -ENODEV; + switch(rev) { + case 3: + ppi[0] = &info_hpt370; + chip_table = &hpt370; + prefer_dpll = 0; + break; + case 4: + ppi[0] = &info_hpt370a; + chip_table = &hpt370a; + prefer_dpll = 0; + break; + case 5: + ppi[0] = &info_hpt372; + chip_table = &hpt372; + break; + default: + printk(KERN_ERR "pata_hpt37x: Unknown HPT366 " + "subtype, please report (%d).\n", rev); + return -ENODEV; } } else { - switch (dev->device) { - case PCI_DEVICE_ID_TTI_HPT372: - /* 372N if rev >= 2 */ - if (rev >= 2) - return -ENODEV; - ppi[0] = &info_hpt372; - chip_table = &hpt372a; - break; - case PCI_DEVICE_ID_TTI_HPT302: - /* 302N if rev > 1 */ - if (rev > 1) - return -ENODEV; - ppi[0] = &info_hpt302; - /* Check this */ - chip_table = &hpt302; - break; - case PCI_DEVICE_ID_TTI_HPT371: - if (rev > 1) - return -ENODEV; - ppi[0] = &info_hpt302; - chip_table = &hpt371; - /* - * Single channel device, master is not present - * but the BIOS (or us for non x86) must mark it - * absent - */ - pci_read_config_byte(dev, 0x50, &mcr1); - mcr1 &= ~0x04; - pci_write_config_byte(dev, 0x50, mcr1); - break; - case PCI_DEVICE_ID_TTI_HPT374: - chip_table = &hpt374; - if (!(PCI_FUNC(dev->devfn) & 1)) - *ppi = &info_hpt374_fn0; - else - *ppi = &info_hpt374_fn1; - break; - default: - printk(KERN_ERR - "pata_hpt37x: PCI table is bogus, please report (%d).\n", - dev->device); + switch(dev->device) { + case PCI_DEVICE_ID_TTI_HPT372: + /* 372N if rev >= 2*/ + if (rev >= 2) + return -ENODEV; + ppi[0] = &info_hpt372; + chip_table = &hpt372a; + break; + case PCI_DEVICE_ID_TTI_HPT302: + /* 302N if rev > 1 */ + if (rev > 1) + return -ENODEV; + ppi[0] = &info_hpt372; + /* Check this */ + chip_table = &hpt302; + break; + case PCI_DEVICE_ID_TTI_HPT371: + if (rev > 1) + return -ENODEV; + ppi[0] = &info_hpt372; + chip_table = &hpt371; + /* Single channel device, master is not present + but the BIOS (or us for non x86) must mark it + absent */ + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); + break; + case PCI_DEVICE_ID_TTI_HPT374: + chip_table = &hpt374; + if (!(PCI_FUNC(dev->devfn) & 1)) + *ppi = &info_hpt374_fn0; + else + *ppi = &info_hpt374_fn1; + break; + default: + printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device); return -ENODEV; } } @@ -939,11 +893,9 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (chip_table == &hpt372a) outb(0x0e, iobase + 0x9c); - /* - * Some devices do not let this value be accessed via PCI space - * according to the old driver. In addition we must use the value - * from FN 0 on the HPT374. - */ + /* Some devices do not let this value be accessed via PCI space + according to the old driver. In addition we must use the value + from FN 0 on the HPT374 */ if (chip_table == &hpt374) { freq = hpt374_read_freq(dev); @@ -957,11 +909,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) u8 sr; u32 total = 0; - printk(KERN_WARNING - "pata_hpt37x: BIOS has not set timing clocks.\n"); + printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n"); /* This is the process the HPT371 BIOS is reported to use */ - for (i = 0; i < 128; i++) { + for(i = 0; i < 128; i++) { pci_read_config_byte(dev, 0x78, &sr); total += sr & 0x1FF; udelay(15); @@ -996,22 +947,17 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* Select the DPLL clock. */ pci_write_config_byte(dev, 0x5b, 0x21); - pci_write_config_dword(dev, 0x5C, - (f_high << 16) | f_low | 0x100); + pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); - for (adjust = 0; adjust < 8; adjust++) { + for(adjust = 0; adjust < 8; adjust++) { if (hpt37x_calibrate_dpll(dev)) break; - /* - * See if it'll settle at a fractionally - * different clock - */ + /* See if it'll settle at a fractionally different clock */ if (adjust & 1) f_low -= adjust >> 1; else f_high += adjust >> 1; - pci_write_config_dword(dev, 0x5C, - (f_high << 16) | f_low | 0x100); + pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); } if (adjust == 8) { printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); @@ -1030,7 +976,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) * Perform a final fixup. Note that we will have used the * DPLL on the HPT372 which means we don't have to worry * about lack of UDMA133 support on lower clocks - */ + */ if (clock_slot < 2 && ppi[0] == &info_hpt370) ppi[0] = &info_hpt370_33; @@ -1055,9 +1001,9 @@ static const struct pci_device_id hpt37x[] = { }; static struct pci_driver hpt37x_pci_driver = { - .name = DRV_NAME, + .name = DRV_NAME, .id_table = hpt37x, - .probe = hpt37x_init_one, + .probe = hpt37x_init_one, .remove = ata_pci_remove_one }; diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index d2239bbdb798..32f3463216b8 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -1,5 +1,5 @@ /* - * Libata driver for the HighPoint 371N, 372N, and 302N UDMA66 ATA controllers. + * Libata driver for the highpoint 372N and 302N UDMA66 ATA controllers. * * This driver is heavily based upon: * @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * * * TODO @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.13" +#define DRV_VERSION "0.3.10" enum { HPT_PCI_FAST = (1 << 31), @@ -103,7 +103,7 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) { struct hpt_clock *clocks = hpt3x2n_clocks; - while (clocks->xfer_speed) { + while(clocks->xfer_speed) { if (clocks->xfer_speed == speed) return clocks->timing; clocks++; @@ -112,22 +112,6 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) return 0xffffffffU; /* silence compiler warning */ } -/** - * hpt372n_filter - mode selection filter - * @adev: ATA device - * @mask: mode mask - * - * The Marvell bridge chips used on the HighPoint SATA cards do not seem - * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... - */ -static unsigned long hpt372n_filter(struct ata_device *adev, unsigned long mask) -{ - if (ata_id_is_sata(adev->id)) - mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); - - return mask; -} - /** * hpt3x2n_cable_detect - Detect the cable type * @ap: ATA port to detect on @@ -169,7 +153,6 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - /* Reset the state machine */ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); @@ -345,10 +328,10 @@ static struct scsi_host_template hpt3x2n_sht = { }; /* - * Configuration for HPT302N/371N. + * Configuration for HPT3x2n. */ -static struct ata_port_operations hpt3xxn_port_ops = { +static struct ata_port_operations hpt3x2n_port_ops = { .inherits = &ata_bmdma_port_ops, .bmdma_stop = hpt3x2n_bmdma_stop, @@ -362,15 +345,6 @@ static struct ata_port_operations hpt3xxn_port_ops = { .prereset = hpt3x2n_pre_reset, }; -/* - * Configuration for HPT372N. Same as 302N/371N but we have a mode filter. - */ - -static struct ata_port_operations hpt372n_port_ops = { - .inherits = &hpt3xxn_port_ops, - .mode_filter = &hpt372n_filter, -}; - /** * hpt3xn_calibrate_dpll - Calibrate the DPLL loop * @dev: PCI device @@ -385,12 +359,12 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) u32 reg5c; int tries; - for (tries = 0; tries < 0x5000; tries++) { + for(tries = 0; tries < 0x5000; tries++) { udelay(50); pci_read_config_byte(dev, 0x5b, ®5b); if (reg5b & 0x80) { /* See if it stays set */ - for (tries = 0; tries < 0x1000; tries++) { + for(tries = 0; tries < 0x1000; tries ++) { pci_read_config_byte(dev, 0x5b, ®5b); /* Failed ? */ if ((reg5b & 0x80) == 0) @@ -398,7 +372,7 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) } /* Turn off tuning, we have the DPLL set */ pci_read_config_dword(dev, 0x5c, ®5c); - pci_write_config_dword(dev, 0x5c, reg5c & ~0x100); + pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); return 1; } } @@ -414,19 +388,8 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ if ((fcnt >> 12) != 0xABCDE) { - int i; - u16 sr; - u32 total = 0; - - printk(KERN_WARNING "pata_hpt3x2n: BIOS clock data not set.\n"); - - /* This is the process the HPT371 BIOS is reported to use */ - for (i = 0; i < 128; i++) { - pci_read_config_word(pdev, 0x78, &sr); - total += sr & 0x1FF; - udelay(15); - } - fcnt = total / 128; + printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); + return 33; /* Not BIOS set */ } fcnt &= 0x1FF; @@ -468,27 +431,21 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) * HPT372N 9 (HPT372N) * UDMA133 * * (1) UDMA133 support depends on the bus clock + * + * To pin down HPT371N */ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - /* HPT372N - UDMA133 */ - static const struct ata_port_info info_hpt372n = { - .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &hpt372n_port_ops - }; - /* HPT302N and HPT371N - UDMA133 */ - static const struct ata_port_info info_hpt3xxn = { + /* HPT372N and friends - UDMA133 */ + static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, - .port_ops = &hpt3xxn_port_ops + .port_ops = &hpt3x2n_port_ops }; - const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL }; + const struct ata_port_info *ppi[] = { &info, NULL }; u8 rev = dev->revision; u8 irqmask; unsigned int pci_mhz; @@ -502,36 +459,30 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (rc) return rc; - switch (dev->device) { - case PCI_DEVICE_ID_TTI_HPT366: - /* 372N if rev >= 6 */ - if (rev < 6) - return -ENODEV; - goto hpt372n; - case PCI_DEVICE_ID_TTI_HPT371: - /* 371N if rev >= 2 */ - if (rev < 2) - return -ENODEV; - break; - case PCI_DEVICE_ID_TTI_HPT372: - /* 372N if rev >= 2 */ - if (rev < 2) - return -ENODEV; - goto hpt372n; - case PCI_DEVICE_ID_TTI_HPT302: - /* 302N if rev >= 2 */ - if (rev < 2) + switch(dev->device) { + case PCI_DEVICE_ID_TTI_HPT366: + if (rev < 6) + return -ENODEV; + break; + case PCI_DEVICE_ID_TTI_HPT371: + if (rev < 2) + return -ENODEV; + /* 371N if rev > 1 */ + break; + case PCI_DEVICE_ID_TTI_HPT372: + /* 372N if rev >= 2*/ + if (rev < 2) + return -ENODEV; + break; + case PCI_DEVICE_ID_TTI_HPT302: + if (rev < 2) + return -ENODEV; + break; + case PCI_DEVICE_ID_TTI_HPT372N: + break; + default: + printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); return -ENODEV; - break; - case PCI_DEVICE_ID_TTI_HPT372N: -hpt372n: - ppi[0] = &info_hpt372n; - break; - default: - printk(KERN_ERR - "pata_hpt3x2n: PCI table is bogus please report (%d).\n", - dev->device); - return -ENODEV; } /* Ok so this is a chip we support */ @@ -558,10 +509,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_byte(dev, 0x50, mcr1); } - /* - * Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or - * 50 for UDMA100. Right now we always use 66 - */ + /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or + 50 for UDMA100. Right now we always use 66 */ pci_mhz = hpt3x2n_pci_clock(dev); @@ -573,7 +522,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_byte(dev, 0x5B, 0x21); /* Unlike the 37x we don't try jiggling the frequency */ - for (adjust = 0; adjust < 8; adjust++) { + for(adjust = 0; adjust < 8; adjust++) { if (hpt3xn_calibrate_dpll(dev)) break; pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); @@ -585,11 +534,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", pci_mhz); - - /* - * Set our private data up. We only need a few flags - * so we use it directly. - */ + /* Set our private data up. We only need a few flags so we use + it directly */ if (pci_mhz > 60) hpriv = (void *)(PCI66 | USE_DPLL); @@ -616,9 +562,9 @@ static const struct pci_device_id hpt3x2n[] = { }; static struct pci_driver hpt3x2n_pci_driver = { - .name = DRV_NAME, + .name = DRV_NAME, .id_table = hpt3x2n, - .probe = hpt3x2n_init_one, + .probe = hpt3x2n_init_one, .remove = ata_pci_remove_one }; @@ -633,7 +579,7 @@ static void __exit hpt3x2n_exit(void) } MODULE_AUTHOR("Alan Cox"); -MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3xxN"); +MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, hpt3x2n); MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 761359261589..6ed645411c40 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -338,35 +338,6 @@ static void device_remove_attributes(struct device *dev, device_remove_file(dev, &attrs[i]); } -static int device_add_bin_attributes(struct device *dev, - struct bin_attribute *attrs) -{ - int error = 0; - int i; - - if (attrs) { - for (i = 0; attr_name(attrs[i]); i++) { - error = device_create_bin_file(dev, &attrs[i]); - if (error) - break; - } - if (error) - while (--i >= 0) - device_remove_bin_file(dev, &attrs[i]); - } - return error; -} - -static void device_remove_bin_attributes(struct device *dev, - struct bin_attribute *attrs) -{ - int i; - - if (attrs) - for (i = 0; attr_name(attrs[i]); i++) - device_remove_bin_file(dev, &attrs[i]); -} - static int device_add_groups(struct device *dev, const struct attribute_group **groups) { @@ -407,15 +378,12 @@ static int device_add_attrs(struct device *dev) error = device_add_attributes(dev, class->dev_attrs); if (error) return error; - error = device_add_bin_attributes(dev, class->dev_bin_attrs); - if (error) - goto err_remove_class_attrs; } if (type) { error = device_add_groups(dev, type->groups); if (error) - goto err_remove_class_bin_attrs; + goto err_remove_class_attrs; } error = device_add_groups(dev, dev->groups); @@ -427,9 +395,6 @@ static int device_add_attrs(struct device *dev) err_remove_type_groups: if (type) device_remove_groups(dev, type->groups); - err_remove_class_bin_attrs: - if (class) - device_remove_bin_attributes(dev, class->dev_bin_attrs); err_remove_class_attrs: if (class) device_remove_attributes(dev, class->dev_attrs); @@ -447,10 +412,8 @@ static void device_remove_attrs(struct device *dev) if (type) device_remove_groups(dev, type->groups); - if (class) { + if (class) device_remove_attributes(dev, class->dev_attrs); - device_remove_bin_attributes(dev, class->dev_bin_attrs); - } } diff --git a/trunk/drivers/base/power/generic_ops.c b/trunk/drivers/base/power/generic_ops.c index 42f97f925629..81f2c84697f4 100644 --- a/trunk/drivers/base/power/generic_ops.c +++ b/trunk/drivers/base/power/generic_ops.c @@ -39,7 +39,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); * * If PM operations are defined for the @dev's driver and they include * ->runtime_suspend(), execute it and return its error code. Otherwise, - * return 0. + * return -EINVAL. */ int pm_generic_runtime_suspend(struct device *dev) { @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); * * If PM operations are defined for the @dev's driver and they include * ->runtime_resume(), execute it and return its error code. Otherwise, - * return 0. + * return -EINVAL. */ int pm_generic_runtime_resume(struct device *dev) { @@ -185,7 +185,7 @@ static int __pm_generic_resume(struct device *dev, int event) return 0; ret = callback(dev); - if (!ret && pm_runtime_enabled(dev)) { + if (!ret) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 2a52270aeb30..ead3e79d6fcf 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "../base.h" #include "power.h" @@ -42,13 +41,16 @@ */ LIST_HEAD(dpm_list); -LIST_HEAD(dpm_prepared_list); -LIST_HEAD(dpm_suspended_list); -LIST_HEAD(dpm_noirq_list); static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; +/* + * Set once the preparation of devices for a PM transition has started, reset + * before starting to resume devices. Protected by dpm_list_mtx. + */ +static bool transition_started; + static int async_error; /** @@ -57,7 +59,7 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.in_suspend = false; + dev->power.status = DPM_ON; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -88,11 +90,22 @@ void device_pm_unlock(void) void device_pm_add(struct device *dev) { pr_debug("PM: Adding info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); + dev->bus ? dev->bus->name : "No Bus", + kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.in_suspend) - dev_warn(dev, "parent %s should not be sleeping\n", - dev_name(dev->parent)); + if (dev->parent) { + if (dev->parent->power.status >= DPM_SUSPENDING) + dev_warn(dev, "parent %s should not be sleeping\n", + dev_name(dev->parent)); + } else if (transition_started) { + /* + * We refuse to register parentless devices while a PM + * transition is in progress in order to avoid leaving them + * unhandled down the road + */ + dev_WARN(dev, "Parentless device registered during a PM transaction\n"); + } + list_add_tail(&dev->power.entry, &dpm_list); mutex_unlock(&dpm_list_mtx); } @@ -104,7 +117,8 @@ void device_pm_add(struct device *dev) void device_pm_remove(struct device *dev) { pr_debug("PM: Removing info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); + dev->bus ? dev->bus->name : "No Bus", + kobject_name(&dev->kobj)); complete_all(&dev->power.completion); mutex_lock(&dpm_list_mtx); list_del_init(&dev->power.entry); @@ -121,8 +135,10 @@ void device_pm_remove(struct device *dev) void device_pm_move_before(struct device *deva, struct device *devb) { pr_debug("PM: Moving %s:%s before %s:%s\n", - deva->bus ? deva->bus->name : "No Bus", dev_name(deva), - devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); + deva->bus ? deva->bus->name : "No Bus", + kobject_name(&deva->kobj), + devb->bus ? devb->bus->name : "No Bus", + kobject_name(&devb->kobj)); /* Delete deva from dpm_list and reinsert before devb. */ list_move_tail(&deva->power.entry, &devb->power.entry); } @@ -135,8 +151,10 @@ void device_pm_move_before(struct device *deva, struct device *devb) void device_pm_move_after(struct device *deva, struct device *devb) { pr_debug("PM: Moving %s:%s after %s:%s\n", - deva->bus ? deva->bus->name : "No Bus", dev_name(deva), - devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); + deva->bus ? deva->bus->name : "No Bus", + kobject_name(&deva->kobj), + devb->bus ? devb->bus->name : "No Bus", + kobject_name(&devb->kobj)); /* Delete deva from dpm_list and reinsert after devb. */ list_move(&deva->power.entry, &devb->power.entry); } @@ -148,7 +166,8 @@ void device_pm_move_after(struct device *deva, struct device *devb) void device_pm_move_last(struct device *dev) { pr_debug("PM: Moving %s:%s to end of list\n", - dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); + dev->bus ? dev->bus->name : "No Bus", + kobject_name(&dev->kobj)); list_move_tail(&dev->power.entry, &dpm_list); } @@ -284,7 +303,7 @@ static int pm_noirq_op(struct device *dev, pm_message_t state) { int error = 0; - ktime_t calltime = ktime_set(0, 0), delta, rettime; + ktime_t calltime, delta, rettime; if (initcall_debug) { pr_info("calling %s+ @ %i, parent: %s\n", @@ -386,7 +405,7 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, int error) { printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", - dev_name(dev), pm_verb(state.event), info, error); + kobject_name(&dev->kobj), pm_verb(state.event), info, error); } static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) @@ -456,24 +475,33 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) */ void dpm_resume_noirq(pm_message_t state) { + struct list_head list; ktime_t starttime = ktime_get(); + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_noirq_list)) { - struct device *dev = to_device(dpm_noirq_list.next); - int error; + transition_started = false; + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.next); get_device(dev); - list_move_tail(&dev->power.entry, &dpm_suspended_list); - mutex_unlock(&dpm_list_mtx); + if (dev->power.status > DPM_OFF) { + int error; - error = device_resume_noirq(dev, state); - if (error) - pm_dev_err(dev, state, " early", error); + dev->power.status = DPM_OFF; + mutex_unlock(&dpm_list_mtx); - mutex_lock(&dpm_list_mtx); + error = device_resume_noirq(dev, state); + + mutex_lock(&dpm_list_mtx); + if (error) + pm_dev_err(dev, state, " early", error); + } + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &list); put_device(dev); } + list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "early"); resume_device_irqs(); @@ -516,7 +544,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dpm_wait(dev->parent, async); device_lock(dev); - dev->power.in_suspend = false; + dev->power.status = DPM_RESUMING; if (dev->bus) { if (dev->bus->pm) { @@ -582,14 +610,19 @@ static bool is_async(struct device *dev) */ static void dpm_resume(pm_message_t state) { + struct list_head list; struct device *dev; ktime_t starttime = ktime_get(); + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; - list_for_each_entry(dev, &dpm_suspended_list, power.entry) { + list_for_each_entry(dev, &dpm_list, power.entry) { + if (dev->power.status < DPM_OFF) + continue; + INIT_COMPLETION(dev->power.completion); if (is_async(dev)) { get_device(dev); @@ -597,24 +630,28 @@ static void dpm_resume(pm_message_t state) } } - while (!list_empty(&dpm_suspended_list)) { - dev = to_device(dpm_suspended_list.next); + while (!list_empty(&dpm_list)) { + dev = to_device(dpm_list.next); get_device(dev); - if (!is_async(dev)) { + if (dev->power.status >= DPM_OFF && !is_async(dev)) { int error; mutex_unlock(&dpm_list_mtx); error = device_resume(dev, state, false); - if (error) - pm_dev_err(dev, state, "", error); mutex_lock(&dpm_list_mtx); + if (error) + pm_dev_err(dev, state, "", error); + } else if (dev->power.status == DPM_SUSPENDING) { + /* Allow new children of the device to be registered */ + dev->power.status = DPM_RESUMING; } if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); + list_move_tail(&dev->power.entry, &list); put_device(dev); } + list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); async_synchronize_full(); dpm_show_time(starttime, state, NULL); @@ -660,18 +697,22 @@ static void dpm_complete(pm_message_t state) INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_prepared_list)) { - struct device *dev = to_device(dpm_prepared_list.prev); + transition_started = false; + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.prev); get_device(dev); - dev->power.in_suspend = false; - list_move(&dev->power.entry, &list); - mutex_unlock(&dpm_list_mtx); + if (dev->power.status > DPM_ON) { + dev->power.status = DPM_ON; + mutex_unlock(&dpm_list_mtx); - device_complete(dev, state); - pm_runtime_put_sync(dev); + device_complete(dev, state); + pm_runtime_put_sync(dev); - mutex_lock(&dpm_list_mtx); + mutex_lock(&dpm_list_mtx); + } + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &list); put_device(dev); } list_splice(&list, &dpm_list); @@ -761,13 +802,15 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) */ int dpm_suspend_noirq(pm_message_t state) { + struct list_head list; ktime_t starttime = ktime_get(); int error = 0; + INIT_LIST_HEAD(&list); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_suspended_list)) { - struct device *dev = to_device(dpm_suspended_list.prev); + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -780,10 +823,12 @@ int dpm_suspend_noirq(pm_message_t state) put_device(dev); break; } + dev->power.status = DPM_OFF_IRQ; if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &dpm_noirq_list); + list_move(&dev->power.entry, &list); put_device(dev); } + list_splice_tail(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); @@ -831,11 +876,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (async_error) goto End; - if (pm_wakeup_pending()) { - async_error = -EBUSY; - goto End; - } - if (dev->class) { if (dev->class->pm) { pm_dev_dbg(dev, state, "class "); @@ -867,6 +907,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } } + if (!error) + dev->power.status = DPM_OFF; + End: device_unlock(dev); complete_all(&dev->power.completion); @@ -908,14 +951,16 @@ static int device_suspend(struct device *dev) */ static int dpm_suspend(pm_message_t state) { + struct list_head list; ktime_t starttime = ktime_get(); int error = 0; + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; - while (!list_empty(&dpm_prepared_list)) { - struct device *dev = to_device(dpm_prepared_list.prev); + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -929,11 +974,12 @@ static int dpm_suspend(pm_message_t state) break; } if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &dpm_suspended_list); + list_move(&dev->power.entry, &list); put_device(dev); if (async_error) break; } + list_splice(&list, dpm_list.prev); mutex_unlock(&dpm_list_mtx); async_synchronize_full(); if (!error) @@ -992,20 +1038,22 @@ static int device_prepare(struct device *dev, pm_message_t state) */ static int dpm_prepare(pm_message_t state) { + struct list_head list; int error = 0; + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); + transition_started = true; while (!list_empty(&dpm_list)) { struct device *dev = to_device(dpm_list.next); get_device(dev); + dev->power.status = DPM_PREPARING; mutex_unlock(&dpm_list_mtx); pm_runtime_get_noresume(dev); - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) - pm_wakeup_event(dev, 0); - - if (pm_wakeup_pending()) { + if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { + /* Wake-up requested during system sleep transition. */ pm_runtime_put_sync(dev); error = -EBUSY; } else { @@ -1014,22 +1062,24 @@ static int dpm_prepare(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) { + dev->power.status = DPM_ON; if (error == -EAGAIN) { put_device(dev); error = 0; continue; } - printk(KERN_INFO "PM: Device %s not prepared " - "for power transition: code %d\n", - dev_name(dev), error); + printk(KERN_ERR "PM: Failed to prepare device %s " + "for power transition: error %d\n", + kobject_name(&dev->kobj), error); put_device(dev); break; } - dev->power.in_suspend = true; + dev->power.status = DPM_SUSPENDING; if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); + list_move_tail(&dev->power.entry, &list); put_device(dev); } + list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); return error; } diff --git a/trunk/drivers/base/power/runtime.c b/trunk/drivers/base/power/runtime.c index 656493a5e073..02c652be83e7 100644 --- a/trunk/drivers/base/power/runtime.c +++ b/trunk/drivers/base/power/runtime.c @@ -250,16 +250,13 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) if (!cb) return -ENOSYS; - if (dev->power.irq_safe) { - retval = cb(dev); - } else { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irq(&dev->power.lock); - retval = cb(dev); + retval = cb(dev); - spin_lock_irq(&dev->power.lock); - } + spin_lock_irq(&dev->power.lock); dev->power.runtime_error = retval; + return retval; } @@ -407,7 +404,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) goto out; } - if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { + if (parent && !parent->power.ignore_children) { spin_unlock_irq(&dev->power.lock); pm_request_idle(parent); @@ -530,13 +527,10 @@ static int rpm_resume(struct device *dev, int rpmflags) if (!parent && dev->parent) { /* - * Increment the parent's usage counter and resume it if - * necessary. Not needed if dev is irq-safe; then the - * parent is permanently resumed. + * Increment the parent's resume counter and resume it if + * necessary. */ parent = dev->parent; - if (dev->power.irq_safe) - goto skip_parent; spin_unlock(&dev->power.lock); pm_runtime_get_noresume(parent); @@ -559,7 +553,6 @@ static int rpm_resume(struct device *dev, int rpmflags) goto out; goto repeat; } - skip_parent: if (dev->power.no_callbacks) goto no_callback; /* Assume success. */ @@ -591,7 +584,7 @@ static int rpm_resume(struct device *dev, int rpmflags) rpm_idle(dev, RPM_ASYNC); out: - if (parent && !dev->power.irq_safe) { + if (parent) { spin_unlock_irq(&dev->power.lock); pm_runtime_put(parent); @@ -1072,6 +1065,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_allow); * Set the power.no_callbacks flag, which tells the PM core that this * device is power-managed through its parent and has no run-time PM * callbacks of its own. The run-time sysfs attributes will be removed. + * */ void pm_runtime_no_callbacks(struct device *dev) { @@ -1083,27 +1077,6 @@ void pm_runtime_no_callbacks(struct device *dev) } EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); -/** - * pm_runtime_irq_safe - Leave interrupts disabled during callbacks. - * @dev: Device to handle - * - * Set the power.irq_safe flag, which tells the PM core that the - * ->runtime_suspend() and ->runtime_resume() callbacks for this device should - * always be invoked with the spinlock held and interrupts disabled. It also - * causes the parent's usage counter to be permanently incremented, preventing - * the parent from runtime suspending -- otherwise an irq-safe child might have - * to wait for a non-irq-safe parent. - */ -void pm_runtime_irq_safe(struct device *dev) -{ - if (dev->parent) - pm_runtime_get_sync(dev->parent); - spin_lock_irq(&dev->power.lock); - dev->power.irq_safe = 1; - spin_unlock_irq(&dev->power.lock); -} -EXPORT_SYMBOL_GPL(pm_runtime_irq_safe); - /** * update_autosuspend - Handle a change to a device's autosuspend settings. * @dev: Device to handle. @@ -1226,6 +1199,4 @@ void pm_runtime_remove(struct device *dev) /* Change the status back to 'suspended' to match the initial status. */ if (dev->power.runtime_status == RPM_ACTIVE) pm_runtime_set_suspended(dev); - if (dev->power.irq_safe && dev->parent) - pm_runtime_put_sync(dev->parent); } diff --git a/trunk/drivers/base/power/wakeup.c b/trunk/drivers/base/power/wakeup.c index 8ec406d8f548..71c5528e1c35 100644 --- a/trunk/drivers/base/power/wakeup.c +++ b/trunk/drivers/base/power/wakeup.c @@ -542,26 +542,26 @@ static void pm_wakeup_update_hit_counts(void) } /** - * pm_wakeup_pending - Check if power transition in progress should be aborted. + * pm_check_wakeup_events - Check for new wakeup events. * * Compare the current number of registered wakeup events with its preserved - * value from the past and return true if new wakeup events have been registered - * since the old value was stored. Also return true if the current number of - * wakeup events being processed is different from zero. + * value from the past to check if new wakeup events have been registered since + * the old value was stored. Check if the current number of wakeup events being + * processed is zero. */ -bool pm_wakeup_pending(void) +bool pm_check_wakeup_events(void) { unsigned long flags; - bool ret = false; + bool ret = true; spin_lock_irqsave(&events_lock, flags); if (events_check_enabled) { - ret = ((unsigned int)atomic_read(&event_count) != saved_count) - || atomic_read(&events_in_progress); - events_check_enabled = !ret; + ret = ((unsigned int)atomic_read(&event_count) == saved_count) + && !atomic_read(&events_in_progress); + events_check_enabled = ret; } spin_unlock_irqrestore(&events_lock, flags); - if (ret) + if (!ret) pm_wakeup_update_hit_counts(); return ret; } diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index f27c04e18aaa..035da9e64a17 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -69,8 +69,6 @@ #ifdef CONFIG_PPC_OF #include #include -#include -#include #endif #define PFX "ipmi_si: " @@ -2548,7 +2546,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, { struct smi_info *info; struct resource resource; - const __be32 *regsize, *regspacing, *regshift; + const int *regsize, *regspacing, *regshift; struct device_node *np = dev->dev.of_node; int ret; int proplen; @@ -2601,9 +2599,9 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, info->io.addr_data = resource.start; - info->io.regsize = regsize ? be32_to_cpup(regsize) : DEFAULT_REGSIZE; - info->io.regspacing = regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING; - info->io.regshift = regshift ? be32_to_cpup(regshift) : 0; + info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE; + info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; + info->io.regshift = regshift ? *regshift : 0; info->irq = irq_of_parse_and_map(dev->dev.of_node, 0); info->dev = &dev->dev; diff --git a/trunk/drivers/char/snsc.h b/trunk/drivers/char/snsc.h index e8c52c882b21..4be62eda9fbc 100644 --- a/trunk/drivers/char/snsc.h +++ b/trunk/drivers/char/snsc.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 1f46f1cd9225..0b3af3fe6766 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -736,7 +736,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) if (chip == NULL) return -ENODEV; rc = __tpm_pcr_read(chip, pcr_idx, res_buf); - tpm_chip_put(chip); + module_put(chip->dev->driver->owner); return rc; } EXPORT_SYMBOL_GPL(tpm_pcr_read); @@ -775,27 +775,11 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, "attempting extend a PCR value"); - tpm_chip_put(chip); + module_put(chip->dev->driver->owner); return rc; } EXPORT_SYMBOL_GPL(tpm_pcr_extend); -int tpm_send(u32 chip_num, void *cmd, size_t buflen) -{ - struct tpm_chip *chip; - int rc; - - chip = tpm_chip_find_get(chip_num); - if (chip == NULL) - return -ENODEV; - - rc = transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd"); - - tpm_chip_put(chip); - return rc; -} -EXPORT_SYMBOL_GPL(tpm_send); - ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index 72ddb031b69a..792868d24f2a 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -113,11 +113,6 @@ struct tpm_chip { #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) -static inline void tpm_chip_put(struct tpm_chip *chip) -{ - module_put(chip->dev->driver->owner); -} - static inline int tpm_read_index(int base, int index) { outb(index, base); diff --git a/trunk/drivers/firewire/Kconfig b/trunk/drivers/firewire/Kconfig index 68f942cb30f2..40a222e19b2d 100644 --- a/trunk/drivers/firewire/Kconfig +++ b/trunk/drivers/firewire/Kconfig @@ -19,7 +19,7 @@ config FIREWIRE config FIREWIRE_OHCI tristate "OHCI-1394 controllers" - depends on PCI && FIREWIRE && MMU + depends on PCI && FIREWIRE help Enable this driver if you have a FireWire controller based on the OHCI specification. For all practical purposes, this diff --git a/trunk/drivers/firewire/core-cdev.c b/trunk/drivers/firewire/core-cdev.c index 48ae712e2101..14bb7b7b5dd7 100644 --- a/trunk/drivers/firewire/core-cdev.c +++ b/trunk/drivers/firewire/core-cdev.c @@ -1501,10 +1501,9 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) e->client = client; e->p.speed = SCODE_100; e->p.generation = a->generation; - e->p.header[0] = TCODE_LINK_INTERNAL << 4; - e->p.header[1] = a->data[0]; - e->p.header[2] = a->data[1]; - e->p.header_length = 12; + e->p.header[0] = a->data[0]; + e->p.header[1] = a->data[1]; + e->p.header_length = 8; e->p.callback = outbound_phy_packet_callback; e->phy_packet.closure = a->closure; e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT; diff --git a/trunk/drivers/firewire/core-transaction.c b/trunk/drivers/firewire/core-transaction.c index d00f8ce902cc..b42a0bde8494 100644 --- a/trunk/drivers/firewire/core-transaction.c +++ b/trunk/drivers/firewire/core-transaction.c @@ -72,15 +72,6 @@ #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) #define PHY_IDENTIFIER(id) ((id) << 30) -/* returns 0 if the split timeout handler is already running */ -static int try_cancel_split_timeout(struct fw_transaction *t) -{ - if (t->is_split_transaction) - return del_timer(&t->split_timeout_timer); - else - return 1; -} - static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode) { @@ -90,7 +81,7 @@ static int close_transaction(struct fw_transaction *transaction, spin_lock_irqsave(&card->lock, flags); list_for_each_entry(t, &card->transaction_list, link) { if (t == transaction) { - if (!try_cancel_split_timeout(t)) { + if (!del_timer(&t->split_timeout_timer)) { spin_unlock_irqrestore(&card->lock, flags); goto timed_out; } @@ -150,26 +141,14 @@ static void split_transaction_timeout_callback(unsigned long data) card->tlabel_mask &= ~(1ULL << t->tlabel); spin_unlock_irqrestore(&card->lock, flags); - t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); -} - -static void start_split_transaction_timeout(struct fw_transaction *t, - struct fw_card *card) -{ - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - - if (list_empty(&t->link) || WARN_ON(t->is_split_transaction)) { - spin_unlock_irqrestore(&card->lock, flags); - return; - } - - t->is_split_transaction = true; - mod_timer(&t->split_timeout_timer, - jiffies + card->split_timeout_jiffies); + card->driver->cancel_packet(card, &t->packet); - spin_unlock_irqrestore(&card->lock, flags); + /* + * At this point cancel_packet will never call the transaction + * callback, since we just took the transaction out of the list. + * So do it here. + */ + t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); } static void transmit_complete_callback(struct fw_packet *packet, @@ -183,7 +162,7 @@ static void transmit_complete_callback(struct fw_packet *packet, close_transaction(t, card, RCODE_COMPLETE); break; case ACK_PENDING: - start_split_transaction_timeout(t, card); + t->timestamp = packet->timestamp; break; case ACK_BUSY_X: case ACK_BUSY_A: @@ -271,7 +250,7 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, break; default: - WARN(1, "wrong tcode %d\n", tcode); + WARN(1, "wrong tcode %d", tcode); } common: packet->speed = speed; @@ -370,9 +349,11 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, t->node_id = destination_id; t->tlabel = tlabel; t->card = card; - t->is_split_transaction = false; setup_timer(&t->split_timeout_timer, split_transaction_timeout_callback, (unsigned long)t); + /* FIXME: start this timer later, relative to t->timestamp */ + mod_timer(&t->split_timeout_timer, + jiffies + card->split_timeout_jiffies); t->callback = callback; t->callback_data = callback_data; @@ -442,8 +423,7 @@ static void transmit_phy_packet_callback(struct fw_packet *packet, } static struct fw_packet phy_config_packet = { - .header_length = 12, - .header[0] = TCODE_LINK_INTERNAL << 4, + .header_length = 8, .payload_length = 0, .speed = SCODE_100, .callback = transmit_phy_packet_callback, @@ -471,8 +451,8 @@ void fw_send_phy_config(struct fw_card *card, mutex_lock(&phy_config_mutex); - phy_config_packet.header[1] = data; - phy_config_packet.header[2] = ~data; + phy_config_packet.header[0] = data; + phy_config_packet.header[1] = ~data; phy_config_packet.generation = generation; INIT_COMPLETION(phy_config_done); @@ -658,7 +638,7 @@ int fw_get_response_length(struct fw_request *r) } default: - WARN(1, "wrong tcode %d\n", tcode); + WARN(1, "wrong tcode %d", tcode); return 0; } } @@ -714,7 +694,7 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header, break; default: - WARN(1, "wrong tcode %d\n", tcode); + WARN(1, "wrong tcode %d", tcode); } response->payload_mapped = false; @@ -945,7 +925,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) spin_lock_irqsave(&card->lock, flags); list_for_each_entry(t, &card->transaction_list, link) { if (t->node_id == source && t->tlabel == tlabel) { - if (!try_cancel_split_timeout(t)) { + if (!del_timer(&t->split_timeout_timer)) { spin_unlock_irqrestore(&card->lock, flags); goto timed_out; } diff --git a/trunk/drivers/firewire/core.h b/trunk/drivers/firewire/core.h index f8dfcf1c6cbe..e6239f971be6 100644 --- a/trunk/drivers/firewire/core.h +++ b/trunk/drivers/firewire/core.h @@ -215,11 +215,9 @@ static inline bool is_next_generation(int new_generation, int old_generation) /* -transaction */ -#define TCODE_LINK_INTERNAL 0xe - #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) -#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == TCODE_LINK_INTERNAL) +#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == 0xe) #define TCODE_IS_REQUEST(tcode) (((tcode) & 2) == 0) #define TCODE_IS_RESPONSE(tcode) (((tcode) & 2) != 0) #define TCODE_HAS_REQUEST_DATA(tcode) (((tcode) & 12) != 4) diff --git a/trunk/drivers/firewire/net.c b/trunk/drivers/firewire/net.c index c2e194c58667..1a467a91fb0b 100644 --- a/trunk/drivers/firewire/net.c +++ b/trunk/drivers/firewire/net.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -180,7 +179,6 @@ struct fwnet_device { /* Number of tx datagrams that have been queued but not yet acked */ int queued_datagrams; - int peer_count; struct list_head peer_list; struct fw_card *card; struct net_device *netdev; @@ -998,23 +996,15 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) static void fwnet_write_complete(struct fw_card *card, int rcode, void *payload, size_t length, void *data) { - struct fwnet_packet_task *ptask = data; - static unsigned long j; - static int last_rcode, errors_skipped; + struct fwnet_packet_task *ptask; + + ptask = data; if (rcode == RCODE_COMPLETE) { fwnet_transmit_packet_done(ptask); } else { + fw_error("fwnet_write_complete: failed: %x\n", rcode); fwnet_transmit_packet_failed(ptask); - - if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { - fw_error("fwnet_write_complete: " - "failed: %x (skipped %d)\n", rcode, errors_skipped); - - errors_skipped = 0; - last_rcode = rcode; - } else - errors_skipped++; } } @@ -1223,14 +1213,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return retval; } -static void set_carrier_state(struct fwnet_device *dev) -{ - if (dev->peer_count > 1) - netif_carrier_on(dev->netdev); - else - netif_carrier_off(dev->netdev); -} - /* ifup */ static int fwnet_open(struct net_device *net) { @@ -1244,10 +1226,6 @@ static int fwnet_open(struct net_device *net) } netif_start_queue(net); - spin_lock_irq(&dev->lock); - set_carrier_state(dev); - spin_unlock_irq(&dev->lock); - return 0; } @@ -1419,10 +1397,6 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) return 0; } -static const struct ethtool_ops fwnet_ethtool_ops = { - .get_link = ethtool_op_get_link, -}; - static const struct net_device_ops fwnet_netdev_ops = { .ndo_open = fwnet_open, .ndo_stop = fwnet_stop, @@ -1441,7 +1415,6 @@ static void fwnet_init_dev(struct net_device *net) net->hard_header_len = FWNET_HLEN; net->type = ARPHRD_IEEE1394; net->tx_queue_len = FWNET_TX_QUEUE_LEN; - net->ethtool_ops = &fwnet_ethtool_ops; } /* caller must hold fwnet_device_mutex */ @@ -1482,8 +1455,6 @@ static int fwnet_add_peer(struct fwnet_device *dev, spin_lock_irq(&dev->lock); list_add_tail(&peer->peer_link, &dev->peer_list); - dev->peer_count++; - set_carrier_state(dev); spin_unlock_irq(&dev->lock); return 0; @@ -1564,15 +1535,13 @@ static int fwnet_probe(struct device *_dev) return ret; } -static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev) +static void fwnet_remove_peer(struct fwnet_peer *peer) { struct fwnet_partial_datagram *pd, *pd_next; - spin_lock_irq(&dev->lock); + spin_lock_irq(&peer->dev->lock); list_del(&peer->peer_link); - dev->peer_count--; - set_carrier_state(dev); - spin_unlock_irq(&dev->lock); + spin_unlock_irq(&peer->dev->lock); list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) fwnet_pd_delete(pd); @@ -1589,7 +1558,7 @@ static int fwnet_remove(struct device *_dev) mutex_lock(&fwnet_device_mutex); - fwnet_remove_peer(peer, dev); + fwnet_remove_peer(peer); if (list_empty(&dev->peer_list)) { net = dev->netdev; diff --git a/trunk/drivers/firewire/nosy.c b/trunk/drivers/firewire/nosy.c index 0618145376ad..bf184fb59a5e 100644 --- a/trunk/drivers/firewire/nosy.c +++ b/trunk/drivers/firewire/nosy.c @@ -302,7 +302,7 @@ nosy_open(struct inode *inode, struct file *file) file->private_data = client; - return nonseekable_open(inode, file); + return 0; fail: kfree(client); lynx_put(lynx); @@ -405,6 +405,7 @@ static const struct file_operations nosy_ops = { .poll = nosy_poll, .open = nosy_open, .release = nosy_release, + .llseek = noop_llseek, }; #define PHY_PACKET_SIZE 12 /* 1 payload, 1 inverse, 1 ack = 3 quadlets */ diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c index d77d120ddc25..e3c8b60bd86b 100644 --- a/trunk/drivers/firewire/ohci.c +++ b/trunk/drivers/firewire/ohci.c @@ -18,7 +18,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include #include @@ -41,7 +40,6 @@ #include #include #include -#include #include #include @@ -82,23 +80,17 @@ struct descriptor { #define COMMAND_PTR(regs) ((regs) + 12) #define CONTEXT_MATCH(regs) ((regs) + 16) -#define AR_BUFFER_SIZE (32*1024) -#define AR_BUFFERS_MIN DIV_ROUND_UP(AR_BUFFER_SIZE, PAGE_SIZE) -/* we need at least two pages for proper list management */ -#define AR_BUFFERS (AR_BUFFERS_MIN >= 2 ? AR_BUFFERS_MIN : 2) - -#define MAX_ASYNC_PAYLOAD 4096 -#define MAX_AR_PACKET_SIZE (16 + MAX_ASYNC_PAYLOAD + 4) -#define AR_WRAPAROUND_PAGES DIV_ROUND_UP(MAX_AR_PACKET_SIZE, PAGE_SIZE) +struct ar_buffer { + struct descriptor descriptor; + struct ar_buffer *next; + __le32 data[0]; +}; struct ar_context { struct fw_ohci *ohci; - struct page *pages[AR_BUFFERS]; - void *buffer; - struct descriptor *descriptors; - dma_addr_t descriptors_bus; + struct ar_buffer *current_buffer; + struct ar_buffer *last_buffer; void *pointer; - unsigned int last_buffer_index; u32 regs; struct tasklet_struct tasklet; }; @@ -125,8 +117,6 @@ struct context { struct fw_ohci *ohci; u32 regs; int total_allocation; - bool running; - bool flushing; /* * List of page-sized buffers for storing DMA descriptors. @@ -171,9 +161,6 @@ struct iso_context { int excess_bytes; void *header; size_t header_length; - - u8 sync; - u8 tags; }; #define CONFIG_ROM_SIZE 1024 @@ -190,8 +177,7 @@ struct fw_ohci { u32 bus_time; bool is_root; bool csr_state_setclear_abdicate; - int n_ir; - int n_it; + /* * Spinlock for accessing fw_ohci data. Never call out of * this driver with this lock held. @@ -200,9 +186,6 @@ struct fw_ohci { struct mutex phy_reg_mutex; - void *misc_buffer; - dma_addr_t misc_buffer_bus; - struct ar_context ar_request_ctx; struct ar_context ar_response_ctx; struct context at_request_ctx; @@ -428,6 +411,10 @@ static const char *tcodes[] = { [0xc] = "-reserved-", [0xd] = "-reserved-", [0xe] = "link internal", [0xf] = "-reserved-", }; +static const char *phys[] = { + [0x0] = "phy config packet", [0x1] = "link-on packet", + [0x2] = "self-id packet", [0x3] = "-reserved-", +}; static void log_ar_at_event(char dir, int speed, u32 *header, int evt) { @@ -446,6 +433,12 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) return; } + if (header[0] == ~header[1]) { + fw_notify("A%c %s, %s, %08x\n", + dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]); + return; + } + switch (tcode) { case 0x0: case 0x6: case 0x8: snprintf(specific, sizeof(specific), " = %08x", @@ -460,13 +453,9 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) } switch (tcode) { - case 0xa: + case 0xe: case 0xa: fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]); break; - case 0xe: - fw_notify("A%c %s, PHY %08x %08x\n", - dir, evts[evt], header[1], header[2]); - break; case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: fw_notify("A%c spd %x tl %02x, " "%04x -> %04x, %s, " @@ -605,150 +594,59 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, return ret; } -static inline dma_addr_t ar_buffer_bus(struct ar_context *ctx, unsigned int i) +static void ar_context_link_page(struct ar_context *ctx, + struct ar_buffer *ab, dma_addr_t ab_bus) { - return page_private(ctx->pages[i]); -} + size_t offset; -static void ar_context_link_page(struct ar_context *ctx, unsigned int index) -{ - struct descriptor *d; - - d = &ctx->descriptors[index]; - d->branch_address &= cpu_to_le32(~0xf); - d->res_count = cpu_to_le16(PAGE_SIZE); - d->transfer_status = 0; + ab->next = NULL; + memset(&ab->descriptor, 0, sizeof(ab->descriptor)); + ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | + DESCRIPTOR_STATUS | + DESCRIPTOR_BRANCH_ALWAYS); + offset = offsetof(struct ar_buffer, data); + ab->descriptor.req_count = cpu_to_le16(PAGE_SIZE - offset); + ab->descriptor.data_address = cpu_to_le32(ab_bus + offset); + ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset); + ab->descriptor.branch_address = 0; wmb(); /* finish init of new descriptors before branch_address update */ - d = &ctx->descriptors[ctx->last_buffer_index]; - d->branch_address |= cpu_to_le32(1); - - ctx->last_buffer_index = index; + ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1); + ctx->last_buffer->next = ab; + ctx->last_buffer = ab; reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); flush_writes(ctx->ohci); } -static void ar_context_release(struct ar_context *ctx) +static int ar_context_add_page(struct ar_context *ctx) { - unsigned int i; + struct device *dev = ctx->ohci->card.device; + struct ar_buffer *ab; + dma_addr_t uninitialized_var(ab_bus); - if (ctx->buffer) - vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); - - for (i = 0; i < AR_BUFFERS; i++) - if (ctx->pages[i]) { - dma_unmap_page(ctx->ohci->card.device, - ar_buffer_bus(ctx, i), - PAGE_SIZE, DMA_FROM_DEVICE); - __free_page(ctx->pages[i]); - } -} - -static void ar_context_abort(struct ar_context *ctx, const char *error_msg) -{ - if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { - reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); - flush_writes(ctx->ohci); - - fw_error("AR error: %s; DMA stopped\n", error_msg); - } - /* FIXME: restart? */ -} - -static inline unsigned int ar_next_buffer_index(unsigned int index) -{ - return (index + 1) % AR_BUFFERS; -} - -static inline unsigned int ar_prev_buffer_index(unsigned int index) -{ - return (index - 1 + AR_BUFFERS) % AR_BUFFERS; -} - -static inline unsigned int ar_first_buffer_index(struct ar_context *ctx) -{ - return ar_next_buffer_index(ctx->last_buffer_index); -} - -/* - * We search for the buffer that contains the last AR packet DMA data written - * by the controller. - */ -static unsigned int ar_search_last_active_buffer(struct ar_context *ctx, - unsigned int *buffer_offset) -{ - unsigned int i, next_i, last = ctx->last_buffer_index; - __le16 res_count, next_res_count; - - i = ar_first_buffer_index(ctx); - res_count = ACCESS_ONCE(ctx->descriptors[i].res_count); - - /* A buffer that is not yet completely filled must be the last one. */ - while (i != last && res_count == 0) { - - /* Peek at the next descriptor. */ - next_i = ar_next_buffer_index(i); - rmb(); /* read descriptors in order */ - next_res_count = ACCESS_ONCE( - ctx->descriptors[next_i].res_count); - /* - * If the next descriptor is still empty, we must stop at this - * descriptor. - */ - if (next_res_count == cpu_to_le16(PAGE_SIZE)) { - /* - * The exception is when the DMA data for one packet is - * split over three buffers; in this case, the middle - * buffer's descriptor might be never updated by the - * controller and look still empty, and we have to peek - * at the third one. - */ - if (MAX_AR_PACKET_SIZE > PAGE_SIZE && i != last) { - next_i = ar_next_buffer_index(next_i); - rmb(); - next_res_count = ACCESS_ONCE( - ctx->descriptors[next_i].res_count); - if (next_res_count != cpu_to_le16(PAGE_SIZE)) - goto next_buffer_is_active; - } - - break; - } - -next_buffer_is_active: - i = next_i; - res_count = next_res_count; - } - - rmb(); /* read res_count before the DMA data */ + ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); + if (ab == NULL) + return -ENOMEM; - *buffer_offset = PAGE_SIZE - le16_to_cpu(res_count); - if (*buffer_offset > PAGE_SIZE) { - *buffer_offset = 0; - ar_context_abort(ctx, "corrupted descriptor"); - } + ar_context_link_page(ctx, ab, ab_bus); - return i; + return 0; } -static void ar_sync_buffers_for_cpu(struct ar_context *ctx, - unsigned int end_buffer_index, - unsigned int end_buffer_offset) +static void ar_context_release(struct ar_context *ctx) { - unsigned int i; + struct ar_buffer *ab, *ab_next; + size_t offset; + dma_addr_t ab_bus; - i = ar_first_buffer_index(ctx); - while (i != end_buffer_index) { - dma_sync_single_for_cpu(ctx->ohci->card.device, - ar_buffer_bus(ctx, i), - PAGE_SIZE, DMA_FROM_DEVICE); - i = ar_next_buffer_index(i); + for (ab = ctx->current_buffer; ab; ab = ab_next) { + ab_next = ab->next; + offset = offsetof(struct ar_buffer, data); + ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE, + ab, ab_bus); } - if (end_buffer_offset > 0) - dma_sync_single_for_cpu(ctx->ohci->card.device, - ar_buffer_bus(ctx, i), - end_buffer_offset, DMA_FROM_DEVICE); } #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) @@ -791,10 +689,6 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) p.header[3] = cond_le32_to_cpu(buffer[3]); p.header_length = 16; p.payload_length = p.header[3] >> 16; - if (p.payload_length > MAX_ASYNC_PAYLOAD) { - ar_context_abort(ctx, "invalid packet length"); - return NULL; - } break; case TCODE_WRITE_RESPONSE: @@ -805,8 +699,9 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) break; default: - ar_context_abort(ctx, "invalid tcode"); - return NULL; + /* FIXME: Stop context, discard everything, and restart? */ + p.header_length = 0; + p.payload_length = 0; } p.payload = (void *) buffer + p.header_length; @@ -856,147 +751,121 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) return buffer + length + 1; } -static void *handle_ar_packets(struct ar_context *ctx, void *p, void *end) -{ - void *next; - - while (p < end) { - next = handle_ar_packet(ctx, p); - if (!next) - return p; - p = next; - } - - return p; -} - -static void ar_recycle_buffers(struct ar_context *ctx, unsigned int end_buffer) -{ - unsigned int i; - - i = ar_first_buffer_index(ctx); - while (i != end_buffer) { - dma_sync_single_for_device(ctx->ohci->card.device, - ar_buffer_bus(ctx, i), - PAGE_SIZE, DMA_FROM_DEVICE); - ar_context_link_page(ctx, i); - i = ar_next_buffer_index(i); - } -} - static void ar_context_tasklet(unsigned long data) { struct ar_context *ctx = (struct ar_context *)data; - unsigned int end_buffer_index, end_buffer_offset; - void *p, *end; + struct ar_buffer *ab; + struct descriptor *d; + void *buffer, *end; + __le16 res_count; - p = ctx->pointer; - if (!p) - return; + ab = ctx->current_buffer; + d = &ab->descriptor; - end_buffer_index = ar_search_last_active_buffer(ctx, - &end_buffer_offset); - ar_sync_buffers_for_cpu(ctx, end_buffer_index, end_buffer_offset); - end = ctx->buffer + end_buffer_index * PAGE_SIZE + end_buffer_offset; + res_count = ACCESS_ONCE(d->res_count); + if (res_count == 0) { + size_t size, size2, rest, pktsize, size3, offset; + dma_addr_t start_bus; + void *start; - if (end_buffer_index < ar_first_buffer_index(ctx)) { /* - * The filled part of the overall buffer wraps around; handle - * all packets up to the buffer end here. If the last packet - * wraps around, its tail will be visible after the buffer end - * because the buffer start pages are mapped there again. + * This descriptor is finished and we may have a + * packet split across this and the next buffer. We + * reuse the page for reassembling the split packet. */ - void *buffer_end = ctx->buffer + AR_BUFFERS * PAGE_SIZE; - p = handle_ar_packets(ctx, p, buffer_end); - if (p < buffer_end) - goto error; - /* adjust p to point back into the actual buffer */ - p -= AR_BUFFERS * PAGE_SIZE; - } - p = handle_ar_packets(ctx, p, end); - if (p != end) { - if (p > end) - ar_context_abort(ctx, "inconsistent descriptor"); - goto error; - } + offset = offsetof(struct ar_buffer, data); + start = ab; + start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + buffer = ab->data; + + ab = ab->next; + d = &ab->descriptor; + size = start + PAGE_SIZE - ctx->pointer; + /* valid buffer data in the next page */ + rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); + /* what actually fits in this page */ + size2 = min(rest, (size_t)PAGE_SIZE - offset - size); + memmove(buffer, ctx->pointer, size); + memcpy(buffer + size, ab->data, size2); + + while (size > 0) { + void *next = handle_ar_packet(ctx, buffer); + pktsize = next - buffer; + if (pktsize >= size) { + /* + * We have handled all the data that was + * originally in this page, so we can now + * continue in the next page. + */ + buffer = next; + break; + } + /* move the next packet to the start of the buffer */ + memmove(buffer, next, size + size2 - pktsize); + size -= pktsize; + /* fill up this page again */ + size3 = min(rest - size2, + (size_t)PAGE_SIZE - offset - size - size2); + memcpy(buffer + size + size2, + (void *) ab->data + size2, size3); + size2 += size3; + } + + if (rest > 0) { + /* handle the packets that are fully in the next page */ + buffer = (void *) ab->data + + (buffer - (start + offset + size)); + end = (void *) ab->data + rest; + + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); - ctx->pointer = p; - ar_recycle_buffers(ctx, end_buffer_index); + ctx->current_buffer = ab; + ctx->pointer = end; - return; + ar_context_link_page(ctx, start, start_bus); + } else { + ctx->pointer = start + PAGE_SIZE; + } + } else { + buffer = ctx->pointer; + ctx->pointer = end = + (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); -error: - ctx->pointer = NULL; + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); + } } -static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, - unsigned int descriptors_offset, u32 regs) +static int ar_context_init(struct ar_context *ctx, + struct fw_ohci *ohci, u32 regs) { - unsigned int i; - dma_addr_t dma_addr; - struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES]; - struct descriptor *d; + struct ar_buffer ab; ctx->regs = regs; ctx->ohci = ohci; + ctx->last_buffer = &ab; tasklet_init(&ctx->tasklet, ar_context_tasklet, (unsigned long)ctx); - for (i = 0; i < AR_BUFFERS; i++) { - ctx->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32); - if (!ctx->pages[i]) - goto out_of_memory; - dma_addr = dma_map_page(ohci->card.device, ctx->pages[i], - 0, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(ohci->card.device, dma_addr)) { - __free_page(ctx->pages[i]); - ctx->pages[i] = NULL; - goto out_of_memory; - } - set_page_private(ctx->pages[i], dma_addr); - } - - for (i = 0; i < AR_BUFFERS; i++) - pages[i] = ctx->pages[i]; - for (i = 0; i < AR_WRAPAROUND_PAGES; i++) - pages[AR_BUFFERS + i] = ctx->pages[i]; - ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES, - -1, PAGE_KERNEL_RO); - if (!ctx->buffer) - goto out_of_memory; - - ctx->descriptors = ohci->misc_buffer + descriptors_offset; - ctx->descriptors_bus = ohci->misc_buffer_bus + descriptors_offset; - - for (i = 0; i < AR_BUFFERS; i++) { - d = &ctx->descriptors[i]; - d->req_count = cpu_to_le16(PAGE_SIZE); - d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | - DESCRIPTOR_STATUS | - DESCRIPTOR_BRANCH_ALWAYS); - d->data_address = cpu_to_le32(ar_buffer_bus(ctx, i)); - d->branch_address = cpu_to_le32(ctx->descriptors_bus + - ar_next_buffer_index(i) * sizeof(struct descriptor)); - } + ar_context_add_page(ctx); + ar_context_add_page(ctx); + ctx->current_buffer = ab.next; + ctx->pointer = ctx->current_buffer->data; return 0; - -out_of_memory: - ar_context_release(ctx); - - return -ENOMEM; } static void ar_context_run(struct ar_context *ctx) { - unsigned int i; - - for (i = 0; i < AR_BUFFERS; i++) - ar_context_link_page(ctx, i); + struct ar_buffer *ab = ctx->current_buffer; + dma_addr_t ab_bus; + size_t offset; - ctx->pointer = ctx->buffer; + offset = offsetof(struct ar_buffer, data); + ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; - reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1); + reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); flush_writes(ctx->ohci); } @@ -1173,7 +1042,6 @@ static void context_run(struct context *ctx, u32 extra) le32_to_cpu(ctx->last->branch_address)); reg_write(ohci, CONTROL_CLEAR(ctx->regs), ~0); reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN | extra); - ctx->running = true; flush_writes(ohci); } @@ -1201,7 +1069,6 @@ static void context_stop(struct context *ctx) int i; reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); - ctx->running = false; flush_writes(ctx->ohci); for (i = 0; i < 10; i++) { @@ -1232,6 +1099,7 @@ static int at_context_queue_packet(struct context *ctx, struct descriptor *d, *last; __le32 *header; int z, tcode; + u32 reg; d = context_get_descriptors(ctx, 4, &d_bus); if (d == NULL) { @@ -1245,27 +1113,21 @@ static int at_context_queue_packet(struct context *ctx, /* * The DMA format for asyncronous link packets is different * from the IEEE1394 layout, so shift the fields around - * accordingly. + * accordingly. If header_length is 8, it's a PHY packet, to + * which we need to prepend an extra quadlet. */ - tcode = (packet->header[0] >> 4) & 0x0f; header = (__le32 *) &d[1]; - switch (tcode) { - case TCODE_WRITE_QUADLET_REQUEST: - case TCODE_WRITE_BLOCK_REQUEST: - case TCODE_WRITE_RESPONSE: - case TCODE_READ_QUADLET_REQUEST: - case TCODE_READ_BLOCK_REQUEST: - case TCODE_READ_QUADLET_RESPONSE: - case TCODE_READ_BLOCK_RESPONSE: - case TCODE_LOCK_REQUEST: - case TCODE_LOCK_RESPONSE: + switch (packet->header_length) { + case 16: + case 12: header[0] = cpu_to_le32((packet->header[0] & 0xffff) | (packet->speed << 16)); header[1] = cpu_to_le32((packet->header[1] & 0xffff) | (packet->header[0] & 0xffff0000)); header[2] = cpu_to_le32(packet->header[2]); + tcode = (packet->header[0] >> 4) & 0x0f; if (TCODE_IS_BLOCK_PACKET(tcode)) header[3] = cpu_to_le32(packet->header[3]); else @@ -1274,18 +1136,18 @@ static int at_context_queue_packet(struct context *ctx, d[0].req_count = cpu_to_le16(packet->header_length); break; - case TCODE_LINK_INTERNAL: + case 8: header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) | (packet->speed << 16)); - header[1] = cpu_to_le32(packet->header[1]); - header[2] = cpu_to_le32(packet->header[2]); + header[1] = cpu_to_le32(packet->header[0]); + header[2] = cpu_to_le32(packet->header[1]); d[0].req_count = cpu_to_le16(12); - if (is_ping_packet(&packet->header[1])) + if (is_ping_packet(packet->header)) d[0].control |= cpu_to_le16(DESCRIPTOR_PING); break; - case TCODE_STREAM_DATA: + case 4: header[0] = cpu_to_le32((packet->header[0] & 0xffff) | (packet->speed << 16)); header[1] = cpu_to_le32(packet->header[0] & 0xffff0000); @@ -1335,8 +1197,6 @@ static int at_context_queue_packet(struct context *ctx, * some controllers (like a JMicron JMB381 PCI-e) misbehave and wind * up stalling out. So we just bail out in software and try again * later, and everyone is happy. - * FIXME: Test of IntEvent.busReset may no longer be necessary since we - * flush AT queues in bus_reset_tasklet. * FIXME: Document how the locking works. */ if (ohci->generation != packet->generation || @@ -1350,23 +1210,14 @@ static int at_context_queue_packet(struct context *ctx, context_append(ctx, d, z, 4 - z); - if (!ctx->running) + /* If the context isn't already running, start it up. */ + reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); + if ((reg & CONTEXT_RUN) == 0) context_run(ctx, 0); return 0; } -static void at_context_flush(struct context *ctx) -{ - tasklet_disable(&ctx->tasklet); - - ctx->flushing = true; - context_tasklet((unsigned long)ctx); - ctx->flushing = false; - - tasklet_enable(&ctx->tasklet); -} - static int handle_at_packet(struct context *context, struct descriptor *d, struct descriptor *last) @@ -1376,7 +1227,7 @@ static int handle_at_packet(struct context *context, struct fw_ohci *ohci = context->ohci; int evt; - if (last->transfer_status == 0 && !context->flushing) + if (last->transfer_status == 0) /* This descriptor isn't done yet, stop iteration. */ return 0; @@ -1410,15 +1261,11 @@ static int handle_at_packet(struct context *context, break; case OHCI1394_evt_missing_ack: - if (context->flushing) - packet->ack = RCODE_GENERATION; - else { - /* - * Using a valid (current) generation count, but the - * node is not on the bus or not sending acks. - */ - packet->ack = RCODE_NO_ACK; - } + /* + * Using a valid (current) generation count, but the + * node is not on the bus or not sending acks. + */ + packet->ack = RCODE_NO_ACK; break; case ACK_COMPLETE + 0x10: @@ -1431,13 +1278,6 @@ static int handle_at_packet(struct context *context, packet->ack = evt - 0x10; break; - case OHCI1394_evt_no_status: - if (context->flushing) { - packet->ack = RCODE_GENERATION; - break; - } - /* fall through */ - default: packet->ack = RCODE_SEND_ERROR; break; @@ -1743,23 +1583,9 @@ static void bus_reset_tasklet(unsigned long data) /* FIXME: Document how the locking works. */ spin_lock_irqsave(&ohci->lock, flags); - ohci->generation = -1; /* prevent AT packet queueing */ + ohci->generation = generation; context_stop(&ohci->at_request_ctx); context_stop(&ohci->at_response_ctx); - - spin_unlock_irqrestore(&ohci->lock, flags); - - /* - * Per OHCI 1.2 draft, clause 7.2.3.3, hardware may leave unsent - * packets in the AT queues and software needs to drain them. - * Some OHCI 1.1 controllers (JMicron) apparently require this too. - */ - at_context_flush(&ohci->at_request_ctx); - at_context_flush(&ohci->at_response_ctx); - - spin_lock_irqsave(&ohci->lock, flags); - - ohci->generation = generation; reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); if (ohci->quirks & QUIRK_RESET_PACKET) @@ -1827,12 +1653,8 @@ static irqreturn_t irq_handler(int irq, void *data) if (!event || !~event) return IRQ_NONE; - /* - * busReset and postedWriteErr must not be cleared yet - * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) - */ - reg_write(ohci, OHCI1394_IntEventClear, - event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); + /* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */ + reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset); log_irqs(event); if (event & OHCI1394_selfIDComplete) @@ -1850,41 +1672,30 @@ static irqreturn_t irq_handler(int irq, void *data) if (event & OHCI1394_respTxComplete) tasklet_schedule(&ohci->at_response_ctx.tasklet); - if (event & OHCI1394_isochRx) { - iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear); - reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event); + iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event); - while (iso_event) { - i = ffs(iso_event) - 1; - tasklet_schedule( - &ohci->ir_context_list[i].context.tasklet); - iso_event &= ~(1 << i); - } + while (iso_event) { + i = ffs(iso_event) - 1; + tasklet_schedule(&ohci->ir_context_list[i].context.tasklet); + iso_event &= ~(1 << i); } - if (event & OHCI1394_isochTx) { - iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear); - reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event); + iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear); + reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event); - while (iso_event) { - i = ffs(iso_event) - 1; - tasklet_schedule( - &ohci->it_context_list[i].context.tasklet); - iso_event &= ~(1 << i); - } + while (iso_event) { + i = ffs(iso_event) - 1; + tasklet_schedule(&ohci->it_context_list[i].context.tasklet); + iso_event &= ~(1 << i); } if (unlikely(event & OHCI1394_regAccessFail)) fw_error("Register access failure - " "please notify linux1394-devel@lists.sf.net\n"); - if (unlikely(event & OHCI1394_postedWriteErr)) { - reg_read(ohci, OHCI1394_PostedWriteAddressHi); - reg_read(ohci, OHCI1394_PostedWriteAddressLo); - reg_write(ohci, OHCI1394_IntEventClear, - OHCI1394_postedWriteErr); + if (unlikely(event & OHCI1394_postedWriteErr)) fw_error("PCI posted write error\n"); - } if (unlikely(event & OHCI1394_cycleTooLong)) { if (printk_ratelimit()) @@ -1908,8 +1719,7 @@ static irqreturn_t irq_handler(int irq, void *data) spin_lock(&ohci->lock); update_bus_time(ohci); spin_unlock(&ohci->lock); - } else - flush_writes(ohci); + } return IRQ_HANDLED; } @@ -2685,10 +2495,6 @@ static int ohci_start_iso(struct fw_iso_context *base, reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match); context_run(&ctx->context, control); - - ctx->sync = sync; - ctx->tags = tags; - break; } @@ -2786,26 +2592,6 @@ static int ohci_set_iso_channels(struct fw_iso_context *base, u64 *channels) return ret; } -#ifdef CONFIG_PM -static void ohci_resume_iso_dma(struct fw_ohci *ohci) -{ - int i; - struct iso_context *ctx; - - for (i = 0 ; i < ohci->n_ir ; i++) { - ctx = &ohci->ir_context_list[i]; - if (ctx->context.running) - ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); - } - - for (i = 0 ; i < ohci->n_it ; i++) { - ctx = &ohci->it_context_list[i]; - if (ctx->context.running) - ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); - } -} -#endif - static int queue_iso_transmit(struct iso_context *ctx, struct fw_iso_packet *packet, struct fw_iso_buffer *buffer, @@ -3115,7 +2901,7 @@ static int __devinit pci_probe(struct pci_dev *dev, struct fw_ohci *ohci; u32 bus_options, max_receive, link_speed, version; u64 guid; - int i, err; + int i, err, n_ir, n_it; size_t size; ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); @@ -3169,55 +2955,31 @@ static int __devinit pci_probe(struct pci_dev *dev, if (param_quirks) ohci->quirks = param_quirks; - /* - * Because dma_alloc_coherent() allocates at least one page, - * we save space by using a common buffer for the AR request/ - * response descriptors and the self IDs buffer. - */ - BUILD_BUG_ON(AR_BUFFERS * sizeof(struct descriptor) > PAGE_SIZE/4); - BUILD_BUG_ON(SELF_ID_BUF_SIZE > PAGE_SIZE/2); - ohci->misc_buffer = dma_alloc_coherent(ohci->card.device, - PAGE_SIZE, - &ohci->misc_buffer_bus, - GFP_KERNEL); - if (!ohci->misc_buffer) { - err = -ENOMEM; - goto fail_iounmap; - } - - err = ar_context_init(&ohci->ar_request_ctx, ohci, 0, - OHCI1394_AsReqRcvContextControlSet); - if (err < 0) - goto fail_misc_buf; + ar_context_init(&ohci->ar_request_ctx, ohci, + OHCI1394_AsReqRcvContextControlSet); - err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4, - OHCI1394_AsRspRcvContextControlSet); - if (err < 0) - goto fail_arreq_ctx; + ar_context_init(&ohci->ar_response_ctx, ohci, + OHCI1394_AsRspRcvContextControlSet); - err = context_init(&ohci->at_request_ctx, ohci, - OHCI1394_AsReqTrContextControlSet, handle_at_packet); - if (err < 0) - goto fail_arrsp_ctx; + context_init(&ohci->at_request_ctx, ohci, + OHCI1394_AsReqTrContextControlSet, handle_at_packet); - err = context_init(&ohci->at_response_ctx, ohci, - OHCI1394_AsRspTrContextControlSet, handle_at_packet); - if (err < 0) - goto fail_atreq_ctx; + context_init(&ohci->at_response_ctx, ohci, + OHCI1394_AsRspTrContextControlSet, handle_at_packet); reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); ohci->ir_context_channels = ~0ULL; ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); - ohci->n_ir = hweight32(ohci->ir_context_mask); - size = sizeof(struct iso_context) * ohci->n_ir; + n_ir = hweight32(ohci->ir_context_mask); + size = sizeof(struct iso_context) * n_ir; ohci->ir_context_list = kzalloc(size, GFP_KERNEL); reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); - ohci->n_it = hweight32(ohci->it_context_mask); - size = sizeof(struct iso_context) * ohci->n_it; + n_it = hweight32(ohci->it_context_mask); + size = sizeof(struct iso_context) * n_it; ohci->it_context_list = kzalloc(size, GFP_KERNEL); if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { @@ -3225,8 +2987,15 @@ static int __devinit pci_probe(struct pci_dev *dev, goto fail_contexts; } - ohci->self_id_cpu = ohci->misc_buffer + PAGE_SIZE/2; - ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2; + /* self-id dma buffer allocation */ + ohci->self_id_cpu = dma_alloc_coherent(ohci->card.device, + SELF_ID_BUF_SIZE, + &ohci->self_id_bus, + GFP_KERNEL); + if (ohci->self_id_cpu == NULL) { + err = -ENOMEM; + goto fail_contexts; + } bus_options = reg_read(ohci, OHCI1394_BusOptions); max_receive = (bus_options >> 12) & 0xf; @@ -3236,30 +3005,26 @@ static int __devinit pci_probe(struct pci_dev *dev, err = fw_card_add(&ohci->card, max_receive, link_speed, guid); if (err) - goto fail_contexts; + goto fail_self_id; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " "%d IR + %d IT contexts, quirks 0x%x\n", dev_name(&dev->dev), version >> 16, version & 0xff, - ohci->n_ir, ohci->n_it, ohci->quirks); + n_ir, n_it, ohci->quirks); return 0; + fail_self_id: + dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, + ohci->self_id_cpu, ohci->self_id_bus); fail_contexts: kfree(ohci->ir_context_list); kfree(ohci->it_context_list); context_release(&ohci->at_response_ctx); - fail_atreq_ctx: context_release(&ohci->at_request_ctx); - fail_arrsp_ctx: ar_context_release(&ohci->ar_response_ctx); - fail_arreq_ctx: ar_context_release(&ohci->ar_request_ctx); - fail_misc_buf: - dma_free_coherent(ohci->card.device, PAGE_SIZE, - ohci->misc_buffer, ohci->misc_buffer_bus); - fail_iounmap: pci_iounmap(dev, ohci->registers); fail_iomem: pci_release_region(dev, 0); @@ -3298,10 +3063,10 @@ static void pci_remove(struct pci_dev *dev) if (ohci->config_rom) dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, ohci->config_rom, ohci->config_rom_bus); + dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, + ohci->self_id_cpu, ohci->self_id_bus); ar_context_release(&ohci->ar_request_ctx); ar_context_release(&ohci->ar_response_ctx); - dma_free_coherent(ohci->card.device, PAGE_SIZE, - ohci->misc_buffer, ohci->misc_buffer_bus); context_release(&ohci->at_request_ctx); context_release(&ohci->at_response_ctx); kfree(ohci->it_context_list); @@ -3352,20 +3117,7 @@ static int pci_resume(struct pci_dev *dev) return err; } - /* Some systems don't setup GUID register on resume from ram */ - if (!reg_read(ohci, OHCI1394_GUIDLo) && - !reg_read(ohci, OHCI1394_GUIDHi)) { - reg_write(ohci, OHCI1394_GUIDLo, (u32)ohci->card.guid); - reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32)); - } - - err = ohci_enable(&ohci->card, NULL, 0); - if (err) - return err; - - ohci_resume_iso_dma(ohci); - - return 0; + return ohci_enable(&ohci->card, NULL, 0); } #endif diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index ffbc278647bf..401acecc7f32 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -150,16 +150,6 @@ config DRAGONRISE_FF Say Y here if you want to enable force feedback support for DragonRise Inc. game controllers. -config HID_EMS_FF - tristate "EMS Production Inc. force feedback support" - depends on USB_HID - select INPUT_FF_MEMLESS - ---help--- - Say Y here if you want to enable force feedback support for devices by - EMS Production Ltd. - Currently the following devices are known to be supported: - - Trio Linker Plus II - config HID_EGALAX tristate "eGalax multi-touch panel" depends on USB_HID @@ -407,13 +397,6 @@ config HID_ROCCAT_KONE ---help--- Support for Roccat Kone mouse. -config HID_ROCCAT_KONEPLUS - tristate "Roccat Kone[+] mouse support" - depends on USB_HID - select HID_ROCCAT - ---help--- - Support for Roccat Kone[+] mouse. - config HID_ROCCAT_PYRA tristate "Roccat Pyra mouse support" depends on USB_HID diff --git a/trunk/drivers/hid/Makefile b/trunk/drivers/hid/Makefile index 6eae9a90b8dd..c335605b9200 100644 --- a/trunk/drivers/hid/Makefile +++ b/trunk/drivers/hid/Makefile @@ -1,7 +1,7 @@ # # Makefile for the HID driver # -hid-y := hid-core.o hid-input.o +hid-objs := hid-core.o hid-input.o ifdef CONFIG_DEBUG_FS hid-objs += hid-debug.o @@ -11,18 +11,18 @@ obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HIDRAW) += hidraw.o -hid-logitech-y := hid-lg.o +hid-logitech-objs := hid-lg.o ifdef CONFIG_LOGITECH_FF - hid-logitech-y += hid-lgff.o + hid-logitech-objs += hid-lgff.o endif ifdef CONFIG_LOGIRUMBLEPAD2_FF - hid-logitech-y += hid-lg2ff.o + hid-logitech-objs += hid-lg2ff.o endif ifdef CONFIG_LOGIG940_FF - hid-logitech-y += hid-lg3ff.o + hid-logitech-objs += hid-lg3ff.o endif ifdef CONFIG_LOGIWII_FF - hid-logitech-y += hid-lg4ff.o + hid-logitech-objs += hid-lg4ff.o endif obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o @@ -35,7 +35,6 @@ obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o -obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o obj-$(CONFIG_HID_EGALAX) += hid-egalax.o obj-$(CONFIG_HID_ELECOM) += hid-elecom.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o @@ -56,7 +55,6 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o -obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o diff --git a/trunk/drivers/hid/hid-3m-pct.c b/trunk/drivers/hid/hid-3m-pct.c index 5243ae2d3730..4fb7c7528d16 100644 --- a/trunk/drivers/hid/hid-3m-pct.c +++ b/trunk/drivers/hid/hid-3m-pct.c @@ -246,7 +246,7 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); if (!md) { - hid_err(hdev, "cannot allocate 3M data\n"); + dev_err(&hdev->dev, "cannot allocate 3M data\n"); return -ENOMEM; } hid_set_drvdata(hdev, md); diff --git a/trunk/drivers/hid/hid-a4tech.c b/trunk/drivers/hid/hid-a4tech.c index 902d1dfeb1b5..1666c1684e79 100644 --- a/trunk/drivers/hid/hid-a4tech.c +++ b/trunk/drivers/hid/hid-a4tech.c @@ -93,7 +93,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) a4 = kzalloc(sizeof(*a4), GFP_KERNEL); if (a4 == NULL) { - hid_err(hdev, "can't alloc device descriptor\n"); + dev_err(&hdev->dev, "can't alloc device descriptor\n"); ret = -ENOMEM; goto err_free; } @@ -104,13 +104,13 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-apple.c b/trunk/drivers/hid/hid-apple.c index 61aa71233392..eaeca564a8d3 100644 --- a/trunk/drivers/hid/hid-apple.c +++ b/trunk/drivers/hid/hid-apple.c @@ -16,8 +16,6 @@ * any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -61,27 +59,6 @@ struct apple_key_translation { u8 flags; }; -static const struct apple_key_translation macbookair_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, - { KEY_ENTER, KEY_INSERT }, - { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, - { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, - { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, - { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, - { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, - { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY }, - { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY }, - { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, - { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, - { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, - { } -}; - static const struct apple_key_translation apple_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, @@ -169,7 +146,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, struct hid_usage *usage, __s32 value) { struct apple_sc *asc = hid_get_drvdata(hid); - const struct apple_key_translation *trans, *table; + const struct apple_key_translation *trans; if (usage->code == KEY_FN) { asc->fn_on = !!value; @@ -180,16 +157,10 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (fnmode) { int do_translate; - if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && - hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) - table = macbookair_fn_keys; - else if (hid->product < 0x21d || hid->product >= 0x300) - table = powerbook_fn_keys; - else - table = apple_fn_keys; - - trans = apple_find_translation (table, usage->code); - + trans = apple_find_translation((hid->product < 0x21d || + hid->product >= 0x300) ? + powerbook_fn_keys : apple_fn_keys, + usage->code); if (trans) { if (test_bit(usage->code, asc->pressed_fn)) do_translate = 1; @@ -282,8 +253,8 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && rdesc[53] == 0x65 && rdesc[59] == 0x65) { - hid_info(hdev, - "fixing up MacBook JIS keyboard report descriptor\n"); + dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " + "descriptor\n"); rdesc[53] = rdesc[59] = 0xe7; } return rdesc; @@ -353,7 +324,7 @@ static int apple_probe(struct hid_device *hdev, asc = kzalloc(sizeof(*asc), GFP_KERNEL); if (asc == NULL) { - hid_err(hdev, "can't alloc apple descriptor\n"); + dev_err(&hdev->dev, "can't alloc apple descriptor\n"); return -ENOMEM; } @@ -363,7 +334,7 @@ static int apple_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } @@ -374,7 +345,7 @@ static int apple_probe(struct hid_device *hdev, ret = hid_hw_start(hdev, connect_mask); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } @@ -469,18 +440,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), @@ -514,7 +473,7 @@ static int __init apple_init(void) ret = hid_register_driver(&apple_driver); if (ret) - pr_err("can't register apple driver\n"); + printk(KERN_ERR "can't register apple driver\n"); return ret; } diff --git a/trunk/drivers/hid/hid-axff.c b/trunk/drivers/hid/hid-axff.c index e5b961d6ff22..f42ee140738a 100644 --- a/trunk/drivers/hid/hid-axff.c +++ b/trunk/drivers/hid/hid-axff.c @@ -73,14 +73,14 @@ static int axff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); + dev_err(&hid->dev, "no output reports found\n"); return -ENODEV; } report = list_first_entry(report_list, struct hid_report, list); if (report->maxfield < 4) { - hid_err(hid, "no fields in the report: %d\n", report->maxfield); + dev_err(&hid->dev, "no fields in the report: %d\n", report->maxfield); return -ENODEV; } @@ -101,7 +101,7 @@ static int axff_init(struct hid_device *hid) axff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, axff->report, USB_DIR_OUT); - hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun\n"); + dev_info(&hid->dev, "Force Feedback for ACRUX game controllers by Sergei Kolzun\n"); return 0; @@ -114,17 +114,17 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) { int error; - dev_dbg(&hdev->dev, "ACRUX HID hardware probe...\n"); + dev_dbg(&hdev->dev, "ACRUX HID hardware probe..."); error = hid_parse(hdev); if (error) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); return error; } error = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (error) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); return error; } @@ -134,7 +134,7 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) * Do not fail device initialization completely as device * may still be partially operable, just warn. */ - hid_warn(hdev, + dev_warn(&hdev->dev, "Failed to enable force feedback support, error: %d\n", error); } diff --git a/trunk/drivers/hid/hid-belkin.c b/trunk/drivers/hid/hid-belkin.c index a1a765a5b08a..4ce7aa3a519f 100644 --- a/trunk/drivers/hid/hid-belkin.c +++ b/trunk/drivers/hid/hid-belkin.c @@ -56,14 +56,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-cando.c b/trunk/drivers/hid/hid-cando.c index 375b50929a50..5925bdcd417d 100644 --- a/trunk/drivers/hid/hid-cando.c +++ b/trunk/drivers/hid/hid-cando.c @@ -207,7 +207,7 @@ static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); if (!td) { - hid_err(hdev, "cannot allocate Cando Touch data\n"); + dev_err(&hdev->dev, "cannot allocate Cando Touch data\n"); return -ENOMEM; } hid_set_drvdata(hdev, td); diff --git a/trunk/drivers/hid/hid-cherry.c b/trunk/drivers/hid/hid-cherry.c index 888ece68a47c..e880086c2311 100644 --- a/trunk/drivers/hid/hid-cherry.c +++ b/trunk/drivers/hid/hid-cherry.c @@ -30,7 +30,8 @@ static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); + dev_info(&hdev->dev, "fixing up Cherry Cymotion report " + "descriptor\n"); rdesc[11] = rdesc[16] = 0xff; rdesc[12] = rdesc[17] = 0x03; } diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 261168607c91..3f9673d94da9 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -14,8 +14,6 @@ * any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -61,8 +59,7 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; - report = kzalloc(sizeof(struct hid_report), GFP_KERNEL); - if (!report) + if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) return NULL; if (id != 0) @@ -93,11 +90,8 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned return NULL; } - field = kzalloc((sizeof(struct hid_field) + - usages * sizeof(struct hid_usage) + - values * sizeof(unsigned)), GFP_KERNEL); - if (!field) - return NULL; + if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + + values * sizeof(unsigned), GFP_KERNEL))) return NULL; field->index = report->maxfield++; report->field[field->index] = field; @@ -178,14 +172,10 @@ static int close_collection(struct hid_parser *parser) static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) { - struct hid_collection *collection = parser->device->collection; int n; - - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) { - unsigned index = parser->collection_stack[n]; - if (collection[index].type == type) - return collection[index].usage; - } + for (n = parser->collection_stack_ptr - 1; n >= 0; n--) + if (parser->device->collection[parser->collection_stack[n]].type == type) + return parser->device->collection[parser->collection_stack[n]].usage; return 0; /* we know nothing about this usage type */ } @@ -219,8 +209,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign unsigned offset; int i; - report = hid_register_report(parser->device, report_type, parser->global.report_id); - if (!report) { + if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { dbg_hid("hid_register_report failed\n"); return -1; } @@ -238,8 +227,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign usages = max_t(int, parser->local.usage_index, parser->global.report_count); - field = hid_register_field(report, usages, parser->global.report_count); - if (!field) + if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) return 0; field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); @@ -664,12 +652,13 @@ int hid_parse_report(struct hid_device *device, __u8 *start, return -ENOMEM; device->rsize = size; - parser = vzalloc(sizeof(struct hid_parser)); + parser = vmalloc(sizeof(struct hid_parser)); if (!parser) { ret = -ENOMEM; goto err; } + memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; @@ -683,8 +672,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start, if (dispatch_type[item.type](parser, &item)) { dbg_hid("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, - (unsigned)item.type, (unsigned)item.tag); + item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); goto err; } @@ -749,14 +737,13 @@ static u32 s32ton(__s32 value, unsigned n) * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */ -static __u32 extract(const struct hid_device *hid, __u8 *report, - unsigned offset, unsigned n) +static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) { u64 x; if (n > 32) - hid_warn(hid, "extract() called with n (%d) > 32! (%s)\n", - n, current->comm); + printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", + n, current->comm); report += offset >> 3; /* adjust byte index */ offset &= 7; /* now only need bit offset into one byte */ @@ -773,19 +760,18 @@ static __u32 extract(const struct hid_device *hid, __u8 *report, * endianness of register values by considering a register * a "cached" copy of the little endiad bit stream. */ -static void implement(const struct hid_device *hid, __u8 *report, - unsigned offset, unsigned n, __u32 value) +static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) { u64 x; u64 m = (1ULL << n) - 1; if (n > 32) - hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n", - __func__, n, current->comm); + printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", + n, current->comm); if (value > m) - hid_warn(hid, "%s() called with too large value %d! (%s)\n", - __func__, value, current->comm); + printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", + value, current->comm); WARN_ON(value > m); value &= m; @@ -802,7 +788,7 @@ static void implement(const struct hid_device *hid, __u8 *report, * Search an array for a value. */ -static int search(__s32 *array, __s32 value, unsigned n) +static __inline__ int search(__s32 *array, __s32 value, unsigned n) { while (n--) { if (*array++ == value) @@ -901,22 +887,18 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __s32 max = field->logical_maximum; __s32 *value; - value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC); - if (!value) + if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) return; for (n = 0; n < count; n++) { - value[n] = min < 0 ? - snto32(extract(hid, data, offset + n * size, size), - size) : - extract(hid, data, offset + n * size, size); + value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : + extract(data, offset + n * size, size); - /* Ignore report if ErrorRollOver */ - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && - value[n] >= min && value[n] <= max && - field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; + if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ + && value[n] >= min && value[n] <= max + && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) + goto exit; } for (n = 0; n < count; n++) { @@ -946,8 +928,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, * Output the field into the report. */ -static void hid_output_field(const struct hid_device *hid, - struct hid_field *field, __u8 *data) +static void hid_output_field(struct hid_field *field, __u8 *data) { unsigned count = field->report_count; unsigned offset = field->report_offset; @@ -956,11 +937,9 @@ static void hid_output_field(const struct hid_device *hid, for (n = 0; n < count; n++) { if (field->logical_minimum < 0) /* signed values */ - implement(hid, data, offset + n * size, size, - s32ton(field->value[n], size)); + implement(data, offset + n * size, size, s32ton(field->value[n], size)); else /* unsigned values */ - implement(hid, data, offset + n * size, size, - field->value[n]); + implement(data, offset + n * size, size, field->value[n]); } } @@ -977,7 +956,7 @@ void hid_output_report(struct hid_report *report, __u8 *data) memset(data, 0, ((report->size - 1) >> 3) + 1); for (n = 0; n < report->maxfield; n++) - hid_output_field(report->device, report->field[n], data); + hid_output_field(report->field[n], data); } EXPORT_SYMBOL_GPL(hid_output_report); @@ -1190,7 +1169,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) hdev->claimed |= HID_CLAIMED_HIDRAW; if (!hdev->claimed) { - hid_err(hdev, "claimed by neither input, hiddev nor hidraw\n"); + dev_err(&hdev->dev, "claimed by neither input, hiddev nor " + "hidraw\n"); return -ENODEV; } @@ -1230,9 +1210,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) bus = ""; } - hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", - buf, bus, hdev->version >> 8, hdev->version & 0xff, - type, hdev->name, hdev->phys); + dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", + buf, bus, hdev->version >> 8, hdev->version & 0xff, + type, hdev->name, hdev->phys); return 0; } @@ -1250,7 +1230,7 @@ void hid_disconnect(struct hid_device *hdev) EXPORT_SYMBOL_GPL(hid_disconnect); /* a list of devices for which there is a specialized driver on HID bus */ -static const struct hid_device_id hid_have_special_driver[] = { +static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, @@ -1296,12 +1276,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -1318,7 +1292,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, @@ -1331,7 +1304,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, - { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, @@ -1400,7 +1372,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, @@ -1528,9 +1499,9 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) if (!hid_match_device(hdev, hdrv)) return 0; - /* generic wants all that don't have specialized driver */ + /* generic wants all non-blacklisted */ if (!strncmp(hdrv->name, "generic-", 8)) - return !hid_match_id(hdev, hid_have_special_driver); + return !hid_match_id(hdev, hid_blacklist); return 1; } @@ -1790,12 +1761,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } @@ -1987,12 +1952,12 @@ static int __init hid_init(void) int ret; if (hid_debug) - pr_warn("hid_debug is now used solely for parser and driver debugging.\n" - "debugfs is now used for inspecting the device (report descriptor, reports)\n"); + printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n" + "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n"); ret = bus_register(&hid_bus_type); if (ret) { - pr_err("can't register hid bus\n"); + printk(KERN_ERR "HID: can't register hid bus\n"); goto err; } diff --git a/trunk/drivers/hid/hid-cypress.c b/trunk/drivers/hid/hid-cypress.c index 2f0be4c66af7..4cd0e2345991 100644 --- a/trunk/drivers/hid/hid-cypress.c +++ b/trunk/drivers/hid/hid-cypress.c @@ -107,13 +107,13 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-debug.c b/trunk/drivers/hid/hid-debug.c index 555382fc7417..75c5e23d09d2 100644 --- a/trunk/drivers/hid/hid-debug.c +++ b/trunk/drivers/hid/hid-debug.c @@ -26,8 +26,6 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -395,7 +393,7 @@ char *hid_resolv_usage(unsigned usage, struct seq_file *f) { buf = resolv_usage_page(usage >> 16, f); if (IS_ERR(buf)) { - pr_err("error allocating HID debug buffer\n"); + printk(KERN_ERR "error allocating HID debug buffer\n"); return NULL; } diff --git a/trunk/drivers/hid/hid-drff.c b/trunk/drivers/hid/hid-drff.c index afcf3d67eb02..968b04f9b796 100644 --- a/trunk/drivers/hid/hid-drff.c +++ b/trunk/drivers/hid/hid-drff.c @@ -96,18 +96,18 @@ static int drff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); + dev_err(&hid->dev, "no output reports found\n"); return -ENODEV; } report = list_first_entry(report_list, struct hid_report, list); if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); + dev_err(&hid->dev, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - hid_err(hid, "not enough values in the field\n"); + dev_err(&hid->dev, "not enough values in the field\n"); return -ENODEV; } @@ -133,8 +133,8 @@ static int drff_init(struct hid_device *hid) drff->report->field[0]->value[6] = 0x00; usbhid_submit_report(hid, drff->report, USB_DIR_OUT); - hid_info(hid, "Force Feedback for DragonRise Inc. " - "game controllers by Richard Walmsley \n"); + dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game " + "controllers by Richard Walmsley \n"); return 0; } @@ -153,13 +153,13 @@ static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-egalax.c b/trunk/drivers/hid/hid-egalax.c index 03bee1970d70..8fbff2358eb6 100644 --- a/trunk/drivers/hid/hid-egalax.c +++ b/trunk/drivers/hid/hid-egalax.c @@ -200,7 +200,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL); if (!td) { - hid_err(hdev, "cannot allocate eGalax data\n"); + dev_err(&hdev->dev, "cannot allocate eGalax data\n"); return -ENOMEM; } hid_set_drvdata(hdev, td); diff --git a/trunk/drivers/hid/hid-elecom.c b/trunk/drivers/hid/hid-elecom.c index 79d0c61e7214..6e31f305397d 100644 --- a/trunk/drivers/hid/hid-elecom.c +++ b/trunk/drivers/hid/hid-elecom.c @@ -24,7 +24,8 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { - hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); + dev_info(&hdev->dev, "Fixing up Elecom BM084 " + "report descriptor.\n"); rdesc[47] = 0x00; } return rdesc; diff --git a/trunk/drivers/hid/hid-emsff.c b/trunk/drivers/hid/hid-emsff.c deleted file mode 100644 index 81877c67caea..000000000000 --- a/trunk/drivers/hid/hid-emsff.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Force feedback support for EMS Trio Linker Plus II - * - * Copyright (c) 2010 Ignaz Forster - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include - -#include "hid-ids.h" -#include "usbhid/usbhid.h" - -struct emsff_device { - struct hid_report *report; -}; - -static int emsff_play(struct input_dev *dev, void *data, - struct ff_effect *effect) -{ - struct hid_device *hid = input_get_drvdata(dev); - struct emsff_device *emsff = data; - int weak, strong; - - weak = effect->u.rumble.weak_magnitude; - strong = effect->u.rumble.strong_magnitude; - - dbg_hid("called with 0x%04x 0x%04x\n", strong, weak); - - weak = weak * 0xff / 0xffff; - strong = strong * 0xff / 0xffff; - - emsff->report->field[0]->value[1] = weak; - emsff->report->field[0]->value[2] = strong; - - dbg_hid("running with 0x%02x 0x%02x\n", strong, weak); - usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); - - return 0; -} - -static int emsff_init(struct hid_device *hid) -{ - struct emsff_device *emsff; - struct hid_report *report; - struct hid_input *hidinput = list_first_entry(&hid->inputs, - struct hid_input, list); - struct list_head *report_list = - &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; - int error; - - if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); - return -ENODEV; - } - - report = list_first_entry(report_list, struct hid_report, list); - if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); - return -ENODEV; - } - - if (report->field[0]->report_count < 7) { - hid_err(hid, "not enough values in the field\n"); - return -ENODEV; - } - - emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL); - if (!emsff) - return -ENOMEM; - - set_bit(FF_RUMBLE, dev->ffbit); - - error = input_ff_create_memless(dev, emsff, emsff_play); - if (error) { - kfree(emsff); - return error; - } - - emsff->report = report; - emsff->report->field[0]->value[0] = 0x01; - emsff->report->field[0]->value[1] = 0x00; - emsff->report->field[0]->value[2] = 0x00; - emsff->report->field[0]->value[3] = 0x00; - emsff->report->field[0]->value[4] = 0x00; - emsff->report->field[0]->value[5] = 0x00; - emsff->report->field[0]->value[6] = 0x00; - usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); - - hid_info(hid, "force feedback for EMS based devices by Ignaz Forster \n"); - - return 0; -} - -static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - hid_err(hdev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto err; - } - - emsff_init(hdev); - - return 0; -err: - return ret; -} - -static const struct hid_device_id ems_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_EMS, 0x118) }, - { } -}; -MODULE_DEVICE_TABLE(hid, ems_devices); - -static struct hid_driver ems_driver = { - .name = "hkems", - .id_table = ems_devices, - .probe = ems_probe, -}; - -static int ems_init(void) -{ - return hid_register_driver(&ems_driver); -} - -static void ems_exit(void) -{ - hid_unregister_driver(&ems_driver); -} - -module_init(ems_init); -module_exit(ems_exit); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/hid/hid-gaff.c b/trunk/drivers/hid/hid-gaff.c index 279ba530003c..88dfcf49a5d7 100644 --- a/trunk/drivers/hid/hid-gaff.c +++ b/trunk/drivers/hid/hid-gaff.c @@ -87,7 +87,7 @@ static int gaff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); + dev_err(&hid->dev, "no output reports found\n"); return -ENODEV; } @@ -95,12 +95,12 @@ static int gaff_init(struct hid_device *hid) report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); + dev_err(&hid->dev, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 6) { - hid_err(hid, "not enough values in the field\n"); + dev_err(&hid->dev, "not enough values in the field\n"); return -ENODEV; } @@ -128,7 +128,8 @@ static int gaff_init(struct hid_device *hid) usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); - hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski \n"); + dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12" + " devices by Lukasz Lubojanski \n"); return 0; } @@ -147,13 +148,13 @@ static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index f65cace77729..8e11af86b014 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -97,12 +97,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 -#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f -#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 -#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b @@ -162,7 +156,6 @@ #define USB_VENDOR_ID_CHICONY 0x04f2 #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d -#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 #define USB_VENDOR_ID_CIDC 0x1677 @@ -215,9 +208,6 @@ #define USB_VENDOR_ID_ELO 0x04E7 #define USB_DEVICE_ID_ELO_TS2700 0x0020 -#define USB_VENDOR_ID_EMS 0x2006 -#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 - #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 @@ -490,7 +480,6 @@ #define USB_VENDOR_ID_ROCCAT 0x1e7d #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced -#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 diff --git a/trunk/drivers/hid/hid-input.c b/trunk/drivers/hid/hid-input.c index e60fdb88101f..d8d372bae3cc 100644 --- a/trunk/drivers/hid/hid-input.c +++ b/trunk/drivers/hid/hid-input.c @@ -319,21 +319,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel switch (field->application) { case HID_GD_MOUSE: - case HID_GD_POINTER: code += BTN_MOUSE; break; + case HID_GD_POINTER: code += 0x110; break; case HID_GD_JOYSTICK: if (code <= 0xf) code += BTN_JOYSTICK; else code += BTN_TRIGGER_HAPPY; break; - case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; + case HID_GD_GAMEPAD: code += 0x130; break; default: switch (field->physical) { case HID_GD_MOUSE: - case HID_GD_POINTER: code += BTN_MOUSE; break; - case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break; - case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; - default: code += BTN_MISC; + case HID_GD_POINTER: code += 0x110; break; + case HID_GD_JOYSTICK: code += 0x120; break; + case HID_GD_GAMEPAD: code += 0x130; break; + default: code += 0x100; } } @@ -817,14 +817,14 @@ static int hidinput_open(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - return hid_hw_open(hid); + return hid->ll_driver->open(hid); } static void hidinput_close(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - hid_hw_close(hid); + hid->ll_driver->close(hid); } /* @@ -871,7 +871,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) if (!hidinput || !input_dev) { kfree(hidinput); input_free_device(input_dev); - hid_err(hid, "Out of memory during hid input probe\n"); + err_hid("Out of memory during hid input probe"); goto out_unwind; } diff --git a/trunk/drivers/hid/hid-kye.c b/trunk/drivers/hid/hid-kye.c index f2ba9efc3a53..817247ee006c 100644 --- a/trunk/drivers/hid/hid-kye.c +++ b/trunk/drivers/hid/hid-kye.c @@ -32,8 +32,8 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[65] == 0x29 && rdesc[66] == 0x0f && rdesc[71] == 0x75 && rdesc[72] == 0x08 && rdesc[73] == 0x95 && rdesc[74] == 0x01) { - hid_info(hdev, - "fixing up Kye/Genius Ergo Mouse report descriptor\n"); + dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report " + "descriptor\n"); rdesc[62] = 0x09; rdesc[64] = 0x04; rdesc[66] = 0x07; diff --git a/trunk/drivers/hid/hid-lg.c b/trunk/drivers/hid/hid-lg.c index aef4104da141..b629fba5a057 100644 --- a/trunk/drivers/hid/hid-lg.c +++ b/trunk/drivers/hid/hid-lg.c @@ -53,22 +53,23 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && rdesc[84] == 0x8c && rdesc[85] == 0x02) { - hid_info(hdev, - "fixing up Logitech keyboard report descriptor\n"); + dev_info(&hdev->dev, "fixing up Logitech keyboard report " + "descriptor\n"); rdesc[84] = rdesc[89] = 0x4d; rdesc[85] = rdesc[90] = 0x10; } if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && rdesc[32] == 0x81 && rdesc[33] == 0x06 && rdesc[49] == 0x81 && rdesc[50] == 0x06) { - hid_info(hdev, - "fixing up rel/abs in Logitech report descriptor\n"); + dev_info(&hdev->dev, "fixing up rel/abs in Logitech " + "report descriptor\n"); rdesc[33] = rdesc[50] = 0x02; } if ((quirks & LG_FF4) && *rsize >= 101 && rdesc[41] == 0x95 && rdesc[42] == 0x0B && rdesc[47] == 0x05 && rdesc[48] == 0x09) { - hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); + dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless " + "button descriptor\n"); rdesc[41] = 0x05; rdesc[42] = 0x09; rdesc[47] = 0x95; @@ -287,7 +288,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } @@ -296,7 +297,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_hw_start(hdev, connect_mask); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-lg2ff.c b/trunk/drivers/hid/hid-lg2ff.c index 3c31bc650e5d..4258253c36b3 100644 --- a/trunk/drivers/hid/hid-lg2ff.c +++ b/trunk/drivers/hid/hid-lg2ff.c @@ -72,18 +72,18 @@ int lg2ff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output report found\n"); + dev_err(&hid->dev, "no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 1) { - hid_err(hid, "output report is empty\n"); + dev_err(&hid->dev, "output report is empty\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - hid_err(hid, "not enough values in the field\n"); + dev_err(&hid->dev, "not enough values in the field\n"); return -ENODEV; } @@ -110,7 +110,8 @@ int lg2ff_init(struct hid_device *hid) usbhid_submit_report(hid, report, USB_DIR_OUT); - hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula \n"); + dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by " + "Anssi Hannula \n"); return 0; } diff --git a/trunk/drivers/hid/hid-lg3ff.c b/trunk/drivers/hid/hid-lg3ff.c index f98644c26c1d..4002832ee4af 100644 --- a/trunk/drivers/hid/hid-lg3ff.c +++ b/trunk/drivers/hid/hid-lg3ff.c @@ -141,20 +141,20 @@ int lg3ff_init(struct hid_device *hid) /* Find the report to use */ if (list_empty(report_list)) { - hid_err(hid, "No output report found\n"); + err_hid("No output report found"); return -1; } /* Check that the report looks ok */ report = list_entry(report_list->next, struct hid_report, list); if (!report) { - hid_err(hid, "NULL output report\n"); + err_hid("NULL output report"); return -1; } field = report->field[0]; if (!field) { - hid_err(hid, "NULL field\n"); + err_hid("NULL field"); return -1; } @@ -169,7 +169,8 @@ int lg3ff_init(struct hid_device *hid) if (test_bit(FF_AUTOCENTER, dev->ffbit)) dev->ff->set_autocenter = hid_lg3ff_set_autocenter; - hid_info(hid, "Force feedback for Logitech Flight System G940 by Gary Stein \n"); + dev_info(&hid->dev, "Force feedback for Logitech Flight System G940 by " + "Gary Stein \n"); return 0; } diff --git a/trunk/drivers/hid/hid-lg4ff.c b/trunk/drivers/hid/hid-lg4ff.c index fa550c8e1d1b..7eef5a2ce948 100644 --- a/trunk/drivers/hid/hid-lg4ff.c +++ b/trunk/drivers/hid/hid-lg4ff.c @@ -101,20 +101,20 @@ int lg4ff_init(struct hid_device *hid) /* Find the report to use */ if (list_empty(report_list)) { - hid_err(hid, "No output report found\n"); + err_hid("No output report found"); return -1; } /* Check that the report looks ok */ report = list_entry(report_list->next, struct hid_report, list); if (!report) { - hid_err(hid, "NULL output report\n"); + err_hid("NULL output report"); return -1; } field = report->field[0]; if (!field) { - hid_err(hid, "NULL field\n"); + err_hid("NULL field"); return -1; } @@ -129,7 +129,8 @@ int lg4ff_init(struct hid_device *hid) if (test_bit(FF_AUTOCENTER, dev->ffbit)) dev->ff->set_autocenter = hid_lg4ff_set_autocenter; - hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood \n"); + dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by " + "Simon Wood \n"); return 0; } diff --git a/trunk/drivers/hid/hid-lgff.c b/trunk/drivers/hid/hid-lgff.c index 90d0ef2c92be..61142b76a9b1 100644 --- a/trunk/drivers/hid/hid-lgff.c +++ b/trunk/drivers/hid/hid-lgff.c @@ -27,8 +27,6 @@ * e-mail - mail your message to */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -148,7 +146,7 @@ int lgff_init(struct hid_device* hid) /* Find the report to use */ if (list_empty(report_list)) { - hid_err(hid, "No output report found\n"); + err_hid("No output report found"); return -1; } @@ -156,7 +154,7 @@ int lgff_init(struct hid_device* hid) report = list_entry(report_list->next, struct hid_report, list); field = report->field[0]; if (!field) { - hid_err(hid, "NULL field\n"); + err_hid("NULL field"); return -1; } @@ -178,7 +176,7 @@ int lgff_init(struct hid_device* hid) if ( test_bit(FF_AUTOCENTER, dev->ffbit) ) dev->ff->set_autocenter = hid_lgff_set_autocenter; - pr_info("Force feedback for Logitech force feedback devices by Johann Deneux \n"); + printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux \n"); return 0; } diff --git a/trunk/drivers/hid/hid-magicmouse.c b/trunk/drivers/hid/hid-magicmouse.c index 698e6459fd0b..e6dc15171664 100644 --- a/trunk/drivers/hid/hid-magicmouse.c +++ b/trunk/drivers/hid/hid-magicmouse.c @@ -12,8 +12,6 @@ * any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -435,11 +433,6 @@ static int magicmouse_input_mapping(struct hid_device *hdev, if (!msc->input) msc->input = hi->input; - /* Magic Trackpad does not give relative data after switching to MT */ - if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD && - field->flags & HID_MAIN_ITEM_RELATIVE) - return -1; - return 0; } @@ -453,7 +446,7 @@ static int magicmouse_probe(struct hid_device *hdev, msc = kzalloc(sizeof(*msc), GFP_KERNEL); if (msc == NULL) { - hid_err(hdev, "can't alloc magicmouse descriptor\n"); + dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n"); return -ENOMEM; } @@ -466,13 +459,13 @@ static int magicmouse_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "magicmouse hid parse failed\n"); + dev_err(&hdev->dev, "magicmouse hid parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "magicmouse hw start failed\n"); + dev_err(&hdev->dev, "magicmouse hw start failed\n"); goto err_free; } @@ -493,7 +486,7 @@ static int magicmouse_probe(struct hid_device *hdev, } if (!report) { - hid_err(hdev, "unable to register touch report\n"); + dev_err(&hdev->dev, "unable to register touch report\n"); ret = -ENOMEM; goto err_stop_hw; } @@ -502,7 +495,8 @@ static int magicmouse_probe(struct hid_device *hdev, ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); if (ret != sizeof(feature)) { - hid_err(hdev, "unable to request touch data (%d)\n", ret); + dev_err(&hdev->dev, "unable to request touch data (%d)\n", + ret); goto err_stop_hw; } @@ -546,7 +540,7 @@ static int __init magicmouse_init(void) ret = hid_register_driver(&magicmouse_driver); if (ret) - pr_err("can't register magicmouse driver\n"); + printk(KERN_ERR "can't register magicmouse driver\n"); return ret; } diff --git a/trunk/drivers/hid/hid-microsoft.c b/trunk/drivers/hid/hid-microsoft.c index 0f6fc54dc196..dc618c33d0a2 100644 --- a/trunk/drivers/hid/hid-microsoft.c +++ b/trunk/drivers/hid/hid-microsoft.c @@ -40,7 +40,8 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && rdesc[559] == 0x29) { - hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); + dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " + "Model 1028 report descriptor\n"); rdesc[557] = 0x35; rdesc[559] = 0x45; } @@ -154,14 +155,14 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? HID_CONNECT_HIDINPUT_FORCE : 0)); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-monterey.c b/trunk/drivers/hid/hid-monterey.c index dedf757781ae..c95c31e2d869 100644 --- a/trunk/drivers/hid/hid-monterey.c +++ b/trunk/drivers/hid/hid-monterey.c @@ -26,7 +26,8 @@ static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { - hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); + dev_info(&hdev->dev, "fixing up button/consumer in HID report " + "descriptor\n"); rdesc[30] = 0x0c; } return rdesc; diff --git a/trunk/drivers/hid/hid-mosart.c b/trunk/drivers/hid/hid-mosart.c index 9fb050ce6f04..ac5421d568f1 100644 --- a/trunk/drivers/hid/hid-mosart.c +++ b/trunk/drivers/hid/hid-mosart.c @@ -90,10 +90,6 @@ static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0xff000000: /* ignore HID features */ return -1; - - case HID_UP_BUTTON: - /* ignore buttons */ - return -1; } return 0; @@ -203,7 +199,7 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); if (!td) { - hid_err(hdev, "cannot allocate MosArt data\n"); + dev_err(&hdev->dev, "cannot allocate MosArt data\n"); return -ENOMEM; } td->valid = false; @@ -234,19 +230,6 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } -#ifdef CONFIG_PM -static int mosart_reset_resume(struct hid_device *hdev) -{ - struct hid_report_enum *re = hdev->report_enum - + HID_FEATURE_REPORT; - struct hid_report *r = re->report_id_hash[7]; - - r->field[0]->value[0] = 0x02; - usbhid_submit_report(hdev, r, USB_DIR_OUT); - return 0; -} -#endif - static void mosart_remove(struct hid_device *hdev) { hid_hw_stop(hdev); @@ -275,9 +258,6 @@ static struct hid_driver mosart_driver = { .input_mapped = mosart_input_mapped, .usage_table = mosart_grabbed_usages, .event = mosart_event, -#ifdef CONFIG_PM - .reset_resume = mosart_reset_resume, -#endif }; static int __init mosart_init(void) diff --git a/trunk/drivers/hid/hid-ntrig.c b/trunk/drivers/hid/hid-ntrig.c index beb403421e72..69169efa1e16 100644 --- a/trunk/drivers/hid/hid-ntrig.c +++ b/trunk/drivers/hid/hid-ntrig.c @@ -130,7 +130,8 @@ static void ntrig_report_version(struct hid_device *hdev) if (ret == 8) { ret = ntrig_version_string(&data[2], buf); - hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n", + dev_info(&hdev->dev, + "Firmware version: %s (%02x%02x %02x%02x)\n", buf, data[2], data[3], data[4], data[5]); } @@ -830,7 +831,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); if (!nd) { - hid_err(hdev, "cannot allocate N-Trig data\n"); + dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); return -ENOMEM; } @@ -849,13 +850,13 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-ortek.c b/trunk/drivers/hid/hid-ortek.c index e90edfc63051..2e79716dca31 100644 --- a/trunk/drivers/hid/hid-ortek.c +++ b/trunk/drivers/hid/hid-ortek.c @@ -23,7 +23,8 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) { - hid_info(hdev, "Fixing up Ortek WKB-2000 report descriptor\n"); + dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 " + "report descriptor.\n"); rdesc[55] = 0x92; } return rdesc; diff --git a/trunk/drivers/hid/hid-petalynx.c b/trunk/drivers/hid/hid-petalynx.c index f1ea3ff8a98d..308d6ae48a3e 100644 --- a/trunk/drivers/hid/hid-petalynx.c +++ b/trunk/drivers/hid/hid-petalynx.c @@ -29,7 +29,8 @@ static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && rdesc[41] == 0x00 && rdesc[59] == 0x26 && rdesc[60] == 0xf9 && rdesc[61] == 0x00) { - hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); + dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " + "descriptor\n"); rdesc[60] = 0xfa; rdesc[40] = 0xfa; } @@ -76,13 +77,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-picolcd.c b/trunk/drivers/hid/hid-picolcd.c index de9cf21b3494..bc2e07740628 100644 --- a/trunk/drivers/hid/hid-picolcd.c +++ b/trunk/drivers/hid/hid-picolcd.c @@ -253,7 +253,7 @@ static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int di if (report->id == id) return report; } - hid_warn(hdev, "No report with id 0x%x found\n", id); + dev_warn(&hdev->dev, "No report with id 0x%x found\n", id); return NULL; } @@ -1329,7 +1329,7 @@ static int picolcd_check_version(struct hid_device *hdev) verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0); if (!verinfo) { - hid_err(hdev, "no version response from PicoLCD\n"); + dev_err(&hdev->dev, "no version response from PicoLCD"); return -ENODEV; } @@ -1337,14 +1337,14 @@ static int picolcd_check_version(struct hid_device *hdev) data->version[0] = verinfo->raw_data[1]; data->version[1] = verinfo->raw_data[0]; if (data->status & PICOLCD_BOOTLOADER) { - hid_info(hdev, "PicoLCD, bootloader version %d.%d\n", - verinfo->raw_data[1], verinfo->raw_data[0]); + dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n", + verinfo->raw_data[1], verinfo->raw_data[0]); } else { - hid_info(hdev, "PicoLCD, firmware version %d.%d\n", - verinfo->raw_data[1], verinfo->raw_data[0]); + dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n", + verinfo->raw_data[1], verinfo->raw_data[0]); } } else { - hid_err(hdev, "confused, got unexpected version response from PicoLCD\n"); + dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n"); ret = -EINVAL; } kfree(verinfo); @@ -1544,7 +1544,7 @@ static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u, /* prepare buffer with info about what we want to read (addr & len) */ raw_data[0] = *off & 0xff; - raw_data[1] = (*off >> 8) & 0xff; + raw_data[1] = (*off >> 8) && 0xff; raw_data[2] = s < 20 ? s : 20; if (*off + raw_data[2] > 0xff) raw_data[2] = 0x100 - *off; @@ -1583,7 +1583,7 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, memset(raw_data, 0, sizeof(raw_data)); raw_data[0] = *off & 0xff; - raw_data[1] = (*off >> 8) & 0xff; + raw_data[1] = (*off >> 8) && 0xff; raw_data[2] = s < 20 ? s : 20; if (*off + raw_data[2] > 0xff) raw_data[2] = 0x100 - *off; @@ -1867,7 +1867,6 @@ static void picolcd_debug_out_report(struct picolcd_data *data, report->id, raw_size); hid_debug_event(hdev, buff); if (raw_size + 5 > sizeof(raw_data)) { - kfree(buff); hid_debug_event(hdev, " TOO BIG\n"); return; } else { @@ -2329,7 +2328,8 @@ static void picolcd_init_devfs(struct picolcd_data *data, (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0), hdev->debug_dir, data, &picolcd_debug_flash_fops); } else if (flash_r || flash_w) - hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n"); + dev_warn(&hdev->dev, "Unexpected FLASH access reports, " + "please submit rdesc for review\n"); } static void picolcd_exit_devfs(struct picolcd_data *data) @@ -2457,13 +2457,13 @@ static int picolcd_init_keys(struct picolcd_data *data, return -ENODEV; if (report->maxfield != 1 || report->field[0]->report_count != 2 || report->field[0]->report_size != 8) { - hid_err(hdev, "unsupported KEY_STATE report\n"); + dev_err(&hdev->dev, "unsupported KEY_STATE report"); return -EINVAL; } idev = input_allocate_device(); if (idev == NULL) { - hid_err(hdev, "failed to allocate input device\n"); + dev_err(&hdev->dev, "failed to allocate input device"); return -ENOMEM; } input_set_drvdata(idev, hdev); @@ -2485,7 +2485,7 @@ static int picolcd_init_keys(struct picolcd_data *data, input_set_capability(idev, EV_KEY, data->keycode[i]); error = input_register_device(idev); if (error) { - hid_err(hdev, "error registering the input device\n"); + dev_err(&hdev->dev, "error registering the input device"); input_free_device(idev); return error; } @@ -2522,8 +2522,9 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data) return error; if (data->version[0] != 0 && data->version[1] != 3) - hid_info(hdev, "Device with untested firmware revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", - dev_name(&hdev->dev)); + dev_info(&hdev->dev, "Device with untested firmware revision, " + "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", + dev_name(&hdev->dev)); /* Setup keypad input device */ error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev)); @@ -2580,8 +2581,9 @@ static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data return error; if (data->version[0] != 1 && data->version[1] != 0) - hid_info(hdev, "Device with untested bootloader revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", - dev_name(&hdev->dev)); + dev_info(&hdev->dev, "Device with untested bootloader revision, " + "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", + dev_name(&hdev->dev)); picolcd_init_devfs(data, NULL, NULL, picolcd_out_report(REPORT_BL_READ_MEMORY, hdev), @@ -2603,7 +2605,7 @@ static int picolcd_probe(struct hid_device *hdev, */ data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL); if (data == NULL) { - hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n"); + dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n"); error = -ENOMEM; goto err_no_cleanup; } @@ -2619,7 +2621,7 @@ static int picolcd_probe(struct hid_device *hdev, /* Parse the device reports and start it up */ error = hid_parse(hdev); if (error) { - hid_err(hdev, "device report parse failed\n"); + dev_err(&hdev->dev, "device report parse failed\n"); goto err_cleanup_data; } @@ -2629,25 +2631,25 @@ static int picolcd_probe(struct hid_device *hdev, error = hid_hw_start(hdev, 0); hdev->claimed = 0; if (error) { - hid_err(hdev, "hardware start failed\n"); + dev_err(&hdev->dev, "hardware start failed\n"); goto err_cleanup_data; } - error = hid_hw_open(hdev); + error = hdev->ll_driver->open(hdev); if (error) { - hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n"); + dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n"); goto err_cleanup_hid_hw; } error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay); if (error) { - hid_err(hdev, "failed to create sysfs attributes\n"); + dev_err(&hdev->dev, "failed to create sysfs attributes\n"); goto err_cleanup_hid_ll; } error = device_create_file(&hdev->dev, &dev_attr_operation_mode); if (error) { - hid_err(hdev, "failed to create sysfs attributes\n"); + dev_err(&hdev->dev, "failed to create sysfs attributes\n"); goto err_cleanup_sysfs1; } @@ -2666,7 +2668,7 @@ static int picolcd_probe(struct hid_device *hdev, err_cleanup_sysfs1: device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); err_cleanup_hid_ll: - hid_hw_close(hdev); + hdev->ll_driver->close(hdev); err_cleanup_hid_hw: hid_hw_stop(hdev); err_cleanup_data: @@ -2697,7 +2699,7 @@ static void picolcd_remove(struct hid_device *hdev) picolcd_exit_devfs(data); device_remove_file(&hdev->dev, &dev_attr_operation_mode); device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); - hid_hw_close(hdev); + hdev->ll_driver->close(hdev); hid_hw_stop(hdev); hid_set_drvdata(hdev, NULL); @@ -2751,7 +2753,7 @@ static void __exit picolcd_exit(void) { hid_unregister_driver(&picolcd_driver); #ifdef CONFIG_HID_PICOLCD_FB - flush_work_sync(&picolcd_fb_cleanup); + flush_scheduled_work(); WARN_ON(fb_pending); #endif } diff --git a/trunk/drivers/hid/hid-pl.c b/trunk/drivers/hid/hid-pl.c index 06e5300d43d2..9f41e2bd8483 100644 --- a/trunk/drivers/hid/hid-pl.c +++ b/trunk/drivers/hid/hid-pl.c @@ -103,7 +103,7 @@ static int plff_init(struct hid_device *hid) */ if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); + dev_err(&hid->dev, "no output reports found\n"); return -ENODEV; } @@ -112,13 +112,14 @@ static int plff_init(struct hid_device *hid) report_ptr = report_ptr->next; if (report_ptr == report_list) { - hid_err(hid, "required output report is missing\n"); + dev_err(&hid->dev, "required output report is " + "missing\n"); return -ENODEV; } report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); + dev_err(&hid->dev, "no fields in the report\n"); return -ENODEV; } @@ -136,7 +137,7 @@ static int plff_init(struct hid_device *hid) weak = &report->field[3]->value[0]; debug("detected 4-field device"); } else { - hid_err(hid, "not enough fields or values\n"); + dev_err(&hid->dev, "not enough fields or values\n"); return -ENODEV; } @@ -163,7 +164,8 @@ static int plff_init(struct hid_device *hid) usbhid_submit_report(hid, plff->report, USB_DIR_OUT); } - hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula \n"); + dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia " + "devices by Anssi Hannula \n"); return 0; } @@ -183,13 +185,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-prodikeys.c b/trunk/drivers/hid/hid-prodikeys.c index ab19f2905d27..48eab84f53b5 100644 --- a/trunk/drivers/hid/hid-prodikeys.c +++ b/trunk/drivers/hid/hid-prodikeys.c @@ -16,8 +16,6 @@ * any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -132,7 +130,7 @@ static ssize_t store_channel(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(channel, S_IRUGO | S_IWUSR | S_IWGRP , show_channel, +static DEVICE_ATTR(channel, S_IRUGO | S_IWUGO, show_channel, store_channel); static struct device_attribute *sysfs_device_attr_channel = { @@ -171,7 +169,7 @@ static ssize_t store_sustain(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(sustain, S_IRUGO | S_IWUSR | S_IWGRP, show_sustain, +static DEVICE_ATTR(sustain, S_IRUGO | S_IWUGO, show_sustain, store_sustain); static struct device_attribute *sysfs_device_attr_sustain = { @@ -209,7 +207,7 @@ static ssize_t store_octave(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(octave, S_IRUGO | S_IWUSR | S_IWGRP, show_octave, +static DEVICE_ATTR(octave, S_IRUGO | S_IWUGO, show_octave, store_octave); static struct device_attribute *sysfs_device_attr_octave = { @@ -287,11 +285,11 @@ static int pcmidi_get_output_report(struct pcmidi_snd *pm) continue; if (report->maxfield < 1) { - hid_err(hdev, "output report is empty\n"); + dev_err(&hdev->dev, "output report is empty\n"); break; } if (report->field[0]->report_count != 2) { - hid_err(hdev, "field count too low\n"); + dev_err(&hdev->dev, "field count too low\n"); break; } pm->pcmidi_report6 = report; @@ -748,8 +746,8 @@ static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (*rsize == 178 && rdesc[111] == 0x06 && rdesc[112] == 0x00 && rdesc[113] == 0xff) { - hid_info(hdev, - "fixing up pc-midi keyboard report descriptor\n"); + dev_info(&hdev->dev, "fixing up pc-midi keyboard report " + "descriptor\n"); rdesc[144] = 0x18; /* report 4: was 0x10 report count */ } @@ -807,7 +805,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) pk = kzalloc(sizeof(*pk), GFP_KERNEL); if (pk == NULL) { - hid_err(hdev, "can't alloc descriptor\n"); + dev_err(&hdev->dev, "prodikeys: can't alloc descriptor\n"); return -ENOMEM; } @@ -815,7 +813,8 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) pm = kzalloc(sizeof(*pm), GFP_KERNEL); if (pm == NULL) { - hid_err(hdev, "can't alloc descriptor\n"); + dev_err(&hdev->dev, + "prodikeys: can't alloc descriptor\n"); ret = -ENOMEM; goto err_free; } @@ -828,7 +827,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "hid parse failed\n"); + dev_err(&hdev->dev, "prodikeys: hid parse failed\n"); goto err_free; } @@ -838,7 +837,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "prodikeys: hw start failed\n"); goto err_free; } @@ -897,7 +896,7 @@ static int pk_init(void) ret = hid_register_driver(&pk_driver); if (ret) - pr_err("can't register prodikeys driver\n"); + printk(KERN_ERR "can't register prodikeys driver\n"); return ret; } diff --git a/trunk/drivers/hid/hid-quanta.c b/trunk/drivers/hid/hid-quanta.c index 87a54df4d4ac..54d3db50605b 100644 --- a/trunk/drivers/hid/hid-quanta.c +++ b/trunk/drivers/hid/hid-quanta.c @@ -195,7 +195,7 @@ static int quanta_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct quanta_data), GFP_KERNEL); if (!td) { - hid_err(hdev, "cannot allocate Quanta Touch data\n"); + dev_err(&hdev->dev, "cannot allocate Quanta Touch data\n"); return -ENOMEM; } td->valid = false; diff --git a/trunk/drivers/hid/hid-roccat-kone.c b/trunk/drivers/hid/hid-roccat-kone.c index cbd8cc42e75a..f77695762cb5 100644 --- a/trunk/drivers/hid/hid-roccat-kone.c +++ b/trunk/drivers/hid/hid-roccat-kone.c @@ -35,11 +35,6 @@ #include "hid-roccat.h" #include "hid-roccat-kone.h" -static uint profile_numbers[5] = {0, 1, 2, 3, 4}; - -/* kone_class is used for creating sysfs attributes via roccat char device */ -static struct class *kone_class; - static void kone_set_settings_checksum(struct kone_settings *settings) { uint16_t checksum = 0; @@ -95,7 +90,8 @@ static int kone_check_write(struct usb_device *usb_dev) kfree(data); return 0; } else { /* unknown answer */ - hid_err(usb_dev, "got retval %d when checking write\n", *data); + dev_err(&usb_dev->dev, "got retval %d when checking write\n", + *data); kfree(data); return -EIO; } @@ -266,8 +262,7 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct kone_settings)) @@ -291,8 +286,7 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0, difference; @@ -325,11 +319,10 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, return sizeof(struct kone_settings); } -static ssize_t kone_sysfs_read_profilex(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; +static ssize_t kone_sysfs_read_profilex(struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count, int number) { + struct device *dev = container_of(kobj, struct device, kobj); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct kone_profile)) @@ -339,18 +332,47 @@ static ssize_t kone_sysfs_read_profilex(struct file *fp, count = sizeof(struct kone_profile) - off; mutex_lock(&kone->kone_lock); - memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count); + memcpy(buf, ((char const *)&kone->profiles[number - 1]) + off, count); mutex_unlock(&kone->kone_lock); return count; } +static ssize_t kone_sysfs_read_profile1(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 1); +} + +static ssize_t kone_sysfs_read_profile2(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 2); +} + +static ssize_t kone_sysfs_read_profile3(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 3); +} + +static ssize_t kone_sysfs_read_profile4(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 4); +} + +static ssize_t kone_sysfs_read_profile5(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 5); +} + /* Writes data only if different to stored data */ -static ssize_t kone_sysfs_write_profilex(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; +static ssize_t kone_sysfs_write_profilex(struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count, int number) { + struct device *dev = container_of(kobj, struct device, kobj); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct kone_profile *profile; @@ -360,14 +382,13 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp, if (off != 0 || count != sizeof(struct kone_profile)) return -EINVAL; - profile = &kone->profiles[*(uint *)(attr->private)]; + profile = &kone->profiles[number - 1]; mutex_lock(&kone->kone_lock); difference = memcmp(buf, profile, sizeof(struct kone_profile)); if (difference) { retval = kone_set_profile(usb_dev, - (struct kone_profile const *)buf, - *(uint *)(attr->private) + 1); + (struct kone_profile const *)buf, number); if (!retval) memcpy(profile, buf, sizeof(struct kone_profile)); } @@ -379,19 +400,47 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp, return sizeof(struct kone_profile); } +static ssize_t kone_sysfs_write_profile1(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 1); +} + +static ssize_t kone_sysfs_write_profile2(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 2); +} + +static ssize_t kone_sysfs_write_profile3(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 3); +} + +static ssize_t kone_sysfs_write_profile4(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 4); +} + +static ssize_t kone_sysfs_write_profile5(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 5); +} + static ssize_t kone_sysfs_show_actual_profile(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); } static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); } @@ -399,15 +448,11 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, static ssize_t kone_sysfs_show_weight(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone; - struct usb_device *usb_dev; + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int weight = 0; int retval; - dev = dev->parent->parent; - kone = hid_get_drvdata(dev_get_drvdata(dev)); - usb_dev = interface_to_usbdev(to_usb_interface(dev)); - mutex_lock(&kone->kone_lock); retval = kone_get_weight(usb_dev, &weight); mutex_unlock(&kone->kone_lock); @@ -420,16 +465,14 @@ static ssize_t kone_sysfs_show_weight(struct device *dev, static ssize_t kone_sysfs_show_firmware_version(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); } static ssize_t kone_sysfs_show_tcu(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu); } @@ -461,15 +504,11 @@ static int kone_tcu_command(struct usb_device *usb_dev, int number) static ssize_t kone_sysfs_set_tcu(struct device *dev, struct device_attribute *attr, char const *buf, size_t size) { - struct kone_device *kone; - struct usb_device *usb_dev; + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; unsigned long state; - dev = dev->parent->parent; - kone = hid_get_drvdata(dev_get_drvdata(dev)); - usb_dev = interface_to_usbdev(to_usb_interface(dev)); - retval = strict_strtoul(buf, 10, &state); if (retval) return retval; @@ -517,7 +556,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = kone_set_settings(usb_dev, &kone->settings); if (retval) { - hid_err(usb_dev, "couldn't set tcu state\n"); + dev_err(&usb_dev->dev, "couldn't set tcu state\n"); /* * try to reread valid settings into buffer overwriting * first error code @@ -531,7 +570,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = size; exit_no_settings: - hid_err(usb_dev, "couldn't read settings\n"); + dev_err(&usb_dev->dev, "couldn't read settings\n"); exit_unlock: mutex_unlock(&kone->kone_lock); return retval; @@ -540,23 +579,18 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, static ssize_t kone_sysfs_show_startup_profile(struct device *dev, struct device_attribute *attr, char *buf) { - struct kone_device *kone = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile); } static ssize_t kone_sysfs_set_startup_profile(struct device *dev, struct device_attribute *attr, char const *buf, size_t size) { - struct kone_device *kone; - struct usb_device *usb_dev; + struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; unsigned long new_startup_profile; - dev = dev->parent->parent; - kone = hid_get_drvdata(dev_get_drvdata(dev)); - usb_dev = interface_to_usbdev(to_usb_interface(dev)); - retval = strict_strtoul(buf, 10, &new_startup_profile); if (retval) return retval; @@ -583,92 +617,160 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev, return size; } -static struct device_attribute kone_attributes[] = { - /* - * Read actual dpi settings. - * Returns raw value for further processing. Refer to enum - * kone_polling_rates to get real value. - */ - __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL), - __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL), +/* + * Read actual dpi settings. + * Returns raw value for further processing. Refer to enum kone_polling_rates to + * get real value. + */ +static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL); - /* - * The mouse can be equipped with one of four supplied weights from 5 - * to 20 grams which are recognized and its value can be read out. - * This returns the raw value reported by the mouse for easy evaluation - * by software. Refer to enum kone_weights to get corresponding real - * weight. - */ - __ATTR(weight, 0440, kone_sysfs_show_weight, NULL), +static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL); - /* - * Prints firmware version stored in mouse as integer. - * The raw value reported by the mouse is returned for easy evaluation, - * to get the real version number the decimal point has to be shifted 2 - * positions to the left. E.g. a value of 138 means 1.38. - */ - __ATTR(firmware_version, 0440, - kone_sysfs_show_firmware_version, NULL), +/* + * The mouse can be equipped with one of four supplied weights from 5 to 20 + * grams which are recognized and its value can be read out. + * This returns the raw value reported by the mouse for easy evaluation by + * software. Refer to enum kone_weights to get corresponding real weight. + */ +static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL); - /* - * Prints state of Tracking Control Unit as number where 0 = off and - * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and - * activates the tcu - */ - __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu), +/* + * Prints firmware version stored in mouse as integer. + * The raw value reported by the mouse is returned for easy evaluation, to get + * the real version number the decimal point has to be shifted 2 positions to + * the left. E.g. a value of 138 means 1.38. + */ +static DEVICE_ATTR(firmware_version, 0440, + kone_sysfs_show_firmware_version, NULL); - /* Prints and takes the number of the profile the mouse starts with */ - __ATTR(startup_profile, 0660, - kone_sysfs_show_startup_profile, - kone_sysfs_set_startup_profile), - __ATTR_NULL +/* + * Prints state of Tracking Control Unit as number where 0 = off and 1 = on + * Writing 0 deactivates tcu and writing 1 calibrates and activates the tcu + */ +static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu); + +/* Prints and takes the number of the profile the mouse starts with */ +static DEVICE_ATTR(startup_profile, 0660, + kone_sysfs_show_startup_profile, + kone_sysfs_set_startup_profile); + +static struct attribute *kone_attributes[] = { + &dev_attr_actual_dpi.attr, + &dev_attr_actual_profile.attr, + &dev_attr_weight.attr, + &dev_attr_firmware_version.attr, + &dev_attr_tcu.attr, + &dev_attr_startup_profile.attr, + NULL }; -static struct bin_attribute kone_bin_attributes[] = { - { - .attr = { .name = "settings", .mode = 0660 }, - .size = sizeof(struct kone_settings), - .read = kone_sysfs_read_settings, - .write = kone_sysfs_write_settings - }, - { - .attr = { .name = "profile1", .mode = 0660 }, - .size = sizeof(struct kone_profile), - .read = kone_sysfs_read_profilex, - .write = kone_sysfs_write_profilex, - .private = &profile_numbers[0] - }, - { - .attr = { .name = "profile2", .mode = 0660 }, - .size = sizeof(struct kone_profile), - .read = kone_sysfs_read_profilex, - .write = kone_sysfs_write_profilex, - .private = &profile_numbers[1] - }, - { - .attr = { .name = "profile3", .mode = 0660 }, - .size = sizeof(struct kone_profile), - .read = kone_sysfs_read_profilex, - .write = kone_sysfs_write_profilex, - .private = &profile_numbers[2] - }, - { - .attr = { .name = "profile4", .mode = 0660 }, - .size = sizeof(struct kone_profile), - .read = kone_sysfs_read_profilex, - .write = kone_sysfs_write_profilex, - .private = &profile_numbers[3] - }, - { - .attr = { .name = "profile5", .mode = 0660 }, - .size = sizeof(struct kone_profile), - .read = kone_sysfs_read_profilex, - .write = kone_sysfs_write_profilex, - .private = &profile_numbers[4] - }, - __ATTR_NULL +static struct attribute_group kone_attribute_group = { + .attrs = kone_attributes }; +static struct bin_attribute kone_settings_attr = { + .attr = { .name = "settings", .mode = 0660 }, + .size = sizeof(struct kone_settings), + .read = kone_sysfs_read_settings, + .write = kone_sysfs_write_settings +}; + +static struct bin_attribute kone_profile1_attr = { + .attr = { .name = "profile1", .mode = 0660 }, + .size = sizeof(struct kone_profile), + .read = kone_sysfs_read_profile1, + .write = kone_sysfs_write_profile1 +}; + +static struct bin_attribute kone_profile2_attr = { + .attr = { .name = "profile2", .mode = 0660 }, + .size = sizeof(struct kone_profile), + .read = kone_sysfs_read_profile2, + .write = kone_sysfs_write_profile2 +}; + +static struct bin_attribute kone_profile3_attr = { + .attr = { .name = "profile3", .mode = 0660 }, + .size = sizeof(struct kone_profile), + .read = kone_sysfs_read_profile3, + .write = kone_sysfs_write_profile3 +}; + +static struct bin_attribute kone_profile4_attr = { + .attr = { .name = "profile4", .mode = 0660 }, + .size = sizeof(struct kone_profile), + .read = kone_sysfs_read_profile4, + .write = kone_sysfs_write_profile4 +}; + +static struct bin_attribute kone_profile5_attr = { + .attr = { .name = "profile5", .mode = 0660 }, + .size = sizeof(struct kone_profile), + .read = kone_sysfs_read_profile5, + .write = kone_sysfs_write_profile5 +}; + +static int kone_create_sysfs_attributes(struct usb_interface *intf) +{ + int retval; + + retval = sysfs_create_group(&intf->dev.kobj, &kone_attribute_group); + if (retval) + goto exit_1; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_settings_attr); + if (retval) + goto exit_2; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile1_attr); + if (retval) + goto exit_3; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile2_attr); + if (retval) + goto exit_4; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile3_attr); + if (retval) + goto exit_5; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile4_attr); + if (retval) + goto exit_6; + + retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile5_attr); + if (retval) + goto exit_7; + + return 0; + +exit_7: + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr); +exit_6: + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr); +exit_5: + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr); +exit_4: + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr); +exit_3: + sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr); +exit_2: + sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group); +exit_1: + return retval; +} + +static void kone_remove_sysfs_attributes(struct usb_interface *intf) +{ + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile5_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr); + sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group); +} + static int kone_init_kone_device_struct(struct usb_device *usb_dev, struct kone_device *kone) { @@ -716,25 +818,32 @@ static int kone_init_specials(struct hid_device *hdev) kone = kzalloc(sizeof(*kone), GFP_KERNEL); if (!kone) { - hid_err(hdev, "can't alloc device descriptor\n"); + dev_err(&hdev->dev, "can't alloc device descriptor\n"); return -ENOMEM; } hid_set_drvdata(hdev, kone); retval = kone_init_kone_device_struct(usb_dev, kone); if (retval) { - hid_err(hdev, "couldn't init struct kone_device\n"); + dev_err(&hdev->dev, + "couldn't init struct kone_device\n"); goto exit_free; } - retval = roccat_connect(kone_class, hdev); + retval = roccat_connect(hdev); if (retval < 0) { - hid_err(hdev, "couldn't init char dev\n"); + dev_err(&hdev->dev, "couldn't init char dev\n"); /* be tolerant about not getting chrdev */ } else { kone->roccat_claimed = 1; kone->chrdev_minor = retval; } + + retval = kone_create_sysfs_attributes(intf); + if (retval) { + dev_err(&hdev->dev, "cannot create sysfs files\n"); + goto exit_free; + } } else { hid_set_drvdata(hdev, NULL); } @@ -745,6 +854,7 @@ static int kone_init_specials(struct hid_device *hdev) return retval; } + static void kone_remove_specials(struct hid_device *hdev) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); @@ -752,6 +862,7 @@ static void kone_remove_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { + kone_remove_sysfs_attributes(intf); kone = hid_get_drvdata(hdev); if (kone->roccat_claimed) roccat_disconnect(kone->chrdev_minor); @@ -765,19 +876,19 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) retval = hid_parse(hdev); if (retval) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto exit; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto exit; } retval = kone_init_specials(hdev); if (retval) { - hid_err(hdev, "couldn't install mouse\n"); + dev_err(&hdev->dev, "couldn't install mouse\n"); goto exit_stop; } @@ -895,24 +1006,11 @@ static struct hid_driver kone_driver = { static int __init kone_init(void) { - int retval; - - /* class name has to be same as driver name */ - kone_class = class_create(THIS_MODULE, "kone"); - if (IS_ERR(kone_class)) - return PTR_ERR(kone_class); - kone_class->dev_attrs = kone_attributes; - kone_class->dev_bin_attrs = kone_bin_attributes; - - retval = hid_register_driver(&kone_driver); - if (retval) - class_destroy(kone_class); - return retval; + return hid_register_driver(&kone_driver); } static void __exit kone_exit(void) { - class_destroy(kone_class); hid_unregister_driver(&kone_driver); } diff --git a/trunk/drivers/hid/hid-roccat-kone.h b/trunk/drivers/hid/hid-roccat-kone.h index 64abb5b8a59a..130d6566ea82 100644 --- a/trunk/drivers/hid/hid-roccat-kone.h +++ b/trunk/drivers/hid/hid-roccat-kone.h @@ -14,11 +14,14 @@ #include +#pragma pack(push) +#pragma pack(1) + struct kone_keystroke { uint8_t key; uint8_t action; uint16_t period; /* in milliseconds */ -} __attribute__ ((__packed__)); +}; enum kone_keystroke_buttons { kone_keystroke_button_1 = 0xf0, /* left mouse button */ @@ -41,7 +44,7 @@ struct kone_button_info { uint8_t macro_name[16]; /* can be max 15 chars long */ uint8_t count; struct kone_keystroke keystrokes[20]; -} __attribute__ ((__packed__)); +}; enum kone_button_info_types { /* valid button types until firmware 1.32 */ @@ -92,7 +95,7 @@ struct kone_light_info { uint8_t red; /* range 0x00-0xff */ uint8_t green; /* range 0x00-0xff */ uint8_t blue; /* range 0x00-0xff */ -} __attribute__ ((__packed__)); +}; struct kone_profile { uint16_t size; /* always 975 */ @@ -127,7 +130,7 @@ struct kone_profile { struct kone_button_info button_infos[8]; uint16_t checksum; /* \brief holds checksum of struct */ -} __attribute__ ((__packed__)); +}; enum kone_polling_rates { kone_polling_rate_125 = 1, @@ -144,7 +147,7 @@ struct kone_settings { uint8_t calibration_data[4]; uint8_t unknown3[2]; uint16_t checksum; -} __attribute__ ((__packed__)); +}; /* * 12 byte mouse event read by interrupt_read @@ -160,7 +163,7 @@ struct kone_mouse_event { uint8_t event; uint8_t value; /* press = 0, release = 1 */ uint8_t macro_key; /* 0 to 8 */ -} __attribute__ ((__packed__)); +}; enum kone_mouse_events { /* osd events are thought to be display on screen */ @@ -188,7 +191,9 @@ struct kone_roccat_report { uint8_t event; uint8_t value; /* holds dpi or profile value */ uint8_t key; /* macro key on overlong macro execution */ -} __attribute__ ((__packed__)); +}; + +#pragma pack(pop) struct kone_device { /* diff --git a/trunk/drivers/hid/hid-roccat-koneplus.c b/trunk/drivers/hid/hid-roccat-koneplus.c deleted file mode 100644 index 1608c8d1efd6..000000000000 --- a/trunk/drivers/hid/hid-roccat-koneplus.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Roccat Kone[+] driver for Linux - * - * Copyright (c) 2010 Stefan Achatz - */ - -/* - * 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. - */ - -/* - * Roccat Kone[+] is an updated/improved version of the Kone with more memory - * and functionality and without the non-standard behaviours the Kone had. - */ - -#include -#include -#include -#include -#include -#include -#include "hid-ids.h" -#include "hid-roccat.h" -#include "hid-roccat-koneplus.h" - -static uint profile_numbers[5] = {0, 1, 2, 3, 4}; - -static struct class *koneplus_class; - -static void koneplus_profile_activated(struct koneplus_device *koneplus, - uint new_profile) -{ - koneplus->actual_profile = new_profile; -} - -static int koneplus_send_control(struct usb_device *usb_dev, uint value, - enum koneplus_control_requests request) -{ - int len; - struct koneplus_control *control; - - if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || - request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && - value > 4) - return -EINVAL; - - control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); - if (!control) - return -ENOMEM; - - control->command = KONEPLUS_COMMAND_CONTROL; - control->value = value; - control->request = request; - - len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), - USB_REQ_SET_CONFIGURATION, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - KONEPLUS_USB_COMMAND_CONTROL, 0, control, - sizeof(struct koneplus_control), - USB_CTRL_SET_TIMEOUT); - - kfree(control); - - if (len != sizeof(struct koneplus_control)) - return len; - - return 0; -} - -static int koneplus_receive(struct usb_device *usb_dev, uint usb_command, - void *buf, uint size) { - int len; - - len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), - USB_REQ_CLEAR_FEATURE, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT); - - return (len != size) ? -EIO : 0; -} - -static int koneplus_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct koneplus_control *control; - - control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); - if (!control) - return -ENOMEM; - - do { - retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, - control, sizeof(struct koneplus_control)); - - /* check if we get a completely wrong answer */ - if (retval) - goto out; - - if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) { - retval = 0; - goto out; - } - - /* indicates that hardware needs some more time to complete action */ - if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { - msleep(500); /* windows driver uses 1000 */ - continue; - } - - /* seems to be critical - replug necessary */ - if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) { - retval = -EINVAL; - goto out; - } - - dev_err(&usb_dev->dev, "koneplus_receive_control_status: " - "unknown response value 0x%x\n", control->value); - retval = -EINVAL; - goto out; - - } while (1); -out: - kfree(control); - return retval; -} - -static int koneplus_send(struct usb_device *usb_dev, uint command, - void *buf, uint size) { - int len; - - len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), - USB_REQ_SET_CONFIGURATION, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - command, 0, buf, size, USB_CTRL_SET_TIMEOUT); - - if (len != size) - return -EIO; - - if (koneplus_receive_control_status(usb_dev)) - return -EIO; - - return 0; -} - -static int koneplus_select_profile(struct usb_device *usb_dev, uint number, - enum koneplus_control_requests request) -{ - int retval; - - retval = koneplus_send_control(usb_dev, number, request); - if (retval) - return retval; - - /* allow time to settle things - windows driver uses 500 */ - msleep(100); - - retval = koneplus_receive_control_status(usb_dev); - if (retval) - return retval; - - return 0; -} - -static int koneplus_get_info(struct usb_device *usb_dev, - struct koneplus_info *buf) -{ - return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO, - buf, sizeof(struct koneplus_info)); -} - -static int koneplus_get_profile_settings(struct usb_device *usb_dev, - struct koneplus_profile_settings *buf, uint number) -{ - int retval; - - retval = koneplus_select_profile(usb_dev, number, - KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); - if (retval) - return retval; - - return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, - buf, sizeof(struct koneplus_profile_settings)); -} - -static int koneplus_set_profile_settings(struct usb_device *usb_dev, - struct koneplus_profile_settings const *settings) -{ - return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, - (void *)settings, sizeof(struct koneplus_profile_settings)); -} - -static int koneplus_get_profile_buttons(struct usb_device *usb_dev, - struct koneplus_profile_buttons *buf, int number) -{ - int retval; - - retval = koneplus_select_profile(usb_dev, number, - KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); - if (retval) - return retval; - - return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, - buf, sizeof(struct koneplus_profile_buttons)); -} - -static int koneplus_set_profile_buttons(struct usb_device *usb_dev, - struct koneplus_profile_buttons const *buttons) -{ - return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, - (void *)buttons, sizeof(struct koneplus_profile_buttons)); -} - -/* retval is 0-4 on success, < 0 on error */ -static int koneplus_get_startup_profile(struct usb_device *usb_dev) -{ - struct koneplus_startup_profile *buf; - int retval; - - buf = kmalloc(sizeof(struct koneplus_startup_profile), GFP_KERNEL); - - retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, - buf, sizeof(struct koneplus_startup_profile)); - - if (retval) - goto out; - - retval = buf->startup_profile; -out: - kfree(buf); - return retval; -} - -static int koneplus_set_startup_profile(struct usb_device *usb_dev, - int startup_profile) -{ - struct koneplus_startup_profile buf; - - buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE; - buf.size = sizeof(struct koneplus_startup_profile); - buf.startup_profile = startup_profile; - - return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, - (char *)&buf, sizeof(struct koneplus_profile_buttons)); -} - -static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, - char *buf, loff_t off, size_t count, - size_t real_size, uint command) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); - int retval; - - if (off != 0 || count != real_size) - return -EINVAL; - - mutex_lock(&koneplus->koneplus_lock); - retval = koneplus_receive(usb_dev, command, buf, real_size); - mutex_unlock(&koneplus->koneplus_lock); - - if (retval) - return retval; - - return real_size; -} - -static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, - void const *buf, loff_t off, size_t count, - size_t real_size, uint command) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); - int retval; - - if (off != 0 || count != real_size) - return -EINVAL; - - mutex_lock(&koneplus->koneplus_lock); - retval = koneplus_send(usb_dev, command, (void *)buf, real_size); - mutex_unlock(&koneplus->koneplus_lock); - - if (retval) - return retval; - - return real_size; -} - -static ssize_t koneplus_sysfs_write_macro(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - return koneplus_sysfs_write(fp, kobj, buf, off, count, - sizeof(struct koneplus_macro), KONEPLUS_USB_COMMAND_MACRO); -} - -static ssize_t koneplus_sysfs_read_sensor(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - return koneplus_sysfs_read(fp, kobj, buf, off, count, - sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); -} - -static ssize_t koneplus_sysfs_write_sensor(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - return koneplus_sysfs_write(fp, kobj, buf, off, count, - sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); -} - -static ssize_t koneplus_sysfs_write_tcu(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - return koneplus_sysfs_write(fp, kobj, buf, off, count, - sizeof(struct koneplus_tcu), KONEPLUS_USB_COMMAND_TCU); -} - -static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - return koneplus_sysfs_read(fp, kobj, buf, off, count, - sizeof(struct koneplus_tcu_image), KONEPLUS_USB_COMMAND_TCU); -} - -static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - - if (off >= sizeof(struct koneplus_profile_settings)) - return 0; - - if (off + count > sizeof(struct koneplus_profile_settings)) - count = sizeof(struct koneplus_profile_settings) - off; - - mutex_lock(&koneplus->koneplus_lock); - memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, - count); - mutex_unlock(&koneplus->koneplus_lock); - - return count; -} - -static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); - int retval = 0; - int difference; - int profile_number; - struct koneplus_profile_settings *profile_settings; - - if (off != 0 || count != sizeof(struct koneplus_profile_settings)) - return -EINVAL; - - profile_number = ((struct koneplus_profile_settings const *)buf)->number; - profile_settings = &koneplus->profile_settings[profile_number]; - - mutex_lock(&koneplus->koneplus_lock); - difference = memcmp(buf, profile_settings, - sizeof(struct koneplus_profile_settings)); - if (difference) { - retval = koneplus_set_profile_settings(usb_dev, - (struct koneplus_profile_settings const *)buf); - if (!retval) - memcpy(profile_settings, buf, - sizeof(struct koneplus_profile_settings)); - } - mutex_unlock(&koneplus->koneplus_lock); - - if (retval) - return retval; - - return sizeof(struct koneplus_profile_settings); -} - -static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - - if (off >= sizeof(struct koneplus_profile_buttons)) - return 0; - - if (off + count > sizeof(struct koneplus_profile_buttons)) - count = sizeof(struct koneplus_profile_buttons) - off; - - mutex_lock(&koneplus->koneplus_lock); - memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, - count); - mutex_unlock(&koneplus->koneplus_lock); - - return count; -} - -static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, - struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) -{ - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; - struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); - int retval = 0; - int difference; - uint profile_number; - struct koneplus_profile_buttons *profile_buttons; - - if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) - return -EINVAL; - - profile_number = ((struct koneplus_profile_buttons const *)buf)->number; - profile_buttons = &koneplus->profile_buttons[profile_number]; - - mutex_lock(&koneplus->koneplus_lock); - difference = memcmp(buf, profile_buttons, - sizeof(struct koneplus_profile_buttons)); - if (difference) { - retval = koneplus_set_profile_buttons(usb_dev, - (struct koneplus_profile_buttons const *)buf); - if (!retval) - memcpy(profile_buttons, buf, - sizeof(struct koneplus_profile_buttons)); - } - mutex_unlock(&koneplus->koneplus_lock); - - if (retval) - return retval; - - return sizeof(struct koneplus_profile_buttons); -} - -static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct koneplus_device *koneplus = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile); -} - -static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, - struct device_attribute *attr, char const *buf, size_t size) -{ - struct koneplus_device *koneplus; - struct usb_device *usb_dev; - unsigned long profile; - int retval; - - dev = dev->parent->parent; - koneplus = hid_get_drvdata(dev_get_drvdata(dev)); - usb_dev = interface_to_usbdev(to_usb_interface(dev)); - - retval = strict_strtoul(buf, 10, &profile); - if (retval) - return retval; - - mutex_lock(&koneplus->koneplus_lock); - retval = koneplus_set_startup_profile(usb_dev, profile); - mutex_unlock(&koneplus->koneplus_lock); - if (retval) - return retval; - - return size; -} - -static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct koneplus_device *koneplus = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); -} - -static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct koneplus_device *koneplus = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); -} - -static struct device_attribute koneplus_attributes[] = { - __ATTR(startup_profile, 0660, - koneplus_sysfs_show_startup_profile, - koneplus_sysfs_set_startup_profile), - __ATTR(actual_profile, 0440, - koneplus_sysfs_show_actual_profile, NULL), - __ATTR(firmware_version, 0440, - koneplus_sysfs_show_firmware_version, NULL), - __ATTR_NULL -}; - -static struct bin_attribute koneplus_bin_attributes[] = { - { - .attr = { .name = "sensor", .mode = 0220 }, - .size = sizeof(struct koneplus_sensor), - .read = koneplus_sysfs_read_sensor, - .write = koneplus_sysfs_write_sensor - }, - { - .attr = { .name = "tcu", .mode = 0220 }, - .size = sizeof(struct koneplus_tcu), - .write = koneplus_sysfs_write_tcu - }, - { - .attr = { .name = "tcu_image", .mode = 0440 }, - .size = sizeof(struct koneplus_tcu_image), - .read = koneplus_sysfs_read_tcu_image - }, - { - .attr = { .name = "profile_settings", .mode = 0220 }, - .size = sizeof(struct koneplus_profile_settings), - .write = koneplus_sysfs_write_profile_settings - }, - { - .attr = { .name = "profile1_settings", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_settings), - .read = koneplus_sysfs_read_profilex_settings, - .private = &profile_numbers[0] - }, - { - .attr = { .name = "profile2_settings", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_settings), - .read = koneplus_sysfs_read_profilex_settings, - .private = &profile_numbers[1] - }, - { - .attr = { .name = "profile3_settings", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_settings), - .read = koneplus_sysfs_read_profilex_settings, - .private = &profile_numbers[2] - }, - { - .attr = { .name = "profile4_settings", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_settings), - .read = koneplus_sysfs_read_profilex_settings, - .private = &profile_numbers[3] - }, - { - .attr = { .name = "profile5_settings", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_settings), - .read = koneplus_sysfs_read_profilex_settings, - .private = &profile_numbers[4] - }, - { - .attr = { .name = "profile_buttons", .mode = 0220 }, - .size = sizeof(struct koneplus_profile_buttons), - .write = koneplus_sysfs_write_profile_buttons - }, - { - .attr = { .name = "profile1_buttons", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_buttons), - .read = koneplus_sysfs_read_profilex_buttons, - .private = &profile_numbers[0] - }, - { - .attr = { .name = "profile2_buttons", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_buttons), - .read = koneplus_sysfs_read_profilex_buttons, - .private = &profile_numbers[1] - }, - { - .attr = { .name = "profile3_buttons", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_buttons), - .read = koneplus_sysfs_read_profilex_buttons, - .private = &profile_numbers[2] - }, - { - .attr = { .name = "profile4_buttons", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_buttons), - .read = koneplus_sysfs_read_profilex_buttons, - .private = &profile_numbers[3] - }, - { - .attr = { .name = "profile5_buttons", .mode = 0440 }, - .size = sizeof(struct koneplus_profile_buttons), - .read = koneplus_sysfs_read_profilex_buttons, - .private = &profile_numbers[4] - }, - { - .attr = { .name = "macro", .mode = 0220 }, - .size = sizeof(struct koneplus_macro), - .write = koneplus_sysfs_write_macro - }, - __ATTR_NULL -}; - -static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, - struct koneplus_device *koneplus) -{ - int retval, i; - static uint wait = 70; /* device will freeze with just 60 */ - - mutex_init(&koneplus->koneplus_lock); - - koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); - - msleep(wait); - retval = koneplus_get_info(usb_dev, &koneplus->info); - if (retval) - return retval; - - for (i = 0; i < 5; ++i) { - msleep(wait); - retval = koneplus_get_profile_settings(usb_dev, - &koneplus->profile_settings[i], i); - if (retval) - return retval; - - msleep(wait); - retval = koneplus_get_profile_buttons(usb_dev, - &koneplus->profile_buttons[i], i); - if (retval) - return retval; - } - - koneplus_profile_activated(koneplus, koneplus->startup_profile); - - return 0; -} - -static int koneplus_init_specials(struct hid_device *hdev) -{ - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *usb_dev = interface_to_usbdev(intf); - struct koneplus_device *koneplus; - int retval; - - if (intf->cur_altsetting->desc.bInterfaceProtocol - == USB_INTERFACE_PROTOCOL_MOUSE) { - - koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); - if (!koneplus) { - dev_err(&hdev->dev, "can't alloc device descriptor\n"); - return -ENOMEM; - } - hid_set_drvdata(hdev, koneplus); - - retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus); - if (retval) { - dev_err(&hdev->dev, - "couldn't init struct koneplus_device\n"); - goto exit_free; - } - - retval = roccat_connect(koneplus_class, hdev); - if (retval < 0) { - dev_err(&hdev->dev, "couldn't init char dev\n"); - } else { - koneplus->chrdev_minor = retval; - koneplus->roccat_claimed = 1; - } - } else { - hid_set_drvdata(hdev, NULL); - } - - return 0; -exit_free: - kfree(koneplus); - return retval; -} - -static void koneplus_remove_specials(struct hid_device *hdev) -{ - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct koneplus_device *koneplus; - - if (intf->cur_altsetting->desc.bInterfaceProtocol - == USB_INTERFACE_PROTOCOL_MOUSE) { - koneplus = hid_get_drvdata(hdev); - if (koneplus->roccat_claimed) - roccat_disconnect(koneplus->chrdev_minor); - kfree(koneplus); - } -} - -static int koneplus_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int retval; - - retval = hid_parse(hdev); - if (retval) { - dev_err(&hdev->dev, "parse failed\n"); - goto exit; - } - - retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (retval) { - dev_err(&hdev->dev, "hw start failed\n"); - goto exit; - } - - retval = koneplus_init_specials(hdev); - if (retval) { - dev_err(&hdev->dev, "couldn't install mouse\n"); - goto exit_stop; - } - - return 0; - -exit_stop: - hid_hw_stop(hdev); -exit: - return retval; -} - -static void koneplus_remove(struct hid_device *hdev) -{ - koneplus_remove_specials(hdev); - hid_hw_stop(hdev); -} - -static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus, - u8 const *data) -{ - struct koneplus_mouse_report_button const *button_report; - - switch (data[0]) { - case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON: - button_report = (struct koneplus_mouse_report_button const *)data; - switch (button_report->type) { - case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE: - koneplus_profile_activated(koneplus, button_report->data1 - 1); - break; - } - break; - } -} - -static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus, - u8 const *data) -{ - struct koneplus_roccat_report roccat_report; - struct koneplus_mouse_report_button const *button_report; - - if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON) - return; - - button_report = (struct koneplus_mouse_report_button const *)data; - - if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH || - button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) && - button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS) - return; - - roccat_report.type = button_report->type; - roccat_report.data1 = button_report->data1; - roccat_report.data2 = button_report->data2; - roccat_report.profile = koneplus->actual_profile + 1; - roccat_report_event(koneplus->chrdev_minor, - (uint8_t const *)&roccat_report, - sizeof(struct koneplus_roccat_report)); -} - -static int koneplus_raw_event(struct hid_device *hdev, - struct hid_report *report, u8 *data, int size) -{ - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct koneplus_device *koneplus = hid_get_drvdata(hdev); - - if (intf->cur_altsetting->desc.bInterfaceProtocol - != USB_INTERFACE_PROTOCOL_MOUSE) - return 0; - - koneplus_keep_values_up_to_date(koneplus, data); - - if (koneplus->roccat_claimed) - koneplus_report_to_chrdev(koneplus, data); - - return 0; -} - -static const struct hid_device_id koneplus_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, - { } -}; - -MODULE_DEVICE_TABLE(hid, koneplus_devices); - -static struct hid_driver koneplus_driver = { - .name = "koneplus", - .id_table = koneplus_devices, - .probe = koneplus_probe, - .remove = koneplus_remove, - .raw_event = koneplus_raw_event -}; - -static int __init koneplus_init(void) -{ - int retval; - - /* class name has to be same as driver name */ - koneplus_class = class_create(THIS_MODULE, "koneplus"); - if (IS_ERR(koneplus_class)) - return PTR_ERR(koneplus_class); - koneplus_class->dev_attrs = koneplus_attributes; - koneplus_class->dev_bin_attrs = koneplus_bin_attributes; - - retval = hid_register_driver(&koneplus_driver); - if (retval) - class_destroy(koneplus_class); - return retval; -} - -static void __exit koneplus_exit(void) -{ - class_destroy(koneplus_class); - hid_unregister_driver(&koneplus_driver); -} - -module_init(koneplus_init); -module_exit(koneplus_exit); - -MODULE_AUTHOR("Stefan Achatz"); -MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hid/hid-roccat-koneplus.h b/trunk/drivers/hid/hid-roccat-koneplus.h deleted file mode 100644 index 57a5c1ab7b05..000000000000 --- a/trunk/drivers/hid/hid-roccat-koneplus.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef __HID_ROCCAT_KONEPLUS_H -#define __HID_ROCCAT_KONEPLUS_H - -/* - * Copyright (c) 2010 Stefan Achatz - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include - -/* - * case 1: writes request 80 and reads value 1 - * - */ -struct koneplus_control { - uint8_t command; /* KONEPLUS_COMMAND_CONTROL */ - /* - * value is profile number in range 0-4 for requesting settings and buttons - * 1 if status ok for requesting status - */ - uint8_t value; - uint8_t request; -} __attribute__ ((__packed__)); - -enum koneplus_control_requests { - KONEPLUS_CONTROL_REQUEST_STATUS = 0x00, - KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, - KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, -}; - -enum koneplus_control_values { - KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, - KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1, - KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, -}; - -struct koneplus_startup_profile { - uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */ - uint8_t size; /* always 3 */ - uint8_t startup_profile; /* Range 0-4! */ -} __attribute__ ((__packed__)); - -struct koneplus_profile_settings { - uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */ - uint8_t size; /* always 43 */ - uint8_t number; /* range 0-4 */ - uint8_t advanced_sensitivity; - uint8_t sensitivity_x; - uint8_t sensitivity_y; - uint8_t cpi_levels_enabled; - uint8_t cpi_levels_x[5]; - uint8_t cpi_startup_level; /* range 0-4 */ - uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */ - uint8_t unknown1; - uint8_t polling_rate; - uint8_t lights_enabled; - uint8_t light_effect_mode; - uint8_t color_flow_effect; - uint8_t light_effect_type; - uint8_t light_effect_speed; - uint8_t lights[16]; - uint16_t checksum; -} __attribute__ ((__packed__)); - -struct koneplus_profile_buttons { - uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */ - uint8_t size; /* always 77 */ - uint8_t number; /* range 0-4 */ - uint8_t data[72]; - uint16_t checksum; -} __attribute__ ((__packed__)); - -struct koneplus_macro { - uint8_t command; /* KONEPLUS_COMMAND_MACRO */ - uint16_t size; /* always 0x822 little endian */ - uint8_t profile; /* range 0-4 */ - uint8_t button; /* range 0-23 */ - uint8_t data[2075]; - uint16_t checksum; -} __attribute__ ((__packed__)); - -struct koneplus_info { - uint8_t command; /* KONEPLUS_COMMAND_INFO */ - uint8_t size; /* always 6 */ - uint8_t firmware_version; - uint8_t unknown[3]; -} __attribute__ ((__packed__)); - -struct koneplus_e { - uint8_t command; /* KONEPLUS_COMMAND_E */ - uint8_t size; /* always 3 */ - uint8_t unknown; /* TODO 1; 0 before firmware update */ -} __attribute__ ((__packed__)); - -struct koneplus_sensor { - uint8_t command; /* KONEPLUS_COMMAND_SENSOR */ - uint8_t size; /* always 6 */ - uint8_t data[4]; -} __attribute__ ((__packed__)); - -struct koneplus_firmware_write { - uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */ - uint8_t unknown[1025]; -} __attribute__ ((__packed__)); - -struct koneplus_firmware_write_control { - uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */ - /* - * value is 1 on success - * 3 means "not finished yet" - */ - uint8_t value; - uint8_t unknown; /* always 0x75 */ -} __attribute__ ((__packed__)); - -struct koneplus_tcu { - uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ - uint8_t data[2]; -} __attribute__ ((__packed__)); - -struct koneplus_tcu_image { - uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ - uint8_t data[1024]; - uint16_t checksum; -} __attribute__ ((__packed__)); - -enum koneplus_commands { - KONEPLUS_COMMAND_CONTROL = 0x4, - KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5, - KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, - KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, - KONEPLUS_COMMAND_MACRO = 0x8, - KONEPLUS_COMMAND_INFO = 0x9, - KONEPLUS_COMMAND_E = 0xe, - KONEPLUS_COMMAND_SENSOR = 0xf, - KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b, - KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, -}; - -enum koneplus_usb_commands { - KONEPLUS_USB_COMMAND_CONTROL = 0x304, - KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305, - KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306, - KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307, - KONEPLUS_USB_COMMAND_MACRO = 0x308, - KONEPLUS_USB_COMMAND_INFO = 0x309, - KONEPLUS_USB_COMMAND_TCU = 0x30c, - KONEPLUS_USB_COMMAND_E = 0x30e, - KONEPLUS_USB_COMMAND_SENSOR = 0x30f, - KONEPLUS_USB_COMMAND_FIRMWARE_WRITE = 0x31b, - KONEPLUS_USB_COMMAND_FIRMWARE_WRITE_CONTROL = 0x31c, -}; - -enum koneplus_mouse_report_numbers { - KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1, - KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2, - KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3, -}; - -struct koneplus_mouse_report_button { - uint8_t report_number; /* always KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON */ - uint8_t zero1; - uint8_t type; - uint8_t data1; - uint8_t data2; - uint8_t zero2; - uint8_t unknown[2]; -} __attribute__ ((__packed__)); - -enum koneplus_mouse_report_button_types { - /* data1 = new profile range 1-5 */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20, - - /* data1 = button number range 1-24; data2 = action */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60, - - /* data1 = button number range 1-24; data2 = action */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80, - - /* data1 = setting number range 1-5 */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0, - - /* data1 and data2 = range 0x1-0xb */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0, - - /* data1 = 22 = next track... - * data2 = action - */ - KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0, -}; - -enum koneplus_mouse_report_button_action { - KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0, - KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1, -}; - -struct koneplus_roccat_report { - uint8_t type; - uint8_t data1; - uint8_t data2; - uint8_t profile; -} __attribute__ ((__packed__)); - -struct koneplus_device { - int actual_profile; - - int roccat_claimed; - int chrdev_minor; - - struct mutex koneplus_lock; - - int startup_profile; - struct koneplus_info info; - struct koneplus_profile_settings profile_settings[5]; - struct koneplus_profile_buttons profile_buttons[5]; -}; - -#endif diff --git a/trunk/drivers/hid/hid-roccat-pyra.c b/trunk/drivers/hid/hid-roccat-pyra.c index 02c58e015bee..9bf23047892a 100644 --- a/trunk/drivers/hid/hid-roccat-pyra.c +++ b/trunk/drivers/hid/hid-roccat-pyra.c @@ -27,11 +27,6 @@ #include "hid-roccat.h" #include "hid-roccat-pyra.h" -static uint profile_numbers[5] = {0, 1, 2, 3, 4}; - -/* pyra_class is used for creating sysfs attributes via roccat char device */ -static struct class *pyra_class; - static void profile_activated(struct pyra_device *pyra, unsigned int new_profile) { @@ -92,8 +87,9 @@ static int pyra_receive_control_status(struct usb_device *usb_dev) control.value == 1) return 0; else { - hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", - control.request, control.value); + dev_err(&usb_dev->dev, "receive control status: " + "unknown response 0x%x 0x%x\n", + control.request, control.value); return -EINVAL; } } @@ -225,10 +221,9 @@ static int pyra_set_settings(struct usb_device *usb_dev, static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, - loff_t off, size_t count) + loff_t off, size_t count, int number) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_profile_settings)) @@ -238,19 +233,58 @@ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, count = sizeof(struct pyra_profile_settings) - off; mutex_lock(&pyra->pyra_lock); - memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, + memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off, count); mutex_unlock(&pyra->pyra_lock); return count; } -static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, +static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_settings(fp, kobj, + attr, buf, off, count, 0); +} + +static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_settings(fp, kobj, + attr, buf, off, count, 1); +} + +static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_settings(fp, kobj, + attr, buf, off, count, 2); +} + +static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + return pyra_sysfs_read_profilex_settings(fp, kobj, + attr, buf, off, count, 3); +} + +static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_settings(fp, kobj, + attr, buf, off, count, 4); +} + +static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count, int number) +{ + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_profile_buttons)) @@ -260,19 +294,58 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, count = sizeof(struct pyra_profile_buttons) - off; mutex_lock(&pyra->pyra_lock); - memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, + memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off, count); mutex_unlock(&pyra->pyra_lock); return count; } +static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_buttons(fp, kobj, + attr, buf, off, count, 0); +} + +static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_buttons(fp, kobj, + attr, buf, off, count, 1); +} + +static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_buttons(fp, kobj, + attr, buf, off, count, 2); +} + +static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_buttons(fp, kobj, + attr, buf, off, count, 3); +} + +static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp, + struct kobject *kobj, struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + return pyra_sysfs_read_profilex_buttons(fp, kobj, + attr, buf, off, count, 4); +} + static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; @@ -308,8 +381,7 @@ static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; @@ -345,8 +417,7 @@ static ssize_t pyra_sysfs_read_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_settings)) @@ -366,8 +437,7 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *dev = - container_of(kobj, struct device, kobj)->parent->parent; + struct device *dev = container_of(kobj, struct device, kobj); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; @@ -399,125 +469,255 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, struct device_attribute *attr, char *buf) { - struct pyra_device *pyra = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); } static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, struct device_attribute *attr, char *buf) { - struct pyra_device *pyra = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); } static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, struct device_attribute *attr, char *buf) { - struct pyra_device *pyra = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); } static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, struct device_attribute *attr, char *buf) { - struct pyra_device *pyra = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); + struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); } -static struct device_attribute pyra_attributes[] = { - __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL), - __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL), - __ATTR(firmware_version, 0440, - pyra_sysfs_show_firmware_version, NULL), - __ATTR(startup_profile, 0440, - pyra_sysfs_show_startup_profile, NULL), - __ATTR_NULL +static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL); + +static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL); + +static DEVICE_ATTR(firmware_version, 0440, + pyra_sysfs_show_firmware_version, NULL); + +static DEVICE_ATTR(startup_profile, 0440, + pyra_sysfs_show_startup_profile, NULL); + +static struct attribute *pyra_attributes[] = { + &dev_attr_actual_cpi.attr, + &dev_attr_actual_profile.attr, + &dev_attr_firmware_version.attr, + &dev_attr_startup_profile.attr, + NULL +}; + +static struct attribute_group pyra_attribute_group = { + .attrs = pyra_attributes }; -static struct bin_attribute pyra_bin_attributes[] = { - { +static struct bin_attribute pyra_profile_settings_attr = { .attr = { .name = "profile_settings", .mode = 0220 }, .size = sizeof(struct pyra_profile_settings), .write = pyra_sysfs_write_profile_settings - }, - { +}; + +static struct bin_attribute pyra_profile1_settings_attr = { .attr = { .name = "profile1_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), - .read = pyra_sysfs_read_profilex_settings, - .private = &profile_numbers[0] - }, - { + .read = pyra_sysfs_read_profile1_settings +}; + +static struct bin_attribute pyra_profile2_settings_attr = { .attr = { .name = "profile2_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), - .read = pyra_sysfs_read_profilex_settings, - .private = &profile_numbers[1] - }, - { + .read = pyra_sysfs_read_profile2_settings +}; + +static struct bin_attribute pyra_profile3_settings_attr = { .attr = { .name = "profile3_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), - .read = pyra_sysfs_read_profilex_settings, - .private = &profile_numbers[2] - }, - { + .read = pyra_sysfs_read_profile3_settings +}; + +static struct bin_attribute pyra_profile4_settings_attr = { .attr = { .name = "profile4_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), - .read = pyra_sysfs_read_profilex_settings, - .private = &profile_numbers[3] - }, - { + .read = pyra_sysfs_read_profile4_settings +}; + +static struct bin_attribute pyra_profile5_settings_attr = { .attr = { .name = "profile5_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), - .read = pyra_sysfs_read_profilex_settings, - .private = &profile_numbers[4] - }, - { + .read = pyra_sysfs_read_profile5_settings +}; + +static struct bin_attribute pyra_profile_buttons_attr = { .attr = { .name = "profile_buttons", .mode = 0220 }, .size = sizeof(struct pyra_profile_buttons), .write = pyra_sysfs_write_profile_buttons - }, - { +}; + +static struct bin_attribute pyra_profile1_buttons_attr = { .attr = { .name = "profile1_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), - .read = pyra_sysfs_read_profilex_buttons, - .private = &profile_numbers[0] - }, - { + .read = pyra_sysfs_read_profile1_buttons +}; + +static struct bin_attribute pyra_profile2_buttons_attr = { .attr = { .name = "profile2_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), - .read = pyra_sysfs_read_profilex_buttons, - .private = &profile_numbers[1] - }, - { + .read = pyra_sysfs_read_profile2_buttons +}; + +static struct bin_attribute pyra_profile3_buttons_attr = { .attr = { .name = "profile3_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), - .read = pyra_sysfs_read_profilex_buttons, - .private = &profile_numbers[2] - }, - { + .read = pyra_sysfs_read_profile3_buttons +}; + +static struct bin_attribute pyra_profile4_buttons_attr = { .attr = { .name = "profile4_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), - .read = pyra_sysfs_read_profilex_buttons, - .private = &profile_numbers[3] - }, - { + .read = pyra_sysfs_read_profile4_buttons +}; + +static struct bin_attribute pyra_profile5_buttons_attr = { .attr = { .name = "profile5_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), - .read = pyra_sysfs_read_profilex_buttons, - .private = &profile_numbers[4] - }, - { + .read = pyra_sysfs_read_profile5_buttons +}; + +static struct bin_attribute pyra_settings_attr = { .attr = { .name = "settings", .mode = 0660 }, .size = sizeof(struct pyra_settings), .read = pyra_sysfs_read_settings, .write = pyra_sysfs_write_settings - }, - __ATTR_NULL }; +static int pyra_create_sysfs_attributes(struct usb_interface *intf) +{ + int retval; + + retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group); + if (retval) + goto exit_1; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile_settings_attr); + if (retval) + goto exit_2; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile1_settings_attr); + if (retval) + goto exit_3; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile2_settings_attr); + if (retval) + goto exit_4; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile3_settings_attr); + if (retval) + goto exit_5; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile4_settings_attr); + if (retval) + goto exit_6; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile5_settings_attr); + if (retval) + goto exit_7; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile_buttons_attr); + if (retval) + goto exit_8; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile1_buttons_attr); + if (retval) + goto exit_9; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile2_buttons_attr); + if (retval) + goto exit_10; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile3_buttons_attr); + if (retval) + goto exit_11; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile4_buttons_attr); + if (retval) + goto exit_12; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_profile5_buttons_attr); + if (retval) + goto exit_13; + + retval = sysfs_create_bin_file(&intf->dev.kobj, + &pyra_settings_attr); + if (retval) + goto exit_14; + + return 0; + +exit_14: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr); +exit_13: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr); +exit_12: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr); +exit_11: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr); +exit_10: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr); +exit_9: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr); +exit_8: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr); +exit_7: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr); +exit_6: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr); +exit_5: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr); +exit_4: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr); +exit_3: + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr); +exit_2: + sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group); +exit_1: + return retval; +} + +static void pyra_remove_sysfs_attributes(struct usb_interface *intf) +{ + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr); + sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr); + sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group); +} + static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, struct pyra_device *pyra) { @@ -570,24 +770,31 @@ static int pyra_init_specials(struct hid_device *hdev) pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); if (!pyra) { - hid_err(hdev, "can't alloc device descriptor\n"); + dev_err(&hdev->dev, "can't alloc device descriptor\n"); return -ENOMEM; } hid_set_drvdata(hdev, pyra); retval = pyra_init_pyra_device_struct(usb_dev, pyra); if (retval) { - hid_err(hdev, "couldn't init struct pyra_device\n"); + dev_err(&hdev->dev, + "couldn't init struct pyra_device\n"); goto exit_free; } - retval = roccat_connect(pyra_class, hdev); + retval = roccat_connect(hdev); if (retval < 0) { - hid_err(hdev, "couldn't init char dev\n"); + dev_err(&hdev->dev, "couldn't init char dev\n"); } else { pyra->chrdev_minor = retval; pyra->roccat_claimed = 1; } + + retval = pyra_create_sysfs_attributes(intf); + if (retval) { + dev_err(&hdev->dev, "cannot create sysfs files\n"); + goto exit_free; + } } else { hid_set_drvdata(hdev, NULL); } @@ -605,6 +812,7 @@ static void pyra_remove_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { + pyra_remove_sysfs_attributes(intf); pyra = hid_get_drvdata(hdev); if (pyra->roccat_claimed) roccat_disconnect(pyra->chrdev_minor); @@ -618,19 +826,19 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) retval = hid_parse(hdev); if (retval) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto exit; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto exit; } retval = pyra_init_specials(hdev); if (retval) { - hid_err(hdev, "couldn't install mouse\n"); + dev_err(&hdev->dev, "couldn't install mouse\n"); goto exit_stop; } return 0; @@ -744,24 +952,11 @@ static struct hid_driver pyra_driver = { static int __init pyra_init(void) { - int retval; - - /* class name has to be same as driver name */ - pyra_class = class_create(THIS_MODULE, "pyra"); - if (IS_ERR(pyra_class)) - return PTR_ERR(pyra_class); - pyra_class->dev_attrs = pyra_attributes; - pyra_class->dev_bin_attrs = pyra_bin_attributes; - - retval = hid_register_driver(&pyra_driver); - if (retval) - class_destroy(pyra_class); - return retval; + return hid_register_driver(&pyra_driver); } static void __exit pyra_exit(void) { - class_destroy(pyra_class); hid_unregister_driver(&pyra_driver); } diff --git a/trunk/drivers/hid/hid-roccat-pyra.h b/trunk/drivers/hid/hid-roccat-pyra.h index 14cbbe1621e0..22f80a8f26f9 100644 --- a/trunk/drivers/hid/hid-roccat-pyra.h +++ b/trunk/drivers/hid/hid-roccat-pyra.h @@ -14,11 +14,14 @@ #include +#pragma pack(push) +#pragma pack(1) + struct pyra_b { uint8_t command; /* PYRA_COMMAND_B */ uint8_t size; /* always 3 */ uint8_t unknown; /* 1 */ -} __attribute__ ((__packed__)); +}; struct pyra_control { uint8_t command; /* PYRA_COMMAND_CONTROL */ @@ -28,7 +31,7 @@ struct pyra_control { */ uint8_t value; /* Range 0-4 */ uint8_t request; -} __attribute__ ((__packed__)); +}; enum pyra_control_requests { PYRA_CONTROL_REQUEST_STATUS = 0x00, @@ -40,7 +43,7 @@ struct pyra_settings { uint8_t command; /* PYRA_COMMAND_SETTINGS */ uint8_t size; /* always 3 */ uint8_t startup_profile; /* Range 0-4! */ -} __attribute__ ((__packed__)); +}; struct pyra_profile_settings { uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */ @@ -55,7 +58,7 @@ struct pyra_profile_settings { uint8_t light_effect; uint8_t handedness; uint16_t checksum; /* byte sum */ -} __attribute__ ((__packed__)); +}; struct pyra_profile_buttons { uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */ @@ -63,7 +66,7 @@ struct pyra_profile_buttons { uint8_t number; /* Range 0-4 */ uint8_t buttons[14]; uint16_t checksum; /* byte sum */ -} __attribute__ ((__packed__)); +}; struct pyra_info { uint8_t command; /* PYRA_COMMAND_INFO */ @@ -72,7 +75,7 @@ struct pyra_info { uint8_t unknown1; /* always 0 */ uint8_t unknown2; /* always 1 */ uint8_t unknown3; /* always 0 */ -} __attribute__ ((__packed__)); +}; enum pyra_commands { PYRA_COMMAND_CONTROL = 0x4, @@ -104,13 +107,13 @@ struct pyra_mouse_event_button { uint8_t type; uint8_t data1; uint8_t data2; -} __attribute__ ((__packed__)); +}; struct pyra_mouse_event_audio { uint8_t report_number; /* always 2 */ uint8_t type; uint8_t unused; /* always 0 */ -} __attribute__ ((__packed__)); +}; /* hid audio controls */ enum pyra_mouse_event_audio_types { @@ -164,7 +167,9 @@ struct pyra_roccat_report { uint8_t type; uint8_t value; uint8_t key; -} __attribute__ ((__packed__)); +}; + +#pragma pack(pop) struct pyra_device { int actual_profile; diff --git a/trunk/drivers/hid/hid-roccat.c b/trunk/drivers/hid/hid-roccat.c index a14c579ea781..5a6879e235ac 100644 --- a/trunk/drivers/hid/hid-roccat.c +++ b/trunk/drivers/hid/hid-roccat.c @@ -21,8 +21,6 @@ * It is inspired by hidraw, but uses only one circular buffer for all readers. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -67,6 +65,7 @@ struct roccat_reader { }; static int roccat_major; +static struct class *roccat_class; static struct cdev roccat_cdev; static struct roccat_device *devices[ROCCAT_MAX_DEVICES]; @@ -166,22 +165,27 @@ static int roccat_open(struct inode *inode, struct file *file) mutex_lock(&device->readers_lock); if (!device) { - pr_emerg("roccat device with minor %d doesn't exist\n", minor); + printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", + minor); error = -ENODEV; goto exit_err; } if (!device->open++) { /* power on device on adding first reader */ - error = hid_hw_power(device->hid, PM_HINT_FULLON); - if (error < 0) { - --device->open; - goto exit_err; + if (device->hid->ll_driver->power) { + error = device->hid->ll_driver->power(device->hid, + PM_HINT_FULLON); + if (error < 0) { + --device->open; + goto exit_err; + } } - - error = hid_hw_open(device->hid); + error = device->hid->ll_driver->open(device->hid); if (error < 0) { - hid_hw_power(device->hid, PM_HINT_NORMAL); + if (device->hid->ll_driver->power) + device->hid->ll_driver->power(device->hid, + PM_HINT_NORMAL); --device->open; goto exit_err; } @@ -214,7 +218,8 @@ static int roccat_release(struct inode *inode, struct file *file) device = devices[minor]; if (!device) { mutex_unlock(&devices_lock); - pr_emerg("roccat device with minor %d doesn't exist\n", minor); + printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", + minor); return -ENODEV; } @@ -226,8 +231,10 @@ static int roccat_release(struct inode *inode, struct file *file) if (!--device->open) { /* removing last reader */ if (device->exist) { - hid_hw_power(device->hid, PM_HINT_NORMAL); - hid_hw_close(device->hid); + if (device->hid->ll_driver->power) + device->hid->ll_driver->power(device->hid, + PM_HINT_NORMAL); + device->hid->ll_driver->close(device->hid); } else { kfree(device); } @@ -288,14 +295,12 @@ EXPORT_SYMBOL_GPL(roccat_report_event); /* * roccat_connect() - create a char device for special event output - * @class: the class thats used to create the device. Meant to hold device - * specific sysfs attributes. * @hid: the hid device the char device should be connected to. * * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on * success, a negative error code on failure. */ -int roccat_connect(struct class *klass, struct hid_device *hid) +int roccat_connect(struct hid_device *hid) { unsigned int minor; struct roccat_device *device; @@ -321,7 +326,7 @@ int roccat_connect(struct class *klass, struct hid_device *hid) return -EINVAL; } - device->dev = device_create(klass, &hid->dev, + device->dev = device_create(roccat_class, &hid->dev, MKDEV(roccat_major, minor), NULL, "%s%s%d", "roccat", hid->driver->name, minor); @@ -362,10 +367,10 @@ void roccat_disconnect(int minor) device->exist = 0; /* TODO exist maybe not needed */ - device_destroy(device->dev->class, MKDEV(roccat_major, minor)); + device_destroy(roccat_class, MKDEV(roccat_major, minor)); if (device->open) { - hid_hw_close(device->hid); + device->hid->ll_driver->close(device->hid); wake_up_interruptible(&device->wait); } else { kfree(device); @@ -393,7 +398,14 @@ static int __init roccat_init(void) roccat_major = MAJOR(dev_id); if (retval < 0) { - pr_warn("can't get major number\n"); + printk(KERN_WARNING "roccat: can't get major number\n"); + return retval; + } + + roccat_class = class_create(THIS_MODULE, "roccat"); + if (IS_ERR(roccat_class)) { + retval = PTR_ERR(roccat_class); + unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); return retval; } @@ -408,6 +420,7 @@ static void __exit roccat_exit(void) dev_t dev_id = MKDEV(roccat_major, 0); cdev_del(&roccat_cdev); + class_destroy(roccat_class); unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); } diff --git a/trunk/drivers/hid/hid-roccat.h b/trunk/drivers/hid/hid-roccat.h index 5784281d613f..09e864e9f79d 100644 --- a/trunk/drivers/hid/hid-roccat.h +++ b/trunk/drivers/hid/hid-roccat.h @@ -16,12 +16,11 @@ #include #if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE) -int roccat_connect(struct class *klass, struct hid_device *hid); +int roccat_connect(struct hid_device *hid); void roccat_disconnect(int minor); int roccat_report_event(int minor, u8 const *data, int len); #else -static inline int roccat_connect(struct class *klass, - struct hid_device *hid) { return -1; } +static inline int roccat_connect(struct hid_device *hid) { return -1; } static inline void roccat_disconnect(int minor) {} static inline int roccat_report_event(int minor, u8 const *data, int len) { diff --git a/trunk/drivers/hid/hid-samsung.c b/trunk/drivers/hid/hid-samsung.c index 3c1fd8af5e0c..35894444e000 100644 --- a/trunk/drivers/hid/hid-samsung.c +++ b/trunk/drivers/hid/hid-samsung.c @@ -57,8 +57,8 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev, unsigned int rsize) { - hid_info(hdev, "fixing up Samsung IrDA %d byte report descriptor\n", - rsize); + dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " + "descriptor\n", rsize); } static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -160,7 +160,7 @@ static int samsung_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } @@ -174,7 +174,7 @@ static int samsung_probe(struct hid_device *hdev, ret = hid_hw_start(hdev, cmask); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-sjoy.c b/trunk/drivers/hid/hid-sjoy.c index 16f7cafc9695..e10a7687ebf2 100644 --- a/trunk/drivers/hid/hid-sjoy.c +++ b/trunk/drivers/hid/hid-sjoy.c @@ -74,25 +74,26 @@ static int sjoyff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output reports found\n"); + dev_err(&hid->dev, "no output reports found\n"); return -ENODEV; } report_ptr = report_ptr->next; if (report_ptr == report_list) { - hid_err(hid, "required output report is missing\n"); + dev_err(&hid->dev, "required output report is " + "missing\n"); return -ENODEV; } report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); + dev_err(&hid->dev, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 3) { - hid_err(hid, "not enough values in the field\n"); + dev_err(&hid->dev, "not enough values in the field\n"); return -ENODEV; } @@ -116,7 +117,8 @@ static int sjoyff_init(struct hid_device *hid) sjoyff->report->field[0]->value[2] = 0x00; usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); - hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); + dev_info(&hid->dev, + "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); return 0; } @@ -133,13 +135,13 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-sony.c b/trunk/drivers/hid/hid-sony.c index 68d7b36e31e4..677bb3da10e8 100644 --- a/trunk/drivers/hid/hid-sony.c +++ b/trunk/drivers/hid/hid-sony.c @@ -40,7 +40,8 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { - hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); + dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " + "descriptor\n"); rdesc[55] = 0x06; } return rdesc; @@ -88,7 +89,7 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) (3 << 8) | 0xf2, ifnum, buf, 17, USB_CTRL_GET_TIMEOUT); if (ret < 0) - hid_err(hdev, "can't set operational mode\n"); + dev_err(&hdev->dev, "can't set operational mode\n"); kfree(buf); @@ -109,7 +110,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) sc = kzalloc(sizeof(*sc), GFP_KERNEL); if (sc == NULL) { - hid_err(hdev, "can't alloc sony descriptor\n"); + dev_err(&hdev->dev, "can't alloc sony descriptor\n"); return -ENOMEM; } @@ -118,14 +119,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hid-stantum.c b/trunk/drivers/hid/hid-stantum.c index b2be1d11916b..3171be28c3d5 100644 --- a/trunk/drivers/hid/hid-stantum.c +++ b/trunk/drivers/hid/hid-stantum.c @@ -222,7 +222,7 @@ static int stantum_probe(struct hid_device *hdev, sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); if (!sd) { - hid_err(hdev, "cannot allocate Stantum data\n"); + dev_err(&hdev->dev, "cannot allocate Stantum data\n"); return -ENOMEM; } sd->valid = false; diff --git a/trunk/drivers/hid/hid-sunplus.c b/trunk/drivers/hid/hid-sunplus.c index d484a0043dd4..164ed568f6cf 100644 --- a/trunk/drivers/hid/hid-sunplus.c +++ b/trunk/drivers/hid/hid-sunplus.c @@ -27,7 +27,8 @@ static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, { if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && rdesc[106] == 0x03) { - hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); + dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " + "report descriptor\n"); rdesc[105] = rdesc[110] = 0x03; rdesc[106] = rdesc[111] = 0x21; } diff --git a/trunk/drivers/hid/hid-tmff.c b/trunk/drivers/hid/hid-tmff.c index 575862b0688e..25be4e1461bd 100644 --- a/trunk/drivers/hid/hid-tmff.c +++ b/trunk/drivers/hid/hid-tmff.c @@ -151,23 +151,28 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) switch (field->usage[0].hid) { case THRUSTMASTER_USAGE_FF: if (field->report_count < 2) { - hid_warn(hid, "ignoring FF field with report_count < 2\n"); + dev_warn(&hid->dev, "ignoring FF field " + "with report_count < 2\n"); continue; } if (field->logical_maximum == field->logical_minimum) { - hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n"); + dev_warn(&hid->dev, "ignoring FF field " + "with logical_maximum " + "== logical_minimum\n"); continue; } if (tmff->report && tmff->report != report) { - hid_warn(hid, "ignoring FF field in other report\n"); + dev_warn(&hid->dev, "ignoring FF field " + "in other report\n"); continue; } if (tmff->ff_field && tmff->ff_field != field) { - hid_warn(hid, "ignoring duplicate FF field\n"); + dev_warn(&hid->dev, "ignoring " + "duplicate FF field\n"); continue; } @@ -180,15 +185,16 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) break; default: - hid_warn(hid, "ignoring unknown output usage %08x\n", - field->usage[0].hid); + dev_warn(&hid->dev, "ignoring unknown output " + "usage %08x\n", + field->usage[0].hid); continue; } } } if (!tmff->report) { - hid_err(hid, "can't find FF field in output reports\n"); + dev_err(&hid->dev, "can't find FF field in output reports\n"); error = -ENODEV; goto fail; } @@ -197,7 +203,8 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) if (error) goto fail; - hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse \n"); + dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx " + "Verituse "); return 0; fail: @@ -217,13 +224,13 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-topseed.c b/trunk/drivers/hid/hid-topseed.c index 613ff7b1d746..956ed9ac19d4 100644 --- a/trunk/drivers/hid/hid-topseed.c +++ b/trunk/drivers/hid/hid-topseed.c @@ -66,7 +66,6 @@ static const struct hid_device_id ts_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { } }; MODULE_DEVICE_TABLE(hid, ts_devices); diff --git a/trunk/drivers/hid/hid-wacom.c b/trunk/drivers/hid/hid-wacom.c index 06888323828c..724f46ed612f 100644 --- a/trunk/drivers/hid/hid-wacom.c +++ b/trunk/drivers/hid/hid-wacom.c @@ -18,8 +18,6 @@ * any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -143,8 +141,8 @@ static void wacom_poke(struct hid_device *hdev, u8 speed) * Note that if the raw queries fail, it's not a hard failure and it * is safe to continue */ - hid_warn(hdev, "failed to poke device, command %d, err %d\n", - rep_data[0], ret); + dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n", + rep_data[0], ret); return; } @@ -174,7 +172,7 @@ static ssize_t wacom_store_speed(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP, +static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO, wacom_show_speed, wacom_store_speed); static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, @@ -314,7 +312,7 @@ static int wacom_probe(struct hid_device *hdev, wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); if (wdata == NULL) { - hid_err(hdev, "can't alloc wacom descriptor\n"); + dev_err(&hdev->dev, "can't alloc wacom descriptor\n"); return -ENOMEM; } @@ -323,20 +321,20 @@ static int wacom_probe(struct hid_device *hdev, /* Parse the HID report now */ ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } ret = device_create_file(&hdev->dev, &dev_attr_speed); if (ret) - hid_warn(hdev, - "can't create sysfs speed attribute err: %d\n", ret); + dev_warn(&hdev->dev, + "can't create sysfs speed attribute err: %d\n", ret); /* Set Wacom mode 2 with high reporting speed */ wacom_poke(hdev, 1); @@ -351,8 +349,8 @@ static int wacom_probe(struct hid_device *hdev, ret = power_supply_register(&hdev->dev, &wdata->battery); if (ret) { - hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", - ret); + dev_warn(&hdev->dev, + "can't create sysfs battery attribute, err: %d\n", ret); /* * battery attribute is not critical for the tablet, but if it * failed then there is no need to create ac attribute @@ -369,8 +367,8 @@ static int wacom_probe(struct hid_device *hdev, ret = power_supply_register(&hdev->dev, &wdata->ac); if (ret) { - hid_warn(hdev, - "can't create ac battery attribute, err: %d\n", ret); + dev_warn(&hdev->dev, + "can't create ac battery attribute, err: %d\n", ret); /* * ac attribute is not critical for the tablet, but if it * failed then we don't want to battery attribute to exist @@ -456,7 +454,7 @@ static int __init wacom_init(void) ret = hid_register_driver(&wacom_driver); if (ret) - pr_err("can't register wacom driver\n"); + printk(KERN_ERR "can't register wacom driver\n"); return ret; } diff --git a/trunk/drivers/hid/hid-zpff.c b/trunk/drivers/hid/hid-zpff.c index f31fab012f2f..b7acceabba80 100644 --- a/trunk/drivers/hid/hid-zpff.c +++ b/trunk/drivers/hid/hid-zpff.c @@ -75,14 +75,14 @@ static int zpff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - hid_err(hid, "no output report found\n"); + dev_err(&hid->dev, "no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 4) { - hid_err(hid, "not enough fields in report\n"); + dev_err(&hid->dev, "not enough fields in report\n"); return -ENODEV; } @@ -105,7 +105,8 @@ static int zpff_init(struct hid_device *hid) zpff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); - hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula \n"); + dev_info(&hid->dev, "force feedback for Zeroplus based devices by " + "Anssi Hannula \n"); return 0; } @@ -122,13 +123,13 @@ static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "hw start failed\n"); goto err; } diff --git a/trunk/drivers/hid/hid-zydacron.c b/trunk/drivers/hid/hid-zydacron.c index e90371508fd2..aac1f9273149 100644 --- a/trunk/drivers/hid/hid-zydacron.c +++ b/trunk/drivers/hid/hid-zydacron.c @@ -34,8 +34,9 @@ static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff && rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff && rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) { - hid_info(hdev, - "fixing up zydacron remote control report descriptor\n"); + dev_info(&hdev->dev, + "fixing up zydacron remote control report " + "descriptor\n"); rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c; rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00; } @@ -171,7 +172,7 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) zc = kzalloc(sizeof(*zc), GFP_KERNEL); if (zc == NULL) { - hid_err(hdev, "can't alloc descriptor\n"); + dev_err(&hdev->dev, "zydacron: can't alloc descriptor\n"); return -ENOMEM; } @@ -179,13 +180,13 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - hid_err(hdev, "parse failed\n"); + dev_err(&hdev->dev, "zydacron: parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - hid_err(hdev, "hw start failed\n"); + dev_err(&hdev->dev, "zydacron: hw start failed\n"); goto err_free; } diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 468e87b53ed2..e1f07483691f 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -19,8 +19,6 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -124,15 +122,15 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t } if (count > HID_MAX_BUFFER_SIZE) { - hid_warn(dev, "pid %d passed too large report\n", - task_pid_nr(current)); + printk(KERN_WARNING "hidraw: pid %d passed too large report\n", + task_pid_nr(current)); ret = -EINVAL; goto out; } if (count < 2) { - hid_warn(dev, "pid %d passed too short report\n", - task_pid_nr(current)); + printk(KERN_WARNING "hidraw: pid %d passed too short report\n", + task_pid_nr(current)); ret = -EINVAL; goto out; } @@ -194,13 +192,15 @@ static int hidraw_open(struct inode *inode, struct file *file) dev = hidraw_table[minor]; if (!dev->open++) { - err = hid_hw_power(dev->hid, PM_HINT_FULLON); - if (err < 0) - goto out_unlock; - - err = hid_hw_open(dev->hid); + if (dev->hid->ll_driver->power) { + err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON); + if (err < 0) + goto out_unlock; + } + err = dev->hid->ll_driver->open(dev->hid); if (err < 0) { - hid_hw_power(dev->hid, PM_HINT_NORMAL); + if (dev->hid->ll_driver->power) + dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); dev->open--; } } @@ -229,8 +229,9 @@ static int hidraw_release(struct inode * inode, struct file * file) dev = hidraw_table[minor]; if (!--dev->open) { if (list->hidraw->exist) { - hid_hw_power(dev->hid, PM_HINT_NORMAL); - hid_hw_close(dev->hid); + if (dev->hid->ll_driver->power) + dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); + dev->hid->ll_driver->close(dev->hid); } else { kfree(list->hidraw); } @@ -344,9 +345,6 @@ static const struct file_operations hidraw_ops = { .open = hidraw_open, .release = hidraw_release, .unlocked_ioctl = hidraw_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = hidraw_ioctl, -#endif .llseek = noop_llseek, }; @@ -435,7 +433,7 @@ void hidraw_disconnect(struct hid_device *hid) device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); if (hidraw->open) { - hid_hw_close(hid); + hid->ll_driver->close(hid); wake_up_interruptible(&hidraw->wait); } else { kfree(hidraw); @@ -454,7 +452,7 @@ int __init hidraw_init(void) hidraw_major = MAJOR(dev_id); if (result < 0) { - pr_warn("can't get major number\n"); + printk(KERN_WARNING "hidraw: can't get major number\n"); result = 0; goto out; } diff --git a/trunk/drivers/hid/usbhid/Makefile b/trunk/drivers/hid/usbhid/Makefile index db3cf31c6fa1..1329ecb37a1c 100644 --- a/trunk/drivers/hid/usbhid/Makefile +++ b/trunk/drivers/hid/usbhid/Makefile @@ -3,15 +3,15 @@ # # Multipart objects. -usbhid-y := hid-core.o hid-quirks.o +usbhid-objs := hid-core.o hid-quirks.o # Optional parts of multipart objects. ifeq ($(CONFIG_USB_HIDDEV),y) - usbhid-y += hiddev.o + usbhid-objs += hiddev.o endif ifeq ($(CONFIG_HID_PID),y) - usbhid-y += hid-pidff.o + usbhid-objs += hid-pidff.o endif obj-$(CONFIG_USB_HID) += usbhid.o diff --git a/trunk/drivers/hid/usbhid/hid-core.c b/trunk/drivers/hid/usbhid/hid-core.c index b336dd84036f..5489eab3a6bd 100644 --- a/trunk/drivers/hid/usbhid/hid-core.c +++ b/trunk/drivers/hid/usbhid/hid-core.c @@ -67,6 +67,7 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " * Input submission and I/O error handler. */ static DEFINE_MUTEX(hid_open_mut); +static struct workqueue_struct *resumption_waker; static void hid_io_error(struct hid_device *hid); static int hid_submit_out(struct hid_device *hid); @@ -135,10 +136,10 @@ static void hid_reset(struct work_struct *work) hid_io_error(hid); break; default: - hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n", - hid_to_usb_dev(hid)->bus->bus_name, - hid_to_usb_dev(hid)->devpath, - usbhid->ifnum, rc); + err_hid("can't reset device, %s-%s/input%d, status %d", + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, + usbhid->ifnum, rc); /* FALLTHROUGH */ case -EHOSTUNREACH: case -ENODEV: @@ -277,18 +278,18 @@ static void hid_irq_in(struct urb *urb) hid_io_error(hid); return; default: /* error */ - hid_warn(urb->dev, "input irq status %d received\n", - urb->status); + dev_warn(&urb->dev->dev, "input irq status %d " + "received\n", urb->status); } status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { clear_bit(HID_IN_RUNNING, &usbhid->iofl); if (status != -EPERM) { - hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n", - hid_to_usb_dev(hid)->bus->bus_name, - hid_to_usb_dev(hid)->devpath, - usbhid->ifnum, status); + err_hid("can't resubmit intr, %s-%s/input%d, status %d", + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, + usbhid->ifnum, status); hid_io_error(hid); } } @@ -299,19 +300,10 @@ static int hid_submit_out(struct hid_device *hid) struct hid_report *report; char *raw_report; struct usbhid_device *usbhid = hid->driver_data; - int r; report = usbhid->out[usbhid->outtail].report; raw_report = usbhid->out[usbhid->outtail].raw_report; - r = usb_autopm_get_interface_async(usbhid->intf); - if (r < 0) - return -1; - - /* - * if the device hasn't been woken, we leave the output - * to resume() - */ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); usbhid->urbout->dev = hid_to_usb_dev(hid); @@ -321,11 +313,17 @@ static int hid_submit_out(struct hid_device *hid) dbg_hid("submitting out urb\n"); if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { - hid_err(hid, "usb_submit_urb(out) failed\n"); - usb_autopm_put_interface_async(usbhid->intf); + err_hid("usb_submit_urb(out) failed"); return -1; } usbhid->last_out = jiffies; + } else { + /* + * queue work to wake up the device. + * as the work queue is freezeable, this is safe + * with respect to STD and STR + */ + queue_work(resumption_waker, &usbhid->restart_work); } return 0; @@ -336,16 +334,13 @@ static int hid_submit_ctrl(struct hid_device *hid) struct hid_report *report; unsigned char dir; char *raw_report; - int len, r; + int len; struct usbhid_device *usbhid = hid->driver_data; report = usbhid->ctrl[usbhid->ctrltail].report; raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; - r = usb_autopm_get_interface_async(usbhid->intf); - if (r < 0) - return -1; if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if (dir == USB_DIR_OUT) { @@ -380,11 +375,17 @@ static int hid_submit_ctrl(struct hid_device *hid) usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { - usb_autopm_put_interface_async(usbhid->intf); - hid_err(hid, "usb_submit_urb(ctrl) failed\n"); + err_hid("usb_submit_urb(ctrl) failed"); return -1; } usbhid->last_ctrl = jiffies; + } else { + /* + * queue work to wake up the device. + * as the work queue is freezeable, this is safe + * with respect to STD and STR + */ + queue_work(resumption_waker, &usbhid->restart_work); } return 0; @@ -412,8 +413,8 @@ static void hid_irq_out(struct urb *urb) case -ENOENT: break; default: /* error */ - hid_warn(urb->dev, "output irq status %d received\n", - urb->status); + dev_warn(&urb->dev->dev, "output irq status %d " + "received\n", urb->status); } spin_lock_irqsave(&usbhid->lock, flags); @@ -434,7 +435,6 @@ static void hid_irq_out(struct urb *urb) clear_bit(HID_OUT_RUNNING, &usbhid->iofl); spin_unlock_irqrestore(&usbhid->lock, flags); - usb_autopm_put_interface_async(usbhid->intf); wake_up(&usbhid->wait); } @@ -466,7 +466,8 @@ static void hid_ctrl(struct urb *urb) case -EPIPE: /* report not available */ break; default: /* error */ - hid_warn(urb->dev, "ctrl urb status %d received\n", status); + dev_warn(&urb->dev->dev, "ctrl urb status %d " + "received\n", status); } if (unplug) @@ -480,13 +481,11 @@ static void hid_ctrl(struct urb *urb) wake_up(&usbhid->wait); } spin_unlock(&usbhid->lock); - usb_autopm_put_interface_async(usbhid->intf); return; } clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); spin_unlock(&usbhid->lock); - usb_autopm_put_interface_async(usbhid->intf); wake_up(&usbhid->wait); } @@ -502,13 +501,13 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { - hid_warn(hid, "output queue full\n"); + dev_warn(&hid->dev, "output queue full\n"); return; } usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->out[usbhid->outhead].raw_report) { - hid_warn(hid, "output queueing failed\n"); + dev_warn(&hid->dev, "output queueing failed\n"); return; } hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); @@ -533,14 +532,14 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re } if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { - hid_warn(hid, "control queue full\n"); + dev_warn(&hid->dev, "control queue full\n"); return; } if (dir == USB_DIR_OUT) { usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { - hid_warn(hid, "control queueing failed\n"); + dev_warn(&hid->dev, "control queueing failed\n"); return; } hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); @@ -591,7 +590,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un return -1; if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { - hid_warn(dev, "event field not found\n"); + dev_warn(&dev->dev, "event field not found\n"); return -1; } @@ -657,7 +656,7 @@ int usbhid_open(struct hid_device *hid) mutex_lock(&hid_open_mut); if (!hid->open++) { res = usb_autopm_get_interface(usbhid->intf); - /* the device must be awake to reliably request remote wakeup */ + /* the device must be awake to reliable request remote wakeup */ if (res < 0) { hid->open--; mutex_unlock(&hid_open_mut); @@ -723,7 +722,7 @@ void usbhid_init_reports(struct hid_device *hid) } if (err) - hid_warn(hid, "timeout initializing reports\n"); + dev_warn(&hid->dev, "timeout initializing reports\n"); } /* @@ -858,6 +857,18 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid) usbhid_restart_ctrl_queue(usbhid); } +static void __usbhid_restart_queues(struct work_struct *work) +{ + struct usbhid_device *usbhid = + container_of(work, struct usbhid_device, restart_work); + int r; + + r = usb_autopm_get_interface(usbhid->intf); + if (r < 0) + return; + usb_autopm_put_interface(usbhid->intf); +} + static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) { struct usbhid_device *usbhid = hid->driver_data; @@ -1129,7 +1140,8 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) has_in++; if (!has_in) { - hid_err(intf, "couldn't find an input interrupt endpoint\n"); + dev_err(&intf->dev, "couldn't find an input interrupt " + "endpoint\n"); return -ENODEV; } @@ -1194,13 +1206,14 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * init_waitqueue_head(&usbhid->wait); INIT_WORK(&usbhid->reset_work, hid_reset); + INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); spin_lock_init(&usbhid->lock); ret = hid_add_device(hid); if (ret) { if (ret != -ENODEV) - hid_err(intf, "can't add hid device: %d\n", ret); + dev_err(&intf->dev, "can't add hid device: %d\n", ret); goto err_free; } @@ -1228,6 +1241,7 @@ static void usbhid_disconnect(struct usb_interface *intf) static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) { del_timer_sync(&usbhid->io_retry); + cancel_work_sync(&usbhid->restart_work); cancel_work_sync(&usbhid->reset_work); } @@ -1248,6 +1262,7 @@ static int hid_pre_reset(struct usb_interface *intf) spin_lock_irq(&usbhid->lock); set_bit(HID_RESET_PENDING, &usbhid->iofl); spin_unlock_irq(&usbhid->lock); + cancel_work_sync(&usbhid->restart_work); hid_cease_io(usbhid); return 0; @@ -1446,6 +1461,9 @@ static int __init hid_init(void) { int retval = -ENOMEM; + resumption_waker = create_freezeable_workqueue("usbhid_resumer"); + if (!resumption_waker) + goto no_queue; retval = hid_register_driver(&hid_usb_driver); if (retval) goto hid_register_fail; @@ -1463,6 +1481,8 @@ static int __init hid_init(void) usbhid_quirks_init_fail: hid_unregister_driver(&hid_usb_driver); hid_register_fail: + destroy_workqueue(resumption_waker); +no_queue: return retval; } @@ -1471,6 +1491,7 @@ static void __exit hid_exit(void) usb_deregister(&hid_driver); usbhid_quirks_exit(); hid_unregister_driver(&hid_usb_driver); + destroy_workqueue(resumption_waker); } module_init(hid_init); diff --git a/trunk/drivers/hid/usbhid/hid-pidff.c b/trunk/drivers/hid/usbhid/hid-pidff.c index f91c136821f7..ef381d79cfa8 100644 --- a/trunk/drivers/hid/usbhid/hid-pidff.c +++ b/trunk/drivers/hid/usbhid/hid-pidff.c @@ -22,7 +22,7 @@ /* #define DEBUG */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg) #include #include @@ -220,7 +220,7 @@ static int pidff_rescale_signed(int i, struct hid_field *field) static void pidff_set(struct pidff_usage *usage, u16 value) { usage->value[0] = pidff_rescale(value, 0xffff, usage->field); - pr_debug("calculated from %d to %d\n", value, usage->value[0]); + debug("calculated from %d to %d", value, usage->value[0]); } static void pidff_set_signed(struct pidff_usage *usage, s16 value) @@ -235,7 +235,7 @@ static void pidff_set_signed(struct pidff_usage *usage, s16 value) usage->value[0] = pidff_rescale(value, 0x7fff, usage->field); } - pr_debug("calculated from %d to %d\n", value, usage->value[0]); + debug("calculated from %d to %d", value, usage->value[0]); } /* @@ -259,9 +259,8 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length; pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length; - hid_dbg(pidff->hid, "attack %u => %d\n", - envelope->attack_level, - pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); + debug("attack %u => %d", envelope->attack_level, + pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], USB_DIR_OUT); @@ -467,33 +466,33 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) pidff->create_new_effect_type->value[0] = efnum; usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], USB_DIR_OUT); - hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum); + debug("create_new_effect sent, type: %d", efnum); pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; pidff->block_load_status->value[0] = 0; usbhid_wait_io(pidff->hid); for (j = 0; j < 60; j++) { - hid_dbg(pidff->hid, "pid_block_load requested\n"); + debug("pid_block_load requested"); usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], USB_DIR_IN); usbhid_wait_io(pidff->hid); if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { - hid_dbg(pidff->hid, "device reported free memory: %d bytes\n", - pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? - pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); + debug("device reported free memory: %d bytes", + pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? + pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); return 0; } if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_FULL]) { - hid_dbg(pidff->hid, "not enough memory free: %d bytes\n", - pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? + debug("not enough memory free: %d bytes", + pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); return -ENOSPC; } } - hid_err(pidff->hid, "pid_block_load failed 60 times\n"); + printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n"); return -EIO; } @@ -547,8 +546,7 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id) struct pidff_device *pidff = dev->ff->private; int pid_id = pidff->pid_id[effect_id]; - hid_dbg(pidff->hid, "starting to erase %d/%d\n", - effect_id, pidff->pid_id[effect_id]); + debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]); /* Wait for the queue to clear. We do not want a full fifo to prevent the effect removal. */ usbhid_wait_io(pidff->hid); @@ -606,7 +604,8 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, type_id = PID_SAW_DOWN; break; default: - hid_err(pidff->hid, "invalid waveform\n"); + printk(KERN_ERR + "hid-pidff: invalid waveform\n"); return -EINVAL; } @@ -697,7 +696,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, break; default: - hid_err(pidff->hid, "invalid type\n"); + printk(KERN_ERR "hid-pidff: invalid type\n"); return -EINVAL; } @@ -705,7 +704,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, pidff->pid_id[effect->id] = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; - hid_dbg(pidff->hid, "uploaded\n"); + debug("uploaded"); return 0; } @@ -771,14 +770,14 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, for (i = 0; i < report->maxfield; i++) { if (report->field[i]->maxusage != report->field[i]->report_count) { - pr_debug("maxusage and report_count do not match, skipping\n"); + debug("maxusage and report_count do not match, " + "skipping"); continue; } for (j = 0; j < report->field[i]->maxusage; j++) { if (report->field[i]->usage[j].hid == (HID_UP_PID | table[k])) { - pr_debug("found %d at %d->%d\n", - k, i, j); + debug("found %d at %d->%d", k, i, j); usage[k].field = report->field[i]; usage[k].value = &report->field[i]->value[j]; @@ -790,7 +789,7 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, break; } if (!found && strict) { - pr_debug("failed to locate %d\n", k); + debug("failed to locate %d", k); return -1; } } @@ -827,8 +826,8 @@ static void pidff_find_reports(struct hid_device *hid, int report_type, continue; ret = pidff_check_usage(report->field[0]->logical); if (ret != -1) { - hid_dbg(hid, "found usage 0x%02x from field->logical\n", - pidff_reports[ret]); + debug("found usage 0x%02x from field->logical", + pidff_reports[ret]); pidff->reports[ret] = report; continue; } @@ -846,9 +845,8 @@ static void pidff_find_reports(struct hid_device *hid, int report_type, continue; ret = pidff_check_usage(hid->collection[i - 1].usage); if (ret != -1 && !pidff->reports[ret]) { - hid_dbg(hid, - "found usage 0x%02x from collection array\n", - pidff_reports[ret]); + debug("found usage 0x%02x from collection array", + pidff_reports[ret]); pidff->reports[ret] = report; } } @@ -863,7 +861,7 @@ static int pidff_reports_ok(struct pidff_device *pidff) for (i = 0; i <= PID_REQUIRED_REPORTS; i++) { if (!pidff->reports[i]) { - hid_dbg(pidff->hid, "%d missing\n", i); + debug("%d missing", i); return 0; } } @@ -886,7 +884,8 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report, report->field[i]->logical_minimum == 1) return report->field[i]; else { - pr_err("logical_minimum is not 1 as it should be\n"); + printk(KERN_ERR "hid-pidff: logical_minimum " + "is not 1 as it should be\n"); return NULL; } } @@ -925,7 +924,7 @@ static int pidff_find_special_keys(int *keys, struct hid_field *fld, */ static int pidff_find_special_fields(struct pidff_device *pidff) { - hid_dbg(pidff->hid, "finding special fields\n"); + debug("finding special fields"); pidff->create_new_effect_type = pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT], @@ -946,30 +945,32 @@ static int pidff_find_special_fields(struct pidff_device *pidff) pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION], 0x78, 1); - hid_dbg(pidff->hid, "search done\n"); + debug("search done"); if (!pidff->create_new_effect_type || !pidff->set_effect_type) { - hid_err(pidff->hid, "effect lists not found\n"); + printk(KERN_ERR "hid-pidff: effect lists not found\n"); return -1; } if (!pidff->effect_direction) { - hid_err(pidff->hid, "direction field not found\n"); + printk(KERN_ERR "hid-pidff: direction field not found\n"); return -1; } if (!pidff->device_control) { - hid_err(pidff->hid, "device control field not found\n"); + printk(KERN_ERR "hid-pidff: device control field not found\n"); return -1; } if (!pidff->block_load_status) { - hid_err(pidff->hid, "block load status field not found\n"); + printk(KERN_ERR + "hid-pidff: block load status field not found\n"); return -1; } if (!pidff->effect_operation_status) { - hid_err(pidff->hid, "effect operation field not found\n"); + printk(KERN_ERR + "hid-pidff: effect operation field not found\n"); return -1; } @@ -981,22 +982,23 @@ static int pidff_find_special_fields(struct pidff_device *pidff) if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type, effect_types)) { - hid_err(pidff->hid, "no effect types found\n"); + printk(KERN_ERR "hid-pidff: no effect types found\n"); return -1; } if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status, block_load_status) != sizeof(pidff_block_load_status)) { - hid_err(pidff->hid, - "block load status identifiers not found\n"); + printk(KERN_ERR + "hidpidff: block load status identifiers not found\n"); return -1; } if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status, effect_operation_status) != sizeof(pidff_effect_operation_status)) { - hid_err(pidff->hid, "effect operation identifiers not found\n"); + printk(KERN_ERR + "hidpidff: effect operation identifiers not found\n"); return -1; } @@ -1015,8 +1017,8 @@ static int pidff_find_effects(struct pidff_device *pidff, int pidff_type = pidff->type_id[i]; if (pidff->set_effect_type->usage[pidff_type].hid != pidff->create_new_effect_type->usage[pidff_type].hid) { - hid_err(pidff->hid, - "effect type number %d is invalid\n", i); + printk(KERN_ERR "hid-pidff: " + "effect type number %d is invalid\n", i); return -1; } } @@ -1071,23 +1073,27 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) int envelope_ok = 0; if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) { - hid_err(pidff->hid, "unknown set_effect report layout\n"); + printk(KERN_ERR + "hid-pidff: unknown set_effect report layout\n"); return -ENODEV; } PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0); if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) { - hid_err(pidff->hid, "unknown pid_block_load report layout\n"); + printk(KERN_ERR + "hid-pidff: unknown pid_block_load report layout\n"); return -ENODEV; } if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) { - hid_err(pidff->hid, "unknown effect_operation report layout\n"); + printk(KERN_ERR + "hid-pidff: unknown effect_operation report layout\n"); return -ENODEV; } if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) { - hid_err(pidff->hid, "unknown pid_block_free report layout\n"); + printk(KERN_ERR + "hid-pidff: unknown pid_block_free report layout\n"); return -ENODEV; } @@ -1099,26 +1105,27 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) if (!envelope_ok) { if (test_and_clear_bit(FF_CONSTANT, dev->ffbit)) - hid_warn(pidff->hid, - "has constant effect but no envelope\n"); + printk(KERN_WARNING "hid-pidff: " + "has constant effect but no envelope\n"); if (test_and_clear_bit(FF_RAMP, dev->ffbit)) - hid_warn(pidff->hid, - "has ramp effect but no envelope\n"); + printk(KERN_WARNING "hid-pidff: " + "has ramp effect but no envelope\n"); if (test_and_clear_bit(FF_PERIODIC, dev->ffbit)) - hid_warn(pidff->hid, - "has periodic effect but no envelope\n"); + printk(KERN_WARNING "hid-pidff: " + "has periodic effect but no envelope\n"); } if (test_bit(FF_CONSTANT, dev->ffbit) && PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) { - hid_warn(pidff->hid, "unknown constant effect layout\n"); + printk(KERN_WARNING + "hid-pidff: unknown constant effect layout\n"); clear_bit(FF_CONSTANT, dev->ffbit); } if (test_bit(FF_RAMP, dev->ffbit) && PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) { - hid_warn(pidff->hid, "unknown ramp effect layout\n"); + printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n"); clear_bit(FF_RAMP, dev->ffbit); } @@ -1127,7 +1134,8 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) test_bit(FF_FRICTION, dev->ffbit) || test_bit(FF_INERTIA, dev->ffbit)) && PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) { - hid_warn(pidff->hid, "unknown condition effect layout\n"); + printk(KERN_WARNING + "hid-pidff: unknown condition effect layout\n"); clear_bit(FF_SPRING, dev->ffbit); clear_bit(FF_DAMPER, dev->ffbit); clear_bit(FF_FRICTION, dev->ffbit); @@ -1136,7 +1144,8 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) if (test_bit(FF_PERIODIC, dev->ffbit) && PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) { - hid_warn(pidff->hid, "unknown periodic effect layout\n"); + printk(KERN_WARNING + "hid-pidff: unknown periodic effect layout\n"); clear_bit(FF_PERIODIC, dev->ffbit); } @@ -1175,12 +1184,12 @@ static void pidff_reset(struct pidff_device *pidff) if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) { if (i++ > 20) { - hid_warn(pidff->hid, - "device reports %d simultaneous effects\n", - pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); + printk(KERN_WARNING "hid-pidff: device reports " + "%d simultaneous effects\n", + pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); break; } - hid_dbg(pidff->hid, "pid_pool requested again\n"); + debug("pid_pool requested again"); usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); usbhid_wait_io(hid); @@ -1206,7 +1215,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff, error = pidff_request_effect_upload(pidff, 1); if (error) { - hid_err(pidff->hid, "upload request failed\n"); + printk(KERN_ERR "hid-pidff: upload request failed\n"); return error; } @@ -1215,8 +1224,8 @@ static int pidff_check_autocenter(struct pidff_device *pidff, pidff_autocenter(pidff, 0xffff); set_bit(FF_AUTOCENTER, dev->ffbit); } else { - hid_notice(pidff->hid, - "device has unknown autocenter control method\n"); + printk(KERN_NOTICE "hid-pidff: " + "device has unknown autocenter control method\n"); } pidff_erase_pid(pidff, @@ -1239,10 +1248,10 @@ int hid_pidff_init(struct hid_device *hid) int max_effects; int error; - hid_dbg(hid, "starting pid init\n"); + debug("starting pid init"); if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) { - hid_dbg(hid, "not a PID device, no output report\n"); + debug("not a PID device, no output report"); return -ENODEV; } @@ -1256,7 +1265,7 @@ int hid_pidff_init(struct hid_device *hid) pidff_find_reports(hid, HID_FEATURE_REPORT, pidff); if (!pidff_reports_ok(pidff)) { - hid_dbg(hid, "reports not ok, aborting\n"); + debug("reports not ok, aborting"); error = -ENODEV; goto fail; } @@ -1269,8 +1278,8 @@ int hid_pidff_init(struct hid_device *hid) if (test_bit(FF_GAIN, dev->ffbit)) { pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN], - USB_DIR_OUT); + usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], + USB_DIR_OUT); } error = pidff_check_autocenter(pidff, dev); @@ -1281,23 +1290,23 @@ int hid_pidff_init(struct hid_device *hid) pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum - pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1; - hid_dbg(hid, "max effects is %d\n", max_effects); + debug("max effects is %d", max_effects); if (max_effects > PID_EFFECTS_MAX) max_effects = PID_EFFECTS_MAX; if (pidff->pool[PID_SIMULTANEOUS_MAX].value) - hid_dbg(hid, "max simultaneous effects is %d\n", - pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); + debug("max simultaneous effects is %d", + pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); if (pidff->pool[PID_RAM_POOL_SIZE].value) - hid_dbg(hid, "device memory size is %d bytes\n", - pidff->pool[PID_RAM_POOL_SIZE].value[0]); + debug("device memory size is %d bytes", + pidff->pool[PID_RAM_POOL_SIZE].value[0]); if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { - hid_notice(hid, - "device does not support device managed pool\n"); + printk(KERN_NOTICE "hid-pidff: " + "device does not support device managed pool\n"); goto fail; } @@ -1313,7 +1322,8 @@ int hid_pidff_init(struct hid_device *hid) ff->set_autocenter = pidff_set_autocenter; ff->playback = pidff_playback; - hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula \n"); + printk(KERN_INFO "Force feedback for USB HID PID devices by " + "Anssi Hannula \n"); return 0; diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index 76b9a149c7df..2c185477eeb3 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -85,7 +85,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, + { 0, 0 } }; diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index af0a7c1002af..984feb351a5a 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -585,168 +585,163 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hiddev_list *list = file->private_data; struct hiddev *hiddev = list->hiddev; - struct hid_device *hid; + struct hid_device *hid = hiddev->hid; + struct usb_device *dev; struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; struct hiddev_devinfo dinfo; struct hid_report *report; struct hid_field *field; + struct usbhid_device *usbhid = hid->driver_data; void __user *user_arg = (void __user *)arg; - int i, r = -EINVAL; - + int i, r; + /* Called without BKL by compat methods so no BKL taken */ - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } + /* FIXME: Who or what stop this racing with a disconnect ?? */ + if (!hiddev->exist || !hid) + return -EIO; - hid = hiddev->hid; + dev = hid_to_usb_dev(hid); switch (cmd) { case HIDIOCGVERSION: - r = put_user(HID_VERSION, (int __user *)arg) ? - -EFAULT : 0; - break; + return put_user(HID_VERSION, (int __user *)arg); case HIDIOCAPPLICATION: if (arg < 0 || arg >= hid->maxapplication) - break; + return -EINVAL; for (i = 0; i < hid->maxcollection; i++) if (hid->collection[i].type == HID_COLLECTION_APPLICATION && arg-- == 0) break; - if (i < hid->maxcollection) - r = hid->collection[i].usage; - break; + if (i == hid->maxcollection) + return -EINVAL; + + return hid->collection[i].usage; case HIDIOCGDEVINFO: - { - struct usb_device *dev = hid_to_usb_dev(hid); - struct usbhid_device *usbhid = hid->driver_data; - - dinfo.bustype = BUS_USB; - dinfo.busnum = dev->bus->busnum; - dinfo.devnum = dev->devnum; - dinfo.ifnum = usbhid->ifnum; - dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); - dinfo.product = le16_to_cpu(dev->descriptor.idProduct); - dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); - dinfo.num_applications = hid->maxapplication; - - r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ? - -EFAULT : 0; - break; - } + dinfo.bustype = BUS_USB; + dinfo.busnum = dev->bus->busnum; + dinfo.devnum = dev->devnum; + dinfo.ifnum = usbhid->ifnum; + dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); + dinfo.product = le16_to_cpu(dev->descriptor.idProduct); + dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); + dinfo.num_applications = hid->maxapplication; + if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) + return -EFAULT; + + return 0; case HIDIOCGFLAG: - r = put_user(list->flags, (int __user *)arg) ? - -EFAULT : 0; - break; + if (put_user(list->flags, (int __user *)arg)) + return -EFAULT; + + return 0; case HIDIOCSFLAG: { int newflags; - - if (get_user(newflags, (int __user *)arg)) { - r = -EFAULT; - break; - } + if (get_user(newflags, (int __user *)arg)) + return -EFAULT; if ((newflags & ~HIDDEV_FLAGS) != 0 || ((newflags & HIDDEV_FLAG_REPORT) != 0 && (newflags & HIDDEV_FLAG_UREF) == 0)) - break; + return -EINVAL; list->flags = newflags; - r = 0; - break; + return 0; } case HIDIOCGSTRING: - r = hiddev_ioctl_string(hiddev, cmd, user_arg); - break; + mutex_lock(&hiddev->existancelock); + if (hiddev->exist) + r = hiddev_ioctl_string(hiddev, cmd, user_arg); + else + r = -ENODEV; + mutex_unlock(&hiddev->existancelock); + return r; case HIDIOCINITREPORT: + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + mutex_unlock(&hiddev->existancelock); + return -ENODEV; + } usbhid_init_reports(hid); - r = 0; - break; + mutex_unlock(&hiddev->existancelock); + + return 0; case HIDIOCGREPORT: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { - r = -EFAULT; - break; - } + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) + return -EFAULT; if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT) - break; + return -EINVAL; - report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) - break; + if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) + return -EINVAL; - usbhid_submit_report(hid, report, USB_DIR_IN); - usbhid_wait_io(hid); + mutex_lock(&hiddev->existancelock); + if (hiddev->exist) { + usbhid_submit_report(hid, report, USB_DIR_IN); + usbhid_wait_io(hid); + } + mutex_unlock(&hiddev->existancelock); - r = 0; - break; + return 0; case HIDIOCSREPORT: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { - r = -EFAULT; - break; - } + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) + return -EFAULT; if (rinfo.report_type == HID_REPORT_TYPE_INPUT) - break; + return -EINVAL; - report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) - break; + if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) + return -EINVAL; - usbhid_submit_report(hid, report, USB_DIR_OUT); - usbhid_wait_io(hid); + mutex_lock(&hiddev->existancelock); + if (hiddev->exist) { + usbhid_submit_report(hid, report, USB_DIR_OUT); + usbhid_wait_io(hid); + } + mutex_unlock(&hiddev->existancelock); - r = 0; - break; + return 0; case HIDIOCGREPORTINFO: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { - r = -EFAULT; - break; - } + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) + return -EFAULT; - report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) - break; + if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) + return -EINVAL; rinfo.num_fields = report->maxfield; - r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ? - -EFAULT : 0; - break; + if (copy_to_user(user_arg, &rinfo, sizeof(rinfo))) + return -EFAULT; - case HIDIOCGFIELDINFO: - if (copy_from_user(&finfo, user_arg, sizeof(finfo))) { - r = -EFAULT; - break; - } + return 0; + case HIDIOCGFIELDINFO: + if (copy_from_user(&finfo, user_arg, sizeof(finfo))) + return -EFAULT; rinfo.report_type = finfo.report_type; rinfo.report_id = finfo.report_id; - - report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) - break; + if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) + return -EINVAL; if (finfo.field_index >= report->maxfield) - break; + return -EINVAL; field = report->field[finfo.field_index]; memset(&finfo, 0, sizeof(finfo)); @@ -765,9 +760,10 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) finfo.unit_exponent = field->unit_exponent; finfo.unit = field->unit; - r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ? - -EFAULT : 0; - break; + if (copy_to_user(user_arg, &finfo, sizeof(finfo))) + return -EFAULT; + + return 0; case HIDIOCGUCODE: /* fall through */ @@ -776,66 +772,57 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case HIDIOCGUSAGES: case HIDIOCSUSAGES: case HIDIOCGCOLLECTIONINDEX: - r = hiddev_ioctl_usage(hiddev, cmd, user_arg); - break; + mutex_lock(&hiddev->existancelock); + if (hiddev->exist) + r = hiddev_ioctl_usage(hiddev, cmd, user_arg); + else + r = -ENODEV; + mutex_unlock(&hiddev->existancelock); + return r; case HIDIOCGCOLLECTIONINFO: - if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) { - r = -EFAULT; - break; - } + if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) + return -EFAULT; if (cinfo.index >= hid->maxcollection) - break; + return -EINVAL; cinfo.type = hid->collection[cinfo.index].type; cinfo.usage = hid->collection[cinfo.index].usage; cinfo.level = hid->collection[cinfo.index].level; - r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ? - -EFAULT : 0; - break; + if (copy_to_user(user_arg, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; default: + if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) - break; + return -EINVAL; if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { int len; - - if (!hid->name) { - r = 0; - break; - } - + if (!hid->name) + return 0; len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - r = copy_to_user(user_arg, hid->name, len) ? + return copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; - break; } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { int len; - - if (!hid->phys) { - r = 0; - break; - } - + if (!hid->phys) + return 0; len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - r = copy_to_user(user_arg, hid->phys, len) ? + return copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; - break; } } - -ret_unlock: - mutex_unlock(&hiddev->existancelock); - return r; + return -EINVAL; } #ifdef CONFIG_COMPAT @@ -905,7 +892,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) hiddev->exist = 1; retval = usb_register_dev(usbhid->intf, &hiddev_class); if (retval) { - hid_err(hid, "Not able to get a minor for this device\n"); + err_hid("Not able to get a minor for this device."); hid->hiddev = NULL; kfree(hiddev); return -1; diff --git a/trunk/drivers/hid/usbhid/usbhid.h b/trunk/drivers/hid/usbhid/usbhid.h index 1673cac93d77..89d2e847dcc6 100644 --- a/trunk/drivers/hid/usbhid/usbhid.h +++ b/trunk/drivers/hid/usbhid/usbhid.h @@ -95,6 +95,7 @@ struct usbhid_device { unsigned long stop_retry; /* Time to give up, in jiffies */ unsigned int retry_delay; /* Delay length in ms */ struct work_struct reset_work; /* Task context for resets */ + struct work_struct restart_work; /* waking up for output to be done in a task */ wait_queue_head_t wait; /* For sleeping */ int ledcount; /* counting the number of active leds */ }; diff --git a/trunk/drivers/hid/usbhid/usbkbd.c b/trunk/drivers/hid/usbhid/usbkbd.c index 065817329f03..a948605564fb 100644 --- a/trunk/drivers/hid/usbhid/usbkbd.c +++ b/trunk/drivers/hid/usbhid/usbkbd.c @@ -24,8 +24,6 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -106,18 +104,16 @@ static void usb_kbd_irq(struct urb *urb) if (usb_kbd_keycode[kbd->old[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); else - hid_info(urb->dev, - "Unknown key (scancode %#x) released.\n", - kbd->old[i]); + dev_info(&urb->dev->dev, + "Unknown key (scancode %#x) released.\n", kbd->old[i]); } if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (usb_kbd_keycode[kbd->new[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); else - hid_info(urb->dev, - "Unknown key (scancode %#x) released.\n", - kbd->new[i]); + dev_info(&urb->dev->dev, + "Unknown key (scancode %#x) released.\n", kbd->new[i]); } } @@ -128,9 +124,9 @@ static void usb_kbd_irq(struct urb *urb) resubmit: i = usb_submit_urb (urb, GFP_ATOMIC); if (i) - hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d", - kbd->usbdev->bus->bus_name, - kbd->usbdev->devpath, i); + err_hid ("can't resubmit intr, %s-%s/input0, status %d", + kbd->usbdev->bus->bus_name, + kbd->usbdev->devpath, i); } static int usb_kbd_event(struct input_dev *dev, unsigned int type, @@ -154,7 +150,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type, *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - pr_err("usb_submit_urb(leds) failed\n"); + err_hid("usb_submit_urb(leds) failed"); return 0; } @@ -164,7 +160,7 @@ static void usb_kbd_led(struct urb *urb) struct usb_kbd *kbd = urb->context; if (urb->status) - hid_warn(urb->dev, "led urb status %d received\n", + dev_warn(&urb->dev->dev, "led urb status %d received\n", urb->status); if (*(kbd->leds) == kbd->newleds) @@ -173,7 +169,7 @@ static void usb_kbd_led(struct urb *urb) *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - hid_err(urb->dev, "usb_submit_urb(leds) failed\n"); + err_hid("usb_submit_urb(leds) failed"); } static int usb_kbd_open(struct input_dev *dev) diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index bdc13d28b1ea..a56f6adf3b76 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -274,16 +274,6 @@ config SENSORS_ATXP1 This driver can also be built as a module. If so, the module will be called atxp1. -config SENSORS_DS620 - tristate "Dallas Semiconductor DS620" - depends on I2C - help - If you say yes here you get support for Dallas Semiconductor - DS620 sensor chip. - - This driver can also be built as a module. If so, the module - will be called ds620. - config SENSORS_DS1621 tristate "Dallas Semiconductor DS1621 and DS1625" depends on I2C @@ -744,16 +734,6 @@ config SENSORS_SHT15 This driver can also be built as a module. If so, the module will be called sht15. -config SENSORS_SHT21 - tristate "Sensiron humidity and temperature sensors. SHT21 and compat." - depends on I2C - help - If you say yes here you get support for the Sensiron SHT21, SHT25 - humidity and temperature sensors. - - This driver can also be built as a module. If so, the module - will be called sht21. - config SENSORS_S3C tristate "Samsung built-in ADC" depends on S3C_ADC diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index dde02d99c238..2479b3da272c 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_PKGTEMP) += pkgtemp.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o -obj-$(CONFIG_SENSORS_DS620) += ds620.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o @@ -91,7 +90,6 @@ obj-$(CONFIG_SENSORS_PC87427) += pc87427.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o obj-$(CONFIG_SENSORS_SHT15) += sht15.o -obj-$(CONFIG_SENSORS_SHT21) += sht21.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMM665) += smm665.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o diff --git a/trunk/drivers/hwmon/abituguru.c b/trunk/drivers/hwmon/abituguru.c index 8f07a9dda152..03694cc17a32 100644 --- a/trunk/drivers/hwmon/abituguru.c +++ b/trunk/drivers/hwmon/abituguru.c @@ -20,9 +20,6 @@ the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because of lack of specs the CPU/RAM voltage & frequency control is not supported! */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -223,10 +220,6 @@ struct abituguru_data { u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5]; }; -static const char *never_happen = "This should never happen."; -static const char *report_this = - "Please report this to the abituguru maintainer (see MAINTAINERS)"; - /* wait till the uguru is in the specified state */ static int abituguru_wait(struct abituguru_data *data, u8 state) { @@ -445,7 +438,8 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, /* Test val is sane / usable for sensor type detection. */ if ((val < 10u) || (val > 250u)) { - pr_warn("bank1-sensor: %d reading (%d) too close to limits, " + printk(KERN_WARNING ABIT_UGURU_NAME + ": bank1-sensor: %d reading (%d) too close to limits, " "unable to determine sensor type, skipping sensor\n", (int)sensor_addr, (int)val); /* assume no sensor is there for sensors for which we can't @@ -541,8 +535,10 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, 3) == 3) break; if (i == 3) { - pr_err("Fatal error could not restore original settings. %s %s\n", - never_happen, report_this); + printk(KERN_ERR ABIT_UGURU_NAME + ": Fatal error could not restore original settings. " + "This should never happen please report this to the " + "abituguru maintainer (see MAINTAINERS)\n"); return -ENODEV; } return ret; @@ -1272,12 +1268,14 @@ static int __devinit abituguru_probe(struct platform_device *pdev) } /* Fail safe check, this should never happen! */ if (sysfs_names_free < 0) { - pr_err("Fatal error ran out of space for sysfs attr names. %s %s", - never_happen, report_this); + printk(KERN_ERR ABIT_UGURU_NAME ": Fatal error ran out of " + "space for sysfs attr names. This should never " + "happen please report to the abituguru maintainer " + "(see MAINTAINERS)\n"); res = -ENAMETOOLONG; goto abituguru_probe_error; } - pr_info("found Abit uGuru\n"); + printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n"); /* Register sysfs hooks */ for (i = 0; i < sysfs_attr_i; i++) @@ -1434,7 +1432,8 @@ static int __init abituguru_detect(void) "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); if (force) { - pr_info("Assuming Abit uGuru is present because of \"force\" parameter\n"); + printk(KERN_INFO ABIT_UGURU_NAME ": Assuming Abit uGuru is " + "present because of \"force\" parameter\n"); return ABIT_UGURU_BASE; } @@ -1468,7 +1467,8 @@ static int __init abituguru_init(void) abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address); if (!abituguru_pdev) { - pr_err("Device allocation failed\n"); + printk(KERN_ERR ABIT_UGURU_NAME + ": Device allocation failed\n"); err = -ENOMEM; goto exit_driver_unregister; } @@ -1479,13 +1479,15 @@ static int __init abituguru_init(void) err = platform_device_add_resources(abituguru_pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR ABIT_UGURU_NAME + ": Device resource addition failed (%d)\n", err); goto exit_device_put; } err = platform_device_add(abituguru_pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR ABIT_UGURU_NAME + ": Device addition failed (%d)\n", err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/abituguru3.c b/trunk/drivers/hwmon/abituguru3.c index 48d21e22e930..3cf28af614b5 100644 --- a/trunk/drivers/hwmon/abituguru3.c +++ b/trunk/drivers/hwmon/abituguru3.c @@ -23,9 +23,6 @@ chip found on newer Abit uGuru motherboards. Note: because of lack of specs only reading the sensors and their settings is supported. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -611,9 +608,6 @@ static int verbose = 1; module_param(verbose, bool, 0644); MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting"); -static const char *never_happen = "This should never happen."; -static const char *report_this = - "Please report this to the abituguru3 maintainer (see MAINTAINERS)"; /* wait while the uguru is busy (usually after a write) */ static int abituguru3_wait_while_busy(struct abituguru3_data *data) @@ -946,13 +940,15 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) if (abituguru3_motherboards[i].id == id) break; if (!abituguru3_motherboards[i].id) { - pr_err("error unknown motherboard ID: %04X. %s\n", - (unsigned int)id, report_this); + printk(KERN_ERR ABIT_UGURU3_NAME ": error unknown motherboard " + "ID: %04X. Please report this to the abituguru3 " + "maintainer (see MAINTAINERS)\n", (unsigned int)id); goto abituguru3_probe_error; } data->sensors = abituguru3_motherboards[i].sensors; - pr_info("found Abit uGuru3, motherboard ID: %04X\n", (unsigned int)id); + printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " + "ID: %04X\n", (unsigned int)id); /* Fill the sysfs attr array */ sysfs_attr_i = 0; @@ -961,8 +957,11 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) for (i = 0; data->sensors[i].name; i++) { /* Fail safe check, this should never happen! */ if (i >= ABIT_UGURU3_MAX_NO_SENSORS) { - pr_err("Fatal error motherboard has more sensors then ABIT_UGURU3_MAX_NO_SENSORS. %s %s\n", - never_happen, report_this); + printk(KERN_ERR ABIT_UGURU3_NAME + ": Fatal error motherboard has more sensors " + "then ABIT_UGURU3_MAX_NO_SENSORS. This should " + "never happen please report to the abituguru3 " + "maintainer (see MAINTAINERS)\n"); res = -ENAMETOOLONG; goto abituguru3_probe_error; } @@ -984,8 +983,10 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) } /* Fail safe check, this should never happen! */ if (sysfs_names_free < 0) { - pr_err("Fatal error ran out of space for sysfs attr names. %s %s\n", - never_happen, report_this); + printk(KERN_ERR ABIT_UGURU3_NAME + ": Fatal error ran out of space for sysfs attr names. " + "This should never happen please report to the " + "abituguru3 maintainer (see MAINTAINERS)\n"); res = -ENAMETOOLONG; goto abituguru3_probe_error; } @@ -1188,7 +1189,8 @@ static int __init abituguru3_detect(void) "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); if (force) { - pr_info("Assuming Abit uGuru3 is present because of \"force\" parameter\n"); + printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " + "present because of \"force\" parameter\n"); return 0; } @@ -1217,8 +1219,10 @@ static int __init abituguru3_init(void) return err; #ifdef CONFIG_DMI - pr_warn("this motherboard was not detected using DMI. " - "Please send the output of \"dmidecode\" to the abituguru3 maintainer (see MAINTAINERS)\n"); + printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " + "not detected using DMI. Please send the output of " + "\"dmidecode\" to the abituguru3 maintainer " + "(see MAINTAINERS)\n"); #endif } @@ -1229,7 +1233,8 @@ static int __init abituguru3_init(void) abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, ABIT_UGURU3_BASE); if (!abituguru3_pdev) { - pr_err("Device allocation failed\n"); + printk(KERN_ERR ABIT_UGURU3_NAME + ": Device allocation failed\n"); err = -ENOMEM; goto exit_driver_unregister; } @@ -1240,13 +1245,15 @@ static int __init abituguru3_init(void) err = platform_device_add_resources(abituguru3_pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR ABIT_UGURU3_NAME + ": Device resource addition failed (%d)\n", err); goto exit_device_put; } err = platform_device_add(abituguru3_pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR ABIT_UGURU3_NAME + ": Device addition failed (%d)\n", err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/adt7470.c b/trunk/drivers/hwmon/adt7470.c index c6d1ce059aea..87d92a56a939 100644 --- a/trunk/drivers/hwmon/adt7470.c +++ b/trunk/drivers/hwmon/adt7470.c @@ -19,8 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -276,7 +274,7 @@ static int adt7470_read_temperatures(struct i2c_client *client, i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]); if (res) { - pr_err("ha ha, interrupted\n"); + printk(KERN_ERR "ha ha, interrupted"); return -EAGAIN; } diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c index ce0372f0615e..b6598aa557a0 100644 --- a/trunk/drivers/hwmon/applesmc.c +++ b/trunk/drivers/hwmon/applesmc.c @@ -4,7 +4,6 @@ * computers. * * Copyright (C) 2007 Nicolas Boichat - * Copyright (C) 2010 Henrik Rydberg * * Based on hdaps.c driver: * Copyright (C) 2005 Robert Love @@ -27,13 +26,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include #include -#include #include #include #include @@ -53,7 +49,6 @@ #define APPLESMC_MAX_DATA_LENGTH 32 -/* wait up to 32 ms for a status change. */ #define APPLESMC_MIN_WAIT 0x0040 #define APPLESMC_MAX_WAIT 0x8000 @@ -78,15 +73,104 @@ #define FANS_COUNT "FNum" /* r-o ui8 */ #define FANS_MANUAL "FS! " /* r-w ui16 */ -#define FAN_ID_FMT "F%dID" /* r-o char[16] */ +#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ +#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */ +#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */ +#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */ +#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */ +#define FAN_POSITION "F0ID" /* r-o char[16] */ + +/* + * Temperature sensors keys (sp78 - 2 bytes). + */ +static const char *temperature_sensors_sets[][41] = { +/* Set 0: Macbook Pro */ + { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", + "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, +/* Set 1: Macbook2 set */ + { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H", + "Th0S", "Th1H", NULL }, +/* Set 2: Macbook set */ + { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", + "Th1H", "Ts0P", NULL }, +/* Set 3: Macmini set */ + { "TC0D", "TC0P", NULL }, +/* Set 4: Mac Pro (2 x Quad-Core) */ + { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", + "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P", + "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", + "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", + "TM9S", "TN0H", "TS0C", NULL }, +/* Set 5: iMac */ + { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P", + "Tp0C", NULL }, +/* Set 6: Macbook3 set */ + { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H", + "Th0S", "Th1H", NULL }, +/* Set 7: Macbook Air */ + { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP", + "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL }, +/* Set 8: Macbook Pro 4,1 (Penryn) */ + { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H", + "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, +/* Set 9: Macbook Pro 3,1 (Santa Rosa) */ + { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", + "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, +/* Set 10: iMac 5,1 */ + { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL }, +/* Set 11: Macbook 5,1 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P", + "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL }, +/* Set 12: Macbook Pro 5,1 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", + "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0", + "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL }, +/* Set 13: iMac 8,1 */ + { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", + "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL }, +/* Set 14: iMac 6,1 */ + { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", + "TO0P", "Tp0P", NULL }, +/* Set 15: MacBook Air 2,1 */ + { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0", + "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P", + "Ts0S", NULL }, +/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */ + { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", + "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P", + "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P", + "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", + "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", + NULL }, +/* Set 17: iMac 9,1 */ + { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P", + "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL }, +/* Set 18: MacBook Pro 2,2 */ + { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", + "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, +/* Set 19: Macbook Pro 5,3 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", + "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H", + "Tm0P", "Ts0P", "Ts0S", NULL }, +/* Set 20: MacBook Pro 5,4 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D", + "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL }, +/* Set 21: MacBook Pro 6,2 */ + { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D", + "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P", + "Ts0P", "Ts0S", NULL }, +/* Set 22: MacBook Pro 7,1 */ + { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S", + "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL }, +}; /* List of keys used to read/write fan speeds */ -static const char *const fan_speed_fmt[] = { - "F%dAc", /* actual speed */ - "F%dMn", /* minimum speed (rw) */ - "F%dMx", /* maximum speed */ - "F%dSf", /* safe speed - not all models */ - "F%dTg", /* target speed (manual: rw) */ +static const char* fan_speed_keys[] = { + FAN_ACTUAL_SPEED, + FAN_MIN_SPEED, + FAN_MAX_SPEED, + FAN_SAFE_SPEED, + FAN_TARGET_SPEED }; #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ @@ -100,48 +184,14 @@ static const char *const fan_speed_fmt[] = { #define SENSOR_Y 1 #define SENSOR_Z 2 -#define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff) -#define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16) - -/* Dynamic device node attributes */ -struct applesmc_dev_attr { - struct sensor_device_attribute sda; /* hwmon attributes */ - char name[32]; /* room for node file name */ -}; - -/* Dynamic device node group */ -struct applesmc_node_group { - char *format; /* format string */ - void *show; /* show function */ - void *store; /* store function */ - int option; /* function argument */ - struct applesmc_dev_attr *nodes; /* dynamic node array */ -}; - -/* AppleSMC entry - cached register information */ -struct applesmc_entry { - char key[5]; /* four-letter key code */ - u8 valid; /* set when entry is successfully read once */ - u8 len; /* bounded by APPLESMC_MAX_DATA_LENGTH */ - char type[5]; /* four-letter type code */ - u8 flags; /* 0x10: func; 0x40: write; 0x80: read */ -}; - -/* Register lookup and registers common to all SMCs */ -static struct applesmc_registers { - struct mutex mutex; /* register read/write mutex */ - unsigned int key_count; /* number of SMC registers */ - unsigned int fan_count; /* number of fans */ - unsigned int temp_count; /* number of temperature registers */ - unsigned int temp_begin; /* temperature lower index bound */ - unsigned int temp_end; /* temperature upper index bound */ - int num_light_sensors; /* number of light sensors */ - bool has_accelerometer; /* has motion sensor */ - bool has_key_backlight; /* has keyboard backlight */ - bool init_complete; /* true when fully initialized */ - struct applesmc_entry *cache; /* cached key entries */ -} smcreg = { - .mutex = __MUTEX_INITIALIZER(smcreg.mutex), +/* Structure to be passed to DMI_MATCH function */ +struct dmi_match_data { +/* Indicates whether this computer has an accelerometer. */ + int accelerometer; +/* Indicates whether this computer has light sensors and keyboard backlight. */ + int light; +/* Indicates which temperature sensors set to use. */ + int temperature_set; }; static const int debug; @@ -153,6 +203,20 @@ static u8 backlight_state[2]; static struct device *hwmon_dev; static struct input_polled_dev *applesmc_idev; +/* Indicates whether this computer has an accelerometer. */ +static unsigned int applesmc_accelerometer; + +/* Indicates whether this computer has light sensors and keyboard backlight. */ +static unsigned int applesmc_light; + +/* The number of fans handled by the driver */ +static unsigned int fans_handled; + +/* Indicates which temperature sensors set to use. */ +static unsigned int applesmc_temperature_set; + +static DEFINE_MUTEX(applesmc_lock); + /* * Last index written to key_at_index sysfs file, and value to use for all other * key_at_index_* sysfs files. @@ -174,10 +238,18 @@ static int __wait_status(u8 val) for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { udelay(us); - if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) + if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { + if (debug) + printk(KERN_DEBUG + "Waited %d us for status %x\n", + 2 * us - APPLESMC_MIN_WAIT, val); return 0; + } } + printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", + val, inb(APPLESMC_CMD_PORT)); + return -EIO; } @@ -195,242 +267,159 @@ static int send_command(u8 cmd) if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) return 0; } + printk(KERN_WARNING "applesmc: command failed: %x -> %x\n", + cmd, inb(APPLESMC_CMD_PORT)); return -EIO; } -static int send_argument(const char *key) +/* + * applesmc_read_key - reads len bytes from a given key, and put them in buffer. + * Returns zero on success or a negative error on failure. Callers must + * hold applesmc_lock. + */ +static int applesmc_read_key(const char* key, u8* buffer, u8 len) { int i; + if (len > APPLESMC_MAX_DATA_LENGTH) { + printk(KERN_ERR "applesmc_read_key: cannot read more than " + "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); + return -EINVAL; + } + + if (send_command(APPLESMC_READ_CMD)) + return -EIO; + for (i = 0; i < 4; i++) { outb(key[i], APPLESMC_DATA_PORT); if (__wait_status(0x04)) return -EIO; } - return 0; -} - -static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) -{ - int i; - - if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: read arg fail\n", key); - return -EIO; - } + if (debug) + printk(KERN_DEBUG "<%s", key); outb(len, APPLESMC_DATA_PORT); + if (debug) + printk(KERN_DEBUG ">%x", len); for (i = 0; i < len; i++) { - if (__wait_status(0x05)) { - pr_warn("%s: read data fail\n", key); + if (__wait_status(0x05)) return -EIO; - } buffer[i] = inb(APPLESMC_DATA_PORT); + if (debug) + printk(KERN_DEBUG "<%x", buffer[i]); } + if (debug) + printk(KERN_DEBUG "\n"); return 0; } -static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len) +/* + * applesmc_write_key - writes len bytes from buffer to a given key. + * Returns zero on success or a negative error on failure. Callers must + * hold applesmc_lock. + */ +static int applesmc_write_key(const char* key, u8* buffer, u8 len) { int i; - if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: write arg fail\n", key); + if (len > APPLESMC_MAX_DATA_LENGTH) { + printk(KERN_ERR "applesmc_write_key: cannot write more than " + "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); + return -EINVAL; + } + + if (send_command(APPLESMC_WRITE_CMD)) return -EIO; + + for (i = 0; i < 4; i++) { + outb(key[i], APPLESMC_DATA_PORT); + if (__wait_status(0x04)) + return -EIO; } outb(len, APPLESMC_DATA_PORT); for (i = 0; i < len; i++) { - if (__wait_status(0x04)) { - pr_warn("%s: write data fail\n", key); + if (__wait_status(0x04)) return -EIO; - } outb(buffer[i], APPLESMC_DATA_PORT); } return 0; } -static int read_register_count(unsigned int *count) -{ - __be32 be; - int ret; - - ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4); - if (ret) - return ret; - - *count = be32_to_cpu(be); - return 0; -} - /* - * Serialized I/O - * - * Returns zero on success or a negative error on failure. - * All functions below are concurrency safe - callers should NOT hold lock. + * applesmc_get_key_at_index - get key at index, and put the result in key + * (char[6]). Returns zero on success or a negative error on failure. Callers + * must hold applesmc_lock. */ - -static int applesmc_read_entry(const struct applesmc_entry *entry, - u8 *buf, u8 len) +static int applesmc_get_key_at_index(int index, char* key) { - int ret; - - if (entry->len != len) - return -EINVAL; - mutex_lock(&smcreg.mutex); - ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); - mutex_unlock(&smcreg.mutex); - - return ret; -} - -static int applesmc_write_entry(const struct applesmc_entry *entry, - const u8 *buf, u8 len) -{ - int ret; - - if (entry->len != len) - return -EINVAL; - mutex_lock(&smcreg.mutex); - ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); - mutex_unlock(&smcreg.mutex); - return ret; -} - -static const struct applesmc_entry *applesmc_get_entry_by_index(int index) -{ - struct applesmc_entry *cache = &smcreg.cache[index]; - u8 key[4], info[6]; - __be32 be; - int ret = 0; - - if (cache->valid) - return cache; - - mutex_lock(&smcreg.mutex); - - if (cache->valid) - goto out; - be = cpu_to_be32(index); - ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4); - if (ret) - goto out; - ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6); - if (ret) - goto out; - - memcpy(cache->key, key, 4); - cache->len = info[0]; - memcpy(cache->type, &info[1], 4); - cache->flags = info[5]; - cache->valid = 1; + int i; + u8 readkey[4]; + readkey[0] = index >> 24; + readkey[1] = index >> 16; + readkey[2] = index >> 8; + readkey[3] = index; -out: - mutex_unlock(&smcreg.mutex); - if (ret) - return ERR_PTR(ret); - return cache; -} + if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) + return -EIO; -static int applesmc_get_lower_bound(unsigned int *lo, const char *key) -{ - int begin = 0, end = smcreg.key_count; - const struct applesmc_entry *entry; - - while (begin != end) { - int middle = begin + (end - begin) / 2; - entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) - return PTR_ERR(entry); - if (strcmp(entry->key, key) < 0) - begin = middle + 1; - else - end = middle; + for (i = 0; i < 4; i++) { + outb(readkey[i], APPLESMC_DATA_PORT); + if (__wait_status(0x04)) + return -EIO; } - *lo = begin; - return 0; -} + outb(4, APPLESMC_DATA_PORT); -static int applesmc_get_upper_bound(unsigned int *hi, const char *key) -{ - int begin = 0, end = smcreg.key_count; - const struct applesmc_entry *entry; - - while (begin != end) { - int middle = begin + (end - begin) / 2; - entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) - return PTR_ERR(entry); - if (strcmp(key, entry->key) < 0) - end = middle; - else - begin = middle + 1; + for (i = 0; i < 4; i++) { + if (__wait_status(0x05)) + return -EIO; + key[i] = inb(APPLESMC_DATA_PORT); } + key[4] = 0; - *hi = begin; return 0; } -static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key) -{ - int begin, end; - int ret; - - ret = applesmc_get_lower_bound(&begin, key); - if (ret) - return ERR_PTR(ret); - ret = applesmc_get_upper_bound(&end, key); - if (ret) - return ERR_PTR(ret); - if (end - begin != 1) - return ERR_PTR(-EINVAL); - - return applesmc_get_entry_by_index(begin); -} - -static int applesmc_read_key(const char *key, u8 *buffer, u8 len) -{ - const struct applesmc_entry *entry; - - entry = applesmc_get_entry_by_key(key); - if (IS_ERR(entry)) - return PTR_ERR(entry); - - return applesmc_read_entry(entry, buffer, len); -} - -static int applesmc_write_key(const char *key, const u8 *buffer, u8 len) +/* + * applesmc_get_key_type - get key type, and put the result in type (char[6]). + * Returns zero on success or a negative error on failure. Callers must + * hold applesmc_lock. + */ +static int applesmc_get_key_type(char* key, char* type) { - const struct applesmc_entry *entry; + int i; - entry = applesmc_get_entry_by_key(key); - if (IS_ERR(entry)) - return PTR_ERR(entry); + if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) + return -EIO; - return applesmc_write_entry(entry, buffer, len); -} + for (i = 0; i < 4; i++) { + outb(key[i], APPLESMC_DATA_PORT); + if (__wait_status(0x04)) + return -EIO; + } -static int applesmc_has_key(const char *key, bool *value) -{ - const struct applesmc_entry *entry; + outb(6, APPLESMC_DATA_PORT); - entry = applesmc_get_entry_by_key(key); - if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) - return PTR_ERR(entry); + for (i = 0; i < 6; i++) { + if (__wait_status(0x05)) + return -EIO; + type[i] = inb(APPLESMC_DATA_PORT); + } + type[5] = 0; - *value = !IS_ERR(entry); return 0; } /* - * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). + * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must + * hold applesmc_lock. */ -static int applesmc_read_motion_sensor(int index, s16 *value) +static int applesmc_read_motion_sensor(int index, s16* value) { u8 buffer[2]; int ret; @@ -455,120 +444,69 @@ static int applesmc_read_motion_sensor(int index, s16 *value) } /* - * applesmc_device_init - initialize the accelerometer. Can sleep. + * applesmc_device_init - initialize the accelerometer. Returns zero on success + * and negative error code on failure. Can sleep. */ -static void applesmc_device_init(void) +static int applesmc_device_init(void) { - int total; + int total, ret = -ENXIO; u8 buffer[2]; - if (!smcreg.has_accelerometer) - return; + if (!applesmc_accelerometer) + return 0; + + mutex_lock(&applesmc_lock); for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { + if (debug) + printk(KERN_DEBUG "applesmc try %d\n", total); if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && - (buffer[0] != 0x00 || buffer[1] != 0x00)) - return; + (buffer[0] != 0x00 || buffer[1] != 0x00)) { + if (total == INIT_TIMEOUT_MSECS) { + printk(KERN_DEBUG "applesmc: device has" + " already been initialized" + " (0x%02x, 0x%02x).\n", + buffer[0], buffer[1]); + } else { + printk(KERN_DEBUG "applesmc: device" + " successfully initialized" + " (0x%02x, 0x%02x).\n", + buffer[0], buffer[1]); + } + ret = 0; + goto out; + } buffer[0] = 0xe0; buffer[1] = 0x00; applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); msleep(INIT_WAIT_MSECS); } - pr_warn("failed to init the device\n"); + printk(KERN_WARNING "applesmc: failed to init the device\n"); + +out: + mutex_unlock(&applesmc_lock); + return ret; } /* - * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. + * applesmc_get_fan_count - get the number of fans. Callers must NOT hold + * applesmc_lock. */ -static int applesmc_init_smcreg_try(void) +static int applesmc_get_fan_count(void) { - struct applesmc_registers *s = &smcreg; - bool left_light_sensor, right_light_sensor; - u8 tmp[1]; int ret; + u8 buffer[1]; - if (s->init_complete) - return 0; + mutex_lock(&applesmc_lock); - ret = read_register_count(&s->key_count); - if (ret) - return ret; - - if (!s->cache) - s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); - if (!s->cache) - return -ENOMEM; + ret = applesmc_read_key(FANS_COUNT, buffer, 1); - ret = applesmc_read_key(FANS_COUNT, tmp, 1); - if (ret) - return ret; - s->fan_count = tmp[0]; - - ret = applesmc_get_lower_bound(&s->temp_begin, "T"); - if (ret) - return ret; - ret = applesmc_get_lower_bound(&s->temp_end, "U"); - if (ret) - return ret; - s->temp_count = s->temp_end - s->temp_begin; - - ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); - if (ret) - return ret; - ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); - if (ret) - return ret; - ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); + mutex_unlock(&applesmc_lock); if (ret) return ret; - ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); - if (ret) - return ret; - - s->num_light_sensors = left_light_sensor + right_light_sensor; - s->init_complete = true; - - pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n", - s->key_count, s->fan_count, s->temp_count, - s->has_accelerometer, - s->num_light_sensors, - s->has_key_backlight); - - return 0; -} - -/* - * applesmc_init_smcreg - Initialize register cache. - * - * Retries until initialization is successful, or the operation times out. - * - */ -static int applesmc_init_smcreg(void) -{ - int ms, ret; - - for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) { - ret = applesmc_init_smcreg_try(); - if (!ret) { - if (ms) - pr_info("init_smcreg() took %d ms\n", ms); - return 0; - } - msleep(INIT_WAIT_MSECS); - } - - kfree(smcreg.cache); - smcreg.cache = NULL; - - return ret; -} - -static void applesmc_destroy_smcreg(void) -{ - kfree(smcreg.cache); - smcreg.cache = NULL; - smcreg.init_complete = false; + else + return buffer[0]; } /* Device model stuff */ @@ -576,27 +514,30 @@ static int applesmc_probe(struct platform_device *dev) { int ret; - ret = applesmc_init_smcreg(); + ret = applesmc_device_init(); if (ret) return ret; - applesmc_device_init(); - + printk(KERN_INFO "applesmc: device successfully initialized.\n"); return 0; } /* Synchronize device with memorized backlight state */ static int applesmc_pm_resume(struct device *dev) { - if (smcreg.has_key_backlight) + mutex_lock(&applesmc_lock); + if (applesmc_light) applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); + mutex_unlock(&applesmc_lock); return 0; } /* Reinitialize device on resume from hibernation */ static int applesmc_pm_restore(struct device *dev) { - applesmc_device_init(); + int ret = applesmc_device_init(); + if (ret) + return ret; return applesmc_pm_resume(dev); } @@ -630,15 +571,20 @@ static void applesmc_idev_poll(struct input_polled_dev *dev) struct input_dev *idev = dev->input; s16 x, y; + mutex_lock(&applesmc_lock); + if (applesmc_read_motion_sensor(SENSOR_X, &x)) - return; + goto out; if (applesmc_read_motion_sensor(SENSOR_Y, &y)) - return; + goto out; x = -x; input_report_abs(idev, ABS_X, x - rest_x); input_report_abs(idev, ABS_Y, y - rest_y); input_sync(idev); + +out: + mutex_unlock(&applesmc_lock); } /* Sysfs Files */ @@ -655,6 +601,8 @@ static ssize_t applesmc_position_show(struct device *dev, int ret; s16 x, y, z; + mutex_lock(&applesmc_lock); + ret = applesmc_read_motion_sensor(SENSOR_X, &x); if (ret) goto out; @@ -666,6 +614,7 @@ static ssize_t applesmc_position_show(struct device *dev, goto out; out: + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -675,20 +624,20 @@ static ssize_t applesmc_position_show(struct device *dev, static ssize_t applesmc_light_show(struct device *dev, struct device_attribute *attr, char *sysfsbuf) { - const struct applesmc_entry *entry; static int data_length; int ret; u8 left = 0, right = 0; - u8 buffer[10]; + u8 buffer[10], query[6]; + + mutex_lock(&applesmc_lock); if (!data_length) { - entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY); - if (IS_ERR(entry)) - return PTR_ERR(entry); - if (entry->len > 10) - return -ENXIO; - data_length = entry->len; - pr_info("light sensor data length set to %d\n", data_length); + ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query); + if (ret) + goto out; + data_length = clamp_val(query[0], 0, 10); + printk(KERN_INFO "applesmc: light sensor data length set to " + "%d\n", data_length); } ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); @@ -704,6 +653,7 @@ static ssize_t applesmc_light_show(struct device *dev, right = buffer[2]; out: + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -714,44 +664,36 @@ static ssize_t applesmc_light_show(struct device *dev, static ssize_t applesmc_show_sensor_label(struct device *dev, struct device_attribute *devattr, char *sysfsbuf) { - int index = smcreg.temp_begin + to_index(devattr); - const struct applesmc_entry *entry; - - entry = applesmc_get_entry_by_index(index); - if (IS_ERR(entry)) - return PTR_ERR(entry); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const char *key = + temperature_sensors_sets[applesmc_temperature_set][attr->index]; - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); } /* Displays degree Celsius * 1000 */ static ssize_t applesmc_show_temperature(struct device *dev, struct device_attribute *devattr, char *sysfsbuf) { - int index = smcreg.temp_begin + to_index(devattr); - const struct applesmc_entry *entry; int ret; u8 buffer[2]; unsigned int temp; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const char* key = + temperature_sensors_sets[applesmc_temperature_set][attr->index]; - entry = applesmc_get_entry_by_index(index); - if (IS_ERR(entry)) - return PTR_ERR(entry); - if (entry->len > 2) - return -EINVAL; + mutex_lock(&applesmc_lock); - ret = applesmc_read_entry(entry, buffer, entry->len); - if (ret) - return ret; + ret = applesmc_read_key(key, buffer, 2); + temp = buffer[0]*1000; + temp += (buffer[1] >> 6) * 250; - if (entry->len == 2) { - temp = buffer[0] * 1000; - temp += (buffer[1] >> 6) * 250; - } else { - temp = buffer[0] * 4000; - } + mutex_unlock(&applesmc_lock); - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); + if (ret) + return ret; + else + return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); } static ssize_t applesmc_show_fan_speed(struct device *dev, @@ -761,12 +703,21 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, unsigned int speed = 0; char newkey[5]; u8 buffer[2]; + struct sensor_device_attribute_2 *sensor_attr = + to_sensor_dev_attr_2(attr); + + newkey[0] = fan_speed_keys[sensor_attr->nr][0]; + newkey[1] = '0' + sensor_attr->index; + newkey[2] = fan_speed_keys[sensor_attr->nr][2]; + newkey[3] = fan_speed_keys[sensor_attr->nr][3]; + newkey[4] = 0; - sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); + mutex_lock(&applesmc_lock); ret = applesmc_read_key(newkey, buffer, 2); speed = ((buffer[0] << 8 | buffer[1]) >> 2); + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -778,19 +729,30 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, const char *sysfsbuf, size_t count) { int ret; - unsigned long speed; + u32 speed; char newkey[5]; u8 buffer[2]; + struct sensor_device_attribute_2 *sensor_attr = + to_sensor_dev_attr_2(attr); + + speed = simple_strtoul(sysfsbuf, NULL, 10); + + if (speed > 0x4000) /* Bigger than a 14-bit value */ + return -EINVAL; - if (strict_strtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000) - return -EINVAL; /* Bigger than a 14-bit value */ + newkey[0] = fan_speed_keys[sensor_attr->nr][0]; + newkey[1] = '0' + sensor_attr->index; + newkey[2] = fan_speed_keys[sensor_attr->nr][2]; + newkey[3] = fan_speed_keys[sensor_attr->nr][3]; + newkey[4] = 0; - sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); + mutex_lock(&applesmc_lock); buffer[0] = (speed >> 6) & 0xff; buffer[1] = (speed << 2) & 0xff; ret = applesmc_write_key(newkey, buffer, 2); + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -798,15 +760,19 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, } static ssize_t applesmc_show_fan_manual(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) + struct device_attribute *devattr, char *sysfsbuf) { int ret; u16 manual = 0; u8 buffer[2]; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + + mutex_lock(&applesmc_lock); ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -814,16 +780,18 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, } static ssize_t applesmc_store_fan_manual(struct device *dev, - struct device_attribute *attr, + struct device_attribute *devattr, const char *sysfsbuf, size_t count) { int ret; u8 buffer[2]; - unsigned long input; + u32 input; u16 val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - if (strict_strtoul(sysfsbuf, 10, &input) < 0) - return -EINVAL; + input = simple_strtoul(sysfsbuf, NULL, 10); + + mutex_lock(&applesmc_lock); ret = applesmc_read_key(FANS_MANUAL, buffer, 2); val = (buffer[0] << 8 | buffer[1]); @@ -831,9 +799,9 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, goto out; if (input) - val = val | (0x01 << to_index(attr)); + val = val | (0x01 << attr->index); else - val = val & ~(0x01 << to_index(attr)); + val = val & ~(0x01 << attr->index); buffer[0] = (val >> 8) & 0xFF; buffer[1] = val & 0xFF; @@ -841,6 +809,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, ret = applesmc_write_key(FANS_MANUAL, buffer, 2); out: + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -853,12 +822,21 @@ static ssize_t applesmc_show_fan_position(struct device *dev, int ret; char newkey[5]; u8 buffer[17]; + struct sensor_device_attribute_2 *sensor_attr = + to_sensor_dev_attr_2(attr); + + newkey[0] = FAN_POSITION[0]; + newkey[1] = '0' + sensor_attr->index; + newkey[2] = FAN_POSITION[2]; + newkey[3] = FAN_POSITION[3]; + newkey[4] = 0; - sprintf(newkey, FAN_ID_FMT, to_index(attr)); + mutex_lock(&applesmc_lock); ret = applesmc_read_key(newkey, buffer, 16); buffer[16] = 0; + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -874,14 +852,18 @@ static ssize_t applesmc_calibrate_show(struct device *dev, static ssize_t applesmc_calibrate_store(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count) { + mutex_lock(&applesmc_lock); applesmc_calibrate(); + mutex_unlock(&applesmc_lock); return count; } static void applesmc_backlight_set(struct work_struct *work) { + mutex_lock(&applesmc_lock); applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); + mutex_unlock(&applesmc_lock); } static DECLARE_WORK(backlight_work, &applesmc_backlight_set); @@ -904,10 +886,13 @@ static ssize_t applesmc_key_count_show(struct device *dev, u8 buffer[4]; u32 count; + mutex_lock(&applesmc_lock); + ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + ((u32)buffer[2]<<8) + buffer[3]; + mutex_unlock(&applesmc_lock); if (ret) return ret; else @@ -917,53 +902,113 @@ static ssize_t applesmc_key_count_show(struct device *dev, static ssize_t applesmc_key_at_index_read_show(struct device *dev, struct device_attribute *attr, char *sysfsbuf) { - const struct applesmc_entry *entry; + char key[5]; + char info[6]; int ret; - entry = applesmc_get_entry_by_index(key_at_index); - if (IS_ERR(entry)) - return PTR_ERR(entry); - ret = applesmc_read_entry(entry, sysfsbuf, entry->len); - if (ret) + mutex_lock(&applesmc_lock); + + ret = applesmc_get_key_at_index(key_at_index, key); + + if (ret || !key[0]) { + mutex_unlock(&applesmc_lock); + + return -EINVAL; + } + + ret = applesmc_get_key_type(key, info); + + if (ret) { + mutex_unlock(&applesmc_lock); + return ret; + } + + /* + * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than + * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf. + */ + ret = applesmc_read_key(key, sysfsbuf, info[0]); + + mutex_unlock(&applesmc_lock); - return entry->len; + if (!ret) { + return info[0]; + } else { + return ret; + } } static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, struct device_attribute *attr, char *sysfsbuf) { - const struct applesmc_entry *entry; + char key[5]; + char info[6]; + int ret; + + mutex_lock(&applesmc_lock); + + ret = applesmc_get_key_at_index(key_at_index, key); - entry = applesmc_get_entry_by_index(key_at_index); - if (IS_ERR(entry)) - return PTR_ERR(entry); + if (ret || !key[0]) { + mutex_unlock(&applesmc_lock); - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", entry->len); + return -EINVAL; + } + + ret = applesmc_get_key_type(key, info); + + mutex_unlock(&applesmc_lock); + + if (!ret) + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]); + else + return ret; } static ssize_t applesmc_key_at_index_type_show(struct device *dev, struct device_attribute *attr, char *sysfsbuf) { - const struct applesmc_entry *entry; + char key[5]; + char info[6]; + int ret; + + mutex_lock(&applesmc_lock); + + ret = applesmc_get_key_at_index(key_at_index, key); + + if (ret || !key[0]) { + mutex_unlock(&applesmc_lock); + + return -EINVAL; + } + + ret = applesmc_get_key_type(key, info); - entry = applesmc_get_entry_by_index(key_at_index); - if (IS_ERR(entry)) - return PTR_ERR(entry); + mutex_unlock(&applesmc_lock); - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->type); + if (!ret) + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1); + else + return ret; } static ssize_t applesmc_key_at_index_name_show(struct device *dev, struct device_attribute *attr, char *sysfsbuf) { - const struct applesmc_entry *entry; + char key[5]; + int ret; - entry = applesmc_get_entry_by_index(key_at_index); - if (IS_ERR(entry)) - return PTR_ERR(entry); + mutex_lock(&applesmc_lock); - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); + ret = applesmc_get_key_at_index(key_at_index, key); + + mutex_unlock(&applesmc_lock); + + if (!ret && key[0]) + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); + else + return -EINVAL; } static ssize_t applesmc_key_at_index_show(struct device *dev, @@ -975,13 +1020,12 @@ static ssize_t applesmc_key_at_index_show(struct device *dev, static ssize_t applesmc_key_at_index_store(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count) { - unsigned long newkey; + mutex_lock(&applesmc_lock); - if (strict_strtoul(sysfsbuf, 10, &newkey) < 0 - || newkey >= smcreg.key_count) - return -EINVAL; + key_at_index = simple_strtoul(sysfsbuf, NULL, 10); + + mutex_unlock(&applesmc_lock); - key_at_index = newkey; return count; } @@ -991,101 +1035,387 @@ static struct led_classdev applesmc_backlight = { .brightness_set = applesmc_brightness_set, }; -static struct applesmc_node_group info_group[] = { - { "name", applesmc_name_show }, - { "key_count", applesmc_key_count_show }, - { "key_at_index", applesmc_key_at_index_show, applesmc_key_at_index_store }, - { "key_at_index_name", applesmc_key_at_index_name_show }, - { "key_at_index_type", applesmc_key_at_index_type_show }, - { "key_at_index_data_length", applesmc_key_at_index_data_length_show }, - { "key_at_index_data", applesmc_key_at_index_read_show }, - { } -}; +static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); -static struct applesmc_node_group accelerometer_group[] = { - { "position", applesmc_position_show }, - { "calibrate", applesmc_calibrate_show, applesmc_calibrate_store }, - { } -}; +static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); +static DEVICE_ATTR(calibrate, 0644, + applesmc_calibrate_show, applesmc_calibrate_store); -static struct applesmc_node_group light_sensor_group[] = { - { "light", applesmc_light_show }, - { } +static struct attribute *accelerometer_attributes[] = { + &dev_attr_position.attr, + &dev_attr_calibrate.attr, + NULL }; -static struct applesmc_node_group fan_group[] = { - { "fan%d_label", applesmc_show_fan_position }, - { "fan%d_input", applesmc_show_fan_speed, NULL, 0 }, - { "fan%d_min", applesmc_show_fan_speed, applesmc_store_fan_speed, 1 }, - { "fan%d_max", applesmc_show_fan_speed, NULL, 2 }, - { "fan%d_safe", applesmc_show_fan_speed, NULL, 3 }, - { "fan%d_output", applesmc_show_fan_speed, applesmc_store_fan_speed, 4 }, - { "fan%d_manual", applesmc_show_fan_manual, applesmc_store_fan_manual }, - { } +static const struct attribute_group accelerometer_attributes_group = + { .attrs = accelerometer_attributes }; + +static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); + +static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL); +static DEVICE_ATTR(key_at_index, 0644, + applesmc_key_at_index_show, applesmc_key_at_index_store); +static DEVICE_ATTR(key_at_index_name, 0444, + applesmc_key_at_index_name_show, NULL); +static DEVICE_ATTR(key_at_index_type, 0444, + applesmc_key_at_index_type_show, NULL); +static DEVICE_ATTR(key_at_index_data_length, 0444, + applesmc_key_at_index_data_length_show, NULL); +static DEVICE_ATTR(key_at_index_data, 0444, + applesmc_key_at_index_read_show, NULL); + +static struct attribute *key_enumeration_attributes[] = { + &dev_attr_key_count.attr, + &dev_attr_key_at_index.attr, + &dev_attr_key_at_index_name.attr, + &dev_attr_key_at_index_type.attr, + &dev_attr_key_at_index_data_length.attr, + &dev_attr_key_at_index_data.attr, + NULL }; -static struct applesmc_node_group temp_group[] = { - { "temp%d_label", applesmc_show_sensor_label }, - { "temp%d_input", applesmc_show_temperature }, - { } +static const struct attribute_group key_enumeration_group = + { .attrs = key_enumeration_attributes }; + +/* + * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries. + * - show actual speed + * - show/store minimum speed + * - show maximum speed + * - show safe speed + * - show/store target speed + * - show/store manual mode + */ +#define sysfs_fan_speeds_offset(offset) \ +static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \ + applesmc_show_fan_speed, NULL, 0, offset-1); \ +\ +static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \ + applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \ +\ +static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \ + applesmc_show_fan_speed, NULL, 2, offset-1); \ +\ +static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \ + applesmc_show_fan_speed, NULL, 3, offset-1); \ +\ +static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \ + applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \ +\ +static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \ + applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \ +\ +static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \ + applesmc_show_fan_position, NULL, offset-1); \ +\ +static struct attribute *fan##offset##_attributes[] = { \ + &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \ + NULL \ }; -/* Module stuff */ +/* + * Create the needed functions for each fan using the macro defined above + * (4 fans are supported) + */ +sysfs_fan_speeds_offset(1); +sysfs_fan_speeds_offset(2); +sysfs_fan_speeds_offset(3); +sysfs_fan_speeds_offset(4); + +static const struct attribute_group fan_attribute_groups[] = { + { .attrs = fan1_attributes }, + { .attrs = fan2_attributes }, + { .attrs = fan3_attributes }, + { .attrs = fan4_attributes }, +}; /* - * applesmc_destroy_nodes - remove files and free associated memory + * Temperature sensors sysfs entries. */ -static void applesmc_destroy_nodes(struct applesmc_node_group *groups) -{ - struct applesmc_node_group *grp; - struct applesmc_dev_attr *node; - - for (grp = groups; grp->nodes; grp++) { - for (node = grp->nodes; node->sda.dev_attr.attr.name; node++) - sysfs_remove_file(&pdev->dev.kobj, - &node->sda.dev_attr.attr); - kfree(grp->nodes); - grp->nodes = NULL; - } -} +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 12); +static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 13); +static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 14); +static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 15); +static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 16); +static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 17); +static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 18); +static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 19); +static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 20); +static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 21); +static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 22); +static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 23); +static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 24); +static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 25); +static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 26); +static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 27); +static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 28); +static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 29); +static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 30); +static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 31); +static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 32); +static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 33); +static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 34); +static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 35); +static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 36); +static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 37); +static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 38); +static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 39); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, + applesmc_show_temperature, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, + applesmc_show_temperature, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, + applesmc_show_temperature, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, + applesmc_show_temperature, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, + applesmc_show_temperature, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, + applesmc_show_temperature, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, + applesmc_show_temperature, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, + applesmc_show_temperature, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, + applesmc_show_temperature, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, + applesmc_show_temperature, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, + applesmc_show_temperature, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, + applesmc_show_temperature, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, + applesmc_show_temperature, NULL, 12); +static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, + applesmc_show_temperature, NULL, 13); +static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, + applesmc_show_temperature, NULL, 14); +static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO, + applesmc_show_temperature, NULL, 15); +static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO, + applesmc_show_temperature, NULL, 16); +static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO, + applesmc_show_temperature, NULL, 17); +static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO, + applesmc_show_temperature, NULL, 18); +static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO, + applesmc_show_temperature, NULL, 19); +static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO, + applesmc_show_temperature, NULL, 20); +static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO, + applesmc_show_temperature, NULL, 21); +static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO, + applesmc_show_temperature, NULL, 22); +static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO, + applesmc_show_temperature, NULL, 23); +static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO, + applesmc_show_temperature, NULL, 24); +static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO, + applesmc_show_temperature, NULL, 25); +static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO, + applesmc_show_temperature, NULL, 26); +static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO, + applesmc_show_temperature, NULL, 27); +static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO, + applesmc_show_temperature, NULL, 28); +static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO, + applesmc_show_temperature, NULL, 29); +static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO, + applesmc_show_temperature, NULL, 30); +static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO, + applesmc_show_temperature, NULL, 31); +static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO, + applesmc_show_temperature, NULL, 32); +static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO, + applesmc_show_temperature, NULL, 33); +static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO, + applesmc_show_temperature, NULL, 34); +static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO, + applesmc_show_temperature, NULL, 35); +static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO, + applesmc_show_temperature, NULL, 36); +static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO, + applesmc_show_temperature, NULL, 37); +static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO, + applesmc_show_temperature, NULL, 38); +static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, + applesmc_show_temperature, NULL, 39); + +static struct attribute *label_attributes[] = { + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + &sensor_dev_attr_temp3_label.dev_attr.attr, + &sensor_dev_attr_temp4_label.dev_attr.attr, + &sensor_dev_attr_temp5_label.dev_attr.attr, + &sensor_dev_attr_temp6_label.dev_attr.attr, + &sensor_dev_attr_temp7_label.dev_attr.attr, + &sensor_dev_attr_temp8_label.dev_attr.attr, + &sensor_dev_attr_temp9_label.dev_attr.attr, + &sensor_dev_attr_temp10_label.dev_attr.attr, + &sensor_dev_attr_temp11_label.dev_attr.attr, + &sensor_dev_attr_temp12_label.dev_attr.attr, + &sensor_dev_attr_temp13_label.dev_attr.attr, + &sensor_dev_attr_temp14_label.dev_attr.attr, + &sensor_dev_attr_temp15_label.dev_attr.attr, + &sensor_dev_attr_temp16_label.dev_attr.attr, + &sensor_dev_attr_temp17_label.dev_attr.attr, + &sensor_dev_attr_temp18_label.dev_attr.attr, + &sensor_dev_attr_temp19_label.dev_attr.attr, + &sensor_dev_attr_temp20_label.dev_attr.attr, + &sensor_dev_attr_temp21_label.dev_attr.attr, + &sensor_dev_attr_temp22_label.dev_attr.attr, + &sensor_dev_attr_temp23_label.dev_attr.attr, + &sensor_dev_attr_temp24_label.dev_attr.attr, + &sensor_dev_attr_temp25_label.dev_attr.attr, + &sensor_dev_attr_temp26_label.dev_attr.attr, + &sensor_dev_attr_temp27_label.dev_attr.attr, + &sensor_dev_attr_temp28_label.dev_attr.attr, + &sensor_dev_attr_temp29_label.dev_attr.attr, + &sensor_dev_attr_temp30_label.dev_attr.attr, + &sensor_dev_attr_temp31_label.dev_attr.attr, + &sensor_dev_attr_temp32_label.dev_attr.attr, + &sensor_dev_attr_temp33_label.dev_attr.attr, + &sensor_dev_attr_temp34_label.dev_attr.attr, + &sensor_dev_attr_temp35_label.dev_attr.attr, + &sensor_dev_attr_temp36_label.dev_attr.attr, + &sensor_dev_attr_temp37_label.dev_attr.attr, + &sensor_dev_attr_temp38_label.dev_attr.attr, + &sensor_dev_attr_temp39_label.dev_attr.attr, + &sensor_dev_attr_temp40_label.dev_attr.attr, + NULL +}; + +static struct attribute *temperature_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp9_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_temp13_input.dev_attr.attr, + &sensor_dev_attr_temp14_input.dev_attr.attr, + &sensor_dev_attr_temp15_input.dev_attr.attr, + &sensor_dev_attr_temp16_input.dev_attr.attr, + &sensor_dev_attr_temp17_input.dev_attr.attr, + &sensor_dev_attr_temp18_input.dev_attr.attr, + &sensor_dev_attr_temp19_input.dev_attr.attr, + &sensor_dev_attr_temp20_input.dev_attr.attr, + &sensor_dev_attr_temp21_input.dev_attr.attr, + &sensor_dev_attr_temp22_input.dev_attr.attr, + &sensor_dev_attr_temp23_input.dev_attr.attr, + &sensor_dev_attr_temp24_input.dev_attr.attr, + &sensor_dev_attr_temp25_input.dev_attr.attr, + &sensor_dev_attr_temp26_input.dev_attr.attr, + &sensor_dev_attr_temp27_input.dev_attr.attr, + &sensor_dev_attr_temp28_input.dev_attr.attr, + &sensor_dev_attr_temp29_input.dev_attr.attr, + &sensor_dev_attr_temp30_input.dev_attr.attr, + &sensor_dev_attr_temp31_input.dev_attr.attr, + &sensor_dev_attr_temp32_input.dev_attr.attr, + &sensor_dev_attr_temp33_input.dev_attr.attr, + &sensor_dev_attr_temp34_input.dev_attr.attr, + &sensor_dev_attr_temp35_input.dev_attr.attr, + &sensor_dev_attr_temp36_input.dev_attr.attr, + &sensor_dev_attr_temp37_input.dev_attr.attr, + &sensor_dev_attr_temp38_input.dev_attr.attr, + &sensor_dev_attr_temp39_input.dev_attr.attr, + &sensor_dev_attr_temp40_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group temperature_attributes_group = + { .attrs = temperature_attributes }; + +static const struct attribute_group label_attributes_group = { + .attrs = label_attributes +}; + +/* Module stuff */ /* - * applesmc_create_nodes - create a two-dimensional group of sysfs files + * applesmc_dmi_match - found a match. return one, short-circuiting the hunt. */ -static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) +static int applesmc_dmi_match(const struct dmi_system_id *id) { - struct applesmc_node_group *grp; - struct applesmc_dev_attr *node; - struct attribute *attr; - int ret, i; - - for (grp = groups; grp->format; grp++) { - grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL); - if (!grp->nodes) { - ret = -ENOMEM; - goto out; - } - for (i = 0; i < num; i++) { - node = &grp->nodes[i]; - sprintf(node->name, grp->format, i + 1); - node->sda.index = (grp->option << 16) | (i & 0xffff); - node->sda.dev_attr.show = grp->show; - node->sda.dev_attr.store = grp->store; - attr = &node->sda.dev_attr.attr; - attr->name = node->name; - attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0); - ret = sysfs_create_file(&pdev->dev.kobj, attr); - if (ret) { - attr->name = NULL; - goto out; - } - } - } - - return 0; -out: - applesmc_destroy_nodes(groups); - return ret; + int i = 0; + struct dmi_match_data* dmi_data = id->driver_data; + printk(KERN_INFO "applesmc: %s detected:\n", id->ident); + applesmc_accelerometer = dmi_data->accelerometer; + printk(KERN_INFO "applesmc: - Model %s accelerometer\n", + applesmc_accelerometer ? "with" : "without"); + applesmc_light = dmi_data->light; + printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n", + applesmc_light ? "with" : "without"); + + applesmc_temperature_set = dmi_data->temperature_set; + while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL) + i++; + printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i); + return 1; } /* Create accelerometer ressources */ @@ -1094,10 +1424,8 @@ static int applesmc_create_accelerometer(void) struct input_dev *idev; int ret; - if (!smcreg.has_accelerometer) - return 0; - - ret = applesmc_create_nodes(accelerometer_group, 1); + ret = sysfs_create_group(&pdev->dev.kobj, + &accelerometer_attributes_group); if (ret) goto out; @@ -1134,96 +1462,184 @@ static int applesmc_create_accelerometer(void) input_free_polled_device(applesmc_idev); out_sysfs: - applesmc_destroy_nodes(accelerometer_group); + sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); out: - pr_warn("driver init failed (ret=%d)!\n", ret); + printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); return ret; } /* Release all ressources used by the accelerometer */ static void applesmc_release_accelerometer(void) { - if (!smcreg.has_accelerometer) - return; input_unregister_polled_device(applesmc_idev); input_free_polled_device(applesmc_idev); - applesmc_destroy_nodes(accelerometer_group); + sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); } -static int applesmc_create_light_sensor(void) -{ - if (!smcreg.num_light_sensors) - return 0; - return applesmc_create_nodes(light_sensor_group, 1); -} - -static void applesmc_release_light_sensor(void) -{ - if (!smcreg.num_light_sensors) - return; - applesmc_destroy_nodes(light_sensor_group); -} - -static int applesmc_create_key_backlight(void) -{ - if (!smcreg.has_key_backlight) - return 0; - applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); - if (!applesmc_led_wq) - return -ENOMEM; - return led_classdev_register(&pdev->dev, &applesmc_backlight); -} - -static void applesmc_release_key_backlight(void) -{ - if (!smcreg.has_key_backlight) - return; - led_classdev_unregister(&applesmc_backlight); - destroy_workqueue(applesmc_led_wq); -} - -static int applesmc_dmi_match(const struct dmi_system_id *id) -{ - return 1; -} +static __initdata struct dmi_match_data applesmc_dmi_data[] = { +/* MacBook Pro: accelerometer, backlight and temperature set 0 */ + { .accelerometer = 1, .light = 1, .temperature_set = 0 }, +/* MacBook2: accelerometer and temperature set 1 */ + { .accelerometer = 1, .light = 0, .temperature_set = 1 }, +/* MacBook: accelerometer and temperature set 2 */ + { .accelerometer = 1, .light = 0, .temperature_set = 2 }, +/* MacMini: temperature set 3 */ + { .accelerometer = 0, .light = 0, .temperature_set = 3 }, +/* MacPro: temperature set 4 */ + { .accelerometer = 0, .light = 0, .temperature_set = 4 }, +/* iMac: temperature set 5 */ + { .accelerometer = 0, .light = 0, .temperature_set = 5 }, +/* MacBook3, MacBook4: accelerometer and temperature set 6 */ + { .accelerometer = 1, .light = 0, .temperature_set = 6 }, +/* MacBook Air: accelerometer, backlight and temperature set 7 */ + { .accelerometer = 1, .light = 1, .temperature_set = 7 }, +/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */ + { .accelerometer = 1, .light = 1, .temperature_set = 8 }, +/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ + { .accelerometer = 1, .light = 1, .temperature_set = 9 }, +/* iMac 5: light sensor only, temperature set 10 */ + { .accelerometer = 0, .light = 0, .temperature_set = 10 }, +/* MacBook 5: accelerometer, backlight and temperature set 11 */ + { .accelerometer = 1, .light = 1, .temperature_set = 11 }, +/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */ + { .accelerometer = 1, .light = 1, .temperature_set = 12 }, +/* iMac 8: light sensor only, temperature set 13 */ + { .accelerometer = 0, .light = 0, .temperature_set = 13 }, +/* iMac 6: light sensor only, temperature set 14 */ + { .accelerometer = 0, .light = 0, .temperature_set = 14 }, +/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */ + { .accelerometer = 1, .light = 1, .temperature_set = 15 }, +/* MacPro3,1: temperature set 16 */ + { .accelerometer = 0, .light = 0, .temperature_set = 16 }, +/* iMac 9,1: light sensor only, temperature set 17 */ + { .accelerometer = 0, .light = 0, .temperature_set = 17 }, +/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ + { .accelerometer = 1, .light = 1, .temperature_set = 18 }, +/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */ + { .accelerometer = 1, .light = 1, .temperature_set = 19 }, +/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */ + { .accelerometer = 1, .light = 1, .temperature_set = 20 }, +/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */ + { .accelerometer = 1, .light = 1, .temperature_set = 21 }, +/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */ + { .accelerometer = 1, .light = 1, .temperature_set = 22 }, +}; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ static __initdata struct dmi_system_id applesmc_whitelist[] = { + { applesmc_dmi_match, "Apple MacBook Air 2", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") }, + &applesmc_dmi_data[15]}, { applesmc_dmi_match, "Apple MacBook Air", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, - }, + &applesmc_dmi_data[7]}, + { applesmc_dmi_match, "Apple MacBook Pro 7", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") }, + &applesmc_dmi_data[22]}, + { applesmc_dmi_match, "Apple MacBook Pro 5,4", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") }, + &applesmc_dmi_data[20]}, + { applesmc_dmi_match, "Apple MacBook Pro 5,3", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") }, + &applesmc_dmi_data[19]}, + { applesmc_dmi_match, "Apple MacBook Pro 6", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") }, + &applesmc_dmi_data[21]}, + { applesmc_dmi_match, "Apple MacBook Pro 5", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, + &applesmc_dmi_data[12]}, + { applesmc_dmi_match, "Apple MacBook Pro 4", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, + &applesmc_dmi_data[8]}, + { applesmc_dmi_match, "Apple MacBook Pro 3", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, + &applesmc_dmi_data[9]}, + { applesmc_dmi_match, "Apple MacBook Pro 2,2", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") }, + &applesmc_dmi_data[18]}, { applesmc_dmi_match, "Apple MacBook Pro", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, + &applesmc_dmi_data[0]}, + { applesmc_dmi_match, "Apple MacBook (v2)", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, + &applesmc_dmi_data[1]}, + { applesmc_dmi_match, "Apple MacBook (v3)", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, + &applesmc_dmi_data[6]}, + { applesmc_dmi_match, "Apple MacBook 4", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro") }, - }, - { applesmc_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") }, + &applesmc_dmi_data[6]}, + { applesmc_dmi_match, "Apple MacBook 5", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, - }, + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") }, + &applesmc_dmi_data[11]}, + { applesmc_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, + &applesmc_dmi_data[2]}, { applesmc_dmi_match, "Apple Macmini", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, + &applesmc_dmi_data[3]}, + { applesmc_dmi_match, "Apple MacPro2", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, + &applesmc_dmi_data[4]}, + { applesmc_dmi_match, "Apple MacPro3", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") }, - }, + DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") }, + &applesmc_dmi_data[16]}, { applesmc_dmi_match, "Apple MacPro", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, - }, - { applesmc_dmi_match, "Apple iMac", { + &applesmc_dmi_data[4]}, + { applesmc_dmi_match, "Apple iMac 9,1", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") }, + &applesmc_dmi_data[17]}, + { applesmc_dmi_match, "Apple iMac 8", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac") }, - }, + DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, + &applesmc_dmi_data[13]}, + { applesmc_dmi_match, "Apple iMac 6", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") }, + &applesmc_dmi_data[14]}, + { applesmc_dmi_match, "Apple iMac 5", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") }, + &applesmc_dmi_data[10]}, + { applesmc_dmi_match, "Apple iMac", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, + &applesmc_dmi_data[5]}, { .ident = NULL } }; static int __init applesmc_init(void) { int ret; + int count; + int i; if (!dmi_check_system(applesmc_whitelist)) { - pr_warn("supported laptop not found!\n"); + printk(KERN_WARNING "applesmc: supported laptop not found!\n"); ret = -ENODEV; goto out; } @@ -1245,34 +1661,83 @@ static int __init applesmc_init(void) goto out_driver; } - /* create register cache */ - ret = applesmc_init_smcreg(); + ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); if (ret) goto out_device; - ret = applesmc_create_nodes(info_group, 1); + /* Create key enumeration sysfs files */ + ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); if (ret) - goto out_smcreg; + goto out_name; - ret = applesmc_create_nodes(fan_group, smcreg.fan_count); - if (ret) - goto out_info; + /* create fan files */ + count = applesmc_get_fan_count(); + if (count < 0) + printk(KERN_ERR "applesmc: Cannot get the number of fans.\n"); + else + printk(KERN_INFO "applesmc: %d fans found.\n", count); - ret = applesmc_create_nodes(temp_group, smcreg.temp_count); - if (ret) - goto out_fans; + if (count > 4) { + count = 4; + printk(KERN_WARNING "applesmc: More than 4 fans found," + " but at most 4 fans are supported" + " by the driver.\n"); + } - ret = applesmc_create_accelerometer(); - if (ret) - goto out_temperature; + while (fans_handled < count) { + ret = sysfs_create_group(&pdev->dev.kobj, + &fan_attribute_groups[fans_handled]); + if (ret) + goto out_fans; + fans_handled++; + } - ret = applesmc_create_light_sensor(); - if (ret) - goto out_accelerometer; + for (i = 0; + temperature_sensors_sets[applesmc_temperature_set][i] != NULL; + i++) { + if (temperature_attributes[i] == NULL || + label_attributes[i] == NULL) { + printk(KERN_ERR "applesmc: More temperature sensors " + "in temperature_sensors_sets (at least %i)" + "than available sysfs files in " + "temperature_attributes (%i), please report " + "this bug.\n", i, i-1); + goto out_temperature; + } + ret = sysfs_create_file(&pdev->dev.kobj, + temperature_attributes[i]); + if (ret) + goto out_temperature; + ret = sysfs_create_file(&pdev->dev.kobj, + label_attributes[i]); + if (ret) + goto out_temperature; + } - ret = applesmc_create_key_backlight(); - if (ret) - goto out_light_sysfs; + if (applesmc_accelerometer) { + ret = applesmc_create_accelerometer(); + if (ret) + goto out_temperature; + } + + if (applesmc_light) { + /* Add light sensor file */ + ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr); + if (ret) + goto out_accelerometer; + + /* Create the workqueue */ + applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); + if (!applesmc_led_wq) { + ret = -ENOMEM; + goto out_light_sysfs; + } + + /* register as a led device */ + ret = led_classdev_register(&pdev->dev, &applesmc_backlight); + if (ret < 0) + goto out_light_wq; + } hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(hwmon_dev)) { @@ -1280,22 +1745,32 @@ static int __init applesmc_init(void) goto out_light_ledclass; } + printk(KERN_INFO "applesmc: driver successfully loaded.\n"); + return 0; out_light_ledclass: - applesmc_release_key_backlight(); + if (applesmc_light) + led_classdev_unregister(&applesmc_backlight); +out_light_wq: + if (applesmc_light) + destroy_workqueue(applesmc_led_wq); out_light_sysfs: - applesmc_release_light_sensor(); + if (applesmc_light) + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); out_accelerometer: - applesmc_release_accelerometer(); + if (applesmc_accelerometer) + applesmc_release_accelerometer(); out_temperature: - applesmc_destroy_nodes(temp_group); + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); + sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); out_fans: - applesmc_destroy_nodes(fan_group); -out_info: - applesmc_destroy_nodes(info_group); -out_smcreg: - applesmc_destroy_smcreg(); + while (fans_handled) + sysfs_remove_group(&pdev->dev.kobj, + &fan_attribute_groups[--fans_handled]); + sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); +out_name: + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); out_device: platform_device_unregister(pdev); out_driver: @@ -1303,23 +1778,32 @@ static int __init applesmc_init(void) out_region: release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); out: - pr_warn("driver init failed (ret=%d)!\n", ret); + printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); return ret; } static void __exit applesmc_exit(void) { hwmon_device_unregister(hwmon_dev); - applesmc_release_key_backlight(); - applesmc_release_light_sensor(); - applesmc_release_accelerometer(); - applesmc_destroy_nodes(temp_group); - applesmc_destroy_nodes(fan_group); - applesmc_destroy_nodes(info_group); - applesmc_destroy_smcreg(); + if (applesmc_light) { + led_classdev_unregister(&applesmc_backlight); + destroy_workqueue(applesmc_led_wq); + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); + } + if (applesmc_accelerometer) + applesmc_release_accelerometer(); + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); + sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); + while (fans_handled) + sysfs_remove_group(&pdev->dev.kobj, + &fan_attribute_groups[--fans_handled]); + sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); platform_device_unregister(pdev); platform_driver_unregister(&applesmc_driver); release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); + + printk(KERN_INFO "applesmc: driver unloaded.\n"); } module_init(applesmc_init); diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index c02a052d3085..7dada559b3a1 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -36,8 +36,6 @@ asb100 7 3 1 4 0x31 0x0694 yes no */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -703,7 +701,8 @@ static int asb100_detect(struct i2c_client *client, int val1, val2; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - pr_debug("detect failed, smbus byte data not supported!\n"); + pr_debug("asb100.o: detect failed, " + "smbus byte data not supported!\n"); return -ENODEV; } @@ -716,7 +715,7 @@ static int asb100_detect(struct i2c_client *client, (((!(val1 & 0x80)) && (val2 != 0x94)) || /* Check for ASB100 ID (high byte ) */ ((val1 & 0x80) && (val2 != 0x06)))) { - pr_debug("detect failed, bad chip id 0x%02x!\n", val2); + pr_debug("asb100: detect failed, bad chip id 0x%02x!\n", val2); return -ENODEV; } @@ -745,7 +744,7 @@ static int asb100_probe(struct i2c_client *client, data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL); if (!data) { - pr_debug("probe failed, kzalloc failed!\n"); + pr_debug("asb100.o: probe failed, kzalloc failed!\n"); err = -ENOMEM; goto ERROR0; } diff --git a/trunk/drivers/hwmon/asus_atk0110.c b/trunk/drivers/hwmon/asus_atk0110.c index 2d68cf3c223b..23b8555215d2 100644 --- a/trunk/drivers/hwmon/asus_atk0110.c +++ b/trunk/drivers/hwmon/asus_atk0110.c @@ -5,8 +5,6 @@ * See COPYING in the top level directory of the kernel tree. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1416,13 +1414,14 @@ static int __init atk0110_init(void) /* Make sure it's safe to access the device through ACPI */ if (!acpi_resources_are_enforced()) { - pr_err("Resources not safely usable due to acpi_enforce_resources kernel parameter\n"); + pr_err("atk: Resources not safely usable due to " + "acpi_enforce_resources kernel parameter\n"); return -EBUSY; } ret = acpi_bus_register_driver(&atk_driver); if (ret) - pr_info("acpi_bus_register_driver failed: %d\n", ret); + pr_info("atk: acpi_bus_register_driver failed: %d\n", ret); return ret; } diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index 194ca0aa8b0c..42de98d73ff5 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -20,8 +20,6 @@ * 02110-1301 USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -447,8 +445,8 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) * without thermal sensors will be filtered out. */ if (!cpu_has(c, X86_FEATURE_DTS)) { - pr_info("CPU (model=0x%x) has no thermal sensor\n", - c->x86_model); + printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" + " has no thermal sensor.\n", c->x86_model); return 0; } @@ -468,7 +466,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } @@ -480,7 +478,8 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_free; } diff --git a/trunk/drivers/hwmon/dme1737.c b/trunk/drivers/hwmon/dme1737.c index e9a610bfd0cc..980c17d5eeae 100644 --- a/trunk/drivers/hwmon/dme1737.c +++ b/trunk/drivers/hwmon/dme1737.c @@ -25,8 +25,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -2448,7 +2446,7 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) /* Get the base address of the runtime registers */ if (!(base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | dme1737_sio_inb(sio_cip, 0x61))) { - pr_err("Base address not set\n"); + printk(KERN_ERR "dme1737: Base address not set.\n"); err = -ENODEV; goto exit; } @@ -2477,18 +2475,20 @@ static int __init dme1737_isa_device_add(unsigned short addr) goto exit; if (!(pdev = platform_device_alloc("dme1737", addr))) { - pr_err("Failed to allocate device\n"); + printk(KERN_ERR "dme1737: Failed to allocate device.\n"); err = -ENOMEM; goto exit; } if ((err = platform_device_add_resources(pdev, &res, 1))) { - pr_err("Failed to add device resource (err = %d)\n", err); + printk(KERN_ERR "dme1737: Failed to add device resource " + "(err = %d).\n", err); goto exit_device_put; } if ((err = platform_device_add(pdev))) { - pr_err("Failed to add device (err = %d)\n", err); + printk(KERN_ERR "dme1737: Failed to add device (err = %d).\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/ds620.c b/trunk/drivers/hwmon/ds620.c deleted file mode 100644 index 257957c69d92..000000000000 --- a/trunk/drivers/hwmon/ds620.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * ds620.c - Support for temperature sensor and thermostat DS620 - * - * Copyright (C) 2010, 2011 Roland Stigge - * - * based on ds1621.c by Christian W. Zuckschwerdt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Many DS620 constants specified below - * 15 14 13 12 11 10 09 08 - * |Done|NVB |THF |TLF |R1 |R0 |AUTOC|1SHOT| - * - * 07 06 05 04 03 02 01 00 - * |PO2 |PO1 |A2 |A1 |A0 | | | | - */ -#define DS620_REG_CONFIG_DONE 0x8000 -#define DS620_REG_CONFIG_NVB 0x4000 -#define DS620_REG_CONFIG_THF 0x2000 -#define DS620_REG_CONFIG_TLF 0x1000 -#define DS620_REG_CONFIG_R1 0x0800 -#define DS620_REG_CONFIG_R0 0x0400 -#define DS620_REG_CONFIG_AUTOC 0x0200 -#define DS620_REG_CONFIG_1SHOT 0x0100 -#define DS620_REG_CONFIG_PO2 0x0080 -#define DS620_REG_CONFIG_PO1 0x0040 -#define DS620_REG_CONFIG_A2 0x0020 -#define DS620_REG_CONFIG_A1 0x0010 -#define DS620_REG_CONFIG_A0 0x0008 - -/* The DS620 registers */ -static const u8 DS620_REG_TEMP[3] = { - 0xAA, /* input, word, RO */ - 0xA2, /* min, word, RW */ - 0xA0, /* max, word, RW */ -}; - -#define DS620_REG_CONF 0xAC /* word, RW */ -#define DS620_COM_START 0x51 /* no data */ -#define DS620_COM_STOP 0x22 /* no data */ - -/* Each client has this additional data */ -struct ds620_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if following fields are valid */ - unsigned long last_updated; /* In jiffies */ - - u16 temp[3]; /* Register values, word */ -}; - -/* - * Temperature registers are word-sized. - * DS620 uses a high-byte first convention, which is exactly opposite to - * the SMBus standard. - */ -static int ds620_read_temp(struct i2c_client *client, u8 reg) -{ - int ret; - - ret = i2c_smbus_read_word_data(client, reg); - if (ret < 0) - return ret; - return swab16(ret); -} - -static int ds620_write_temp(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, swab16(value)); -} - -static void ds620_init_client(struct i2c_client *client) -{ - struct ds620_platform_data *ds620_info = client->dev.platform_data; - u16 conf, new_conf; - - new_conf = conf = - swab16(i2c_smbus_read_word_data(client, DS620_REG_CONF)); - - /* switch to continuous conversion mode */ - new_conf &= ~DS620_REG_CONFIG_1SHOT; - /* already high at power-on, but don't trust the BIOS! */ - new_conf |= DS620_REG_CONFIG_PO2; - /* thermostat mode according to platform data */ - if (ds620_info && ds620_info->pomode == 1) - new_conf &= ~DS620_REG_CONFIG_PO1; /* PO_LOW */ - else if (ds620_info && ds620_info->pomode == 2) - new_conf |= DS620_REG_CONFIG_PO1; /* PO_HIGH */ - else - new_conf &= ~DS620_REG_CONFIG_PO2; /* always low */ - /* with highest precision */ - new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; - - if (conf != new_conf) - i2c_smbus_write_word_data(client, DS620_REG_CONF, - swab16(new_conf)); - - /* start conversion */ - i2c_smbus_write_byte(client, DS620_COM_START); -} - -static struct ds620_data *ds620_update_client(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds620_data *data = i2c_get_clientdata(client); - struct ds620_data *ret = data; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i; - int res; - - dev_dbg(&client->dev, "Starting ds620 update\n"); - - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - res = ds620_read_temp(client, - DS620_REG_TEMP[i]); - if (res < 0) { - ret = ERR_PTR(res); - goto abort; - } - - data->temp[i] = res; - } - - data->last_updated = jiffies; - data->valid = 1; - } -abort: - mutex_unlock(&data->update_lock); - - return ret; -} - -static ssize_t show_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ds620_data *data = ds620_update_client(dev); - - if (IS_ERR(data)) - return PTR_ERR(data); - - return sprintf(buf, "%d\n", ((data->temp[attr->index] / 8) * 625) / 10); -} - -static ssize_t set_temp(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - int res; - long val; - - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ds620_data *data = i2c_get_clientdata(client); - - res = strict_strtol(buf, 10, &val); - - if (res) - return res; - - val = (val * 10 / 625) * 8; - - mutex_lock(&data->update_lock); - data->temp[attr->index] = val; - ds620_write_temp(client, DS620_REG_TEMP[attr->index], - data->temp[attr->index]); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t show_alarm(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ds620_data *data = ds620_update_client(dev); - struct i2c_client *client = to_i2c_client(dev); - u16 conf, new_conf; - int res; - - if (IS_ERR(data)) - return PTR_ERR(data); - - /* reset alarms if necessary */ - res = i2c_smbus_read_word_data(client, DS620_REG_CONF); - if (res < 0) - return res; - - conf = swab16(res); - new_conf = conf; - new_conf &= ~attr->index; - if (conf != new_conf) { - res = i2c_smbus_write_word_data(client, DS620_REG_CONF, - swab16(new_conf)); - if (res < 0) - return res; - } - - return sprintf(buf, "%d\n", !!(conf & attr->index)); -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, 1); -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, 2); -static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, - DS620_REG_CONFIG_TLF); -static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, - DS620_REG_CONFIG_THF); - -static struct attribute *ds620_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - NULL -}; - -static const struct attribute_group ds620_group = { - .attrs = ds620_attributes, -}; - -static int ds620_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct ds620_data *data; - int err; - - data = kzalloc(sizeof(struct ds620_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Initialize the DS620 chip */ - ds620_init_client(client); - - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &ds620_group); - if (err) - goto exit_free; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - dev_info(&client->dev, "temperature sensor found\n"); - - return 0; - -exit_remove_files: - sysfs_remove_group(&client->dev.kobj, &ds620_group); -exit_free: - kfree(data); -exit: - return err; -} - -static int ds620_remove(struct i2c_client *client) -{ - struct ds620_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ds620_group); - - kfree(data); - - return 0; -} - -static const struct i2c_device_id ds620_id[] = { - {"ds620", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ds620_id); - -/* This is the driver that will be inserted */ -static struct i2c_driver ds620_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ds620", - }, - .probe = ds620_probe, - .remove = ds620_remove, - .id_table = ds620_id, -}; - -static int __init ds620_init(void) -{ - return i2c_add_driver(&ds620_driver); -} - -static void __exit ds620_exit(void) -{ - i2c_del_driver(&ds620_driver); -} - -MODULE_AUTHOR("Roland Stigge "); -MODULE_DESCRIPTION("DS620 driver"); -MODULE_LICENSE("GPL"); - -module_init(ds620_init); -module_exit(ds620_exit); diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index 92f949767ece..525a00bd70b1 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -28,8 +28,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1311,7 +1309,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev) if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { err = -ENOMEM; - pr_err("Out of memory\n"); + printk(KERN_ERR DRVNAME ": Out of memory\n"); goto exit; } @@ -1453,7 +1451,7 @@ static int __init f71805f_device_add(unsigned short address, pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } @@ -1464,20 +1462,22 @@ static int __init f71805f_device_add(unsigned short address, err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add_data(pdev, sio_data, sizeof(struct f71805f_sio_data)); if (err) { - pr_err("Platform data allocation failed\n"); + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_put; } @@ -1516,27 +1516,30 @@ static int __init f71805f_find(int sioaddr, unsigned short *address, sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1); break; default: - pr_info("Unsupported Fintek device, skipping\n"); + printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " + "skipping\n"); goto exit; } superio_select(sioaddr, F71805F_LD_HWM); if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { - pr_warn("Device not activated, skipping\n"); + printk(KERN_WARNING DRVNAME ": Device not activated, " + "skipping\n"); goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { - pr_warn("Base address not set, skipping\n"); + printk(KERN_WARNING DRVNAME ": Base address not set, " + "skipping\n"); goto exit; } *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ err = 0; - pr_info("Found %s chip at %#x, revision %u\n", - names[sio_data->kind], *address, - superio_inb(sioaddr, SIO_REG_DEVREV)); + printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n", + names[sio_data->kind], *address, + superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); diff --git a/trunk/drivers/hwmon/f71882fg.c b/trunk/drivers/hwmon/f71882fg.c index 3f49dd376f02..75afb3b0e076 100644 --- a/trunk/drivers/hwmon/f71882fg.c +++ b/trunk/drivers/hwmon/f71882fg.c @@ -18,8 +18,6 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -867,7 +865,8 @@ static inline int superio_enter(int base) { /* Don't step on other drivers' I/O space by accident */ if (!request_muxed_region(base, 2, DRVNAME)) { - pr_err("I/O address 0x%04x already in use\n", base); + printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", + base); return -EBUSY; } @@ -2193,7 +2192,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) { - pr_debug("Not a Fintek device\n"); + pr_debug(DRVNAME ": Not a Fintek device\n"); err = -ENODEV; goto exit; } @@ -2216,8 +2215,8 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, sio_data->type = f8000; break; default: - pr_info("Unsupported Fintek device: %04x\n", - (unsigned int)devid); + printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", + (unsigned int)devid); err = -ENODEV; goto exit; } @@ -2228,21 +2227,21 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, superio_select(sioaddr, SIO_F71882FG_LD_HWM); if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { - pr_warn("Device not activated\n"); + printk(KERN_WARNING DRVNAME ": Device not activated\n"); err = -ENODEV; goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { - pr_warn("Base address not set\n"); + printk(KERN_WARNING DRVNAME ": Base address not set\n"); err = -ENODEV; goto exit; } *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ err = 0; - pr_info("Found %s chip at %#x, revision %d\n", + printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n", f71882fg_names[sio_data->type], (unsigned int)*address, (int)superio_inb(sioaddr, SIO_REG_DEVREV)); exit: @@ -2271,20 +2270,20 @@ static int __init f71882fg_device_add(unsigned short address, err = platform_device_add_resources(f71882fg_pdev, &res, 1); if (err) { - pr_err("Device resource addition failed\n"); + printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); goto exit_device_put; } err = platform_device_add_data(f71882fg_pdev, sio_data, sizeof(struct f71882fg_sio_data)); if (err) { - pr_err("Platform data allocation failed\n"); + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } err = platform_device_add(f71882fg_pdev); if (err) { - pr_err("Device addition failed\n"); + printk(KERN_ERR DRVNAME ": Device addition failed\n"); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/hp_accel.c b/trunk/drivers/hwmon/hp_accel.c index 3d21fa2b97cd..a56a78412fcb 100644 --- a/trunk/drivers/hwmon/hp_accel.c +++ b/trunk/drivers/hwmon/hp_accel.c @@ -20,8 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -149,7 +147,7 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) { lis3_dev.ac = *((union axis_conversion *)dmi->driver_data); - pr_info("hardware type %s found\n", dmi->ident); + printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); return 1; } @@ -305,10 +303,11 @@ static int lis3lv02d_add(struct acpi_device *device) /* If possible use a "standard" axes order */ if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) { - pr_info("Using custom axes %d,%d,%d\n", - lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z); + printk(KERN_INFO DRIVER_NAME ": Using custom axes %d,%d,%d\n", + lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z); } else if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { - pr_info("laptop model unknown, using default axes configuration\n"); + printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " + "using default axes configuration\n"); lis3_dev.ac = lis3lv02d_axis_normal; } @@ -386,7 +385,7 @@ static int __init lis3lv02d_init_module(void) if (ret < 0) return ret; - pr_info("driver loaded\n"); + printk(KERN_INFO DRIVER_NAME " driver loaded.\n"); return 0; } diff --git a/trunk/drivers/hwmon/hwmon-vid.c b/trunk/drivers/hwmon/hwmon-vid.c index 2582bfef6ccb..2b2ca1694f95 100644 --- a/trunk/drivers/hwmon/hwmon-vid.c +++ b/trunk/drivers/hwmon/hwmon-vid.c @@ -22,8 +22,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -148,8 +146,8 @@ int vid_from_reg(int val, u8 vrm) return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000); default: /* report 0 for unknown */ if (vrm) - pr_warn("Requested unsupported VRM version (%u)\n", - (unsigned int)vrm); + printk(KERN_WARNING "hwmon-vid: Requested unsupported " + "VRM version (%u)\n", (unsigned int)vrm); return 0; } } @@ -248,7 +246,8 @@ u8 vid_which_vrm(void) } vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); if (vrm_ret == 0) - pr_info("Unknown VRM version of your x86 CPU\n"); + printk(KERN_INFO "hwmon-vid: Unknown VRM version of your " + "x86 CPU\n"); return vrm_ret; } @@ -256,7 +255,7 @@ u8 vid_which_vrm(void) #else u8 vid_which_vrm(void) { - pr_info("Unknown VRM version of your CPU\n"); + printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n"); return 0; } #endif diff --git a/trunk/drivers/hwmon/hwmon.c b/trunk/drivers/hwmon/hwmon.c index a61e7815a2a9..29ea6753f3bb 100644 --- a/trunk/drivers/hwmon/hwmon.c +++ b/trunk/drivers/hwmon/hwmon.c @@ -10,8 +10,6 @@ the Free Software Foundation; version 2 of the License. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -121,7 +119,7 @@ static int __init hwmon_init(void) hwmon_class = class_create(THIS_MODULE, "hwmon"); if (IS_ERR(hwmon_class)) { - pr_err("couldn't create sysfs class\n"); + printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); return PTR_ERR(hwmon_class); } return 0; diff --git a/trunk/drivers/hwmon/ibmaem.c b/trunk/drivers/hwmon/ibmaem.c index bc6e2ab3a361..eaee546af19a 100644 --- a/trunk/drivers/hwmon/ibmaem.c +++ b/trunk/drivers/hwmon/ibmaem.c @@ -20,8 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1092,7 +1090,7 @@ static int __init aem_init(void) res = driver_register(&aem_driver.driver); if (res) { - pr_err("Can't register aem driver\n"); + printk(KERN_ERR "Can't register aem driver\n"); return res; } diff --git a/trunk/drivers/hwmon/lis3lv02d.c b/trunk/drivers/hwmon/lis3lv02d.c index 1b674b7d4584..0cee73a6124e 100644 --- a/trunk/drivers/hwmon/lis3lv02d.c +++ b/trunk/drivers/hwmon/lis3lv02d.c @@ -20,8 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -862,7 +860,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, (p->irq_flags2 & IRQF_TRIGGER_MASK), DRIVER_NAME, &lis3_dev); if (err < 0) - pr_err("No second IRQ. Limited functionality\n"); + printk(KERN_ERR DRIVER_NAME + "No second IRQ. Limited functionality\n"); } } @@ -880,7 +879,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) switch (dev->whoami) { case WAI_12B: - pr_info("12 bits sensor found\n"); + printk(KERN_INFO DRIVER_NAME ": 12 bits sensor found\n"); dev->read_data = lis3lv02d_read_12; dev->mdps_max_val = 2048; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; @@ -891,7 +890,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); break; case WAI_8B: - pr_info("8 bits sensor found\n"); + printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; @@ -902,7 +901,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); break; case WAI_3DC: - pr_info("8 bits 3DC sensor found\n"); + printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; @@ -911,7 +910,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) dev->scale = LIS3_SENSITIVITY_8B; break; default: - pr_err("unknown sensor type 0x%X\n", dev->whoami); + printk(KERN_ERR DRIVER_NAME + ": unknown sensor type 0x%X\n", dev->whoami); return -EINVAL; } @@ -935,7 +935,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) } if (lis3lv02d_joystick_enable()) - pr_err("joystick initialization failed\n"); + printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); /* passing in platform specific data is purely optional and only * used by the SPI transport layer at the moment */ @@ -957,7 +957,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) /* bail if we did not get an IRQ from the bus layer */ if (!dev->irq) { - pr_err("No IRQ. Disabling /dev/freefall\n"); + printk(KERN_ERR DRIVER_NAME + ": No IRQ. Disabling /dev/freefall\n"); goto out; } @@ -984,12 +985,12 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) DRIVER_NAME, &lis3_dev); if (err < 0) { - pr_err("Cannot get IRQ\n"); + printk(KERN_ERR DRIVER_NAME "Cannot get IRQ\n"); goto out; } if (misc_register(&lis3lv02d_misc_device)) - pr_err("misc_register failed\n"); + printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); out: return 0; } diff --git a/trunk/drivers/hwmon/lm70.c b/trunk/drivers/hwmon/lm70.c index 3b84fb503053..fd108cfc05c7 100644 --- a/trunk/drivers/hwmon/lm70.c +++ b/trunk/drivers/hwmon/lm70.c @@ -24,8 +24,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -69,7 +67,8 @@ static ssize_t lm70_sense_temp(struct device *dev, */ status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2); if (status < 0) { - pr_warn("spi_write_then_read failed with status %d\n", status); + printk(KERN_WARNING + "spi_write_then_read failed with status %d\n", status); goto out; } raw = (rxbuf[0] << 8) + rxbuf[1]; diff --git a/trunk/drivers/hwmon/lm95241.c b/trunk/drivers/hwmon/lm95241.c index 1a6dfb6df1e7..4546d82f024a 100644 --- a/trunk/drivers/hwmon/lm95241.c +++ b/trunk/drivers/hwmon/lm95241.c @@ -1,9 +1,13 @@ /* - * Copyright (C) 2008, 2010 Davide Rizzo + * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2008 Davide Rizzo * - * The LM95241 is a sensor chip made by National Semiconductors. - * It reports up to three temperatures (its own plus up to two external ones). - * Complete datasheet can be obtained from National's website at: + * Based on the max1619 driver. The LM95241 is a sensor chip made by National + * Semiconductors. + * It reports up to three temperatures (its own plus up to + * two external ones). Complete datasheet can be + * obtained from National's website at: * http://www.national.com/ds.cgi/LM/LM95241.pdf * * This program is free software; you can redistribute it and/or modify @@ -32,10 +36,8 @@ #include #include -#define DEVNAME "lm95241" - static const unsigned short normal_i2c[] = { - 0x19, 0x2a, 0x2b, I2C_CLIENT_END }; + 0x19, 0x2a, 0x2b, I2C_CLIENT_END}; /* LM95241 registers */ #define LM95241_REG_R_MAN_ID 0xFE @@ -44,7 +46,7 @@ static const unsigned short normal_i2c[] = { #define LM95241_REG_RW_CONFIG 0x03 #define LM95241_REG_RW_REM_FILTER 0x06 #define LM95241_REG_RW_TRUTHERM 0x07 -#define LM95241_REG_W_ONE_SHOT 0x0F +#define LM95241_REG_W_ONE_SHOT 0x0F #define LM95241_REG_R_LOCAL_TEMPH 0x10 #define LM95241_REG_R_REMOTE1_TEMPH 0x11 #define LM95241_REG_R_REMOTE2_TEMPH 0x12 @@ -77,246 +79,235 @@ static const unsigned short normal_i2c[] = { #define MANUFACTURER_ID 0x01 #define DEFAULT_REVISION 0xA4 -static const u8 lm95241_reg_address[] = { - LM95241_REG_R_LOCAL_TEMPH, - LM95241_REG_R_LOCAL_TEMPL, - LM95241_REG_R_REMOTE1_TEMPH, - LM95241_REG_R_REMOTE1_TEMPL, - LM95241_REG_R_REMOTE2_TEMPH, - LM95241_REG_R_REMOTE2_TEMPL -}; +/* Conversions and various macros */ +#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \ + (val_h)) * 1000 + (val_l) * 1000 / 256) + +/* Functions declaration */ +static void lm95241_init_client(struct i2c_client *client); +static struct lm95241_data *lm95241_update_device(struct device *dev); /* Client data (each client gets its own) */ struct lm95241_data { struct device *hwmon_dev; struct mutex update_lock; - unsigned long last_updated, interval; /* in jiffies */ - char valid; /* zero until following fields are valid */ + unsigned long last_updated, interval; /* in jiffies */ + char valid; /* zero until following fields are valid */ /* registers values */ - u8 temp[ARRAY_SIZE(lm95241_reg_address)]; + u8 local_h, local_l; /* local */ + u8 remote1_h, remote1_l; /* remote1 */ + u8 remote2_h, remote2_l; /* remote2 */ u8 config, model, trutherm; }; -/* Conversions */ -static int TempFromReg(u8 val_h, u8 val_l) -{ - if (val_h & 0x80) - return val_h - 0x100; - return val_h * 1000 + val_l * 1000 / 256; -} - -static struct lm95241_data *lm95241_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->interval) || - !data->valid) { - int i; - - dev_dbg(&client->dev, "Updating lm95241 data.\n"); - for (i = 0; i < ARRAY_SIZE(lm95241_reg_address); i++) - data->temp[i] - = i2c_smbus_read_byte_data(client, - lm95241_reg_address[i]); - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - /* Sysfs stuff */ -static ssize_t show_input(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct lm95241_data *data = lm95241_update_device(dev); - - return snprintf(buf, PAGE_SIZE - 1, "%d\n", - TempFromReg(data->temp[to_sensor_dev_attr(attr)->index], - data->temp[to_sensor_dev_attr(attr)->index + 1])); +#define show_temp(value) \ +static ssize_t show_##value(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct lm95241_data *data = lm95241_update_device(dev); \ + snprintf(buf, PAGE_SIZE - 1, "%d\n", \ + TEMP_FROM_REG(data->value##_h, data->value##_l)); \ + return strlen(buf); \ } +show_temp(local); +show_temp(remote1); +show_temp(remote2); -static ssize_t show_type(struct device *dev, struct device_attribute *attr, +static ssize_t show_interval(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); + struct lm95241_data *data = lm95241_update_device(dev); - return snprintf(buf, PAGE_SIZE - 1, - data->model & to_sensor_dev_attr(attr)->index ? "1\n" : "2\n"); + snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval / HZ); + return strlen(buf); } -static ssize_t set_type(struct device *dev, struct device_attribute *attr, +static ssize_t set_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm95241_data *data = i2c_get_clientdata(client); unsigned long val; - int shift; - u8 mask = to_sensor_dev_attr(attr)->index; if (strict_strtoul(buf, 10, &val) < 0) return -EINVAL; - if (val != 1 && val != 2) - return -EINVAL; - - shift = mask == R1MS_MASK ? TT1_SHIFT : TT2_SHIFT; - mutex_lock(&data->update_lock); - - data->trutherm &= ~(TT_MASK << shift); - if (val == 1) { - data->model |= mask; - data->trutherm |= (TT_ON << shift); - } else { - data->model &= ~mask; - data->trutherm |= (TT_OFF << shift); - } - data->valid = 0; - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, - data->model); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, - data->trutherm); - - mutex_unlock(&data->update_lock); + data->interval = val * HZ / 1000; return count; } -static ssize_t show_min(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - return snprintf(buf, PAGE_SIZE - 1, - data->config & to_sensor_dev_attr(attr)->index ? - "-127000\n" : "0\n"); +#define show_type(flag) \ +static ssize_t show_type##flag(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + snprintf(buf, PAGE_SIZE - 1, \ + data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \ + return strlen(buf); \ } - -static ssize_t set_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - long val; - - if (strict_strtol(buf, 10, &val) < 0) - return -EINVAL; - if (val < -128000) - return -EINVAL; - - mutex_lock(&data->update_lock); - - if (val < 0) - data->config |= to_sensor_dev_attr(attr)->index; - else - data->config &= ~to_sensor_dev_attr(attr)->index; - data->valid = 0; - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); - - mutex_unlock(&data->update_lock); - - return count; +show_type(1); +show_type(2); + +#define show_min(flag) \ +static ssize_t show_min##flag(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + snprintf(buf, PAGE_SIZE - 1, \ + data->config & R##flag##DF_MASK ? \ + "-127000\n" : "0\n"); \ + return strlen(buf); \ } - -static ssize_t show_max(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - return snprintf(buf, PAGE_SIZE - 1, - data->config & to_sensor_dev_attr(attr)->index ? - "127000\n" : "255000\n"); +show_min(1); +show_min(2); + +#define show_max(flag) \ +static ssize_t show_max##flag(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + snprintf(buf, PAGE_SIZE - 1, \ + data->config & R##flag##DF_MASK ? \ + "127000\n" : "255000\n"); \ + return strlen(buf); \ } - -static ssize_t set_max(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - long val; - - if (strict_strtol(buf, 10, &val) < 0) - return -EINVAL; - if (val >= 256000) - return -EINVAL; - - mutex_lock(&data->update_lock); - - if (val <= 127000) - data->config |= to_sensor_dev_attr(attr)->index; - else - data->config &= ~to_sensor_dev_attr(attr)->index; - data->valid = 0; - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); - - mutex_unlock(&data->update_lock); - - return count; +show_max(1); +show_max(2); + +#define set_type(flag) \ +static ssize_t set_type##flag(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + long val; \ +\ + if (strict_strtol(buf, 10, &val) < 0) \ + return -EINVAL; \ +\ + if ((val == 1) || (val == 2)) { \ +\ + mutex_lock(&data->update_lock); \ +\ + data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \ + if (val == 1) { \ + data->model |= R##flag##MS_MASK; \ + data->trutherm |= (TT_ON << TT##flag##_SHIFT); \ + } \ + else { \ + data->model &= ~R##flag##MS_MASK; \ + data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \ + } \ +\ + data->valid = 0; \ +\ + i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \ + data->model); \ + i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \ + data->trutherm); \ +\ + mutex_unlock(&data->update_lock); \ +\ + } \ + return count; \ } - -static ssize_t show_interval(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct lm95241_data *data = lm95241_update_device(dev); - - return snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval - / HZ); +set_type(1); +set_type(2); + +#define set_min(flag) \ +static ssize_t set_min##flag(struct device *dev, \ + struct device_attribute *devattr, const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + long val; \ +\ + if (strict_strtol(buf, 10, &val) < 0) \ + return -EINVAL;\ +\ + mutex_lock(&data->update_lock); \ +\ + if (val < 0) \ + data->config |= R##flag##DF_MASK; \ + else \ + data->config &= ~R##flag##DF_MASK; \ +\ + data->valid = 0; \ +\ + i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ + data->config); \ +\ + mutex_unlock(&data->update_lock); \ +\ + return count; \ } - -static ssize_t set_interval(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - unsigned long val; - - if (strict_strtoul(buf, 10, &val) < 0) - return -EINVAL; - - data->interval = val * HZ / 1000; - - return count; +set_min(1); +set_min(2); + +#define set_max(flag) \ +static ssize_t set_max##flag(struct device *dev, \ + struct device_attribute *devattr, const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm95241_data *data = i2c_get_clientdata(client); \ +\ + long val; \ +\ + if (strict_strtol(buf, 10, &val) < 0) \ + return -EINVAL; \ +\ + mutex_lock(&data->update_lock); \ +\ + if (val <= 127000) \ + data->config |= R##flag##DF_MASK; \ + else \ + data->config &= ~R##flag##DF_MASK; \ +\ + data->valid = 0; \ +\ + i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ + data->config); \ +\ + mutex_unlock(&data->update_lock); \ +\ + return count; \ } - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2); -static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 4); -static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type, - R1MS_MASK); -static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type, - R2MS_MASK); -static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min, - R1DF_MASK); -static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, - R2DF_MASK); -static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max, - R1DF_MASK); -static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, - R2DF_MASK); +set_max(1); +set_max(2); + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL); +static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL); +static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL); +static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1); +static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2); +static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1); +static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); +static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); +static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, set_interval); static struct attribute *lm95241_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp2_type.dev_attr.attr, - &sensor_dev_attr_temp3_type.dev_attr.attr, - &sensor_dev_attr_temp2_min.dev_attr.attr, - &sensor_dev_attr_temp3_min.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp2_type.attr, + &dev_attr_temp3_type.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp3_min.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp3_max.attr, &dev_attr_update_interval.attr, NULL }; @@ -338,9 +329,9 @@ static int lm95241_detect(struct i2c_client *new_client, if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) == MANUFACTURER_ID) - && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) - >= DEFAULT_REVISION)) { - name = DEVNAME; + && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) + >= DEFAULT_REVISION)) { + name = "lm95241"; } else { dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n", address); @@ -352,25 +343,6 @@ static int lm95241_detect(struct i2c_client *new_client, return 0; } -static void lm95241_init_client(struct i2c_client *client) -{ - struct lm95241_data *data = i2c_get_clientdata(client); - - data->interval = HZ; /* 1 sec default */ - data->valid = 0; - data->config = CFG_CR0076; - data->model = 0; - data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, - R1FE_MASK | R2FE_MASK); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, - data->trutherm); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, - data->model); -} - static int lm95241_probe(struct i2c_client *new_client, const struct i2c_device_id *id) { @@ -410,6 +382,26 @@ static int lm95241_probe(struct i2c_client *new_client, return err; } +static void lm95241_init_client(struct i2c_client *client) +{ + struct lm95241_data *data = i2c_get_clientdata(client); + + data->interval = HZ; /* 1 sec default */ + data->valid = 0; + data->config = CFG_CR0076; + data->model = 0; + data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); + + i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, + data->config); + i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, + R1FE_MASK | R2FE_MASK); + i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, + data->trutherm); + i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, + data->model); +} + static int lm95241_remove(struct i2c_client *client) { struct lm95241_data *data = i2c_get_clientdata(client); @@ -421,9 +413,46 @@ static int lm95241_remove(struct i2c_client *client) return 0; } +static struct lm95241_data *lm95241_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct lm95241_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + data->interval) || + !data->valid) { + dev_dbg(&client->dev, "Updating lm95241 data.\n"); + data->local_h = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_LOCAL_TEMPH); + data->local_l = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_LOCAL_TEMPL); + data->remote1_h = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_REMOTE1_TEMPH); + data->remote1_l = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_REMOTE1_TEMPL); + data->remote2_h = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_REMOTE2_TEMPH); + data->remote2_l = + i2c_smbus_read_byte_data(client, + LM95241_REG_R_REMOTE2_TEMPL); + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + /* Driver data (common to all clients) */ static const struct i2c_device_id lm95241_id[] = { - { DEVNAME, 0 }, + { "lm95241", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm95241_id); @@ -431,7 +460,7 @@ MODULE_DEVICE_TABLE(i2c, lm95241_id); static struct i2c_driver lm95241_driver = { .class = I2C_CLASS_HWMON, .driver = { - .name = DEVNAME, + .name = "lm95241", }, .probe = lm95241_probe, .remove = lm95241_remove, @@ -450,7 +479,7 @@ static void __exit sensors_lm95241_exit(void) i2c_del_driver(&lm95241_driver); } -MODULE_AUTHOR("Davide Rizzo "); +MODULE_AUTHOR("Davide Rizzo "); MODULE_DESCRIPTION("LM95241 sensor driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/pcf8591.c b/trunk/drivers/hwmon/pcf8591.c index 731b09af76b9..dc7259d69812 100644 --- a/trunk/drivers/hwmon/pcf8591.c +++ b/trunk/drivers/hwmon/pcf8591.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -292,7 +290,8 @@ static struct i2c_driver pcf8591_driver = { static int __init pcf8591_init(void) { if (input_mode < 0 || input_mode > 3) { - pr_warn("invalid input_mode (%d)\n", input_mode); + printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n", + input_mode); input_mode = 0; } return i2c_add_driver(&pcf8591_driver); diff --git a/trunk/drivers/hwmon/pkgtemp.c b/trunk/drivers/hwmon/pkgtemp.c index 21c817d98123..0798210590bc 100644 --- a/trunk/drivers/hwmon/pkgtemp.c +++ b/trunk/drivers/hwmon/pkgtemp.c @@ -20,8 +20,6 @@ * 02110-1301 USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -305,7 +303,7 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu) pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } @@ -317,7 +315,8 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu) err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_free; } diff --git a/trunk/drivers/hwmon/sht21.c b/trunk/drivers/hwmon/sht21.c deleted file mode 100644 index 1c8c9812f244..000000000000 --- a/trunk/drivers/hwmon/sht21.c +++ /dev/null @@ -1,307 +0,0 @@ -/* Sensirion SHT21 humidity and temperature sensor driver - * - * Copyright (C) 2010 Urs Fleisch - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA - * - * Data sheet available (5/2010) at - * http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-SHT21.pdf - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* I2C command bytes */ -#define SHT21_TRIG_T_MEASUREMENT_HM 0xe3 -#define SHT21_TRIG_RH_MEASUREMENT_HM 0xe5 - -/** - * struct sht21 - SHT21 device specific data - * @hwmon_dev: device registered with hwmon - * @lock: mutex to protect measurement values - * @valid: only 0 before first measurement is taken - * @last_update: time of last update (jiffies) - * @temperature: cached temperature measurement value - * @humidity: cached humidity measurement value - */ -struct sht21 { - struct device *hwmon_dev; - struct mutex lock; - char valid; - unsigned long last_update; - int temperature; - int humidity; -}; - -/** - * sht21_temp_ticks_to_millicelsius() - convert raw temperature ticks to - * milli celsius - * @ticks: temperature ticks value received from sensor - */ -static inline int sht21_temp_ticks_to_millicelsius(int ticks) -{ - ticks &= ~0x0003; /* clear status bits */ - /* - * Formula T = -46.85 + 175.72 * ST / 2^16 from data sheet 6.2, - * optimized for integer fixed point (3 digits) arithmetic - */ - return ((21965 * ticks) >> 13) - 46850; -} - -/** - * sht21_rh_ticks_to_per_cent_mille() - convert raw humidity ticks to - * one-thousandths of a percent relative humidity - * @ticks: humidity ticks value received from sensor - */ -static inline int sht21_rh_ticks_to_per_cent_mille(int ticks) -{ - ticks &= ~0x0003; /* clear status bits */ - /* - * Formula RH = -6 + 125 * SRH / 2^16 from data sheet 6.1, - * optimized for integer fixed point (3 digits) arithmetic - */ - return ((15625 * ticks) >> 13) - 6000; -} - -/** - * sht21_read_word_data() - read word from register - * @client: I2C client device - * @reg: I2C command byte - * - * Returns value, negative errno on error. - */ -static inline int sht21_read_word_data(struct i2c_client *client, u8 reg) -{ - int ret = i2c_smbus_read_word_data(client, reg); - if (ret < 0) - return ret; - /* - * SMBus specifies low byte first, but the SHT21 returns MSB - * first, so we have to swab16 the values - */ - return swab16(ret); -} - -/** - * sht21_update_measurements() - get updated measurements from device - * @client: I2C client device - * - * Returns 0 on success, else negative errno. - */ -static int sht21_update_measurements(struct i2c_client *client) -{ - int ret = 0; - struct sht21 *sht21 = i2c_get_clientdata(client); - - mutex_lock(&sht21->lock); - /* - * Data sheet 2.4: - * SHT2x should not be active for more than 10% of the time - e.g. - * maximum two measurements per second at 12bit accuracy shall be made. - */ - if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) { - ret = sht21_read_word_data(client, SHT21_TRIG_T_MEASUREMENT_HM); - if (ret < 0) - goto out; - sht21->temperature = sht21_temp_ticks_to_millicelsius(ret); - ret = sht21_read_word_data(client, - SHT21_TRIG_RH_MEASUREMENT_HM); - if (ret < 0) - goto out; - sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret); - sht21->last_update = jiffies; - sht21->valid = 1; - } -out: - mutex_unlock(&sht21->lock); - - return ret >= 0 ? 0 : ret; -} - -/** - * sht21_show_temperature() - show temperature measurement value in sysfs - * @dev: device - * @attr: device attribute - * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to - * - * Will be called on read access to temp1_input sysfs attribute. - * Returns number of bytes written into buffer, negative errno on error. - */ -static ssize_t sht21_show_temperature(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct sht21 *sht21 = i2c_get_clientdata(client); - int ret = sht21_update_measurements(client); - if (ret < 0) - return ret; - return sprintf(buf, "%d\n", sht21->temperature); -} - -/** - * sht21_show_humidity() - show humidity measurement value in sysfs - * @dev: device - * @attr: device attribute - * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to - * - * Will be called on read access to humidity1_input sysfs attribute. - * Returns number of bytes written into buffer, negative errno on error. - */ -static ssize_t sht21_show_humidity(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct sht21 *sht21 = i2c_get_clientdata(client); - int ret = sht21_update_measurements(client); - if (ret < 0) - return ret; - return sprintf(buf, "%d\n", sht21->humidity); -} - -/* sysfs attributes */ -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature, - NULL, 0); -static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity, - NULL, 0); - -static struct attribute *sht21_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_humidity1_input.dev_attr.attr, - NULL -}; - -static const struct attribute_group sht21_attr_group = { - .attrs = sht21_attributes, -}; - -/** - * sht21_probe() - probe device - * @client: I2C client device - * @id: device ID - * - * Called by the I2C core when an entry in the ID table matches a - * device's name. - * Returns 0 on success. - */ -static int __devinit sht21_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct sht21 *sht21; - int err; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WORD_DATA)) { - dev_err(&client->dev, - "adapter does not support SMBus word transactions\n"); - return -ENODEV; - } - - sht21 = kzalloc(sizeof(*sht21), GFP_KERNEL); - if (!sht21) { - dev_dbg(&client->dev, "kzalloc failed\n"); - return -ENOMEM; - } - i2c_set_clientdata(client, sht21); - - mutex_init(&sht21->lock); - - err = sysfs_create_group(&client->dev.kobj, &sht21_attr_group); - if (err) { - dev_dbg(&client->dev, "could not create sysfs files\n"); - goto fail_free; - } - sht21->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(sht21->hwmon_dev)) { - dev_dbg(&client->dev, "unable to register hwmon device\n"); - err = PTR_ERR(sht21->hwmon_dev); - goto fail_remove_sysfs; - } - - dev_info(&client->dev, "initialized\n"); - - return 0; - -fail_remove_sysfs: - sysfs_remove_group(&client->dev.kobj, &sht21_attr_group); -fail_free: - kfree(sht21); - - return err; -} - -/** - * sht21_remove() - remove device - * @client: I2C client device - */ -static int __devexit sht21_remove(struct i2c_client *client) -{ - struct sht21 *sht21 = i2c_get_clientdata(client); - - hwmon_device_unregister(sht21->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &sht21_attr_group); - kfree(sht21); - - return 0; -} - -/* Device ID table */ -static const struct i2c_device_id sht21_id[] = { - { "sht21", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sht21_id); - -static struct i2c_driver sht21_driver = { - .driver.name = "sht21", - .probe = sht21_probe, - .remove = __devexit_p(sht21_remove), - .id_table = sht21_id, -}; - -/** - * sht21_init() - initialize driver - * - * Called when kernel is booted or module is inserted. - * Returns 0 on success. - */ -static int __init sht21_init(void) -{ - return i2c_add_driver(&sht21_driver); -} -module_init(sht21_init); - -/** - * sht21_init() - clean up driver - * - * Called when module is removed. - */ -static void __exit sht21_exit(void) -{ - i2c_del_driver(&sht21_driver); -} -module_exit(sht21_exit); - -MODULE_AUTHOR("Urs Fleisch "); -MODULE_DESCRIPTION("Sensirion SHT21 humidity and temperature sensor driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/sis5595.c b/trunk/drivers/hwmon/sis5595.c index 47d7ce9af8fb..79c2931e3008 100644 --- a/trunk/drivers/hwmon/sis5595.c +++ b/trunk/drivers/hwmon/sis5595.c @@ -50,8 +50,6 @@ 735 0008 0735 */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -737,19 +735,21 @@ static int __devinit sis5595_device_add(unsigned short address) pdev = platform_device_alloc("sis5595", address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR "sis5595: Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR "sis5595: Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR "sis5595: Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/smsc47b397.c b/trunk/drivers/hwmon/smsc47b397.c index 9fb7516e6f45..f46d936c12da 100644 --- a/trunk/drivers/hwmon/smsc47b397.c +++ b/trunk/drivers/hwmon/smsc47b397.c @@ -26,8 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -313,19 +311,21 @@ static int __init smsc47b397_device_add(unsigned short address) pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_put; } @@ -367,7 +367,8 @@ static int __init smsc47b397_find(unsigned short *addr) *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); - pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", + printk(KERN_INFO DRVNAME ": found SMSC %s " + "(base address 0x%04x, revision %u)\n", name, *addr, rev); superio_exit(); diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index f44a89aac381..8fa462f2b570 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -26,8 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -437,29 +435,30 @@ static int __init smsc47m1_find(unsigned short *addr, */ switch (val) { case 0x51: - pr_info("Found SMSC LPC47B27x\n"); + pr_info(DRVNAME ": Found SMSC LPC47B27x\n"); sio_data->type = smsc47m1; break; case 0x59: - pr_info("Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n"); + pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n"); sio_data->type = smsc47m1; break; case 0x5F: - pr_info("Found SMSC LPC47M14x\n"); + pr_info(DRVNAME ": Found SMSC LPC47M14x\n"); sio_data->type = smsc47m1; break; case 0x60: - pr_info("Found SMSC LPC47M15x/LPC47M192/LPC47M997\n"); + pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n"); sio_data->type = smsc47m1; break; case 0x6B: if (superio_inb(SUPERIO_REG_DEVREV) & 0x80) { - pr_debug("Found SMSC LPC47M233, unsupported\n"); + pr_debug(DRVNAME ": " + "Found SMSC LPC47M233, unsupported\n"); superio_exit(); return -ENODEV; } - pr_info("Found SMSC LPC47M292\n"); + pr_info(DRVNAME ": Found SMSC LPC47M292\n"); sio_data->type = smsc47m2; break; default: @@ -471,7 +470,7 @@ static int __init smsc47m1_find(unsigned short *addr, *addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); if (*addr == 0) { - pr_info("Device address not set, will not use\n"); + pr_info(DRVNAME ": Device address not set, will not use\n"); superio_exit(); return -ENODEV; } @@ -480,7 +479,7 @@ static int __init smsc47m1_find(unsigned short *addr, * Compaq Presario S4000NX) */ sio_data->activate = superio_inb(SUPERIO_REG_ACT); if ((sio_data->activate & 0x01) == 0) { - pr_info("Enabling device\n"); + pr_info(DRVNAME ": Enabling device\n"); superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01); } @@ -495,7 +494,7 @@ static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data) superio_enter(); superio_select(); - pr_info("Disabling device\n"); + pr_info(DRVNAME ": Disabling device\n"); superio_outb(SUPERIO_REG_ACT, sio_data->activate); superio_exit(); @@ -824,26 +823,28 @@ static int __init smsc47m1_device_add(unsigned short address, pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add_data(pdev, sio_data, sizeof(struct smsc47m1_sio_data)); if (err) { - pr_err("Platform data allocation failed\n"); + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/via-cputemp.c b/trunk/drivers/hwmon/via-cputemp.c index 0d18de424c66..ec7fad747adc 100644 --- a/trunk/drivers/hwmon/via-cputemp.c +++ b/trunk/drivers/hwmon/via-cputemp.c @@ -21,8 +21,6 @@ * 02110-1301 USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -204,7 +202,7 @@ static int __cpuinit via_cputemp_device_add(unsigned int cpu) pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } @@ -216,7 +214,8 @@ static int __cpuinit via_cputemp_device_add(unsigned int cpu) err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_free; } @@ -238,16 +237,13 @@ static int __cpuinit via_cputemp_device_add(unsigned int cpu) static void __cpuinit via_cputemp_device_remove(unsigned int cpu) { - struct pdev_entry *p; - + struct pdev_entry *p, *n; mutex_lock(&pdev_list_mutex); - list_for_each_entry(p, &pdev_list, list) { + list_for_each_entry_safe(p, n, &pdev_list, list) { if (p->cpu == cpu) { platform_device_unregister(p->pdev); list_del(&p->list); - mutex_unlock(&pdev_list_mutex); kfree(p); - return; } } mutex_unlock(&pdev_list_mutex); @@ -277,6 +273,7 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { static int __init via_cputemp_init(void) { int i, err; + struct pdev_entry *p, *n; if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); @@ -298,27 +295,33 @@ static int __init via_cputemp_init(void) continue; if (c->x86_model > 0x0f) { - pr_warn("Unknown CPU model 0x%x\n", c->x86_model); + printk(KERN_WARNING DRVNAME ": Unknown CPU " + "model 0x%x\n", c->x86_model); continue; } - via_cputemp_device_add(i); + err = via_cputemp_device_add(i); + if (err) + goto exit_devices_unreg; } - -#ifndef CONFIG_HOTPLUG_CPU if (list_empty(&pdev_list)) { err = -ENODEV; goto exit_driver_unreg; } -#endif register_hotcpu_notifier(&via_cputemp_cpu_notifier); return 0; -#ifndef CONFIG_HOTPLUG_CPU +exit_devices_unreg: + mutex_lock(&pdev_list_mutex); + list_for_each_entry_safe(p, n, &pdev_list, list) { + platform_device_unregister(p->pdev); + list_del(&p->list); + kfree(p); + } + mutex_unlock(&pdev_list_mutex); exit_driver_unreg: platform_driver_unregister(&via_cputemp_driver); -#endif exit: return err; } diff --git a/trunk/drivers/hwmon/via686a.c b/trunk/drivers/hwmon/via686a.c index 13e8d218e495..f397ce7ad598 100644 --- a/trunk/drivers/hwmon/via686a.c +++ b/trunk/drivers/hwmon/via686a.c @@ -30,8 +30,6 @@ Warning - only supports a single device. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -793,19 +791,21 @@ static int __devinit via686a_device_add(unsigned short address) pdev = platform_device_alloc("via686a", address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR "via686a: Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR "via686a: Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR "via686a: Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/vt1211.c b/trunk/drivers/hwmon/vt1211.c index 49163d48e966..ae33bbb577c7 100644 --- a/trunk/drivers/hwmon/vt1211.c +++ b/trunk/drivers/hwmon/vt1211.c @@ -21,8 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1256,7 +1254,8 @@ static int __init vt1211_device_add(unsigned short address) pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device allocation failed (%d)\n", + err); goto EXIT; } @@ -1267,13 +1266,15 @@ static int __init vt1211_device_add(unsigned short address) err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto EXIT_DEV_PUT; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto EXIT_DEV_PUT; } @@ -1300,20 +1301,23 @@ static int __init vt1211_find(int sio_cip, unsigned short *address) superio_select(sio_cip, SIO_VT1211_LDN_HWMON); if ((superio_inb(sio_cip, SIO_VT1211_ACTIVE) & 1) == 0) { - pr_warn("HW monitor is disabled, skipping\n"); + printk(KERN_WARNING DRVNAME ": HW monitor is disabled, " + "skipping\n"); goto EXIT; } *address = ((superio_inb(sio_cip, SIO_VT1211_BADDR) << 8) | (superio_inb(sio_cip, SIO_VT1211_BADDR + 1))) & 0xff00; if (*address == 0) { - pr_warn("Base address is not set, skipping\n"); + printk(KERN_WARNING DRVNAME ": Base address is not set, " + "skipping\n"); goto EXIT; } err = 0; - pr_info("Found VT1211 chip at 0x%04x, revision %u\n", - *address, superio_inb(sio_cip, SIO_VT1211_DEVREV)); + printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, " + "revision %u\n", *address, + superio_inb(sio_cip, SIO_VT1211_DEVREV)); EXIT: superio_exit(sio_cip); @@ -1332,15 +1336,15 @@ static int __init vt1211_init(void) if ((uch_config < -1) || (uch_config > 31)) { err = -EINVAL; - pr_warn("Invalid UCH configuration %d. " - "Choose a value between 0 and 31.\n", uch_config); + printk(KERN_WARNING DRVNAME ": Invalid UCH configuration %d. " + "Choose a value between 0 and 31.\n", uch_config); goto EXIT; } if ((int_mode < -1) || (int_mode > 0)) { err = -EINVAL; - pr_warn("Invalid interrupt mode %d. " - "Only mode 0 is supported.\n", int_mode); + printk(KERN_WARNING DRVNAME ": Invalid interrupt mode %d. " + "Only mode 0 is supported.\n", int_mode); goto EXIT; } diff --git a/trunk/drivers/hwmon/vt8231.c b/trunk/drivers/hwmon/vt8231.c index db3b2e8d2a67..e6078c9f0e27 100644 --- a/trunk/drivers/hwmon/vt8231.c +++ b/trunk/drivers/hwmon/vt8231.c @@ -24,8 +24,6 @@ /* Supports VIA VT8231 South Bridge embedded sensors */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -904,19 +902,21 @@ static int __devinit vt8231_device_add(unsigned short address) pdev = platform_device_alloc("vt8231", address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR "vt8231: Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR "vt8231: Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR "vt8231: Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 073eabedc432..072c58008a63 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -42,8 +42,6 @@ w83667hg-b 9 5 3 3 0xb350 0xc1 0x5ca3 */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1670,7 +1668,8 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, break; default: if (val != 0xffff) - pr_debug("unsupported chip ID: 0x%04x\n", val); + pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", + val); superio_exit(sioaddr); return -ENODEV; } @@ -1681,7 +1680,8 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | superio_inb(sioaddr, SIO_REG_ADDR + 1); *addr = val & IOREGION_ALIGNMENT; if (*addr == 0) { - pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n"); + printk(KERN_ERR DRVNAME ": Refusing to enable a Super-I/O " + "device with a base I/O port 0.\n"); superio_exit(sioaddr); return -ENODEV; } @@ -1689,12 +1689,13 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, /* Activate logical device if needed */ val = superio_inb(sioaddr, SIO_REG_ENABLE); if (!(val & 0x01)) { - pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); + printk(KERN_WARNING DRVNAME ": Forcibly enabling Super-I/O. " + "Sensor is probably unusable.\n"); superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); } superio_exit(sioaddr); - pr_info("Found %s chip at %#x\n", sio_name, *addr); + pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr); sio_data->sioreg = sioaddr; return 0; @@ -1728,14 +1729,14 @@ static int __init sensors_w83627ehf_init(void) if (!(pdev = platform_device_alloc(DRVNAME, address))) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit_unregister; } err = platform_device_add_data(pdev, &sio_data, sizeof(struct w83627ehf_sio_data)); if (err) { - pr_err("Platform data allocation failed\n"); + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } @@ -1751,14 +1752,16 @@ static int __init sensors_w83627ehf_init(void) err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } /* platform_device_add calls probe() */ err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index bde50e34d013..38e280523071 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -39,8 +39,6 @@ supported yet. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -1168,13 +1166,14 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, superio_inb(sio_data, WINB_BASE_REG + 1); *addr = val & WINB_ALIGNMENT; if (*addr == 0) { - pr_warn("Base address not set, skipping\n"); + printk(KERN_WARNING DRVNAME ": Base address not set, " + "skipping\n"); goto exit; } val = superio_inb(sio_data, WINB_ACT_REG); if (!(val & 0x01)) { - pr_warn("Enabling HWM logical device\n"); + printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); superio_outb(sio_data, WINB_ACT_REG, val | 0x01); } @@ -1790,26 +1789,28 @@ static int __init w83627hf_device_add(unsigned short address, pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; - pr_err("Device allocation failed\n"); + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { - pr_err("Device resource addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); goto exit_device_put; } err = platform_device_add_data(pdev, sio_data, sizeof(struct w83627hf_sio_data)); if (err) { - pr_err("Platform data allocation failed\n"); + printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } err = platform_device_add(pdev); if (err) { - pr_err("Device addition failed (%d)\n", err); + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); goto exit_device_put; } diff --git a/trunk/drivers/input/mouse/bcm5974.c b/trunk/drivers/input/mouse/bcm5974.c index ee82851afe3e..b95231763911 100644 --- a/trunk/drivers/input/mouse/bcm5974.c +++ b/trunk/drivers/input/mouse/bcm5974.c @@ -55,14 +55,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 -/* MacbookAir3,2 (unibody), aka wellspring5 */ -#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f -#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 -#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 -/* MacbookAir3,1 (unibody), aka wellspring4 */ -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 -#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -88,14 +80,6 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), - /* MacbookAir3,2 */ - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), - /* MacbookAir3,1 */ - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), /* Terminating entry */ {} }; @@ -250,30 +234,6 @@ static const struct bcm5974_config bcm5974_config_table[] = { { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } }, - { - USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, - USB_DEVICE_ID_APPLE_WELLSPRING4_ISO, - USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, - HAS_INTEGRATED_BUTTON, - 0x84, sizeof(struct bt_data), - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } - }, - { - USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, - USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO, - USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, - HAS_INTEGRATED_BUTTON, - 0x84, sizeof(struct bt_data), - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, - { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } - }, {} }; diff --git a/trunk/drivers/misc/eeprom/at24.c b/trunk/drivers/misc/eeprom/at24.c index ab1ad41786d1..559b0b3c16c3 100644 --- a/trunk/drivers/misc/eeprom/at24.c +++ b/trunk/drivers/misc/eeprom/at24.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -458,27 +457,6 @@ static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_OF -static void at24_get_ofdata(struct i2c_client *client, - struct at24_platform_data *chip) -{ - const __be32 *val; - struct device_node *node = client->dev.of_node; - - if (node) { - if (of_get_property(node, "read-only", NULL)) - chip->flags |= AT24_FLAG_READONLY; - val = of_get_property(node, "pagesize", NULL); - if (val) - chip->page_size = be32_to_cpup(val); - } -} -#else -static void at24_get_ofdata(struct i2c_client *client, - struct at24_platform_data *chip) -{ } -#endif /* CONFIG_OF */ - static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct at24_platform_data chip; @@ -507,9 +485,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) */ chip.page_size = 1; - /* update chipdata if OF is present */ - at24_get_ofdata(client, &chip); - chip.setup = NULL; chip.context = NULL; } @@ -517,11 +492,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!is_power_of_2(chip.byte_len)) dev_warn(&client->dev, "byte_len looks suspicious (no power of 2)!\n"); - if (!chip.page_size) { - dev_err(&client->dev, "page_size must not be 0!\n"); - err = -EINVAL; - goto err_out; - } if (!is_power_of_2(chip.page_size)) dev_warn(&client->dev, "page_size looks suspicious (no power of 2)!\n"); @@ -627,15 +597,19 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, at24); - dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", + dev_info(&client->dev, "%zu byte %s EEPROM %s\n", at24->bin.size, client->name, - writable ? "writable" : "read-only", at24->write_max); + writable ? "(writable)" : "(read-only)"); if (use_smbus == I2C_SMBUS_WORD_DATA || use_smbus == I2C_SMBUS_BYTE_DATA) { dev_notice(&client->dev, "Falling back to %s reads, " "performance will suffer\n", use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte"); } + dev_dbg(&client->dev, + "page_size %d, num_addresses %d, write_max %d, use_smbus %d\n", + chip.page_size, num_addresses, + at24->write_max, use_smbus); /* export data to kernel code */ if (chip.setup) @@ -686,11 +660,6 @@ static struct i2c_driver at24_driver = { static int __init at24_init(void) { - if (!io_limit) { - pr_err("at24: io_limit must not be 0!\n"); - return -EINVAL; - } - io_limit = rounddown_pow_of_two(io_limit); return i2c_add_driver(&at24_driver); } diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig index e960a9300eb2..d618e8673996 100644 --- a/trunk/drivers/mmc/host/Kconfig +++ b/trunk/drivers/mmc/host/Kconfig @@ -83,7 +83,7 @@ config MMC_RICOH_MMC config MMC_SDHCI_OF tristate "SDHCI support on OpenFirmware platforms" - depends on MMC_SDHCI && OF + depends on MMC_SDHCI && PPC_OF help This selects the OF support for Secure Digital Host Controller Interfaces. @@ -93,7 +93,6 @@ config MMC_SDHCI_OF config MMC_SDHCI_OF_ESDHC bool "SDHCI OF support for the Freescale eSDHC controller" depends on MMC_SDHCI_OF - depends on PPC_OF select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER help This selects the Freescale eSDHC controller support. @@ -103,7 +102,6 @@ config MMC_SDHCI_OF_ESDHC config MMC_SDHCI_OF_HLWD bool "SDHCI OF support for the Nintendo Wii SDHCI controllers" depends on MMC_SDHCI_OF - depends on PPC_OF select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER help This selects the Secure Digital Host Controller Interface (SDHCI) diff --git a/trunk/drivers/mmc/host/sdhci-of-core.c b/trunk/drivers/mmc/host/sdhci-of-core.c index fa19d849a920..c51b71174c1d 100644 --- a/trunk/drivers/mmc/host/sdhci-of-core.c +++ b/trunk/drivers/mmc/host/sdhci-of-core.c @@ -122,7 +122,7 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev, struct sdhci_of_data *sdhci_of_data = match->data; struct sdhci_host *host; struct sdhci_of_host *of_host; - const __be32 *clk; + const u32 *clk; int size; int ret; @@ -166,7 +166,7 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev, clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) - of_host->clock = be32_to_cpup(clk); + of_host->clock = *clk; ret = sdhci_add_host(host); if (ret) diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index b1f768917395..1e2cbf5d9aa1 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -159,7 +159,7 @@ config MTD_AFS_PARTS config MTD_OF_PARTS tristate "Flash partition map based on OF description" - depends on OF && MTD_PARTITIONS + depends on (MICROBLAZE || PPC_OF) && MTD_PARTITIONS help This provides a partition parsing function which derives the partition map from the children of the flash node, diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index 5d37d315fa98..a0dd7bba9481 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -72,7 +72,7 @@ config MTD_PHYSMAP_BANKWIDTH config MTD_PHYSMAP_OF tristate "Flash device in physical memory map based on OF description" - depends on OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM) + depends on (MICROBLAZE || PPC_OF) && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM) help This provides a 'mapping' driver which allows the NOR Flash and ROM driver code to communicate with chips which are mapped diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 31fe980e4e28..4da384cc7603 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "bond_3ad.h" diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index 7a1f3d0ffa78..d684f187de57 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index 6de4675016b5..45c4b7bfcf39 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -95,7 +95,6 @@ #include #include #include -#include #include "gianfar.h" #include "fsl_pq_mdio.h" diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 73a3e0d93237..acbdab3d66ca 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/xilinx_emaclite.c b/trunk/drivers/net/xilinx_emaclite.c index cad66ce1640b..de6c3086d232 100644 --- a/trunk/drivers/net/xilinx_emaclite.c +++ b/trunk/drivers/net/xilinx_emaclite.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #define DRIVER_NAME "xilinx_emaclite" diff --git a/trunk/drivers/of/Kconfig b/trunk/drivers/of/Kconfig index 3c6e100a3ad0..aa675ebd8eb3 100644 --- a/trunk/drivers/of/Kconfig +++ b/trunk/drivers/of/Kconfig @@ -19,10 +19,6 @@ config OF_FLATTREE bool select DTC -config OF_EARLY_FLATTREE - bool - select OF_FLATTREE - config OF_PROMTREE bool @@ -53,10 +49,6 @@ config OF_I2C help OpenFirmware I2C accessors -config OF_NET - depends on NETDEVICES - def_bool y - config OF_SPI def_tristate SPI depends on SPI && !SPARC diff --git a/trunk/drivers/of/Makefile b/trunk/drivers/of/Makefile index 3ab21a0a4907..7888155bea08 100644 --- a/trunk/drivers/of/Makefile +++ b/trunk/drivers/of/Makefile @@ -6,6 +6,5 @@ obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o -obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o obj-$(CONFIG_OF_MDIO) += of_mdio.o diff --git a/trunk/drivers/of/address.c b/trunk/drivers/of/address.c index b4559c58c095..3a1c7e70b192 100644 --- a/trunk/drivers/of/address.c +++ b/trunk/drivers/of/address.c @@ -12,13 +12,13 @@ (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, - const __be32 *addrp, u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, struct resource *r); /* Debug utility */ #ifdef DEBUG -static void of_dump_addr(const char *s, const __be32 *addr, int na) +static void of_dump_addr(const char *s, const u32 *addr, int na) { printk(KERN_DEBUG "%s", s); while (na--) @@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const __be32 *addr, int na) printk("\n"); } #else -static void of_dump_addr(const char *s, const __be32 *addr, int na) { } +static void of_dump_addr(const char *s, const u32 *addr, int na) { } #endif /* Callbacks for bus specific translators */ @@ -36,10 +36,10 @@ struct of_bus { int (*match)(struct device_node *parent); void (*count_cells)(struct device_node *child, int *addrc, int *sizec); - u64 (*map)(u32 *addr, const __be32 *range, + u64 (*map)(u32 *addr, const u32 *range, int na, int ns, int pna); int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(const __be32 *addr); + unsigned int (*get_flags)(const u32 *addr); }; /* @@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev, *sizec = of_n_size_cells(dev); } -static u64 of_bus_default_map(u32 *addr, const __be32 *range, +static u64 of_bus_default_map(u32 *addr, const u32 *range, int na, int ns, int pna) { u64 cp, s, da; @@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) return 0; } -static unsigned int of_bus_default_get_flags(const __be32 *addr) +static unsigned int of_bus_default_get_flags(const u32 *addr) { return IORESOURCE_MEM; } @@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np, *sizec = 2; } -static unsigned int of_bus_pci_get_flags(const __be32 *addr) +static unsigned int of_bus_pci_get_flags(const u32 *addr) { unsigned int flags = 0; - u32 w = be32_to_cpup(addr); + u32 w = addr[0]; switch((w >> 24) & 0x03) { case 0x01: @@ -129,8 +129,7 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr) return flags; } -static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, - int pna) +static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) { u64 cp, s, da; unsigned int af, rf; @@ -161,7 +160,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, +const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { const __be32 *prop; @@ -208,7 +207,7 @@ EXPORT_SYMBOL(of_get_pci_address); int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r) { - const __be32 *addrp; + const u32 *addrp; u64 size; unsigned int flags; @@ -238,13 +237,12 @@ static void of_bus_isa_count_cells(struct device_node *child, *sizec = 1; } -static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, - int pna) +static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) { u64 cp, s, da; /* Check address type match */ - if ((addr[0] ^ range[0]) & cpu_to_be32(1)) + if ((addr[0] ^ range[0]) & 0x00000001) return OF_BAD_ADDR; /* Read address values, skipping high cell */ @@ -266,10 +264,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -static unsigned int of_bus_isa_get_flags(const __be32 *addr) +static unsigned int of_bus_isa_get_flags(const u32 *addr) { unsigned int flags = 0; - u32 w = be32_to_cpup(addr); + u32 w = addr[0]; if (w & 1) flags |= IORESOURCE_IO; @@ -332,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna, const char *rprop) { - const __be32 *ranges; + const u32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; @@ -400,7 +398,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ -u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, +u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, const char *rprop) { struct device_node *parent = NULL; @@ -477,22 +475,22 @@ u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, return result; } -u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) +u64 of_translate_address(struct device_node *dev, const u32 *in_addr) { return __of_translate_address(dev, in_addr, "ranges"); } EXPORT_SYMBOL(of_translate_address); -u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) +u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) { return __of_translate_address(dev, in_addr, "dma-ranges"); } EXPORT_SYMBOL(of_translate_dma_address); -const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, +const u32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { - const __be32 *prop; + const u32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; @@ -527,8 +525,8 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, - const __be32 *addrp, u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, struct resource *r) { u64 taddr; @@ -566,7 +564,7 @@ static int __of_address_to_resource(struct device_node *dev, int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { - const __be32 *addrp; + const u32 *addrp; u64 size; unsigned int flags; diff --git a/trunk/drivers/of/fdt.c b/trunk/drivers/of/fdt.c index c787c3d95c60..c1360e02f921 100644 --- a/trunk/drivers/of/fdt.c +++ b/trunk/drivers/of/fdt.c @@ -11,12 +11,10 @@ #include #include -#include #include #include #include #include -#include #ifdef CONFIG_PPC #include @@ -24,19 +22,104 @@ #include -char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) +int __initdata dt_root_addr_cells; +int __initdata dt_root_size_cells; + +struct boot_param_header *initial_boot_params; + +char *find_flat_dt_string(u32 offset) { - return ((char *)blob) + - be32_to_cpu(blob->off_dt_strings) + offset; + return ((char *)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_strings) + offset; +} + +/** + * of_scan_flat_dt - scan flattened tree blob and call callback on each. + * @it: callback function + * @data: context data pointer + * + * This function is used to scan the flattened device-tree, it is + * used to extract the memory information at boot before we can + * unflatten the tree + */ +int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + int rc = 0; + int depth = -1; + + do { + u32 tag = be32_to_cpup((__be32 *)p); + char *pathp; + + p += 4; + if (tag == OF_DT_END_NODE) { + depth--; + continue; + } + if (tag == OF_DT_NOP) + continue; + if (tag == OF_DT_END) + break; + if (tag == OF_DT_PROP) { + u32 sz = be32_to_cpup((__be32 *)p); + p += 8; + if (be32_to_cpu(initial_boot_params->version) < 0x10) + p = ALIGN(p, sz >= 8 ? 8 : 4); + p += sz; + p = ALIGN(p, 4); + continue; + } + if (tag != OF_DT_BEGIN_NODE) { + pr_err("Invalid tag %x in flat device tree!\n", tag); + return -EINVAL; + } + depth++; + pathp = (char *)p; + p = ALIGN(p + strlen(pathp) + 1, 4); + if ((*pathp) == '/') { + char *lp, *np; + for (lp = NULL, np = pathp; *np; np++) + if ((*np) == '/') + lp = np+1; + if (lp != NULL) + pathp = lp; + } + rc = it(p, pathp, depth, data); + if (rc != 0) + break; + } while (1); + + return rc; } /** - * of_fdt_get_property - Given a node in the given flat blob, return - * the property ptr + * of_get_flat_dt_root - find the root node in the flat blob */ -void *of_fdt_get_property(struct boot_param_header *blob, - unsigned long node, const char *name, - unsigned long *size) +unsigned long __init of_get_flat_dt_root(void) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + + while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) + p += 4; + BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); + p += 4; + return ALIGN(p + strlen((char *)p) + 1, 4); +} + +/** + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr + * + * This function can be used within scan_flattened_dt callback to get + * access to properties + */ +void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size) { unsigned long p = node; @@ -54,10 +137,10 @@ void *of_fdt_get_property(struct boot_param_header *blob, sz = be32_to_cpup((__be32 *)p); noff = be32_to_cpup((__be32 *)(p + 4)); p += 8; - if (be32_to_cpu(blob->version) < 0x10) + if (be32_to_cpu(initial_boot_params->version) < 0x10) p = ALIGN(p, sz >= 8 ? 8 : 4); - nstr = of_fdt_get_string(blob, noff); + nstr = find_flat_dt_string(noff); if (nstr == NULL) { pr_warning("Can't find property index name !\n"); return NULL; @@ -73,28 +156,21 @@ void *of_fdt_get_property(struct boot_param_header *blob, } /** - * of_fdt_is_compatible - Return true if given node from the given blob has - * compat in its compatible list - * @blob: A device tree blob + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list * @node: node to test * @compat: compatible string to compare with compatible list. - * - * On match, returns a non-zero value with smaller values returned for more - * specific compatible values. */ -int of_fdt_is_compatible(struct boot_param_header *blob, - unsigned long node, const char *compat) +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) { const char *cp; - unsigned long cplen, l, score = 0; + unsigned long cplen, l; - cp = of_fdt_get_property(blob, node, "compatible", &cplen); + cp = of_get_flat_dt_prop(node, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { - score++; if (of_compat_cmp(cp, compat, strlen(compat)) == 0) - return score; + return 1; l = strlen(cp) + 1; cp += l; cplen -= l; @@ -103,28 +179,7 @@ int of_fdt_is_compatible(struct boot_param_header *blob, return 0; } -/** - * of_fdt_match - Return true if node matches a list of compatible values - */ -int of_fdt_match(struct boot_param_header *blob, unsigned long node, - const char **compat) -{ - unsigned int tmp, score = 0; - - if (!compat) - return 0; - - while (*compat) { - tmp = of_fdt_is_compatible(blob, node, *compat); - if (tmp && (score == 0 || (tmp < score))) - score = tmp; - compat++; - } - - return score; -} - -static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { void *res; @@ -138,18 +193,16 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, /** * unflatten_dt_node - Alloc and populate a device_node from the flat tree - * @blob: The parent device tree blob * @p: pointer to node in flat tree * @dad: Parent struct device_node * @allnextpp: pointer to ->allnext from last allocated device_node * @fpsize: Size of the node path up at the current depth. */ -unsigned long unflatten_dt_node(struct boot_param_header *blob, - unsigned long mem, - unsigned long *p, - struct device_node *dad, - struct device_node ***allnextpp, - unsigned long fpsize) +unsigned long __init unflatten_dt_node(unsigned long mem, + unsigned long *p, + struct device_node *dad, + struct device_node ***allnextpp, + unsigned long fpsize) { struct device_node *np; struct property *pp, **prev_pp = NULL; @@ -245,10 +298,10 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob, sz = be32_to_cpup((__be32 *)(*p)); noff = be32_to_cpup((__be32 *)((*p) + 4)); *p += 8; - if (be32_to_cpu(blob->version) < 0x10) + if (be32_to_cpu(initial_boot_params->version) < 0x10) *p = ALIGN(*p, sz >= 8 ? 8 : 4); - pname = of_fdt_get_string(blob, noff); + pname = find_flat_dt_string(noff); if (pname == NULL) { pr_info("Can't find property name in list !\n"); break; @@ -327,8 +380,7 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob, if (tag == OF_DT_NOP) *p += 4; else - mem = unflatten_dt_node(blob, mem, p, np, allnextpp, - fpsize); + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); tag = be32_to_cpup((__be32 *)(*p)); } if (tag != OF_DT_END_NODE) { @@ -339,211 +391,6 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob, return mem; } -/** - * __unflatten_device_tree - create tree of device_nodes from flat blob - * - * unflattens a device-tree, creating the - * tree of struct device_node. It also fills the "name" and "type" - * pointers of the nodes so the normal device-tree walking functions - * can be used. - * @blob: The blob to expand - * @mynodes: The device_node tree created by the call - * @dt_alloc: An allocator that provides a virtual address to memory - * for the resulting tree - */ -void __unflatten_device_tree(struct boot_param_header *blob, - struct device_node **mynodes, - void * (*dt_alloc)(u64 size, u64 align)) -{ - unsigned long start, mem, size; - struct device_node **allnextp = mynodes; - - pr_debug(" -> unflatten_device_tree()\n"); - - if (!blob) { - pr_debug("No device tree pointer\n"); - return; - } - - pr_debug("Unflattening device tree:\n"); - pr_debug("magic: %08x\n", be32_to_cpu(blob->magic)); - pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize)); - pr_debug("version: %08x\n", be32_to_cpu(blob->version)); - - if (be32_to_cpu(blob->magic) != OF_DT_HEADER) { - pr_err("Invalid device tree blob header\n"); - return; - } - - /* First pass, scan for size */ - start = ((unsigned long)blob) + - be32_to_cpu(blob->off_dt_struct); - size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); - size = (size | 3) + 1; - - pr_debug(" size is %lx, allocating...\n", size); - - /* Allocate memory for the expanded device tree */ - mem = (unsigned long) - dt_alloc(size + 4, __alignof__(struct device_node)); - - ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); - - pr_debug(" unflattening %lx...\n", mem); - - /* Second pass, do actual unflattening */ - start = ((unsigned long)blob) + - be32_to_cpu(blob->off_dt_struct); - unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); - if (be32_to_cpup((__be32 *)start) != OF_DT_END) - pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); - if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) - pr_warning("End of tree marker overwritten: %08x\n", - be32_to_cpu(((__be32 *)mem)[size / 4])); - *allnextp = NULL; - - pr_debug(" <- unflatten_device_tree()\n"); -} - -static void *kernel_tree_alloc(u64 size, u64 align) -{ - return kzalloc(size, GFP_KERNEL); -} - -/** - * of_fdt_unflatten_tree - create tree of device_nodes from flat blob - * - * unflattens the device-tree passed by the firmware, creating the - * tree of struct device_node. It also fills the "name" and "type" - * pointers of the nodes so the normal device-tree walking functions - * can be used. - */ -void of_fdt_unflatten_tree(unsigned long *blob, - struct device_node **mynodes) -{ - struct boot_param_header *device_tree = - (struct boot_param_header *)blob; - __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc); -} -EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); - -/* Everything below here references initial_boot_params directly. */ -int __initdata dt_root_addr_cells; -int __initdata dt_root_size_cells; - -struct boot_param_header *initial_boot_params; - -#ifdef CONFIG_OF_EARLY_FLATTREE - -/** - * of_scan_flat_dt - scan flattened tree blob and call callback on each. - * @it: callback function - * @data: context data pointer - * - * This function is used to scan the flattened device-tree, it is - * used to extract the memory information at boot before we can - * unflatten the tree - */ -int __init of_scan_flat_dt(int (*it)(unsigned long node, - const char *uname, int depth, - void *data), - void *data) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - int rc = 0; - int depth = -1; - - do { - u32 tag = be32_to_cpup((__be32 *)p); - char *pathp; - - p += 4; - if (tag == OF_DT_END_NODE) { - depth--; - continue; - } - if (tag == OF_DT_NOP) - continue; - if (tag == OF_DT_END) - break; - if (tag == OF_DT_PROP) { - u32 sz = be32_to_cpup((__be32 *)p); - p += 8; - if (be32_to_cpu(initial_boot_params->version) < 0x10) - p = ALIGN(p, sz >= 8 ? 8 : 4); - p += sz; - p = ALIGN(p, 4); - continue; - } - if (tag != OF_DT_BEGIN_NODE) { - pr_err("Invalid tag %x in flat device tree!\n", tag); - return -EINVAL; - } - depth++; - pathp = (char *)p; - p = ALIGN(p + strlen(pathp) + 1, 4); - if ((*pathp) == '/') { - char *lp, *np; - for (lp = NULL, np = pathp; *np; np++) - if ((*np) == '/') - lp = np+1; - if (lp != NULL) - pathp = lp; - } - rc = it(p, pathp, depth, data); - if (rc != 0) - break; - } while (1); - - return rc; -} - -/** - * of_get_flat_dt_root - find the root node in the flat blob - */ -unsigned long __init of_get_flat_dt_root(void) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - - while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) - p += 4; - BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); - p += 4; - return ALIGN(p + strlen((char *)p) + 1, 4); -} - -/** - * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr - * - * This function can be used within scan_flattened_dt callback to get - * access to properties - */ -void *__init of_get_flat_dt_prop(unsigned long node, const char *name, - unsigned long *size) -{ - return of_fdt_get_property(initial_boot_params, node, name, size); -} - -/** - * of_flat_dt_is_compatible - Return true if given node has compat in compatible list - * @node: node to test - * @compat: compatible string to compare with compatible list. - */ -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) -{ - return of_fdt_is_compatible(initial_boot_params, node, compat); -} - -/** - * of_flat_dt_match - Return true if node matches a list of compatible values - */ -int __init of_flat_dt_match(unsigned long node, const char **compat) -{ - return of_fdt_match(initial_boot_params, node, compat); -} - #ifdef CONFIG_BLK_DEV_INITRD /** * early_init_dt_check_for_initrd - Decode initrd location from flat tree @@ -692,12 +539,6 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, return 1; } -static void *__init early_device_tree_alloc(u64 size, u64 align) -{ - unsigned long mem = early_init_dt_alloc_memory_arch(size, align); - return __va(mem); -} - /** * unflatten_device_tree - create tree of device_nodes from flat blob * @@ -708,13 +549,58 @@ static void *__init early_device_tree_alloc(u64 size, u64 align) */ void __init unflatten_device_tree(void) { - __unflatten_device_tree(initial_boot_params, &allnodes, - early_device_tree_alloc); + unsigned long start, mem, size; + struct device_node **allnextp = &allnodes; + + pr_debug(" -> unflatten_device_tree()\n"); + + if (!initial_boot_params) { + pr_debug("No device tree pointer\n"); + return; + } + + pr_debug("Unflattening device tree:\n"); + pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); + pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); + pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); + + if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { + pr_err("Invalid device tree blob header\n"); + return; + } + + /* First pass, scan for size */ + start = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + size = unflatten_dt_node(0, &start, NULL, NULL, 0); + size = (size | 3) + 1; + + pr_debug(" size is %lx, allocating...\n", size); + + /* Allocate memory for the expanded device tree */ + mem = early_init_dt_alloc_memory_arch(size + 4, + __alignof__(struct device_node)); + mem = (unsigned long) __va(mem); + + ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); + + pr_debug(" unflattening %lx...\n", mem); + + /* Second pass, do actual unflattening */ + start = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + unflatten_dt_node(mem, &start, NULL, &allnextp, 0); + if (be32_to_cpup((__be32 *)start) != OF_DT_END) + pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); + if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) + pr_warning("End of tree marker overwritten: %08x\n", + be32_to_cpu(((__be32 *)mem)[size / 4])); + *allnextp = NULL; /* Get pointer to OF "/chosen" node for use everywhere */ of_chosen = of_find_node_by_path("/chosen"); if (of_chosen == NULL) of_chosen = of_find_node_by_path("/chosen@0"); -} -#endif /* CONFIG_OF_EARLY_FLATTREE */ + pr_debug(" <- unflatten_device_tree()\n"); +} diff --git a/trunk/drivers/of/of_mdio.c b/trunk/drivers/of/of_mdio.c index dcd7857784f2..1fce00eb421b 100644 --- a/trunk/drivers/of/of_mdio.c +++ b/trunk/drivers/of/of_mdio.c @@ -52,35 +52,27 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Loop over the child nodes and register a phy_device for each one */ for_each_child_of_node(np, child) { - const __be32 *paddr; - u32 addr; + const __be32 *addr; int len; /* A PHY must have a reg property in the range [0-31] */ - paddr = of_get_property(child, "reg", &len); - if (!paddr || len < sizeof(*paddr)) { + addr = of_get_property(child, "reg", &len); + if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) { dev_err(&mdio->dev, "%s has invalid PHY address\n", child->full_name); continue; } - addr = be32_to_cpup(paddr); - if (addr >= 32) { - dev_err(&mdio->dev, "%s PHY address %i is too large\n", - child->full_name, addr); - continue; - } - if (mdio->irq) { - mdio->irq[addr] = irq_of_parse_and_map(child, 0); - if (!mdio->irq[addr]) - mdio->irq[addr] = PHY_POLL; + mdio->irq[*addr] = irq_of_parse_and_map(child, 0); + if (!mdio->irq[*addr]) + mdio->irq[*addr] = PHY_POLL; } - phy = get_phy_device(mdio, addr); + phy = get_phy_device(mdio, be32_to_cpup(addr)); if (!phy || IS_ERR(phy)) { dev_err(&mdio->dev, "error probing PHY at address %i\n", - addr); + *addr); continue; } phy_scan_fixups(phy); @@ -99,7 +91,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) } dev_dbg(&mdio->dev, "registered phy %s at address %i\n", - child->name, addr); + child->name, *addr); } return 0; diff --git a/trunk/drivers/of/of_net.c b/trunk/drivers/of/of_net.c deleted file mode 100644 index 86f334a2769c..000000000000 --- a/trunk/drivers/of/of_net.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * OF helpers for network devices. - * - * This file is released under the GPLv2 - * - * Initially copied out of arch/powerpc/kernel/prom_parse.c - */ -#include -#include -#include - -/** - * Search the device tree for the best MAC address to use. 'mac-address' is - * checked first, because that is supposed to contain to "most recent" MAC - * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. - * - * Note that the 'address' property is supposed to contain a virtual address of - * the register set, but some DTS files have redefined that property to be the - * MAC address. - * - * All-zero MAC addresses are rejected, because those could be properties that - * exist in the device tree, but were not set by U-Boot. For example, the - * DTS could define 'mac-address' and 'local-mac-address', with zero MAC - * addresses. Some older U-Boots only initialized 'local-mac-address'. In - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. -*/ -const void *of_get_mac_address(struct device_node *np) -{ - struct property *pp; - - pp = of_find_property(np, "mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "local-mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - return NULL; -} -EXPORT_SYMBOL(of_get_mac_address); diff --git a/trunk/drivers/of/platform.c b/trunk/drivers/of/platform.c index c01cd1ac7617..5b4a07f1220e 100644 --- a/trunk/drivers/of/platform.c +++ b/trunk/drivers/of/platform.c @@ -633,9 +633,6 @@ EXPORT_SYMBOL(of_device_alloc); * @np: pointer to node to create device for * @bus_id: name to assign device * @parent: Linux device model parent device. - * - * Returns pointer to created platform device, or NULL if a device was not - * registered. Unavailable devices will not get registered. */ struct platform_device *of_platform_device_create(struct device_node *np, const char *bus_id, @@ -643,9 +640,6 @@ struct platform_device *of_platform_device_create(struct device_node *np, { struct platform_device *dev; - if (!of_device_is_available(np)) - return NULL; - dev = of_device_alloc(np, bus_id, parent); if (!dev) return NULL; @@ -689,9 +683,8 @@ static int of_platform_bus_create(const struct device_node *bus, pr_debug(" create child: %s\n", child->full_name); dev = of_platform_device_create(child, NULL, parent); if (dev == NULL) - continue; - - if (!of_match_node(matches, child)) + rc = -ENOMEM; + else if (!of_match_node(matches, child)) continue; if (rc == 0) { pr_debug(" and sub busses\n"); @@ -740,9 +733,10 @@ int of_platform_bus_probe(struct device_node *root, if (of_match_node(matches, root)) { pr_debug(" root match, create all sub devices\n"); dev = of_platform_device_create(root, NULL, parent); - if (dev == NULL) + if (dev == NULL) { + rc = -ENOMEM; goto bail; - + } pr_debug(" create all sub busses\n"); rc = of_platform_bus_create(root, matches, &dev->dev); goto bail; @@ -754,9 +748,9 @@ int of_platform_bus_probe(struct device_node *root, pr_debug(" match: %s\n", child->full_name); dev = of_platform_device_create(child, NULL, parent); if (dev == NULL) - continue; - - rc = of_platform_bus_create(child, matches, &dev->dev); + rc = -ENOMEM; + else + rc = of_platform_bus_create(child, matches, &dev->dev); if (rc) { of_node_put(child); break; diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index 7722108e78df..bab52047baa8 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -36,6 +36,7 @@ #define _ACPIPHP_H #include +#include #include #include diff --git a/trunk/drivers/pci/hotplug/rpaphp_slot.c b/trunk/drivers/pci/hotplug/rpaphp_slot.c index b283bbea6d24..2ea9cf1a8d02 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_slot.c +++ b/trunk/drivers/pci/hotplug/rpaphp_slot.c @@ -24,6 +24,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/drivers/s390/char/tape_class.h b/trunk/drivers/s390/char/tape_class.h index 9e32780c317f..707b7f48c232 100644 --- a/trunk/drivers/s390/char/tape_class.h +++ b/trunk/drivers/s390/char/tape_class.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/sbus/char/jsflash.c b/trunk/drivers/sbus/char/jsflash.c index e8566224fe4b..a624f5af4320 100644 --- a/trunk/drivers/sbus/char/jsflash.c +++ b/trunk/drivers/sbus/char/jsflash.c @@ -467,7 +467,7 @@ static int jsflash_init(void) node = prom_getchild(prom_root_node); node = prom_searchsiblings(node, "flash-memory"); - if (node != 0 && (s32)node != -1) { + if (node != 0 && node != -1) { if (prom_getproperty(node, "reg", (char *)®0, sizeof(reg0)) == -1) { printk("jsflash: no \"reg\" property\n"); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index d3c5905b22ec..de2e09e49a3e 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -5748,7 +5748,7 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd, } if (ipr_is_gata(res) && res->sata_port) - return ata_sas_queuecmd(scsi_cmd, res->sata_port->ap); + return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap); ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; diff --git a/trunk/drivers/scsi/libsas/sas_scsi_host.c b/trunk/drivers/scsi/libsas/sas_scsi_host.c index 5815cbeb27a6..29251fabecc6 100644 --- a/trunk/drivers/scsi/libsas/sas_scsi_host.c +++ b/trunk/drivers/scsi/libsas/sas_scsi_host.c @@ -211,7 +211,8 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd, unsigned long flags; spin_lock_irqsave(dev->sata_dev.ap->lock, flags); - res = ata_sas_queuecmd(cmd, dev->sata_dev.ap); + res = ata_sas_queuecmd(cmd, scsi_done, + dev->sata_dev.ap); spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); goto out; } diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index 188aff6d263f..ec3c214598d0 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -1412,7 +1412,7 @@ config SERIAL_NETX_CONSOLE config SERIAL_OF_PLATFORM tristate "Serial port on Open Firmware platform bus" - depends on OF + depends on PPC_OF || MICROBLAZE depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL help If you have a PowerPC based system that has serial ports diff --git a/trunk/drivers/serial/of_serial.c b/trunk/drivers/serial/of_serial.c index 5c7abe4c94dd..17849dcb9adc 100644 --- a/trunk/drivers/serial/of_serial.c +++ b/trunk/drivers/serial/of_serial.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/sh/clk/core.c b/trunk/drivers/sh/clk/core.c index 5f63c3b83828..3f5e387ed564 100644 --- a/trunk/drivers/sh/clk/core.c +++ b/trunk/drivers/sh/clk/core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 34bb17f03019..b02d0cbce890 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -28,7 +28,6 @@ #include #include #include -#include static void spidev_release(struct device *dev) { @@ -101,8 +100,9 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#ifdef CONFIG_PM_SLEEP -static int spi_legacy_suspend(struct device *dev, pm_message_t message) +#ifdef CONFIG_PM + +static int spi_suspend(struct device *dev, pm_message_t message) { int value = 0; struct spi_driver *drv = to_spi_driver(dev->driver); @@ -117,7 +117,7 @@ static int spi_legacy_suspend(struct device *dev, pm_message_t message) return value; } -static int spi_legacy_resume(struct device *dev) +static int spi_resume(struct device *dev) { int value = 0; struct spi_driver *drv = to_spi_driver(dev->driver); @@ -132,94 +132,18 @@ static int spi_legacy_resume(struct device *dev) return value; } -static int spi_pm_suspend(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_suspend(dev); - else - return spi_legacy_suspend(dev, PMSG_SUSPEND); -} - -static int spi_pm_resume(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_resume(dev); - else - return spi_legacy_resume(dev); -} - -static int spi_pm_freeze(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_freeze(dev); - else - return spi_legacy_suspend(dev, PMSG_FREEZE); -} - -static int spi_pm_thaw(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_thaw(dev); - else - return spi_legacy_resume(dev); -} - -static int spi_pm_poweroff(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_poweroff(dev); - else - return spi_legacy_suspend(dev, PMSG_HIBERNATE); -} - -static int spi_pm_restore(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_restore(dev); - else - return spi_legacy_resume(dev); -} #else -#define spi_pm_suspend NULL -#define spi_pm_resume NULL -#define spi_pm_freeze NULL -#define spi_pm_thaw NULL -#define spi_pm_poweroff NULL -#define spi_pm_restore NULL +#define spi_suspend NULL +#define spi_resume NULL #endif -static const struct dev_pm_ops spi_pm = { - .suspend = spi_pm_suspend, - .resume = spi_pm_resume, - .freeze = spi_pm_freeze, - .thaw = spi_pm_thaw, - .poweroff = spi_pm_poweroff, - .restore = spi_pm_restore, - SET_RUNTIME_PM_OPS( - pm_generic_runtime_suspend, - pm_generic_runtime_resume, - pm_generic_runtime_idle - ) -}; - struct bus_type spi_bus_type = { .name = "spi", .dev_attrs = spi_dev_attrs, .match = spi_match_device, .uevent = spi_uevent, - .pm = &spi_pm, + .suspend = spi_suspend, + .resume = spi_resume, }; EXPORT_SYMBOL_GPL(spi_bus_type); diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index fca61720b873..b9278a1fb9e5 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && !intf->dev.power.in_suspend) { + } else if (!error && intf->dev.power.status == DPM_ON) { r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); if (r < 0) @@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - if (!intf->dev.power.in_suspend) { + if (intf->dev.power.status == DPM_ON) { intf->needs_binding = 0; rc = device_attach(&intf->dev); if (rc < 0) @@ -1107,7 +1107,8 @@ static int usb_resume_interface(struct usb_device *udev, if (intf->condition == USB_INTERFACE_UNBOUND) { /* Carry out a deferred switch to altsetting 0 */ - if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { + if (intf->needs_altsetting0 && + intf->dev.power.status == DPM_ON) { usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); intf->needs_altsetting0 = 0; diff --git a/trunk/drivers/usb/musb/musb_debugfs.c b/trunk/drivers/usb/musb/musb_debugfs.c index b0176e4569e0..9e8639d4e862 100644 --- a/trunk/drivers/usb/musb/musb_debugfs.c +++ b/trunk/drivers/usb/musb/musb_debugfs.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/video/xen-fbfront.c b/trunk/drivers/video/xen-fbfront.c index 3e6934d4bea8..4abb0b9ed653 100644 --- a/trunk/drivers/video/xen-fbfront.c +++ b/trunk/drivers/video/xen-fbfront.c @@ -562,24 +562,26 @@ static void xenfb_init_shared_page(struct xenfb_info *info, static int xenfb_connect_backend(struct xenbus_device *dev, struct xenfb_info *info) { - int ret, evtchn, irq; + int ret, evtchn; struct xenbus_transaction xbt; ret = xenbus_alloc_evtchn(dev, &evtchn); if (ret) return ret; - irq = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, + ret = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, 0, dev->devicetype, info); - if (irq < 0) { + if (ret < 0) { xenbus_free_evtchn(dev, evtchn); xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); - return irq; + return ret; } + info->irq = ret; + again: ret = xenbus_transaction_start(&xbt); if (ret) { xenbus_dev_fatal(dev, ret, "starting transaction"); - goto unbind_irq; + return ret; } ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", virt_to_mfn(info->page)); @@ -601,25 +603,20 @@ static int xenfb_connect_backend(struct xenbus_device *dev, if (ret == -EAGAIN) goto again; xenbus_dev_fatal(dev, ret, "completing transaction"); - goto unbind_irq; + return ret; } xenbus_switch_state(dev, XenbusStateInitialised); - info->irq = irq; return 0; error_xenbus: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, ret, "writing xenstore"); - unbind_irq: - unbind_from_irqhandler(irq, info); return ret; } static void xenfb_disconnect_backend(struct xenfb_info *info) { - /* Prevent xenfb refresh */ - info->update_wanted = 0; if (info->irq >= 0) unbind_from_irqhandler(info->irq, info); info->irq = -1; diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 74681478100a..65f8637d13cf 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -170,9 +170,6 @@ static struct irq_info *info_for_irq(unsigned irq) static unsigned int evtchn_from_irq(unsigned irq) { - if (unlikely(WARN(irq < 0 || irq >= nr_irqs, "Invalid irq %d!\n", irq))) - return 0; - return info_for_irq(irq)->evtchn; } @@ -408,21 +405,15 @@ static int find_unbound_irq(void) { struct irq_data *data; int irq, res; - int bottom = get_nr_hw_irqs(); - int top = nr_irqs-1; + int start = get_nr_hw_irqs(); - if (bottom == nr_irqs) + if (start == nr_irqs) goto no_irqs; - /* This loop starts from the top of IRQ space and goes down. - * We need this b/c if we have a PCI device in a Xen PV guest - * we do not have an IO-APIC (though the backend might have them) - * mapped in. To not have a collision of physical IRQs with the Xen - * event channels start at the top of the IRQ space for virtual IRQs. - */ - for (irq = top; irq > bottom; irq--) { + /* nr_irqs is a magic value. Must not use it.*/ + for (irq = nr_irqs-1; irq > start; irq--) { data = irq_get_irq_data(irq); - /* only 15->0 have init'd desc; handle irq > 16 */ + /* only 0->15 have init'd desc; handle irq > 16 */ if (!data) break; if (data->chip == &no_irq_chip) @@ -433,7 +424,7 @@ static int find_unbound_irq(void) return irq; } - if (irq == bottom) + if (irq == start) goto no_irqs; res = irq_alloc_desc_at(irq, -1); diff --git a/trunk/fs/cifs/cache.c b/trunk/fs/cifs/cache.c index e654dfd092c3..224d7bbd1fcc 100644 --- a/trunk/fs/cifs/cache.c +++ b/trunk/fs/cifs/cache.c @@ -64,9 +64,7 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data, void *buffer, uint16_t maxbuf) { const struct TCP_Server_Info *server = cookie_netfs_data; - const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr; - const struct sockaddr_in *addr = (struct sockaddr_in *) sa; - const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa; + const struct sockaddr *sa = (struct sockaddr *) &server->addr.sockAddr; struct cifs_server_key *key = buffer; uint16_t key_len = sizeof(struct cifs_server_key); @@ -78,16 +76,16 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data, */ switch (sa->sa_family) { case AF_INET: - key->family = sa->sa_family; - key->port = addr->sin_port; - key->addr[0].ipv4_addr = addr->sin_addr; + key->family = server->addr.sockAddr.sin_family; + key->port = server->addr.sockAddr.sin_port; + key->addr[0].ipv4_addr = server->addr.sockAddr.sin_addr; key_len += sizeof(key->addr[0].ipv4_addr); break; case AF_INET6: - key->family = sa->sa_family; - key->port = addr6->sin6_port; - key->addr[0].ipv6_addr = addr6->sin6_addr; + key->family = server->addr.sockAddr6.sin6_family; + key->port = server->addr.sockAddr6.sin6_port; + key->addr[0].ipv6_addr = server->addr.sockAddr6.sin6_addr; key_len += sizeof(key->addr[0].ipv6_addr); break; diff --git a/trunk/fs/cifs/cifs_debug.c b/trunk/fs/cifs/cifs_debug.c index ede98300a8cd..103ab8b605b0 100644 --- a/trunk/fs/cifs/cifs_debug.c +++ b/trunk/fs/cifs/cifs_debug.c @@ -119,27 +119,29 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) "Display Internal CIFS Data Structures for Debugging\n" "---------------------------------------------------\n"); seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); - seq_printf(m, "Features:"); + seq_printf(m, "Features: "); #ifdef CONFIG_CIFS_DFS_UPCALL - seq_printf(m, " dfs"); + seq_printf(m, "dfs"); + seq_putc(m, ' '); #endif #ifdef CONFIG_CIFS_FSCACHE - seq_printf(m, " fscache"); + seq_printf(m, "fscache"); + seq_putc(m, ' '); #endif #ifdef CONFIG_CIFS_WEAK_PW_HASH - seq_printf(m, " lanman"); + seq_printf(m, "lanman"); + seq_putc(m, ' '); #endif #ifdef CONFIG_CIFS_POSIX - seq_printf(m, " posix"); + seq_printf(m, "posix"); + seq_putc(m, ' '); #endif #ifdef CONFIG_CIFS_UPCALL - seq_printf(m, " spnego"); + seq_printf(m, "spnego"); + seq_putc(m, ' '); #endif #ifdef CONFIG_CIFS_XATTR - seq_printf(m, " xattr"); -#endif -#ifdef CONFIG_CIFS_ACL - seq_printf(m, " acl"); + seq_printf(m, "xattr"); #endif seq_putc(m, '\n'); seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); diff --git a/trunk/fs/cifs/cifs_spnego.c b/trunk/fs/cifs/cifs_spnego.c index 4dfba8283165..87044906cd1f 100644 --- a/trunk/fs/cifs/cifs_spnego.c +++ b/trunk/fs/cifs/cifs_spnego.c @@ -98,8 +98,6 @@ struct key * cifs_get_spnego_key(struct cifsSesInfo *sesInfo) { struct TCP_Server_Info *server = sesInfo->server; - struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr; - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr; char *description, *dp; size_t desc_len; struct key *spnego_key; @@ -129,10 +127,10 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) dp = description + strlen(description); /* add the server address */ - if (server->dstaddr.ss_family == AF_INET) - sprintf(dp, "ip4=%pI4", &sa->sin_addr); - else if (server->dstaddr.ss_family == AF_INET6) - sprintf(dp, "ip6=%pI6", &sa6->sin6_addr); + if (server->addr.sockAddr.sin_family == AF_INET) + sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr); + else if (server->addr.sockAddr.sin_family == AF_INET6) + sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr); else goto out; diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index 66f3d50d0676..f856732161ab 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -72,7 +72,6 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, return 0; } -/* must be called with server->srv_mutex held */ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { @@ -85,12 +84,14 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) return rc; + spin_lock(&GlobalMid_Lock); cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number); cifs_pdu->Signature.Sequence.Reserved = 0; *pexpected_response_sequence_number = server->sequence_number++; server->sequence_number++; + spin_unlock(&GlobalMid_Lock); rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); if (rc) @@ -148,7 +149,6 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, return rc; } -/* must be called with server->srv_mutex held */ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { @@ -162,12 +162,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) return rc; + spin_lock(&GlobalMid_Lock); cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number); cifs_pdu->Signature.Sequence.Reserved = 0; *pexpected_response_sequence_number = server->sequence_number++; server->sequence_number++; + spin_unlock(&GlobalMid_Lock); rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); if (rc) diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 5e7075d5f139..8e21e0fe65d5 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -329,8 +329,6 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->invalid_mapping = false; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ cifs_inode->server_eof = 0; - cifs_inode->uniqueid = 0; - cifs_inode->createtime = 0; /* Can not set i_flags here - they get immediately overwritten to zero by the VFS */ @@ -363,19 +361,18 @@ cifs_evict_inode(struct inode *inode) static void cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) { - struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr; - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr; - seq_printf(s, ",addr="); - switch (server->dstaddr.ss_family) { + switch (server->addr.sockAddr.sin_family) { case AF_INET: - seq_printf(s, "%pI4", &sa->sin_addr.s_addr); + seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); break; case AF_INET6: - seq_printf(s, "%pI6", &sa6->sin6_addr.s6_addr); - if (sa6->sin6_scope_id) - seq_printf(s, "%%%u", sa6->sin6_scope_id); + seq_printf(s, "%pI6", + &server->addr.sockAddr6.sin6_addr.s6_addr); + if (server->addr.sockAddr6.sin6_scope_id) + seq_printf(s, "%%%u", + server->addr.sockAddr6.sin6_scope_id); break; default: seq_printf(s, "(unknown)"); diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 606ca8bb7102..7136c0c3e2f9 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -163,7 +163,10 @@ struct TCP_Server_Info { char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; char *hostname; /* hostname portion of UNC string */ struct socket *ssocket; - struct sockaddr_storage dstaddr; + union { + struct sockaddr_in sockAddr; + struct sockaddr_in6 sockAddr6; + } addr; struct sockaddr_storage srcaddr; /* locally bind to this IP */ wait_queue_head_t response_q; wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ @@ -207,7 +210,7 @@ struct TCP_Server_Info { char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */ /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; - __u32 sequence_number; /* for signing, protected by srv_mutex */ + __u32 sequence_number; /* needed for CIFS PDU signature */ struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ u16 dialect; /* dialect index that server chose */ @@ -453,7 +456,6 @@ struct cifsInodeInfo { bool invalid_mapping:1; /* pagecache is invalid */ u64 server_eof; /* current file size on server */ u64 uniqueid; /* server inode number */ - u64 createtime; /* creation time on server */ #ifdef CONFIG_CIFS_FSCACHE struct fscache_cookie *fscache; #endif @@ -574,7 +576,6 @@ struct cifs_fattr { u64 cf_uniqueid; u64 cf_eof; u64 cf_bytes; - u64 cf_createtime; uid_t cf_uid; gid_t cf_gid; umode_t cf_mode; diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 2f6795e524d3..67acfb3acad2 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -401,12 +401,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { cFYI(1, "Kerberos only mechanism, enable extended security"); pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; - } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP) + } +#ifdef CONFIG_CIFS_EXPERIMENTAL + else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP) pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) { cFYI(1, "NTLMSSP only mechanism, enable extended security"); pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; } +#endif count = 0; for (i = 0; i < CIFS_NUM_PROT; i++) { diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index a65d311d163a..cc1a8604a790 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -64,8 +64,8 @@ struct smb_vol { char *UNC; char *UNCip; char *iocharset; /* local code page for mapping to and from Unicode */ - char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ - char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ + char source_rfc1001_name[16]; /* netbios name of client */ + char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ uid_t cred_uid; uid_t linux_uid; gid_t linux_gid; @@ -115,8 +115,8 @@ struct smb_vol { #define TLINK_ERROR_EXPIRE (1 * HZ) #define TLINK_IDLE_EXPIRE (600 * HZ) -static int ip_connect(struct TCP_Server_Info *server); -static int generic_ip_connect(struct TCP_Server_Info *server); +static int ipv4_connect(struct TCP_Server_Info *server); +static int ipv6_connect(struct TCP_Server_Info *server); static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); static void cifs_prune_tlinks(struct work_struct *work); @@ -200,9 +200,10 @@ cifs_reconnect(struct TCP_Server_Info *server) while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) { try_to_freeze(); - - /* we should try only the port we connected to before */ - rc = generic_ip_connect(server); + if (server->addr.sockAddr6.sin6_family == AF_INET6) + rc = ipv6_connect(server); + else + rc = ipv4_connect(server); if (rc) { cFYI(1, "reconnect error %d", rc); msleep(3000); @@ -476,7 +477,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) * initialize frame) */ cifs_set_port((struct sockaddr *) - &server->dstaddr, CIFS_PORT); + &server->addr.sockAddr, CIFS_PORT); cifs_reconnect(server); csocket = server->ssocket; wake_up(&server->response_q); @@ -816,11 +817,11 @@ cifs_parse_mount_options(char *options, const char *devname, * informational, only used for servers that do not support * port 445 and it can be overridden at mount time */ - memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); - for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++) + memset(vol->source_rfc1001_name, 0x20, 15); + for (i = 0; i < strnlen(nodename, 15); i++) vol->source_rfc1001_name[i] = toupper(nodename[i]); - vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0; + vol->source_rfc1001_name[15] = 0; /* null target name indicates to use *SMBSERVR default called name if we end up sending RFC1001 session initialize */ vol->target_rfc1001_name[0] = 0; @@ -984,11 +985,13 @@ cifs_parse_mount_options(char *options, const char *devname, return 1; } else if (strnicmp(value, "krb5", 4) == 0) { vol->secFlg |= CIFSSEC_MAY_KRB5; +#ifdef CONFIG_CIFS_EXPERIMENTAL } else if (strnicmp(value, "ntlmsspi", 8) == 0) { vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; } else if (strnicmp(value, "ntlmssp", 7) == 0) { vol->secFlg |= CIFSSEC_MAY_NTLMSSP; +#endif } else if (strnicmp(value, "ntlmv2i", 7) == 0) { vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN; @@ -1165,22 +1168,22 @@ cifs_parse_mount_options(char *options, const char *devname, if (!value || !*value || (*value == ' ')) { cFYI(1, "invalid (empty) netbiosname"); } else { - memset(vol->source_rfc1001_name, 0x20, - RFC1001_NAME_LEN); - /* - * FIXME: are there cases in which a comma can - * be valid in workstation netbios name (and - * need special handling)? - */ - for (i = 0; i < RFC1001_NAME_LEN; i++) { - /* don't ucase netbiosname for user */ + memset(vol->source_rfc1001_name, 0x20, 15); + for (i = 0; i < 15; i++) { + /* BB are there cases in which a comma can be + valid in this workstation netbios name (and need + special handling)? */ + + /* We do not uppercase netbiosname for user */ if (value[i] == 0) break; - vol->source_rfc1001_name[i] = value[i]; + else + vol->source_rfc1001_name[i] = + value[i]; } /* The string has 16th byte zero still from set at top of the function */ - if (i == RFC1001_NAME_LEN && value[i] != 0) + if ((i == 15) && (value[i] != 0)) printk(KERN_WARNING "CIFS: netbiosname" " longer than 15 truncated.\n"); } @@ -1190,8 +1193,7 @@ cifs_parse_mount_options(char *options, const char *devname, cFYI(1, "empty server netbiosname specified"); } else { /* last byte, type, is 0x20 for servr type */ - memset(vol->target_rfc1001_name, 0x20, - RFC1001_NAME_LEN_WITH_NULL); + memset(vol->target_rfc1001_name, 0x20, 16); for (i = 0; i < 15; i++) { /* BB are there cases in which a comma can be @@ -1208,7 +1210,7 @@ cifs_parse_mount_options(char *options, const char *devname, } /* The string has 16th byte zero still from set at top of the function */ - if (i == RFC1001_NAME_LEN && value[i] != 0) + if ((i == 15) && (value[i] != 0)) printk(KERN_WARNING "CIFS: server net" "biosname longer than 15 truncated.\n"); } @@ -1339,8 +1341,10 @@ cifs_parse_mount_options(char *options, const char *devname, vol->no_psx_acl = 0; } else if (strnicmp(data, "noacl", 5) == 0) { vol->no_psx_acl = 1; +#ifdef CONFIG_CIFS_EXPERIMENTAL } else if (strnicmp(data, "locallease", 6) == 0) { vol->local_lease = 1; +#endif } else if (strnicmp(data, "sign", 4) == 0) { vol->secFlg |= CIFSSEC_MUST_SIGN; } else if (strnicmp(data, "seal", 4) == 0) { @@ -1450,71 +1454,35 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs) } } -/* - * If no port is specified in addr structure, we try to match with 445 port - * and if it fails - with 139 ports. It should be called only if address - * families of server and addr are equal. - */ -static bool -match_port(struct TCP_Server_Info *server, struct sockaddr *addr) -{ - unsigned short int port, *sport; - - switch (addr->sa_family) { - case AF_INET: - sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; - port = ((struct sockaddr_in *) addr)->sin_port; - break; - case AF_INET6: - sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port; - port = ((struct sockaddr_in6 *) addr)->sin6_port; - break; - default: - WARN_ON(1); - return false; - } - - if (!port) { - port = htons(CIFS_PORT); - if (port == *sport) - return true; - - port = htons(RFC1001_PORT); - } - - return port == *sport; -} static bool match_address(struct TCP_Server_Info *server, struct sockaddr *addr, struct sockaddr *srcaddr) { - switch (addr->sa_family) { - case AF_INET: { - struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; - struct sockaddr_in *srv_addr4 = - (struct sockaddr_in *)&server->dstaddr; + struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; - if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr) + switch (addr->sa_family) { + case AF_INET: + if (addr4->sin_addr.s_addr != + server->addr.sockAddr.sin_addr.s_addr) + return false; + if (addr4->sin_port && + addr4->sin_port != server->addr.sockAddr.sin_port) return false; break; - } - case AF_INET6: { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; - struct sockaddr_in6 *srv_addr6 = - (struct sockaddr_in6 *)&server->dstaddr; - + case AF_INET6: if (!ipv6_addr_equal(&addr6->sin6_addr, - &srv_addr6->sin6_addr)) + &server->addr.sockAddr6.sin6_addr)) return false; - if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id) + if (addr6->sin6_scope_id != + server->addr.sockAddr6.sin6_scope_id) + return false; + if (addr6->sin6_port && + addr6->sin6_port != server->addr.sockAddr6.sin6_port) return false; break; } - default: - WARN_ON(1); - return false; /* don't expect to be here */ - } if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) return false; @@ -1581,9 +1549,6 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) (struct sockaddr *)&vol->srcaddr)) continue; - if (!match_port(server, addr)) - continue; - if (!match_security(server, vol)) continue; @@ -1716,13 +1681,14 @@ cifs_get_tcp_session(struct smb_vol *volume_info) cFYI(1, "attempting ipv6 connect"); /* BB should we allow ipv6 on port 139? */ /* other OS never observed in Wild doing 139 with v6 */ - memcpy(&tcp_ses->dstaddr, sin_server6, - sizeof(struct sockaddr_in6)); - } else - memcpy(&tcp_ses->dstaddr, sin_server, - sizeof(struct sockaddr_in)); - - rc = ip_connect(tcp_ses); + memcpy(&tcp_ses->addr.sockAddr6, sin_server6, + sizeof(struct sockaddr_in6)); + rc = ipv6_connect(tcp_ses); + } else { + memcpy(&tcp_ses->addr.sockAddr, sin_server, + sizeof(struct sockaddr_in)); + rc = ipv4_connect(tcp_ses); + } if (rc < 0) { cERROR(1, "Error connecting to socket. Aborting operation"); goto out_err_crypto_release; @@ -1827,8 +1793,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) { int rc = -ENOMEM, xid; struct cifsSesInfo *ses; - struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; xid = GetXid(); @@ -1872,10 +1836,12 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) /* new SMB session uses our server ref */ ses->server = server; - if (server->dstaddr.ss_family == AF_INET6) - sprintf(ses->serverName, "%pI6", &addr6->sin6_addr); + if (server->addr.sockAddr6.sin6_family == AF_INET6) + sprintf(ses->serverName, "%pI6", + &server->addr.sockAddr6.sin6_addr); else - sprintf(ses->serverName, "%pI4", &addr->sin_addr); + sprintf(ses->serverName, "%pI4", + &server->addr.sockAddr.sin_addr.s_addr); if (volume_info->username) strncpy(ses->userName, volume_info->username, @@ -2170,106 +2136,19 @@ bind_socket(struct TCP_Server_Info *server) } static int -ip_rfc1001_connect(struct TCP_Server_Info *server) -{ - int rc = 0; - /* - * some servers require RFC1001 sessinit before sending - * negprot - BB check reconnection in case where second - * sessinit is sent but no second negprot - */ - struct rfc1002_session_packet *ses_init_buf; - struct smb_hdr *smb_buf; - ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), - GFP_KERNEL); - if (ses_init_buf) { - ses_init_buf->trailer.session_req.called_len = 32; - - if (server->server_RFC1001_name && - server->server_RFC1001_name[0] != 0) - rfc1002mangle(ses_init_buf->trailer. - session_req.called_name, - server->server_RFC1001_name, - RFC1001_NAME_LEN_WITH_NULL); - else - rfc1002mangle(ses_init_buf->trailer. - session_req.called_name, - DEFAULT_CIFS_CALLED_NAME, - RFC1001_NAME_LEN_WITH_NULL); - - ses_init_buf->trailer.session_req.calling_len = 32; - - /* - * calling name ends in null (byte 16) from old smb - * convention. - */ - if (server->workstation_RFC1001_name && - server->workstation_RFC1001_name[0] != 0) - rfc1002mangle(ses_init_buf->trailer. - session_req.calling_name, - server->workstation_RFC1001_name, - RFC1001_NAME_LEN_WITH_NULL); - else - rfc1002mangle(ses_init_buf->trailer. - session_req.calling_name, - "LINUX_CIFS_CLNT", - RFC1001_NAME_LEN_WITH_NULL); - - ses_init_buf->trailer.session_req.scope1 = 0; - ses_init_buf->trailer.session_req.scope2 = 0; - smb_buf = (struct smb_hdr *)ses_init_buf; - - /* sizeof RFC1002_SESSION_REQUEST with no scope */ - smb_buf->smb_buf_length = 0x81000044; - rc = smb_send(server, smb_buf, 0x44); - kfree(ses_init_buf); - /* - * RFC1001 layer in at least one server - * requires very short break before negprot - * presumably because not expecting negprot - * to follow so fast. This is a simple - * solution that works without - * complicating the code and causes no - * significant slowing down on mount - * for everyone else - */ - usleep_range(1000, 2000); - } - /* - * else the negprot may still work without this - * even though malloc failed - */ - - return rc; -} - -static int -generic_ip_connect(struct TCP_Server_Info *server) +ipv4_connect(struct TCP_Server_Info *server) { int rc = 0; - unsigned short int sport; - int slen, sfamily; + int val; + bool connected = false; + __be16 orig_port = 0; struct socket *socket = server->ssocket; - struct sockaddr *saddr; - - saddr = (struct sockaddr *) &server->dstaddr; - - if (server->dstaddr.ss_family == AF_INET6) { - sport = ((struct sockaddr_in6 *) saddr)->sin6_port; - slen = sizeof(struct sockaddr_in6); - sfamily = AF_INET6; - } else { - sport = ((struct sockaddr_in *) saddr)->sin_port; - slen = sizeof(struct sockaddr_in); - sfamily = AF_INET; - } if (socket == NULL) { - rc = sock_create_kern(sfamily, SOCK_STREAM, + rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &socket); if (rc < 0) { cERROR(1, "Error %d creating socket", rc); - server->ssocket = NULL; return rc; } @@ -2277,28 +2156,63 @@ generic_ip_connect(struct TCP_Server_Info *server) cFYI(1, "Socket created"); server->ssocket = socket; socket->sk->sk_allocation = GFP_NOFS; - if (sfamily == AF_INET6) - cifs_reclassify_socket6(socket); - else - cifs_reclassify_socket4(socket); + cifs_reclassify_socket4(socket); } rc = bind_socket(server); if (rc < 0) return rc; - rc = socket->ops->connect(socket, saddr, slen, 0); - if (rc < 0) { - cFYI(1, "Error %d connecting to server", rc); + /* user overrode default port */ + if (server->addr.sockAddr.sin_port) { + rc = socket->ops->connect(socket, (struct sockaddr *) + &server->addr.sockAddr, + sizeof(struct sockaddr_in), 0); + if (rc >= 0) + connected = true; + } + + if (!connected) { + /* save original port so we can retry user specified port + later if fall back ports fail this time */ + orig_port = server->addr.sockAddr.sin_port; + + /* do not retry on the same port we just failed on */ + if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) { + server->addr.sockAddr.sin_port = htons(CIFS_PORT); + rc = socket->ops->connect(socket, + (struct sockaddr *) + &server->addr.sockAddr, + sizeof(struct sockaddr_in), 0); + if (rc >= 0) + connected = true; + } + } + if (!connected) { + server->addr.sockAddr.sin_port = htons(RFC1001_PORT); + rc = socket->ops->connect(socket, (struct sockaddr *) + &server->addr.sockAddr, + sizeof(struct sockaddr_in), 0); + if (rc >= 0) + connected = true; + } + + /* give up here - unless we want to retry on different + protocol families some day */ + if (!connected) { + if (orig_port) + server->addr.sockAddr.sin_port = orig_port; + cFYI(1, "Error %d connecting to server via ipv4", rc); sock_release(socket); server->ssocket = NULL; return rc; } + /* * Eventually check for other socket options to change from - * the default. sock_setsockopt not used because it expects - * user space buffer + * the default. sock_setsockopt not used because it expects + * user space buffer */ socket->sk->sk_rcvtimeo = 7 * HZ; socket->sk->sk_sndtimeo = 5 * HZ; @@ -2312,7 +2226,7 @@ generic_ip_connect(struct TCP_Server_Info *server) } if (server->tcp_nodelay) { - int val = 1; + val = 1; rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); if (rc) @@ -2323,39 +2237,161 @@ generic_ip_connect(struct TCP_Server_Info *server) socket->sk->sk_sndbuf, socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); - if (sport == htons(RFC1001_PORT)) - rc = ip_rfc1001_connect(server); + /* send RFC1001 sessinit */ + if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { + /* some servers require RFC1001 sessinit before sending + negprot - BB check reconnection in case where second + sessinit is sent but no second negprot */ + struct rfc1002_session_packet *ses_init_buf; + struct smb_hdr *smb_buf; + ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), + GFP_KERNEL); + if (ses_init_buf) { + ses_init_buf->trailer.session_req.called_len = 32; + if (server->server_RFC1001_name && + server->server_RFC1001_name[0] != 0) + rfc1002mangle(ses_init_buf->trailer. + session_req.called_name, + server->server_RFC1001_name, + RFC1001_NAME_LEN_WITH_NULL); + else + rfc1002mangle(ses_init_buf->trailer. + session_req.called_name, + DEFAULT_CIFS_CALLED_NAME, + RFC1001_NAME_LEN_WITH_NULL); + + ses_init_buf->trailer.session_req.calling_len = 32; + + /* calling name ends in null (byte 16) from old smb + convention. */ + if (server->workstation_RFC1001_name && + server->workstation_RFC1001_name[0] != 0) + rfc1002mangle(ses_init_buf->trailer. + session_req.calling_name, + server->workstation_RFC1001_name, + RFC1001_NAME_LEN_WITH_NULL); + else + rfc1002mangle(ses_init_buf->trailer. + session_req.calling_name, + "LINUX_CIFS_CLNT", + RFC1001_NAME_LEN_WITH_NULL); + + ses_init_buf->trailer.session_req.scope1 = 0; + ses_init_buf->trailer.session_req.scope2 = 0; + smb_buf = (struct smb_hdr *)ses_init_buf; + /* sizeof RFC1002_SESSION_REQUEST with no scope */ + smb_buf->smb_buf_length = 0x81000044; + rc = smb_send(server, smb_buf, 0x44); + kfree(ses_init_buf); + msleep(1); /* RFC1001 layer in at least one server + requires very short break before negprot + presumably because not expecting negprot + to follow so fast. This is a simple + solution that works without + complicating the code and causes no + significant slowing down on mount + for everyone else */ + } + /* else the negprot may still work without this + even though malloc failed */ + + } return rc; } static int -ip_connect(struct TCP_Server_Info *server) +ipv6_connect(struct TCP_Server_Info *server) { - unsigned short int *sport; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; - struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; + int rc = 0; + int val; + bool connected = false; + __be16 orig_port = 0; + struct socket *socket = server->ssocket; - if (server->dstaddr.ss_family == AF_INET6) - sport = &addr6->sin6_port; - else - sport = &addr->sin_port; + if (socket == NULL) { + rc = sock_create_kern(PF_INET6, SOCK_STREAM, + IPPROTO_TCP, &socket); + if (rc < 0) { + cERROR(1, "Error %d creating ipv6 socket", rc); + socket = NULL; + return rc; + } - if (*sport == 0) { - int rc; + /* BB other socket options to set KEEPALIVE, NODELAY? */ + cFYI(1, "ipv6 Socket created"); + server->ssocket = socket; + socket->sk->sk_allocation = GFP_NOFS; + cifs_reclassify_socket6(socket); + } - /* try with 445 port at first */ - *sport = htons(CIFS_PORT); + rc = bind_socket(server); + if (rc < 0) + return rc; - rc = generic_ip_connect(server); + /* user overrode default port */ + if (server->addr.sockAddr6.sin6_port) { + rc = socket->ops->connect(socket, + (struct sockaddr *) &server->addr.sockAddr6, + sizeof(struct sockaddr_in6), 0); if (rc >= 0) - return rc; + connected = true; + } + + if (!connected) { + /* save original port so we can retry user specified port + later if fall back ports fail this time */ + + orig_port = server->addr.sockAddr6.sin6_port; + /* do not retry on the same port we just failed on */ + if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) { + server->addr.sockAddr6.sin6_port = htons(CIFS_PORT); + rc = socket->ops->connect(socket, (struct sockaddr *) + &server->addr.sockAddr6, + sizeof(struct sockaddr_in6), 0); + if (rc >= 0) + connected = true; + } + } + if (!connected) { + server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT); + rc = socket->ops->connect(socket, (struct sockaddr *) + &server->addr.sockAddr6, + sizeof(struct sockaddr_in6), 0); + if (rc >= 0) + connected = true; + } + + /* give up here - unless we want to retry on different + protocol families some day */ + if (!connected) { + if (orig_port) + server->addr.sockAddr6.sin6_port = orig_port; + cFYI(1, "Error %d connecting to server via ipv6", rc); + sock_release(socket); + server->ssocket = NULL; + return rc; + } - /* if it failed, try with 139 port */ - *sport = htons(RFC1001_PORT); + /* + * Eventually check for other socket options to change from + * the default. sock_setsockopt not used because it expects + * user space buffer + */ + socket->sk->sk_rcvtimeo = 7 * HZ; + socket->sk->sk_sndtimeo = 5 * HZ; + + if (server->tcp_nodelay) { + val = 1; + rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, + (char *)&val, sizeof(val)); + if (rc) + cFYI(1, "set TCP_NODELAY socket option error %d", rc); } - return generic_ip_connect(server); + server->ssocket = socket; + + return rc; } void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index 2e773825835e..db2a58c00f7b 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -293,8 +293,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, args.uid = NO_CHANGE_64; args.gid = NO_CHANGE_64; } - CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle, - current->tgid); + CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); } else { /* BB implement mode setting via Windows security descriptors e.g. */ diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index d843631c028d..5a28660ca2b5 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -104,6 +104,53 @@ static inline int cifs_get_disposition(unsigned int flags) return FILE_OPEN; } +static inline int cifs_open_inode_helper(struct inode *inode, + struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf, + char *full_path, int xid) +{ + struct cifsInodeInfo *pCifsInode = CIFS_I(inode); + struct timespec temp; + int rc; + + if (pCifsInode->clientCanCacheRead) { + /* we have the inode open somewhere else + no need to discard cache data */ + goto client_can_cache; + } + + /* BB need same check in cifs_create too? */ + /* if not oplocked, invalidate inode pages if mtime or file + size changed */ + temp = cifs_NTtimeToUnix(buf->LastWriteTime); + if (timespec_equal(&inode->i_mtime, &temp) && + (inode->i_size == + (loff_t)le64_to_cpu(buf->EndOfFile))) { + cFYI(1, "inode unchanged on server"); + } else { + if (inode->i_mapping) { + /* BB no need to lock inode until after invalidate + since namei code should already have it locked? */ + rc = filemap_write_and_wait(inode->i_mapping); + mapping_set_error(inode->i_mapping, rc); + } + cFYI(1, "invalidating remote inode since open detected it " + "changed"); + invalidate_remote_inode(inode); + } + +client_can_cache: + if (pTcon->unix_ext) + rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, + xid); + else + rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, + xid, NULL); + + cifs_set_oplock_level(pCifsInode, oplock); + + return rc; +} + int cifs_posix_open(char *full_path, struct inode **pinode, struct super_block *sb, int mode, unsigned int f_flags, __u32 *poplock, __u16 *pnetfid, int xid) @@ -166,76 +213,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, return rc; } -static int -cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, - struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock, - __u16 *pnetfid, int xid) -{ - int rc; - int desiredAccess; - int disposition; - FILE_ALL_INFO *buf; - - desiredAccess = cifs_convert_flags(f_flags); - -/********************************************************************* - * open flag mapping table: - * - * POSIX Flag CIFS Disposition - * ---------- ---------------- - * O_CREAT FILE_OPEN_IF - * O_CREAT | O_EXCL FILE_CREATE - * O_CREAT | O_TRUNC FILE_OVERWRITE_IF - * O_TRUNC FILE_OVERWRITE - * none of the above FILE_OPEN - * - * Note that there is not a direct match between disposition - * FILE_SUPERSEDE (ie create whether or not file exists although - * O_CREAT | O_TRUNC is similar but truncates the existing - * file rather than creating a new file as FILE_SUPERSEDE does - * (which uses the attributes / metadata passed in on open call) - *? - *? O_SYNC is a reasonable match to CIFS writethrough flag - *? and the read write flags match reasonably. O_LARGEFILE - *? is irrelevant because largefile support is always used - *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, - * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation - *********************************************************************/ - - disposition = cifs_get_disposition(f_flags); - - /* BB pass O_SYNC flag through on file attributes .. BB */ - - buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (tcon->ses->capabilities & CAP_NT_SMBS) - rc = CIFSSMBOpen(xid, tcon, full_path, disposition, - desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags - & CIFS_MOUNT_MAP_SPECIAL_CHR); - else - rc = SMBLegacyOpen(xid, tcon, full_path, disposition, - desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags - & CIFS_MOUNT_MAP_SPECIAL_CHR); - - if (rc) - goto out; - - if (tcon->unix_ext) - rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, - xid); - else - rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, - xid, pnetfid); - -out: - kfree(buf); - return rc; -} - struct cifsFileInfo * cifs_new_fileinfo(__u16 fileHandle, struct file *file, struct tcon_link *tlink, __u32 oplock) @@ -340,8 +317,10 @@ int cifs_open(struct inode *inode, struct file *file) struct cifsFileInfo *pCifsFile = NULL; struct cifsInodeInfo *pCifsInode; char *full_path = NULL; - bool posix_open_ok = false; + int desiredAccess; + int disposition; __u16 netfid; + FILE_ALL_INFO *buf = NULL; xid = GetXid(); @@ -379,7 +358,17 @@ int cifs_open(struct inode *inode, struct file *file) file->f_flags, &oplock, &netfid, xid); if (rc == 0) { cFYI(1, "posix open succeeded"); - posix_open_ok = true; + + pCifsFile = cifs_new_fileinfo(netfid, file, tlink, + oplock); + if (pCifsFile == NULL) { + CIFSSMBClose(xid, tcon, netfid); + rc = -ENOMEM; + } + + cifs_fscache_set_inode_cookie(inode, file); + + goto out; } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { if (tcon->ses->serverNOS) cERROR(1, "server %s of type %s returned" @@ -396,39 +385,103 @@ int cifs_open(struct inode *inode, struct file *file) or DFS errors */ } - if (!posix_open_ok) { - rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, - file->f_flags, &oplock, &netfid, xid); - if (rc) - goto out; + desiredAccess = cifs_convert_flags(file->f_flags); + +/********************************************************************* + * open flag mapping table: + * + * POSIX Flag CIFS Disposition + * ---------- ---------------- + * O_CREAT FILE_OPEN_IF + * O_CREAT | O_EXCL FILE_CREATE + * O_CREAT | O_TRUNC FILE_OVERWRITE_IF + * O_TRUNC FILE_OVERWRITE + * none of the above FILE_OPEN + * + * Note that there is not a direct match between disposition + * FILE_SUPERSEDE (ie create whether or not file exists although + * O_CREAT | O_TRUNC is similar but truncates the existing + * file rather than creating a new file as FILE_SUPERSEDE does + * (which uses the attributes / metadata passed in on open call) + *? + *? O_SYNC is a reasonable match to CIFS writethrough flag + *? and the read write flags match reasonably. O_LARGEFILE + *? is irrelevant because largefile support is always used + *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, + * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation + *********************************************************************/ + + disposition = cifs_get_disposition(file->f_flags); + + /* BB pass O_SYNC flag through on file attributes .. BB */ + + /* Also refresh inode by passing in file_info buf returned by SMBOpen + and calling get_inode_info with returned buf (at least helps + non-Unix server case) */ + + /* BB we can not do this if this is the second open of a file + and the first handle has writebehind data, we might be + able to simply do a filemap_fdatawrite/filemap_fdatawait first */ + buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + if (!buf) { + rc = -ENOMEM; + goto out; + } + + if (tcon->ses->capabilities & CAP_NT_SMBS) + rc = CIFSSMBOpen(xid, tcon, full_path, disposition, + desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags + & CIFS_MOUNT_MAP_SPECIAL_CHR); + else + rc = -EIO; /* no NT SMB support fall into legacy open below */ + + if (rc == -EIO) { + /* Old server, try legacy style OpenX */ + rc = SMBLegacyOpen(xid, tcon, full_path, disposition, + desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags + & CIFS_MOUNT_MAP_SPECIAL_CHR); + } + if (rc) { + cFYI(1, "cifs_open returned 0x%x", rc); + goto out; } + rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid); + if (rc != 0) + goto out; + pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock); if (pCifsFile == NULL) { - CIFSSMBClose(xid, tcon, netfid); rc = -ENOMEM; goto out; } cifs_fscache_set_inode_cookie(inode, file); - if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) { + if (oplock & CIFS_CREATE_ACTION) { /* time to set mode which we can not set earlier due to problems creating new read-only files */ - struct cifs_unix_set_info_args args = { - .mode = inode->i_mode, - .uid = NO_CHANGE_64, - .gid = NO_CHANGE_64, - .ctime = NO_CHANGE_64, - .atime = NO_CHANGE_64, - .mtime = NO_CHANGE_64, - .device = 0, - }; - CIFSSMBUnixSetFileInfo(xid, tcon, &args, netfid, - pCifsFile->pid); + if (tcon->unix_ext) { + struct cifs_unix_set_info_args args = { + .mode = inode->i_mode, + .uid = NO_CHANGE_64, + .gid = NO_CHANGE_64, + .ctime = NO_CHANGE_64, + .atime = NO_CHANGE_64, + .mtime = NO_CHANGE_64, + .device = 0, + }; + CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + } } out: + kfree(buf); kfree(full_path); FreeXid(xid); cifs_put_tlink(tlink); diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 0c7e36910e31..a853a89857a5 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -518,7 +518,6 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); - fattr->cf_createtime = le64_to_cpu(info->CreationTime); if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; @@ -780,10 +779,6 @@ cifs_find_inode(struct inode *inode, void *opaque) if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) return 0; - /* use createtime like an i_generation field */ - if (CIFS_I(inode)->createtime != fattr->cf_createtime) - return 0; - /* don't match inode of different type */ if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) return 0; @@ -801,7 +796,6 @@ cifs_init_inode(struct inode *inode, void *opaque) struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; CIFS_I(inode)->uniqueid = fattr->cf_uniqueid; - CIFS_I(inode)->createtime = fattr->cf_createtime; return 0; } diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 76b1b37c9e6b..ec5b68e3b928 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -160,7 +160,6 @@ cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); - fattr->cf_createtime = le64_to_cpu(info->CreationTime); fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index eb746486e49e..7b01d3f6eed6 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -420,6 +420,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, return 0; } +#ifdef CONFIG_CIFS_EXPERIMENTAL /* BB Move to ntlmssp.c eventually */ /* We do not malloc the blob, it is passed in pbuffer, because @@ -430,14 +431,13 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; __u32 flags; - memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE)); memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); sec_blob->MessageType = NtLmNegotiate; /* BB is NTLMV2 session security format easier to use here? */ flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; + NTLMSSP_NEGOTIATE_NTLM; if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { flags |= NTLMSSP_NEGOTIATE_SIGN; @@ -446,7 +446,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, NTLMSSP_NEGOTIATE_EXTENDED_SEC; } - sec_blob->NegotiateFlags = cpu_to_le32(flags); + sec_blob->NegotiateFlags |= cpu_to_le32(flags); sec_blob->WorkstationName.BufferOffset = 0; sec_blob->WorkstationName.Length = 0; @@ -477,7 +477,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; + NTLMSSP_NEGOTIATE_NTLM; if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) flags |= NTLMSSP_NEGOTIATE_SIGN; @@ -485,7 +485,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); - sec_blob->NegotiateFlags = cpu_to_le32(flags); + sec_blob->NegotiateFlags |= cpu_to_le32(flags); sec_blob->LmChallengeResponse.BufferOffset = cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE)); @@ -544,9 +544,8 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, sec_blob->WorkstationName.MaximumLength = 0; tmp += 2; - if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) || - (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) - && !calc_seckey(ses)) { + if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && + !calc_seckey(ses)) { memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); @@ -564,6 +563,17 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, return rc; } + +static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB, + struct cifsSesInfo *ses) +{ + build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses); + pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE)); + + return; +} +#endif + int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const struct nls_table *nls_cp) @@ -804,70 +814,71 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, rc = -ENOSYS; goto ssetup_exit; #endif /* CONFIG_CIFS_UPCALL */ - } else if (type == RawNTLMSSP) { - if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { - cERROR(1, "NTLMSSP requires Unicode support"); - rc = -ENOSYS; - goto ssetup_exit; - } - - cFYI(1, "ntlmssp session setup phase %d", phase); - pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; - capabilities |= CAP_EXTENDED_SECURITY; - pSMB->req.Capabilities |= cpu_to_le32(capabilities); - switch(phase) { - case NtLmNegotiate: - build_ntlmssp_negotiate_blob( - pSMB->req.SecurityBlob, ses); - iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); - iov[1].iov_base = pSMB->req.SecurityBlob; - pSMB->req.SecurityBlobLength = - cpu_to_le16(sizeof(NEGOTIATE_MESSAGE)); - break; - case NtLmAuthenticate: - /* - * 5 is an empirical value, large enough to hold - * authenticate message plus max 10 of av paris, - * domain, user, workstation names, flags, etc. - */ - ntlmsspblob = kzalloc( - 5*sizeof(struct _AUTHENTICATE_MESSAGE), - GFP_KERNEL); - if (!ntlmsspblob) { - cERROR(1, "Can't allocate NTLMSSP blob"); - rc = -ENOMEM; + } else { +#ifdef CONFIG_CIFS_EXPERIMENTAL + if (type == RawNTLMSSP) { + if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { + cERROR(1, "NTLMSSP requires Unicode support"); + rc = -ENOSYS; goto ssetup_exit; } - rc = build_ntlmssp_auth_blob(ntlmsspblob, - &blob_len, ses, nls_cp); - if (rc) + cFYI(1, "ntlmssp session setup phase %d", phase); + pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; + capabilities |= CAP_EXTENDED_SECURITY; + pSMB->req.Capabilities |= cpu_to_le32(capabilities); + if (phase == NtLmNegotiate) { + setup_ntlmssp_neg_req(pSMB, ses); + iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); + iov[1].iov_base = &pSMB->req.SecurityBlob[0]; + } else if (phase == NtLmAuthenticate) { + /* 5 is an empirical value, large enought to + * hold authenticate message, max 10 of + * av paris, doamin,user,workstation mames, + * flags etc.. + */ + ntlmsspblob = kmalloc( + 5*sizeof(struct _AUTHENTICATE_MESSAGE), + GFP_KERNEL); + if (!ntlmsspblob) { + cERROR(1, "Can't allocate NTLMSSP"); + rc = -ENOMEM; + goto ssetup_exit; + } + + rc = build_ntlmssp_auth_blob(ntlmsspblob, + &blob_len, ses, nls_cp); + if (rc) + goto ssetup_exit; + iov[1].iov_len = blob_len; + iov[1].iov_base = ntlmsspblob; + pSMB->req.SecurityBlobLength = + cpu_to_le16(blob_len); + /* Make sure that we tell the server that we + are using the uid that it just gave us back + on the response (challenge) */ + smb_buf->Uid = ses->Suid; + } else { + cERROR(1, "invalid phase %d", phase); + rc = -ENOSYS; goto ssetup_exit; - iov[1].iov_len = blob_len; - iov[1].iov_base = ntlmsspblob; - pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len); - /* - * Make sure that we tell the server that we are using - * the uid that it just gave us back on the response - * (challenge) - */ - smb_buf->Uid = ses->Suid; - break; - default: - cERROR(1, "invalid phase %d", phase); + } + /* unicode strings must be word aligned */ + if ((iov[0].iov_len + iov[1].iov_len) % 2) { + *bcc_ptr = 0; + bcc_ptr++; + } + unicode_oslm_strings(&bcc_ptr, nls_cp); + } else { + cERROR(1, "secType %d not supported!", type); rc = -ENOSYS; goto ssetup_exit; } - /* unicode strings must be word aligned */ - if ((iov[0].iov_len + iov[1].iov_len) % 2) { - *bcc_ptr = 0; - bcc_ptr++; - } - unicode_oslm_strings(&bcc_ptr, nls_cp); - } else { +#else cERROR(1, "secType %d not supported!", type); rc = -ENOSYS; goto ssetup_exit; +#endif } iov[2].iov_base = str_area; diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index 59ca81b16919..e0588cdf4cc5 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -119,7 +119,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) if (ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ - smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; + smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr; smb_msg.msg_namelen = sizeof(struct sockaddr); smb_msg.msg_control = NULL; smb_msg.msg_controllen = 0; diff --git a/trunk/fs/dlm/lowcomms.c b/trunk/fs/dlm/lowcomms.c index 9c64ae9e4c1a..37a34c2c622a 100644 --- a/trunk/fs/dlm/lowcomms.c +++ b/trunk/fs/dlm/lowcomms.c @@ -63,9 +63,6 @@ #define NEEDED_RMEM (4*1024*1024) #define CONN_HASH_SIZE 32 -/* Number of messages to send before rescheduling */ -#define MAX_SEND_MSG_COUNT 25 - struct cbuf { unsigned int base; unsigned int len; @@ -111,7 +108,6 @@ struct connection { #define CF_INIT_PENDING 4 #define CF_IS_OTHERCON 5 #define CF_CLOSE 6 -#define CF_APP_LIMITED 7 struct list_head writequeue; /* List of outgoing writequeue_entries */ spinlock_t writequeue_lock; int (*rx_action) (struct connection *); /* What to do when active */ @@ -299,17 +295,7 @@ static void lowcomms_write_space(struct sock *sk) { struct connection *con = sock2con(sk); - if (!con) - return; - - clear_bit(SOCK_NOSPACE, &con->sock->flags); - - if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) { - con->sock->sk->sk_write_pending--; - clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags); - } - - if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) + if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) queue_work(send_workqueue, &con->swork); } @@ -929,7 +915,6 @@ static void tcp_connect_to_sock(struct connection *con) struct sockaddr_storage saddr, src_addr; int addr_len; struct socket *sock = NULL; - int one = 1; if (con->nodeid == 0) { log_print("attempt to connect sock 0 foiled"); @@ -975,11 +960,6 @@ static void tcp_connect_to_sock(struct connection *con) make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); log_print("connecting to %d", con->nodeid); - - /* Turn off Nagle's algorithm */ - kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, - sizeof(one)); - result = sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, O_NONBLOCK); @@ -1031,10 +1011,6 @@ static struct socket *tcp_create_listen_sock(struct connection *con, goto create_out; } - /* Turn off Nagle's algorithm */ - kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, - sizeof(one)); - result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); @@ -1321,7 +1297,6 @@ static void send_to_sock(struct connection *con) const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; struct writequeue_entry *e; int len, offset; - int count = 0; mutex_lock(&con->sock_mutex); if (con->sock == NULL) @@ -1344,27 +1319,14 @@ static void send_to_sock(struct connection *con) ret = kernel_sendpage(con->sock, e->page, offset, len, msg_flags); if (ret == -EAGAIN || ret == 0) { - if (ret == -EAGAIN && - test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) && - !test_and_set_bit(CF_APP_LIMITED, &con->flags)) { - /* Notify TCP that we're limited by the - * application window size. - */ - set_bit(SOCK_NOSPACE, &con->sock->flags); - con->sock->sk->sk_write_pending++; - } cond_resched(); goto out; } if (ret <= 0) goto send_error; } - - /* Don't starve people filling buffers */ - if (++count >= MAX_SEND_MSG_COUNT) { + /* Don't starve people filling buffers */ cond_resched(); - count = 0; - } spin_lock(&con->writequeue_lock); e->offset += ret; @@ -1468,19 +1430,20 @@ static void work_stop(void) static int work_start(void) { - recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM | - WQ_HIGHPRI | WQ_FREEZEABLE, 0); - if (!recv_workqueue) { - log_print("can't start dlm_recv"); - return -ENOMEM; + int error; + recv_workqueue = create_workqueue("dlm_recv"); + error = IS_ERR(recv_workqueue); + if (error) { + log_print("can't start dlm_recv %d", error); + return error; } - send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM | - WQ_HIGHPRI | WQ_FREEZEABLE, 0); - if (!send_workqueue) { - log_print("can't start dlm_send"); + send_workqueue = create_singlethread_workqueue("dlm_send"); + error = IS_ERR(send_workqueue); + if (error) { + log_print("can't start dlm_send %d", error); destroy_workqueue(recv_workqueue); - return -ENOMEM; + return error; } return 0; diff --git a/trunk/fs/fuse/dev.c b/trunk/fs/fuse/dev.c index cf8d28d1fbad..6e07696308dc 100644 --- a/trunk/fs/fuse/dev.c +++ b/trunk/fs/fuse/dev.c @@ -251,20 +251,6 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) kill_fasync(&fc->fasync, SIGIO, POLL_IN); } -void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, - u64 nodeid, u64 nlookup) -{ - forget->forget_one.nodeid = nodeid; - forget->forget_one.nlookup = nlookup; - - spin_lock(&fc->lock); - fc->forget_list_tail->next = forget; - fc->forget_list_tail = forget; - wake_up(&fc->waitq); - kill_fasync(&fc->fasync, SIGIO, POLL_IN); - spin_unlock(&fc->lock); -} - static void flush_bg_queue(struct fuse_conn *fc) { while (fc->active_background < fc->max_background && @@ -452,6 +438,12 @@ static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) } } +void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) +{ + req->isreply = 0; + fuse_request_send_nowait(fc, req); +} + void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) { req->isreply = 1; @@ -904,15 +896,9 @@ static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, return err; } -static int forget_pending(struct fuse_conn *fc) -{ - return fc->forget_list_head.next != NULL; -} - static int request_pending(struct fuse_conn *fc) { - return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || - forget_pending(fc); + return !list_empty(&fc->pending) || !list_empty(&fc->interrupts); } /* Wait until a request is available on the pending list */ @@ -974,120 +960,6 @@ __releases(fc->lock) return err ? err : reqsize; } -static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, - unsigned max, - unsigned *countp) -{ - struct fuse_forget_link *head = fc->forget_list_head.next; - struct fuse_forget_link **newhead = &head; - unsigned count; - - for (count = 0; *newhead != NULL && count < max; count++) - newhead = &(*newhead)->next; - - fc->forget_list_head.next = *newhead; - *newhead = NULL; - if (fc->forget_list_head.next == NULL) - fc->forget_list_tail = &fc->forget_list_head; - - if (countp != NULL) - *countp = count; - - return head; -} - -static int fuse_read_single_forget(struct fuse_conn *fc, - struct fuse_copy_state *cs, - size_t nbytes) -__releases(fc->lock) -{ - int err; - struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); - struct fuse_forget_in arg = { - .nlookup = forget->forget_one.nlookup, - }; - struct fuse_in_header ih = { - .opcode = FUSE_FORGET, - .nodeid = forget->forget_one.nodeid, - .unique = fuse_get_unique(fc), - .len = sizeof(ih) + sizeof(arg), - }; - - spin_unlock(&fc->lock); - kfree(forget); - if (nbytes < ih.len) - return -EINVAL; - - err = fuse_copy_one(cs, &ih, sizeof(ih)); - if (!err) - err = fuse_copy_one(cs, &arg, sizeof(arg)); - fuse_copy_finish(cs); - - if (err) - return err; - - return ih.len; -} - -static int fuse_read_batch_forget(struct fuse_conn *fc, - struct fuse_copy_state *cs, size_t nbytes) -__releases(fc->lock) -{ - int err; - unsigned max_forgets; - unsigned count; - struct fuse_forget_link *head; - struct fuse_batch_forget_in arg = { .count = 0 }; - struct fuse_in_header ih = { - .opcode = FUSE_BATCH_FORGET, - .unique = fuse_get_unique(fc), - .len = sizeof(ih) + sizeof(arg), - }; - - if (nbytes < ih.len) { - spin_unlock(&fc->lock); - return -EINVAL; - } - - max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); - head = dequeue_forget(fc, max_forgets, &count); - spin_unlock(&fc->lock); - - arg.count = count; - ih.len += count * sizeof(struct fuse_forget_one); - err = fuse_copy_one(cs, &ih, sizeof(ih)); - if (!err) - err = fuse_copy_one(cs, &arg, sizeof(arg)); - - while (head) { - struct fuse_forget_link *forget = head; - - if (!err) { - err = fuse_copy_one(cs, &forget->forget_one, - sizeof(forget->forget_one)); - } - head = forget->next; - kfree(forget); - } - - fuse_copy_finish(cs); - - if (err) - return err; - - return ih.len; -} - -static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, - size_t nbytes) -__releases(fc->lock) -{ - if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) - return fuse_read_single_forget(fc, cs, nbytes); - else - return fuse_read_batch_forget(fc, cs, nbytes); -} - /* * Read a single request into the userspace filesystem's buffer. This * function waits until a request is available, then removes it from @@ -1126,14 +998,6 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, return fuse_read_interrupt(fc, cs, nbytes, req); } - if (forget_pending(fc)) { - if (list_empty(&fc->pending) || fc->forget_batch-- > 0) - return fuse_read_forget(fc, cs, nbytes); - - if (fc->forget_batch <= -8) - fc->forget_batch = 16; - } - req = list_entry(fc->pending.next, struct fuse_req, list); req->state = FUSE_REQ_READING; list_move(&req->list, &fc->io); @@ -1226,7 +1090,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, if (!fc) return -EPERM; - bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); if (!bufs) return -ENOMEM; @@ -1762,7 +1626,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, if (!fc) return -EPERM; - bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); if (!bufs) return -ENOMEM; @@ -1906,8 +1770,6 @@ __acquires(fc->lock) flush_bg_queue(fc); end_requests(fc, &fc->pending); end_requests(fc, &fc->processing); - while (forget_pending(fc)) - kfree(dequeue_forget(fc, 1, NULL)); } /* diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 042af7346ec1..f738599fd8cd 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -10,9 +10,9 @@ #include #include +#include #include #include -#include #if BITS_PER_LONG >= 64 static inline void fuse_dentry_settime(struct dentry *entry, u64 time) @@ -169,7 +169,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) struct fuse_entry_out outarg; struct fuse_conn *fc; struct fuse_req *req; - struct fuse_forget_link *forget; + struct fuse_req *forget_req; struct dentry *parent; u64 attr_version; @@ -182,8 +182,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (IS_ERR(req)) return 0; - forget = fuse_alloc_forget(); - if (!forget) { + forget_req = fuse_get_req(fc); + if (IS_ERR(forget_req)) { fuse_put_request(fc, req); return 0; } @@ -203,14 +203,15 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (!err) { struct fuse_inode *fi = get_fuse_inode(inode); if (outarg.nodeid != get_node_id(inode)) { - fuse_queue_forget(fc, forget, outarg.nodeid, 1); + fuse_send_forget(fc, forget_req, + outarg.nodeid, 1); return 0; } spin_lock(&fc->lock); fi->nlookup++; spin_unlock(&fc->lock); } - kfree(forget); + fuse_put_request(fc, forget_req); if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) return 0; @@ -262,7 +263,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, { struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_req *req; - struct fuse_forget_link *forget; + struct fuse_req *forget_req; u64 attr_version; int err; @@ -276,9 +277,9 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, if (IS_ERR(req)) goto out; - forget = fuse_alloc_forget(); - err = -ENOMEM; - if (!forget) { + forget_req = fuse_get_req(fc); + err = PTR_ERR(forget_req); + if (IS_ERR(forget_req)) { fuse_put_request(fc, req); goto out; } @@ -304,13 +305,13 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, attr_version); err = -ENOMEM; if (!*inode) { - fuse_queue_forget(fc, forget, outarg->nodeid, 1); + fuse_send_forget(fc, forget_req, outarg->nodeid, 1); goto out; } err = 0; out_put_forget: - kfree(forget); + fuse_put_request(fc, forget_req); out: return err; } @@ -377,7 +378,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, struct inode *inode; struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_req *req; - struct fuse_forget_link *forget; + struct fuse_req *forget_req; struct fuse_create_in inarg; struct fuse_open_out outopen; struct fuse_entry_out outentry; @@ -391,9 +392,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, if (flags & O_DIRECT) return -EINVAL; - forget = fuse_alloc_forget(); - if (!forget) - return -ENOMEM; + forget_req = fuse_get_req(fc); + if (IS_ERR(forget_req)) + return PTR_ERR(forget_req); req = fuse_get_req(fc); err = PTR_ERR(req); @@ -451,10 +452,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); fuse_sync_release(ff, flags); - fuse_queue_forget(fc, forget, outentry.nodeid, 1); + fuse_send_forget(fc, forget_req, outentry.nodeid, 1); return -ENOMEM; } - kfree(forget); + fuse_put_request(fc, forget_req); d_instantiate(entry, inode); fuse_change_entry_timeout(entry, &outentry); fuse_invalidate_attr(dir); @@ -472,7 +473,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, out_put_request: fuse_put_request(fc, req); out_put_forget_req: - kfree(forget); + fuse_put_request(fc, forget_req); return err; } @@ -486,12 +487,12 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, struct fuse_entry_out outarg; struct inode *inode; int err; - struct fuse_forget_link *forget; + struct fuse_req *forget_req; - forget = fuse_alloc_forget(); - if (!forget) { + forget_req = fuse_get_req(fc); + if (IS_ERR(forget_req)) { fuse_put_request(fc, req); - return -ENOMEM; + return PTR_ERR(forget_req); } memset(&outarg, 0, sizeof(outarg)); @@ -518,10 +519,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, &outarg.attr, entry_attr_timeout(&outarg), 0); if (!inode) { - fuse_queue_forget(fc, forget, outarg.nodeid, 1); + fuse_send_forget(fc, forget_req, outarg.nodeid, 1); return -ENOMEM; } - kfree(forget); + fuse_put_request(fc, forget_req); if (S_ISDIR(inode->i_mode)) { struct dentry *alias; @@ -544,7 +545,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, return 0; out_put_forget_req: - kfree(forget); + fuse_put_request(fc, forget_req); return err; } diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 95da1bc1c826..8b984a2cebbd 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -1634,9 +1634,9 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, * and 64bit. Fortunately we can determine which structure the server * used from the size of the reply. */ -static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src, - size_t transferred, unsigned count, - bool is_compat) +static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, + size_t transferred, unsigned count, + bool is_compat) { #ifdef CONFIG_COMPAT if (count * sizeof(struct compat_iovec) == transferred) { @@ -1680,42 +1680,6 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) return 0; } -static int fuse_copy_ioctl_iovec(struct fuse_conn *fc, struct iovec *dst, - void *src, size_t transferred, unsigned count, - bool is_compat) -{ - unsigned i; - struct fuse_ioctl_iovec *fiov = src; - - if (fc->minor < 16) { - return fuse_copy_ioctl_iovec_old(dst, src, transferred, - count, is_compat); - } - - if (count * sizeof(struct fuse_ioctl_iovec) != transferred) - return -EIO; - - for (i = 0; i < count; i++) { - /* Did the server supply an inappropriate value? */ - if (fiov[i].base != (unsigned long) fiov[i].base || - fiov[i].len != (unsigned long) fiov[i].len) - return -EIO; - - dst[i].iov_base = (void __user *) (unsigned long) fiov[i].base; - dst[i].iov_len = (size_t) fiov[i].len; - -#ifdef CONFIG_COMPAT - if (is_compat && - (ptr_to_compat(dst[i].iov_base) != fiov[i].base || - (compat_size_t) dst[i].iov_len != fiov[i].len)) - return -EIO; -#endif - } - - return 0; -} - - /* * For ioctls, there is no generic way to determine how much memory * needs to be read and/or written. Furthermore, ioctls are allowed @@ -1776,25 +1740,18 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, struct fuse_ioctl_out outarg; struct fuse_req *req = NULL; struct page **pages = NULL; - struct iovec *iov_page = NULL; + struct page *iov_page = NULL; struct iovec *in_iov = NULL, *out_iov = NULL; unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; size_t in_size, out_size, transferred; int err; -#if BITS_PER_LONG == 32 - inarg.flags |= FUSE_IOCTL_32BIT; -#else - if (flags & FUSE_IOCTL_COMPAT) - inarg.flags |= FUSE_IOCTL_32BIT; -#endif - /* assume all the iovs returned by client always fits in a page */ - BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); + BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); err = -ENOMEM; pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); - iov_page = (struct iovec *) __get_free_page(GFP_KERNEL); + iov_page = alloc_page(GFP_KERNEL); if (!pages || !iov_page) goto out; @@ -1803,7 +1760,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, * RETRY from server is not allowed. */ if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { - struct iovec *iov = iov_page; + struct iovec *iov = page_address(iov_page); iov->iov_base = (void __user *)arg; iov->iov_len = _IOC_SIZE(cmd); @@ -1884,7 +1841,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, /* did it ask for retry? */ if (outarg.flags & FUSE_IOCTL_RETRY) { - void *vaddr; + char *vaddr; /* no retry if in restricted mode */ err = -EIO; @@ -1905,14 +1862,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, goto out; vaddr = kmap_atomic(pages[0], KM_USER0); - err = fuse_copy_ioctl_iovec(fc, iov_page, vaddr, + err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, transferred, in_iovs + out_iovs, (flags & FUSE_IOCTL_COMPAT) != 0); kunmap_atomic(vaddr, KM_USER0); if (err) goto out; - in_iov = iov_page; + in_iov = page_address(iov_page); out_iov = in_iov + in_iovs; err = fuse_verify_ioctl_iov(in_iov, in_iovs); @@ -1934,7 +1891,8 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, out: if (req) fuse_put_request(fc, req); - free_page((unsigned long) iov_page); + if (iov_page) + __free_page(iov_page); while (num_pages) __free_page(pages[--num_pages]); kfree(pages); diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index ae5744a2f9e9..57d4a3a0f102 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -53,12 +53,6 @@ extern struct mutex fuse_mutex; extern unsigned max_user_bgreq; extern unsigned max_user_congthresh; -/* One forget request */ -struct fuse_forget_link { - struct fuse_forget_one forget_one; - struct fuse_forget_link *next; -}; - /** FUSE inode */ struct fuse_inode { /** Inode data */ @@ -72,7 +66,7 @@ struct fuse_inode { u64 nlookup; /** The request used for sending the FORGET message */ - struct fuse_forget_link *forget; + struct fuse_req *forget_req; /** Time in jiffies until the file attributes are valid */ u64 i_time; @@ -261,6 +255,7 @@ struct fuse_req { /** Data for asynchronous requests */ union { + struct fuse_forget_in forget_in; struct { struct fuse_release_in in; struct path path; @@ -374,13 +369,6 @@ struct fuse_conn { /** Pending interrupts */ struct list_head interrupts; - /** Queue of pending forgets */ - struct fuse_forget_link forget_list_head; - struct fuse_forget_link *forget_list_tail; - - /** Batching of FORGET requests (positive indicates FORGET batch) */ - int forget_batch; - /** Flag indicating if connection is blocked. This will be the case before the INIT reply is received, and if there are too many outstading backgrounds requests */ @@ -555,10 +543,8 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, /** * Send FORGET command */ -void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, - u64 nodeid, u64 nlookup); - -struct fuse_forget_link *fuse_alloc_forget(void); +void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, + u64 nodeid, u64 nlookup); /** * Initialize READ or READDIR request @@ -669,6 +655,11 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); */ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); +/** + * Send a request with no reply + */ +void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); + /** * Send a request in the background */ diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index f62b32cffea9..a8b31da19b93 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -71,11 +71,6 @@ struct fuse_mount_data { unsigned blksize; }; -struct fuse_forget_link *fuse_alloc_forget() -{ - return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL); -} - static struct inode *fuse_alloc_inode(struct super_block *sb) { struct inode *inode; @@ -95,8 +90,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&fi->queued_writes); INIT_LIST_HEAD(&fi->writepages); init_waitqueue_head(&fi->page_waitq); - fi->forget = fuse_alloc_forget(); - if (!fi->forget) { + fi->forget_req = fuse_request_alloc(); + if (!fi->forget_req) { kmem_cache_free(fuse_inode_cachep, inode); return NULL; } @@ -116,10 +111,24 @@ static void fuse_destroy_inode(struct inode *inode) struct fuse_inode *fi = get_fuse_inode(inode); BUG_ON(!list_empty(&fi->write_files)); BUG_ON(!list_empty(&fi->queued_writes)); - kfree(fi->forget); + if (fi->forget_req) + fuse_request_free(fi->forget_req); call_rcu(&inode->i_rcu, fuse_i_callback); } +void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, + u64 nodeid, u64 nlookup) +{ + struct fuse_forget_in *inarg = &req->misc.forget_in; + inarg->nlookup = nlookup; + req->in.h.opcode = FUSE_FORGET; + req->in.h.nodeid = nodeid; + req->in.numargs = 1; + req->in.args[0].size = sizeof(struct fuse_forget_in); + req->in.args[0].value = inarg; + fuse_request_send_noreply(fc, req); +} + static void fuse_evict_inode(struct inode *inode) { truncate_inode_pages(&inode->i_data, 0); @@ -127,8 +136,8 @@ static void fuse_evict_inode(struct inode *inode) if (inode->i_sb->s_flags & MS_ACTIVE) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); - fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); - fi->forget = NULL; + fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup); + fi->forget_req = NULL; } } @@ -532,7 +541,6 @@ void fuse_conn_init(struct fuse_conn *fc) INIT_LIST_HEAD(&fc->interrupts); INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->entry); - fc->forget_list_tail = &fc->forget_list_head; atomic_set(&fc->num_waiting, 0); fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; diff --git a/trunk/fs/gfs2/incore.h b/trunk/fs/gfs2/incore.h index a79790c06275..8d3d2b4a0a7d 100644 --- a/trunk/fs/gfs2/incore.h +++ b/trunk/fs/gfs2/incore.h @@ -11,7 +11,6 @@ #define __INCORE_DOT_H__ #include -#include #include #include #include diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 24ece10470b6..19433cdba011 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -202,7 +202,7 @@ static int acl_permission_check(struct inode *inode, int mask, unsigned int flag * @inode: inode to check access rights for * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) * @check_acl: optional callback to check for Posix ACLs - * @flags: IPERM_FLAG_ flags. + * @flags IPERM_FLAG_ flags. * * Used to check for read/write/execute permissions on a file. * We use "fsuid" for this, letting us set arbitrary permissions @@ -407,7 +407,7 @@ void path_put_long(struct path *path) /** * nameidata_drop_rcu - drop this nameidata out of rcu-walk * @nd: nameidata pathwalk data to drop - * Returns: 0 on success, -ECHILD on failure + * @Returns: 0 on success, -ECHLID on failure * * Path walking has 2 modes, rcu-walk and ref-walk (see * Documentation/filesystems/path-lookup.txt). __drop_rcu* functions attempt @@ -468,7 +468,7 @@ static inline int nameidata_drop_rcu_maybe(struct nameidata *nd) * nameidata_dentry_drop_rcu - drop nameidata and dentry out of rcu-walk * @nd: nameidata pathwalk data to drop * @dentry: dentry to drop - * Returns: 0 on success, -ECHILD on failure + * @Returns: 0 on success, -ECHLID on failure * * nameidata_dentry_drop_rcu attempts to drop the current nd->path and nd->root, * and dentry into ref-walk. @dentry must be a path found by a do_lookup call on @@ -530,7 +530,7 @@ static inline int nameidata_dentry_drop_rcu_maybe(struct nameidata *nd, struct d /** * nameidata_drop_rcu_last - drop nameidata ending path walk out of rcu-walk * @nd: nameidata pathwalk data to drop - * Returns: 0 on success, -ECHILD on failure + * @Returns: 0 on success, -ECHLID on failure * * nameidata_drop_rcu_last attempts to drop the current nd->path into ref-walk. * nd->path should be the final element of the lookup, so nd->root is discarded. diff --git a/trunk/fs/nilfs2/bmap.c b/trunk/fs/nilfs2/bmap.c index 3ee67c67cc52..8b782b062baa 100644 --- a/trunk/fs/nilfs2/bmap.c +++ b/trunk/fs/nilfs2/bmap.c @@ -35,20 +35,7 @@ struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) { - return NILFS_I_NILFS(bmap->b_inode)->ns_dat; -} - -static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap, - const char *fname, int err) -{ - struct inode *inode = bmap->b_inode; - - if (err == -EINVAL) { - nilfs_error(inode->i_sb, fname, - "broken bmap (inode number=%lu)\n", inode->i_ino); - err = -EIO; - } - return err; + return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); } /** @@ -79,10 +66,8 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, down_read(&bmap->b_sem); ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); - if (ret < 0) { - ret = nilfs_bmap_convert_error(bmap, __func__, ret); + if (ret < 0) goto out; - } if (NILFS_BMAP_USE_VBN(bmap)) { ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, &blocknr); @@ -103,8 +88,7 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, down_read(&bmap->b_sem); ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks); up_read(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) @@ -160,8 +144,7 @@ int nilfs_bmap_insert(struct nilfs_bmap *bmap, down_write(&bmap->b_sem); ret = nilfs_bmap_do_insert(bmap, key, rec); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key) @@ -197,12 +180,9 @@ int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) down_read(&bmap->b_sem); ret = bmap->b_ops->bop_last_key(bmap, &lastkey); - up_read(&bmap->b_sem); - - if (ret < 0) - ret = nilfs_bmap_convert_error(bmap, __func__, ret); - else + if (!ret) *key = lastkey; + up_read(&bmap->b_sem); return ret; } @@ -230,8 +210,7 @@ int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) down_write(&bmap->b_sem); ret = nilfs_bmap_do_delete(bmap, key); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) @@ -282,8 +261,7 @@ int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key) down_write(&bmap->b_sem); ret = nilfs_bmap_do_truncate(bmap, key); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } /** @@ -322,8 +300,7 @@ int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh) down_write(&bmap->b_sem); ret = bmap->b_ops->bop_propagate(bmap, bh); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } /** @@ -367,8 +344,7 @@ int nilfs_bmap_assign(struct nilfs_bmap *bmap, down_write(&bmap->b_sem); ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } /** @@ -397,8 +373,7 @@ int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level) down_write(&bmap->b_sem); ret = bmap->b_ops->bop_mark(bmap, key, level); up_write(&bmap->b_sem); - - return nilfs_bmap_convert_error(bmap, __func__, ret); + return ret; } /** diff --git a/trunk/fs/nilfs2/btnode.c b/trunk/fs/nilfs2/btnode.c index 388e9e8f5286..5115814cb745 100644 --- a/trunk/fs/nilfs2/btnode.c +++ b/trunk/fs/nilfs2/btnode.c @@ -104,7 +104,8 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, if (pblocknr == 0) { pblocknr = blocknr; if (inode->i_ino != NILFS_DAT_INO) { - struct inode *dat = NILFS_I_NILFS(inode)->ns_dat; + struct inode *dat = + nilfs_dat_inode(NILFS_I_NILFS(inode)); /* blocknr is a virtual block number */ err = nilfs_dat_translate(dat, blocknr, &pblocknr); diff --git a/trunk/fs/nilfs2/dir.c b/trunk/fs/nilfs2/dir.c index 9d45773b79e6..cb003c8ee1f6 100644 --- a/trunk/fs/nilfs2/dir.c +++ b/trunk/fs/nilfs2/dir.c @@ -91,6 +91,7 @@ static void nilfs_commit_chunk(struct page *page, unsigned from, unsigned to) { struct inode *dir = mapping->host; + struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb); loff_t pos = page_offset(page) + from; unsigned len = to - from; unsigned nr_dirty, copied; @@ -102,7 +103,7 @@ static void nilfs_commit_chunk(struct page *page, i_size_write(dir, pos + copied); if (IS_DIRSYNC(dir)) nilfs_set_transaction_flag(NILFS_TI_SYNC); - err = nilfs_set_file_dirty(dir, nr_dirty); + err = nilfs_set_file_dirty(sbi, dir, nr_dirty); WARN_ON(err); /* do not happen */ unlock_page(page); } diff --git a/trunk/fs/nilfs2/file.c b/trunk/fs/nilfs2/file.c index 2f560c9fb808..c9a30d7ff6fc 100644 --- a/trunk/fs/nilfs2/file.c +++ b/trunk/fs/nilfs2/file.c @@ -155,7 +155,6 @@ const struct inode_operations nilfs_file_inode_operations = { .truncate = nilfs_truncate, .setattr = nilfs_setattr, .permission = nilfs_permission, - .fiemap = nilfs_fiemap, }; /* end of file */ diff --git a/trunk/fs/nilfs2/ifile.c b/trunk/fs/nilfs2/ifile.c index bfc73d3a30ed..9f8a2da67f90 100644 --- a/trunk/fs/nilfs2/ifile.c +++ b/trunk/fs/nilfs2/ifile.c @@ -149,9 +149,14 @@ int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino, } err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh); - if (unlikely(err)) - nilfs_warning(sb, __func__, "unable to read inode: %lu", - (unsigned long) ino); + if (unlikely(err)) { + if (err == -EINVAL) + nilfs_error(sb, __func__, "ifile is broken"); + else + nilfs_warning(sb, __func__, + "unable to read inode: %lu", + (unsigned long) ino); + } return err; } diff --git a/trunk/fs/nilfs2/inode.c b/trunk/fs/nilfs2/inode.c index 2fd440d8d6b8..77b48c8fab17 100644 --- a/trunk/fs/nilfs2/inode.c +++ b/trunk/fs/nilfs2/inode.c @@ -58,7 +58,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, struct nilfs_inode_info *ii = NILFS_I(inode); __u64 blknum = 0; int err = 0, ret; - struct inode *dat = NILFS_I_NILFS(inode)->ns_dat; + struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode)); unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; down_read(&NILFS_MDT(dat)->mi_sem); @@ -96,6 +96,11 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, inode->i_ino, (unsigned long long)blkoff); err = 0; + } else if (err == -EINVAL) { + nilfs_error(inode->i_sb, __func__, + "broken bmap (inode=%lu)\n", + inode->i_ino); + err = -EIO; } nilfs_transaction_abort(inode->i_sb); goto out; @@ -104,7 +109,6 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, nilfs_transaction_commit(inode->i_sb); /* never fails */ /* Error handling should be detailed */ set_buffer_new(bh_result); - set_buffer_delay(bh_result); map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed to proper value */ } else if (ret == -ENOENT) { @@ -181,9 +185,10 @@ static int nilfs_set_page_dirty(struct page *page) if (ret) { struct inode *inode = page->mapping->host; + struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); - nilfs_set_file_dirty(inode, nr_dirty); + nilfs_set_file_dirty(sbi, inode, nr_dirty); } return ret; } @@ -224,7 +229,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, start + copied); copied = generic_write_end(file, mapping, pos, len, copied, page, fsdata); - nilfs_set_file_dirty(inode, nr_dirty); + nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty); err = nilfs_transaction_commit(inode->i_sb); return err ? : copied; } @@ -420,12 +425,13 @@ static int __nilfs_read_inode(struct super_block *sb, struct nilfs_root *root, unsigned long ino, struct inode *inode) { - struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; + struct nilfs_sb_info *sbi = NILFS_SB(sb); + struct inode *dat = nilfs_dat_inode(sbi->s_nilfs); struct buffer_head *bh; struct nilfs_inode *raw_inode; int err; - down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh); if (unlikely(err)) goto bad_inode; @@ -455,7 +461,7 @@ static int __nilfs_read_inode(struct super_block *sb, } nilfs_ifile_unmap_inode(root->ifile, ino, bh); brelse(bh); - up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ nilfs_set_inode_flags(inode); return 0; @@ -464,7 +470,7 @@ static int __nilfs_read_inode(struct super_block *sb, brelse(bh); bad_inode: - up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ return err; } @@ -623,7 +629,7 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, if (!test_bit(NILFS_I_BMAP, &ii->i_state)) return; -repeat: + repeat: ret = nilfs_bmap_last_key(ii->i_bmap, &b); if (ret == -ENOENT) return; @@ -640,10 +646,14 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, nilfs_bmap_truncate(ii->i_bmap, b) == 0)) goto repeat; -failed: - nilfs_warning(ii->vfs_inode.i_sb, __func__, - "failed to truncate bmap (ino=%lu, err=%d)", - ii->vfs_inode.i_ino, ret); + failed: + if (ret == -EINVAL) + nilfs_error(ii->vfs_inode.i_sb, __func__, + "bmap is broken (ino=%lu)", ii->vfs_inode.i_ino); + else + nilfs_warning(ii->vfs_inode.i_sb, __func__, + "failed to truncate bmap (ino=%lu, err=%d)", + ii->vfs_inode.i_ino, ret); } void nilfs_truncate(struct inode *inode) @@ -672,7 +682,7 @@ void nilfs_truncate(struct inode *inode) nilfs_set_transaction_flag(NILFS_TI_SYNC); nilfs_mark_inode_dirty(inode); - nilfs_set_file_dirty(inode, 0); + nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); nilfs_transaction_commit(sb); /* May construct a logical segment and may fail in sync mode. But truncate has no return value. */ @@ -790,9 +800,9 @@ int nilfs_permission(struct inode *inode, int mask, unsigned int flags) return generic_permission(inode, mask, flags, NULL); } -int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) +int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, + struct buffer_head **pbh) { - struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); struct nilfs_inode_info *ii = NILFS_I(inode); int err; @@ -833,9 +843,9 @@ int nilfs_inode_dirty(struct inode *inode) return ret; } -int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) +int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode, + unsigned nr_dirty) { - struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); struct nilfs_inode_info *ii = NILFS_I(inode); atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks); @@ -868,10 +878,11 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) int nilfs_mark_inode_dirty(struct inode *inode) { + struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); struct buffer_head *ibh; int err; - err = nilfs_load_inode_block(inode, &ibh); + err = nilfs_load_inode_block(sbi, inode, &ibh); if (unlikely(err)) { nilfs_warning(inode->i_sb, __func__, "failed to reget inode block.\n"); @@ -913,134 +924,3 @@ void nilfs_dirty_inode(struct inode *inode) nilfs_mark_inode_dirty(inode); nilfs_transaction_commit(inode->i_sb); /* never fails */ } - -int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - __u64 start, __u64 len) -{ - struct the_nilfs *nilfs = NILFS_I_NILFS(inode); - __u64 logical = 0, phys = 0, size = 0; - __u32 flags = 0; - loff_t isize; - sector_t blkoff, end_blkoff; - sector_t delalloc_blkoff; - unsigned long delalloc_blklen; - unsigned int blkbits = inode->i_blkbits; - int ret, n; - - ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); - if (ret) - return ret; - - mutex_lock(&inode->i_mutex); - - isize = i_size_read(inode); - - blkoff = start >> blkbits; - end_blkoff = (start + len - 1) >> blkbits; - - delalloc_blklen = nilfs_find_uncommitted_extent(inode, blkoff, - &delalloc_blkoff); - - do { - __u64 blkphy; - unsigned int maxblocks; - - if (delalloc_blklen && blkoff == delalloc_blkoff) { - if (size) { - /* End of the current extent */ - ret = fiemap_fill_next_extent( - fieinfo, logical, phys, size, flags); - if (ret) - break; - } - if (blkoff > end_blkoff) - break; - - flags = FIEMAP_EXTENT_MERGED | FIEMAP_EXTENT_DELALLOC; - logical = blkoff << blkbits; - phys = 0; - size = delalloc_blklen << blkbits; - - blkoff = delalloc_blkoff + delalloc_blklen; - delalloc_blklen = nilfs_find_uncommitted_extent( - inode, blkoff, &delalloc_blkoff); - continue; - } - - /* - * Limit the number of blocks that we look up so as - * not to get into the next delayed allocation extent. - */ - maxblocks = INT_MAX; - if (delalloc_blklen) - maxblocks = min_t(sector_t, delalloc_blkoff - blkoff, - maxblocks); - blkphy = 0; - - down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); - n = nilfs_bmap_lookup_contig( - NILFS_I(inode)->i_bmap, blkoff, &blkphy, maxblocks); - up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); - - if (n < 0) { - int past_eof; - - if (unlikely(n != -ENOENT)) - break; /* error */ - - /* HOLE */ - blkoff++; - past_eof = ((blkoff << blkbits) >= isize); - - if (size) { - /* End of the current extent */ - - if (past_eof) - flags |= FIEMAP_EXTENT_LAST; - - ret = fiemap_fill_next_extent( - fieinfo, logical, phys, size, flags); - if (ret) - break; - size = 0; - } - if (blkoff > end_blkoff || past_eof) - break; - } else { - if (size) { - if (phys && blkphy << blkbits == phys + size) { - /* The current extent goes on */ - size += n << blkbits; - } else { - /* Terminate the current extent */ - ret = fiemap_fill_next_extent( - fieinfo, logical, phys, size, - flags); - if (ret || blkoff > end_blkoff) - break; - - /* Start another extent */ - flags = FIEMAP_EXTENT_MERGED; - logical = blkoff << blkbits; - phys = blkphy << blkbits; - size = n << blkbits; - } - } else { - /* Start a new extent */ - flags = FIEMAP_EXTENT_MERGED; - logical = blkoff << blkbits; - phys = blkphy << blkbits; - size = n << blkbits; - } - blkoff += n; - } - cond_resched(); - } while (true); - - /* If ret is 1 then we just hit the end of the extent array */ - if (ret == 1) - ret = 0; - - mutex_unlock(&inode->i_mutex); - return ret; -} diff --git a/trunk/fs/nilfs2/ioctl.c b/trunk/fs/nilfs2/ioctl.c index 496738963fdb..b185e937a335 100644 --- a/trunk/fs/nilfs2/ioctl.c +++ b/trunk/fs/nilfs2/ioctl.c @@ -233,7 +233,7 @@ nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, int ret; down_read(&nilfs->ns_segctor_sem); - ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs); + ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, size, nmembs); up_read(&nilfs->ns_segctor_sem); return ret; } @@ -242,7 +242,8 @@ static ssize_t nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags, void *buf, size_t size, size_t nmembs) { - struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; + struct inode *dat = nilfs_dat_inode(nilfs); + struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap; struct nilfs_bdesc *bdescs = buf; int ret, i; @@ -420,7 +421,7 @@ static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs, size_t nmembs = argv->v_nmembs; int ret; - ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs); + ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs); return (ret < 0) ? ret : nmembs; } @@ -429,7 +430,8 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, struct nilfs_argv *argv, void *buf) { size_t nmembs = argv->v_nmembs; - struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; + struct inode *dat = nilfs_dat_inode(nilfs); + struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap; struct nilfs_bdesc *bdescs = buf; int ret, i; @@ -448,7 +450,7 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, /* skip dead block */ continue; if (bdescs[i].bd_level == 0) { - ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat, + ret = nilfs_mdt_mark_block_dirty(dat, bdescs[i].bd_offset); if (ret < 0) { WARN_ON(ret == -ENOENT); diff --git a/trunk/fs/nilfs2/mdt.c b/trunk/fs/nilfs2/mdt.c index 6a0e2a189f60..39a5b84e2c9f 100644 --- a/trunk/fs/nilfs2/mdt.c +++ b/trunk/fs/nilfs2/mdt.c @@ -237,6 +237,8 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, * * %-ENOENT - the specified block does not exist (hole block) * + * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) + * * %-EROFS - Read only filesystem (for create mode) */ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, @@ -271,6 +273,8 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, * %-ENOMEM - Insufficient memory available. * * %-EIO - I/O error + * + * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) */ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block) { @@ -346,6 +350,8 @@ int nilfs_mdt_forget_block(struct inode *inode, unsigned long block) * %-EIO - I/O error * * %-ENOENT - the specified block does not exist (hole block) + * + * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) */ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) { @@ -493,29 +499,31 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh) struct buffer_head *bh_frozen; struct page *page; int blkbits = inode->i_blkbits; + int ret = -ENOMEM; page = grab_cache_page(&shadow->frozen_data, bh->b_page->index); if (!page) - return -ENOMEM; + return ret; if (!page_has_buffers(page)) create_empty_buffers(page, 1 << blkbits, 0); bh_frozen = nilfs_page_get_nth_block(page, bh_offset(bh) >> blkbits); - - if (!buffer_uptodate(bh_frozen)) - nilfs_copy_buffer(bh_frozen, bh); - if (list_empty(&bh_frozen->b_assoc_buffers)) { - list_add_tail(&bh_frozen->b_assoc_buffers, - &shadow->frozen_buffers); - set_buffer_nilfs_redirected(bh); - } else { - brelse(bh_frozen); /* already frozen */ + if (bh_frozen) { + if (!buffer_uptodate(bh_frozen)) + nilfs_copy_buffer(bh_frozen, bh); + if (list_empty(&bh_frozen->b_assoc_buffers)) { + list_add_tail(&bh_frozen->b_assoc_buffers, + &shadow->frozen_buffers); + set_buffer_nilfs_redirected(bh); + } else { + brelse(bh_frozen); /* already frozen */ + } + ret = 0; } - unlock_page(page); page_cache_release(page); - return 0; + return ret; } struct buffer_head * diff --git a/trunk/fs/nilfs2/namei.c b/trunk/fs/nilfs2/namei.c index 98034271cd02..6e9557ecf161 100644 --- a/trunk/fs/nilfs2/namei.c +++ b/trunk/fs/nilfs2/namei.c @@ -577,7 +577,6 @@ const struct inode_operations nilfs_dir_inode_operations = { .rename = nilfs_rename, .setattr = nilfs_setattr, .permission = nilfs_permission, - .fiemap = nilfs_fiemap, }; const struct inode_operations nilfs_special_inode_operations = { diff --git a/trunk/fs/nilfs2/nilfs.h b/trunk/fs/nilfs2/nilfs.h index 777e8fd04304..0ca98823db59 100644 --- a/trunk/fs/nilfs2/nilfs.h +++ b/trunk/fs/nilfs2/nilfs.h @@ -190,6 +190,11 @@ static inline int nilfs_doing_construction(void) return nilfs_test_transaction_flag(NILFS_TI_WRITER); } +static inline struct inode *nilfs_dat_inode(const struct the_nilfs *nilfs) +{ + return nilfs->ns_dat; +} + /* * function prototype */ @@ -252,13 +257,13 @@ extern void nilfs_truncate(struct inode *); extern void nilfs_evict_inode(struct inode *); extern int nilfs_setattr(struct dentry *, struct iattr *); int nilfs_permission(struct inode *inode, int mask, unsigned int flags); -int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); +extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *, + struct buffer_head **); extern int nilfs_inode_dirty(struct inode *); -int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); +extern int nilfs_set_file_dirty(struct nilfs_sb_info *, struct inode *, + unsigned); extern int nilfs_mark_inode_dirty(struct inode *); extern void nilfs_dirty_inode(struct inode *); -int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - __u64 start, __u64 len); /* super.c */ extern struct inode *nilfs_alloc_inode(struct super_block *); diff --git a/trunk/fs/nilfs2/page.c b/trunk/fs/nilfs2/page.c index 0c432416cfef..a6c3c2e817f8 100644 --- a/trunk/fs/nilfs2/page.c +++ b/trunk/fs/nilfs2/page.c @@ -491,7 +491,7 @@ unsigned nilfs_page_count_clean_buffers(struct page *page, } return nc; } - + void nilfs_mapping_init_once(struct address_space *mapping) { memset(mapping, 0, sizeof(*mapping)); @@ -546,87 +546,3 @@ int __nilfs_clear_page_dirty(struct page *page) } return TestClearPageDirty(page); } - -/** - * nilfs_find_uncommitted_extent - find extent of uncommitted data - * @inode: inode - * @start_blk: start block offset (in) - * @blkoff: start offset of the found extent (out) - * - * This function searches an extent of buffers marked "delayed" which - * starts from a block offset equal to or larger than @start_blk. If - * such an extent was found, this will store the start offset in - * @blkoff and return its length in blocks. Otherwise, zero is - * returned. - */ -unsigned long nilfs_find_uncommitted_extent(struct inode *inode, - sector_t start_blk, - sector_t *blkoff) -{ - unsigned int i; - pgoff_t index; - unsigned int nblocks_in_page; - unsigned long length = 0; - sector_t b; - struct pagevec pvec; - struct page *page; - - if (inode->i_mapping->nrpages == 0) - return 0; - - index = start_blk >> (PAGE_CACHE_SHIFT - inode->i_blkbits); - nblocks_in_page = 1U << (PAGE_CACHE_SHIFT - inode->i_blkbits); - - pagevec_init(&pvec, 0); - -repeat: - pvec.nr = find_get_pages_contig(inode->i_mapping, index, PAGEVEC_SIZE, - pvec.pages); - if (pvec.nr == 0) - return length; - - if (length > 0 && pvec.pages[0]->index > index) - goto out; - - b = pvec.pages[0]->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); - i = 0; - do { - page = pvec.pages[i]; - - lock_page(page); - if (page_has_buffers(page)) { - struct buffer_head *bh, *head; - - bh = head = page_buffers(page); - do { - if (b < start_blk) - continue; - if (buffer_delay(bh)) { - if (length == 0) - *blkoff = b; - length++; - } else if (length > 0) { - goto out_locked; - } - } while (++b, bh = bh->b_this_page, bh != head); - } else { - if (length > 0) - goto out_locked; - - b += nblocks_in_page; - } - unlock_page(page); - - } while (++i < pagevec_count(&pvec)); - - index = page->index + 1; - pagevec_release(&pvec); - cond_resched(); - goto repeat; - -out_locked: - unlock_page(page); -out: - pagevec_release(&pvec); - return length; -} diff --git a/trunk/fs/nilfs2/page.h b/trunk/fs/nilfs2/page.h index 622df27cd891..fb9e8a8a2038 100644 --- a/trunk/fs/nilfs2/page.h +++ b/trunk/fs/nilfs2/page.h @@ -66,9 +66,6 @@ void nilfs_mapping_init(struct address_space *mapping, struct backing_dev_info *bdi, const struct address_space_operations *aops); unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); -unsigned long nilfs_find_uncommitted_extent(struct inode *inode, - sector_t start_blk, - sector_t *blkoff); #define NILFS_PAGE_BUG(page, m, a...) \ do { nilfs_page_bug(page); BUG(); } while (0) diff --git a/trunk/fs/nilfs2/recovery.c b/trunk/fs/nilfs2/recovery.c index 3dfcd3b7d389..5d2711c28da7 100644 --- a/trunk/fs/nilfs2/recovery.c +++ b/trunk/fs/nilfs2/recovery.c @@ -535,7 +535,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, if (unlikely(err)) goto failed_page; - err = nilfs_set_file_dirty(inode, 1); + err = nilfs_set_file_dirty(sbi, inode, 1); if (unlikely(err)) goto failed_page; diff --git a/trunk/fs/nilfs2/sb.h b/trunk/fs/nilfs2/sb.h index 7a17715f215f..35a07157b980 100644 --- a/trunk/fs/nilfs2/sb.h +++ b/trunk/fs/nilfs2/sb.h @@ -27,6 +27,14 @@ #include #include +/* + * Mount options + */ +struct nilfs_mount_options { + unsigned long mount_opt; + __u64 snapshot_cno; +}; + struct the_nilfs; struct nilfs_sc_info; diff --git a/trunk/fs/nilfs2/segment.c b/trunk/fs/nilfs2/segment.c index 55ebae5c7f39..687d090cea34 100644 --- a/trunk/fs/nilfs2/segment.c +++ b/trunk/fs/nilfs2/segment.c @@ -504,6 +504,17 @@ static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci, return err; } +static int nilfs_handle_bmap_error(int err, const char *fname, + struct inode *inode, struct super_block *sb) +{ + if (err == -EINVAL) { + nilfs_error(sb, fname, "broken bmap (inode=%lu)\n", + inode->i_ino); + err = -EIO; + } + return err; +} + /* * Callback functions that enumerate, mark, and collect dirty blocks */ @@ -513,8 +524,9 @@ static int nilfs_collect_file_data(struct nilfs_sc_info *sci, int err; err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); - if (err < 0) - return err; + if (unlikely(err < 0)) + return nilfs_handle_bmap_error(err, __func__, inode, + sci->sc_super); err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(struct nilfs_binfo_v)); @@ -527,7 +539,13 @@ static int nilfs_collect_file_node(struct nilfs_sc_info *sci, struct buffer_head *bh, struct inode *inode) { - return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); + int err; + + err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); + if (unlikely(err < 0)) + return nilfs_handle_bmap_error(err, __func__, inode, + sci->sc_super); + return 0; } static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci, @@ -570,8 +588,9 @@ static int nilfs_collect_dat_data(struct nilfs_sc_info *sci, int err; err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh); - if (err < 0) - return err; + if (unlikely(err < 0)) + return nilfs_handle_bmap_error(err, __func__, inode, + sci->sc_super); err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64)); if (!err) @@ -757,8 +776,9 @@ static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs, ret++; if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile)) ret++; - if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat)) - ret++; + if (ret || nilfs_doing_gc()) + if (nilfs_mdt_fetch_dirty(nilfs_dat_inode(nilfs))) + ret++; return ret; } @@ -794,7 +814,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) nilfs_mdt_clear_dirty(sci->sc_root->ifile); nilfs_mdt_clear_dirty(nilfs->ns_cpfile); nilfs_mdt_clear_dirty(nilfs->ns_sufile); - nilfs_mdt_clear_dirty(nilfs->ns_dat); + nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); } static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) @@ -903,7 +923,7 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, nilfs->ns_nongc_ctime : sci->sc_seg_ctime); raw_sr->sr_flags = 0; - nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr + + nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr + NILFS_SR_DAT_OFFSET(isz), 1); nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr + NILFS_SR_CPFILE_OFFSET(isz), 1); @@ -1159,7 +1179,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) sci->sc_stage.scnt++; /* Fall through */ case NILFS_ST_DAT: dat_stage: - err = nilfs_segctor_scan_file(sci, nilfs->ns_dat, + err = nilfs_segctor_scan_file(sci, nilfs_dat_inode(nilfs), &nilfs_sc_dat_ops); if (unlikely(err)) break; @@ -1543,6 +1563,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci, return 0; failed_bmap: + err = nilfs_handle_bmap_error(err, __func__, inode, sci->sc_super); return err; } @@ -1762,7 +1783,6 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err) if (!err) { set_buffer_uptodate(bh); clear_buffer_dirty(bh); - clear_buffer_delay(bh); clear_buffer_nilfs_volatile(bh); } brelse(bh); /* for b_assoc_buffers */ @@ -1889,7 +1909,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) b_assoc_buffers) { set_buffer_uptodate(bh); clear_buffer_dirty(bh); - clear_buffer_delay(bh); clear_buffer_nilfs_volatile(bh); clear_buffer_nilfs_redirected(bh); if (bh == segbuf->sb_super_root) { diff --git a/trunk/fs/nilfs2/super.c b/trunk/fs/nilfs2/super.c index 70dfdd532b83..e2dcc9c733f7 100644 --- a/trunk/fs/nilfs2/super.c +++ b/trunk/fs/nilfs2/super.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "nilfs.h" @@ -110,17 +111,12 @@ void nilfs_error(struct super_block *sb, const char *function, const char *fmt, ...) { struct nilfs_sb_info *sbi = NILFS_SB(sb); - struct va_format vaf; va_list args; va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - printk(KERN_CRIT "NILFS error (device %s): %s: %pV\n", - sb->s_id, function, &vaf); - + printk(KERN_CRIT "NILFS error (device %s): %s: ", sb->s_id, function); + vprintk(fmt, args); + printk("\n"); va_end(args); if (!(sb->s_flags & MS_RDONLY)) { @@ -140,17 +136,13 @@ void nilfs_error(struct super_block *sb, const char *function, void nilfs_warning(struct super_block *sb, const char *function, const char *fmt, ...) { - struct va_format vaf; va_list args; va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - printk(KERN_WARNING "NILFS warning (device %s): %s: %pV\n", - sb->s_id, function, &vaf); - + printk(KERN_WARNING "NILFS warning (device %s): %s: ", + sb->s_id, function); + vprintk(fmt, args); + printk("\n"); va_end(args); } @@ -1018,11 +1010,11 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sbi->s_nilfs; unsigned long old_sb_flags; - unsigned long old_mount_opt; + struct nilfs_mount_options old_opts; int err; old_sb_flags = sb->s_flags; - old_mount_opt = sbi->s_mount_opt; + old_opts.mount_opt = sbi->s_mount_opt; if (!parse_options(data, sb, 1)) { err = -EINVAL; @@ -1091,7 +1083,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) restore_opts: sb->s_flags = old_sb_flags; - sbi->s_mount_opt = old_mount_opt; + sbi->s_mount_opt = old_opts.mount_opt; return err; } diff --git a/trunk/fs/nilfs2/the_nilfs.c b/trunk/fs/nilfs2/the_nilfs.c index ad4ac607cf57..0254be2d73c6 100644 --- a/trunk/fs/nilfs2/the_nilfs.c +++ b/trunk/fs/nilfs2/the_nilfs.c @@ -329,6 +329,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) printk(KERN_INFO "NILFS: recovery complete.\n"); skip_recovery: + set_nilfs_loaded(nilfs); nilfs_clear_recovery_info(&ri); sbi->s_super->s_flags = s_flags; return 0; @@ -650,11 +651,12 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump, int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks) { + struct inode *dat = nilfs_dat_inode(nilfs); unsigned long ncleansegs; - down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile); - up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; return 0; } diff --git a/trunk/fs/nilfs2/the_nilfs.h b/trunk/fs/nilfs2/the_nilfs.h index fd85e4c05c6b..69226e14b745 100644 --- a/trunk/fs/nilfs2/the_nilfs.h +++ b/trunk/fs/nilfs2/the_nilfs.h @@ -36,6 +36,8 @@ /* the_nilfs struct */ enum { THE_NILFS_INIT = 0, /* Information from super_block is set */ + THE_NILFS_LOADED, /* Roll-back/roll-forward has done and + the latest checkpoint was loaded */ THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ THE_NILFS_GC_RUNNING, /* gc process is running */ THE_NILFS_SB_DIRTY, /* super block is dirty */ @@ -176,6 +178,7 @@ static inline int nilfs_##name(struct the_nilfs *nilfs) \ } THE_NILFS_FNS(INIT, init) +THE_NILFS_FNS(LOADED, loaded) THE_NILFS_FNS(DISCONTINUED, discontinued) THE_NILFS_FNS(GC_RUNNING, gc_running) THE_NILFS_FNS(SB_DIRTY, sb_dirty) diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 0a12eb89cd32..30ac27345586 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include "sysfs.h" diff --git a/trunk/fs/sysfs/sysfs.h b/trunk/fs/sysfs/sysfs.h index 3d28af31d863..ffaaa816bfba 100644 --- a/trunk/fs/sysfs/sysfs.h +++ b/trunk/fs/sysfs/sysfs.h @@ -9,7 +9,6 @@ */ #include -#include #include struct sysfs_open_dirent; diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 05cbad03c5ab..bd69d79208de 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -67,8 +67,7 @@ * Align to a 32 byte boundary equal to the * alignment gcc 4.5 uses for a struct */ -#define STRUCT_ALIGNMENT 32 -#define STRUCT_ALIGN() . = ALIGN(STRUCT_ALIGNMENT) +#define STRUCT_ALIGN() . = ALIGN(32) /* The actual configuration determine if the init/exit sections * are handled as text/data or they can be discarded (which @@ -147,13 +146,6 @@ #define TRACE_SYSCALLS() #endif - -#define KERNEL_DTB() \ - STRUCT_ALIGN(); \ - VMLINUX_SYMBOL(__dtb_start) = .; \ - *(.dtb.init.rodata) \ - VMLINUX_SYMBOL(__dtb_end) = .; - /* .data section */ #define DATA_DATA \ *(.data) \ @@ -476,8 +468,7 @@ MCOUNT_REC() \ DEV_DISCARD(init.rodata) \ CPU_DISCARD(init.rodata) \ - MEM_DISCARD(init.rodata) \ - KERNEL_DTB() + MEM_DISCARD(init.rodata) #define INIT_TEXT \ *(.init.text) \ diff --git a/trunk/include/keys/encrypted-type.h b/trunk/include/keys/encrypted-type.h deleted file mode 100644 index 95855017a32b..000000000000 --- a/trunk/include/keys/encrypted-type.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2010 IBM Corporation - * Author: Mimi Zohar - * - * 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 of the License. - */ - -#ifndef _KEYS_ENCRYPTED_TYPE_H -#define _KEYS_ENCRYPTED_TYPE_H - -#include -#include - -struct encrypted_key_payload { - struct rcu_head rcu; - char *master_desc; /* datablob: master key name */ - char *datalen; /* datablob: decrypted key length */ - u8 *iv; /* datablob: iv */ - u8 *encrypted_data; /* datablob: encrypted data */ - unsigned short datablob_len; /* length of datablob */ - unsigned short decrypted_datalen; /* decrypted data length */ - u8 decrypted_data[0]; /* decrypted data + datablob + hmac */ -}; - -extern struct key_type key_type_encrypted; - -#endif /* _KEYS_ENCRYPTED_TYPE_H */ diff --git a/trunk/include/keys/trusted-type.h b/trunk/include/keys/trusted-type.h deleted file mode 100644 index 56f82e5c9975..000000000000 --- a/trunk/include/keys/trusted-type.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010 IBM Corporation - * Author: David Safford - * - * 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 of the License. - */ - -#ifndef _KEYS_TRUSTED_TYPE_H -#define _KEYS_TRUSTED_TYPE_H - -#include -#include - -#define MIN_KEY_SIZE 32 -#define MAX_KEY_SIZE 128 -#define MAX_BLOB_SIZE 320 - -struct trusted_key_payload { - struct rcu_head rcu; - unsigned int key_len; - unsigned int blob_len; - unsigned char migratable; - unsigned char key[MAX_KEY_SIZE + 1]; - unsigned char blob[MAX_BLOB_SIZE]; -}; - -extern struct key_type key_type_trusted; - -#endif /* _KEYS_TRUSTED_TYPE_H */ diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index d1580c17cab3..a354c199ab98 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -20,18 +20,15 @@ header-y += wimax/ objhdr-y += version.h ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \ - $(srctree)/include/asm-$(SRCARCH)/a.out.h \ - $(INSTALL_HDR_PATH)/include/asm-*/a.out.h),) + $(srctree)/include/asm-$(SRCARCH)/a.out.h),) header-y += a.out.h endif ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm.h \ - $(INSTALL_HDR_PATH)/include/asm-*/kvm.h),) + $(srctree)/include/asm-$(SRCARCH)/kvm.h),) header-y += kvm.h endif ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm_para.h \ - $(INSTALL_HDR_PATH)/include/asm-*/kvm_para.h),) + $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),) header-y += kvm_para.h endif diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 359df0487690..8b5c0620abf9 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -372,7 +372,6 @@ struct audit_buffer; struct audit_context; struct inode; struct netlink_skb_parms; -struct path; struct linux_binprm; struct mq_attr; struct mqstat; diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index fb16a3699b99..90012b9ddbf3 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -246,6 +246,7 @@ struct cpu_vfs_cap_data { /* Allow configuration of the secure attention key */ /* Allow administration of the random device */ /* Allow examination and configuration of disk quotas */ +/* Allow configuring the kernel's syslog (printk behaviour) */ /* Allow setting the domainname */ /* Allow setting the hostname */ /* Allow calling bdflush() */ @@ -351,11 +352,7 @@ struct cpu_vfs_cap_data { #define CAP_MAC_ADMIN 33 -/* Allow configuring the kernel's syslog (printk behaviour) */ - -#define CAP_SYSLOG 34 - -#define CAP_LAST_CAP CAP_SYSLOG +#define CAP_LAST_CAP CAP_MAC_ADMIN #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 59fcd24b1468..bd07758943e0 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -307,7 +307,7 @@ extern struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok * @dentry: dentry to take a ref on * @seq: seqcount to verify against - * Returns: 0 on failure, else 1. + * @Returns: 0 on failure, else 1. * * __d_rcu_to_refcount operates on a dentry,seq pair that was returned * by __d_lookup_rcu, to get a reference on an rcu-walk dentry. diff --git a/trunk/include/linux/dcookies.h b/trunk/include/linux/dcookies.h index 5ac3bdd5cee6..24c806f12a6c 100644 --- a/trunk/include/linux/dcookies.h +++ b/trunk/include/linux/dcookies.h @@ -13,10 +13,10 @@ #ifdef CONFIG_PROFILING #include +#include #include struct dcookie_user; -struct path; /** * dcookie_register - register a user of dcookies diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index d96af9701d60..dd4895313468 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -197,7 +197,6 @@ struct class { struct class_attribute *class_attrs; struct device_attribute *dev_attrs; - struct bin_attribute *dev_bin_attrs; struct kobject *dev_kobj; int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); @@ -509,13 +508,13 @@ static inline int device_is_registered(struct device *dev) static inline void device_enable_async_suspend(struct device *dev) { - if (!dev->power.in_suspend) + if (dev->power.status == DPM_ON) dev->power.async_suspend = true; } static inline void device_disable_async_suspend(struct device *dev) { - if (!dev->power.in_suspend) + if (dev->power.status == DPM_ON) dev->power.async_suspend = false; } diff --git a/trunk/include/linux/firewire.h b/trunk/include/linux/firewire.h index 9a3f5f9383f6..1cd637ef62d2 100644 --- a/trunk/include/linux/firewire.h +++ b/trunk/include/linux/firewire.h @@ -302,9 +302,9 @@ struct fw_packet { struct fw_transaction { int node_id; /* The generation is implied; it is always the current. */ int tlabel; + int timestamp; struct list_head link; struct fw_card *card; - bool is_split_transaction; struct timer_list split_timeout_timer; struct fw_packet packet; diff --git a/trunk/include/linux/firmware-map.h b/trunk/include/linux/firmware-map.h index 43fe52fcef0f..c6dcc1dfe781 100644 --- a/trunk/include/linux/firmware-map.h +++ b/trunk/include/linux/firmware-map.h @@ -17,6 +17,7 @@ #define _LINUX_FIRMWARE_MAP_H #include +#include /* * provide a dummy interface if CONFIG_FIRMWARE_MEMMAP is disabled diff --git a/trunk/include/linux/flex_array.h b/trunk/include/linux/flex_array.h index 70e4efabe0fb..631b77f2ac70 100644 --- a/trunk/include/linux/flex_array.h +++ b/trunk/include/linux/flex_array.h @@ -71,7 +71,7 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr); int flex_array_shrink(struct flex_array *fa); #define flex_array_put_ptr(fa, nr, src, gfp) \ - flex_array_put(fa, nr, (void *)&(src), gfp) + flex_array_put(fa, nr, &(void *)(src), gfp) void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index f84d9928bdb1..baf3e556ff0e 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -382,6 +382,7 @@ struct inodes_stat_t { #include #include #include +#include #include #include #include @@ -401,7 +402,6 @@ struct hd_geometry; struct iovec; struct nameidata; struct kiocb; -struct kobject; struct pipe_inode_info; struct poll_table_struct; struct kstatfs; diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index d464de53db43..c3c578e09833 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -41,12 +41,6 @@ * 7.15 * - add store notify * - add retrieve notify - * - * 7.16 - * - add BATCH_FORGET request - * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct - * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' - * - add FUSE_IOCTL_32BIT flag */ #ifndef _LINUX_FUSE_H @@ -78,7 +72,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 16 +#define FUSE_KERNEL_MINOR_VERSION 15 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -206,14 +200,12 @@ struct fuse_file_lock { * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed * FUSE_IOCTL_RETRY: retry with new iovecs - * FUSE_IOCTL_32BIT: 32bit ioctl * * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs */ #define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_RETRY (1 << 2) -#define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_MAX_IOV 256 @@ -264,7 +256,6 @@ enum fuse_opcode { FUSE_IOCTL = 39, FUSE_POLL = 40, FUSE_NOTIFY_REPLY = 41, - FUSE_BATCH_FORGET = 42, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -299,16 +290,6 @@ struct fuse_forget_in { __u64 nlookup; }; -struct fuse_forget_one { - __u64 nodeid; - __u64 nlookup; -}; - -struct fuse_batch_forget_in { - __u32 count; - __u32 dummy; -}; - struct fuse_getattr_in { __u32 getattr_flags; __u32 dummy; @@ -529,11 +510,6 @@ struct fuse_ioctl_in { __u32 out_size; }; -struct fuse_ioctl_iovec { - __u64 base; - __u64 len; -}; - struct fuse_ioctl_out { __s32 result; __u32 flags; diff --git a/trunk/include/linux/hid.h b/trunk/include/linux/hid.h index 20b9801f669b..bb0f56f5c01e 100644 --- a/trunk/include/linux/hid.h +++ b/trunk/include/linux/hid.h @@ -820,49 +820,6 @@ static inline void hid_hw_stop(struct hid_device *hdev) hdev->ll_driver->stop(hdev); } -/** - * hid_hw_open - signal underlaying HW to start delivering events - * - * @hdev: hid device - * - * Tell underlying HW to start delivering events from the device. - * This function should be called sometime after successful call - * to hid_hiw_start(). - */ -static inline int __must_check hid_hw_open(struct hid_device *hdev) -{ - return hdev->ll_driver->open(hdev); -} - -/** - * hid_hw_close - signal underlaying HW to stop delivering events - * - * @hdev: hid device - * - * This function indicates that we are not interested in the events - * from this device anymore. Delivery of events may or may not stop, - * depending on the number of users still outstanding. - */ -static inline void hid_hw_close(struct hid_device *hdev) -{ - hdev->ll_driver->close(hdev); -} - -/** - * hid_hw_power - requests underlying HW to go into given power mode - * - * @hdev: hid device - * @level: requested power level (one of %PM_HINT_* defines) - * - * This function requests underlying hardware to enter requested power - * mode. - */ - -static inline int hid_hw_power(struct hid_device *hdev, int level) -{ - return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; -} - void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); @@ -881,32 +838,12 @@ int hid_pidff_init(struct hid_device *hid); #define hid_pidff_init NULL #endif -#define dbg_hid(format, arg...) \ -do { \ - if (hid_debug) \ - printk(KERN_DEBUG "%s: " format, __FILE__, ##arg); \ -} while (0) - -#define hid_printk(level, hid, fmt, arg...) \ - dev_printk(level, &(hid)->dev, fmt, ##arg) -#define hid_emerg(hid, fmt, arg...) \ - dev_emerg(&(hid)->dev, fmt, ##arg) -#define hid_crit(hid, fmt, arg...) \ - dev_crit(&(hid)->dev, fmt, ##arg) -#define hid_alert(hid, fmt, arg...) \ - dev_alert(&(hid)->dev, fmt, ##arg) -#define hid_err(hid, fmt, arg...) \ - dev_err(&(hid)->dev, fmt, ##arg) -#define hid_notice(hid, fmt, arg...) \ - dev_notice(&(hid)->dev, fmt, ##arg) -#define hid_warn(hid, fmt, arg...) \ - dev_warn(&(hid)->dev, fmt, ##arg) -#define hid_info(hid, fmt, arg...) \ - dev_info(&(hid)->dev, fmt, ##arg) -#define hid_dbg(hid, fmt, arg...) \ - dev_dbg(&(hid)->dev, fmt, ##arg) - -#endif /* __KERNEL__ */ +#define dbg_hid(format, arg...) if (hid_debug) \ + printk(KERN_DEBUG "%s: " format ,\ + __FILE__ , ## arg) +#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ + __FILE__ , ## arg) +#endif /* HID_FF */ #endif diff --git a/trunk/include/linux/hrtimer.h b/trunk/include/linux/hrtimer.h index f376ddc64c4d..330586ffffbb 100644 --- a/trunk/include/linux/hrtimer.h +++ b/trunk/include/linux/hrtimer.h @@ -131,6 +131,7 @@ struct hrtimer_sleeper { * @index: clock type index for per_cpu support when moving a * timer to a base on another cpu. * @active: red black tree root node for the active timers + * @first: pointer to the timer node which expires first * @resolution: the resolution of the clock, in nanoseconds * @get_time: function to retrieve the current time of the clock * @softirq_time: the time when running the hrtimer queue in the softirq diff --git a/trunk/include/linux/i2c/ds620.h b/trunk/include/linux/i2c/ds620.h deleted file mode 100644 index 736bb87ac0fc..000000000000 --- a/trunk/include/linux/i2c/ds620.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _LINUX_DS620_H -#define _LINUX_DS620_H - -#include -#include - -/* platform data for the DS620 temperature sensor and thermostat */ - -struct ds620_platform_data { - /* - * Thermostat output pin PO mode: - * 0 = always low (default) - * 1 = PO_LOW - * 2 = PO_HIGH - * - * (see Documentation/hwmon/ds620) - */ - int pomode; -}; - -#endif /* _LINUX_DS620_H */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index d0fbc043de60..b6de9a6f7018 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -56,8 +56,6 @@ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) - -/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */ #define roundup(x, y) ( \ { \ const typeof(y) __y = y; \ @@ -265,7 +263,6 @@ static inline char *pack_hex_byte(char *buf, u8 byte) } extern int hex_to_bin(char ch); -extern void hex2bin(u8 *dst, const char *src, size_t count); /* * General tracing related utility functions - trace_printk(), diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index c9c5d7ad1a2b..d947b1231662 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -996,7 +996,8 @@ extern int ata_sas_port_init(struct ata_port *); extern int ata_sas_port_start(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); -extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); +extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), + struct ata_port *ap); extern int sata_scr_valid(struct ata_link *link); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val); @@ -1039,7 +1040,8 @@ extern unsigned int ata_do_dev_read_id(struct ata_device *dev, struct ata_taskfile *tf, u16 *id); extern void ata_qc_complete(struct ata_queued_cmd *qc); extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active); -extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); +extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); diff --git a/trunk/include/linux/of_address.h b/trunk/include/linux/of_address.h index 2feda6ee6140..8aea06f0564c 100644 --- a/trunk/include/linux/of_address.h +++ b/trunk/include/linux/of_address.h @@ -3,7 +3,7 @@ #include #include -extern u64 of_translate_address(struct device_node *np, const __be32 *addr); +extern u64 of_translate_address(struct device_node *np, const u32 *addr); extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); @@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #ifdef CONFIG_PCI -extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, +extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); @@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar, return -ENOSYS; } -static inline const __be32 *of_get_pci_address(struct device_node *dev, +static inline const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { return NULL; diff --git a/trunk/include/linux/of_fdt.h b/trunk/include/linux/of_fdt.h index 0ef22a1f129e..7bbf5b328438 100644 --- a/trunk/include/linux/of_fdt.h +++ b/trunk/include/linux/of_fdt.h @@ -58,23 +58,6 @@ struct boot_param_header { }; #if defined(CONFIG_OF_FLATTREE) - -struct device_node; - -/* For scanning an arbitrary device-tree at any time */ -extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset); -extern void *of_fdt_get_property(struct boot_param_header *blob, - unsigned long node, - const char *name, - unsigned long *size); -extern int of_fdt_is_compatible(struct boot_param_header *blob, - unsigned long node, - const char *compat); -extern int of_fdt_match(struct boot_param_header *blob, unsigned long node, - const char **compat); -extern void of_fdt_unflatten_tree(unsigned long *blob, - struct device_node **mynodes); - /* TBD: Temporary export of fdt globals - remove when code fully merged */ extern int __initdata dt_root_addr_cells; extern int __initdata dt_root_size_cells; @@ -88,7 +71,6 @@ extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, extern void *of_get_flat_dt_prop(unsigned long node, const char *name, unsigned long *size); extern int of_flat_dt_is_compatible(unsigned long node, const char *name); -extern int of_flat_dt_match(unsigned long node, const char **matches); extern unsigned long of_get_flat_dt_root(void); extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, diff --git a/trunk/include/linux/of_net.h b/trunk/include/linux/of_net.h deleted file mode 100644 index e913081fb52a..000000000000 --- a/trunk/include/linux/of_net.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * OF helpers for network devices. - * - * This file is released under the GPLv2 - */ - -#ifndef __LINUX_OF_NET_H -#define __LINUX_OF_NET_H - -#ifdef CONFIG_OF_NET -#include -extern const void *of_get_mac_address(struct device_node *np); -#endif - -#endif /* __LINUX_OF_NET_H */ diff --git a/trunk/include/linux/pipe_fs_i.h b/trunk/include/linux/pipe_fs_i.h index 77257c92155a..bb27d7ec2fb9 100644 --- a/trunk/include/linux/pipe_fs_i.h +++ b/trunk/include/linux/pipe_fs_i.h @@ -30,7 +30,6 @@ struct pipe_buffer { * struct pipe_inode_info - a linux kernel pipe * @wait: reader/writer wait point in case of empty/full pipe * @nrbufs: the number of non-empty pipe buffers in this pipe - * @buffers: total number of buffers (should be a power of 2) * @curbuf: the current pipe buffer entry * @tmp_page: cached released page * @readers: number of current readers of this pipe diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index dd9c7ab38270..40f3f45702ba 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -366,6 +366,45 @@ extern struct dev_pm_ops generic_subsys_pm_ops; #define PMSG_AUTO_RESUME ((struct pm_message) \ { .event = PM_EVENT_AUTO_RESUME, }) +/** + * Device power management states + * + * These state labels are used internally by the PM core to indicate the current + * status of a device with respect to the PM core operations. + * + * DPM_ON Device is regarded as operational. Set this way + * initially and when ->complete() is about to be called. + * Also set when ->prepare() fails. + * + * DPM_PREPARING Device is going to be prepared for a PM transition. Set + * when ->prepare() is about to be called. + * + * DPM_RESUMING Device is going to be resumed. Set when ->resume(), + * ->thaw(), or ->restore() is about to be called. + * + * DPM_SUSPENDING Device has been prepared for a power transition. Set + * when ->prepare() has just succeeded. + * + * DPM_OFF Device is regarded as inactive. Set immediately after + * ->suspend(), ->freeze(), or ->poweroff() has succeeded. + * Also set when ->resume()_noirq, ->thaw_noirq(), or + * ->restore_noirq() is about to be called. + * + * DPM_OFF_IRQ Device is in a "deep sleep". Set immediately after + * ->suspend_noirq(), ->freeze_noirq(), or + * ->poweroff_noirq() has just succeeded. + */ + +enum dpm_state { + DPM_INVALID, + DPM_ON, + DPM_PREPARING, + DPM_RESUMING, + DPM_SUSPENDING, + DPM_OFF, + DPM_OFF_IRQ, +}; + /** * Device run-time power management status. * @@ -424,8 +463,8 @@ struct wakeup_source; struct dev_pm_info { pm_message_t power_state; unsigned int can_wakeup:1; - unsigned int async_suspend:1; - unsigned int in_suspend:1; /* Owned by the PM core */ + unsigned async_suspend:1; + enum dpm_state status; /* Owned by the PM core */ spinlock_t lock; #ifdef CONFIG_PM_SLEEP struct list_head entry; @@ -447,7 +486,6 @@ struct dev_pm_info { unsigned int run_wake:1; unsigned int runtime_auto:1; unsigned int no_callbacks:1; - unsigned int irq_safe:1; unsigned int use_autosuspend:1; unsigned int timer_autosuspends:1; enum rpm_request request; @@ -572,11 +610,4 @@ extern unsigned int pm_flags; #define PM_APM 1 #define PM_ACPI 2 -extern int pm_generic_suspend(struct device *dev); -extern int pm_generic_resume(struct device *dev); -extern int pm_generic_freeze(struct device *dev); -extern int pm_generic_thaw(struct device *dev); -extern int pm_generic_restore(struct device *dev); -extern int pm_generic_poweroff(struct device *dev); - #endif /* _LINUX_PM_H */ diff --git a/trunk/include/linux/pm_runtime.h b/trunk/include/linux/pm_runtime.h index d34f067e2a7f..d19f1cca7f74 100644 --- a/trunk/include/linux/pm_runtime.h +++ b/trunk/include/linux/pm_runtime.h @@ -40,7 +40,6 @@ extern int pm_generic_runtime_idle(struct device *dev); extern int pm_generic_runtime_suspend(struct device *dev); extern int pm_generic_runtime_resume(struct device *dev); extern void pm_runtime_no_callbacks(struct device *dev); -extern void pm_runtime_irq_safe(struct device *dev); extern void __pm_runtime_use_autosuspend(struct device *dev, bool use); extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay); extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev); @@ -82,11 +81,6 @@ static inline bool pm_runtime_suspended(struct device *dev) && !dev->power.disable_depth; } -static inline bool pm_runtime_enabled(struct device *dev) -{ - return !dev->power.disable_depth; -} - static inline void pm_runtime_mark_last_busy(struct device *dev) { ACCESS_ONCE(dev->power.last_busy) = jiffies; @@ -125,13 +119,11 @@ static inline void pm_runtime_put_noidle(struct device *dev) {} static inline bool device_run_wake(struct device *dev) { return false; } static inline void device_set_run_wake(struct device *dev, bool enable) {} static inline bool pm_runtime_suspended(struct device *dev) { return false; } -static inline bool pm_runtime_enabled(struct device *dev) { return false; } static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } static inline void pm_runtime_no_callbacks(struct device *dev) {} -static inline void pm_runtime_irq_safe(struct device *dev) {} static inline void pm_runtime_mark_last_busy(struct device *dev) {} static inline void __pm_runtime_use_autosuspend(struct device *dev, @@ -204,11 +196,6 @@ static inline int pm_runtime_put_sync(struct device *dev) return __pm_runtime_idle(dev, RPM_GET_PUT); } -static inline int pm_runtime_put_sync_suspend(struct device *dev) -{ - return __pm_runtime_suspend(dev, RPM_GET_PUT); -} - static inline int pm_runtime_put_sync_autosuspend(struct device *dev) { return __pm_runtime_suspend(dev, RPM_GET_PUT | RPM_AUTO); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index abc527aa8550..341acbbc434a 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -70,6 +70,7 @@ struct sched_param { #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ struct sched_param { #include #include #include +#include #include #include diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index c642bb8b8f5a..1ac42475ea08 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -1058,7 +1058,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @cred points to the credentials to provide the context against which to * evaluate the security data on the key. * @perm describes the combination of permissions required of this key. - * Return 0 if permission is granted, -ve error otherwise. + * Return 1 if permission granted, 0 if permission denied and -ve it the + * normal permissions model should be effected. * @key_getsecurity: * Get a textual representation of the security context attached to a key * for the purposes of honouring KEYCTL_GETSECURITY. This function diff --git a/trunk/include/linux/slab_def.h b/trunk/include/linux/slab_def.h index 83203ae9390b..791a502f6906 100644 --- a/trunk/include/linux/slab_def.h +++ b/trunk/include/linux/slab_def.h @@ -138,12 +138,11 @@ void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_trace(size_t size, - struct kmem_cache *cachep, gfp_t flags); +extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags); extern size_t slab_buffer_size(struct kmem_cache *cachep); #else static __always_inline void * -kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags) +kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) { return kmem_cache_alloc(cachep, flags); } @@ -180,7 +179,10 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) #endif cachep = malloc_sizes[i].cs_cachep; - ret = kmem_cache_alloc_trace(size, cachep, flags); + ret = kmem_cache_alloc_notrace(cachep, flags); + + trace_kmalloc(_THIS_IP_, ret, + size, slab_buffer_size(cachep), flags); return ret; } @@ -192,16 +194,14 @@ extern void *__kmalloc_node(size_t size, gfp_t flags, int node); extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_trace(size_t size, - struct kmem_cache *cachep, - gfp_t flags, - int nodeid); +extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, + gfp_t flags, + int nodeid); #else static __always_inline void * -kmem_cache_alloc_node_trace(size_t size, - struct kmem_cache *cachep, - gfp_t flags, - int nodeid) +kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, + gfp_t flags, + int nodeid) { return kmem_cache_alloc_node(cachep, flags, nodeid); } @@ -210,6 +210,7 @@ kmem_cache_alloc_node_trace(size_t size, static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { struct kmem_cache *cachep; + void *ret; if (__builtin_constant_p(size)) { int i = 0; @@ -233,7 +234,13 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) #endif cachep = malloc_sizes[i].cs_cachep; - return kmem_cache_alloc_node_trace(size, cachep, flags, node); + ret = kmem_cache_alloc_node_notrace(cachep, flags, node); + + trace_kmalloc_node(_THIS_IP_, ret, + size, slab_buffer_size(cachep), + flags, node); + + return ret; } return __kmalloc_node(size, flags, node); } diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index 8b6e8ae5d5ca..e4f5ed180b9b 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -10,9 +10,10 @@ #include #include #include - #include +#include + enum stat_item { ALLOC_FASTPATH, /* Allocation from cpu slab */ ALLOC_SLOWPATH, /* Allocation by getting a new cpu slab */ @@ -215,40 +216,31 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -static __always_inline void * -kmalloc_order(size_t size, gfp_t flags, unsigned int order) -{ - void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); - kmemleak_alloc(ret, size, 1, flags); - return ret; -} - #ifdef CONFIG_TRACING -extern void * -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size); -extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order); +extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags); #else static __always_inline void * -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) +kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) { return kmem_cache_alloc(s, gfpflags); } - -static __always_inline void * -kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) -{ - return kmalloc_order(size, flags, order); -} #endif static __always_inline void *kmalloc_large(size_t size, gfp_t flags) { unsigned int order = get_order(size); - return kmalloc_order_trace(size, flags, order); + void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); + + kmemleak_alloc(ret, size, 1, flags); + trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags); + + return ret; } static __always_inline void *kmalloc(size_t size, gfp_t flags) { + void *ret; + if (__builtin_constant_p(size)) { if (size > SLUB_MAX_SIZE) return kmalloc_large(size, flags); @@ -259,7 +251,11 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) if (!s) return ZERO_SIZE_PTR; - return kmem_cache_alloc_trace(s, flags, size); + ret = kmem_cache_alloc_notrace(s, flags); + + trace_kmalloc(_THIS_IP_, ret, size, s->size, flags); + + return ret; } } return __kmalloc(size, flags); @@ -270,14 +266,14 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node); void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, +extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, - int node, size_t size); + int node); #else static __always_inline void * -kmem_cache_alloc_node_trace(struct kmem_cache *s, +kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, - int node, size_t size) + int node) { return kmem_cache_alloc_node(s, gfpflags, node); } @@ -285,6 +281,8 @@ kmem_cache_alloc_node_trace(struct kmem_cache *s, static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { + void *ret; + if (__builtin_constant_p(size) && size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) { struct kmem_cache *s = kmalloc_slab(size); @@ -292,7 +290,12 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) if (!s) return ZERO_SIZE_PTR; - return kmem_cache_alloc_node_trace(s, flags, node, size); + ret = kmem_cache_alloc_node_notrace(s, flags, node); + + trace_kmalloc_node(_THIS_IP_, ret, + size, s->size, flags, node); + + return ret; } return __kmalloc_node(size, flags, node); } diff --git a/trunk/include/linux/sunrpc/cache.h b/trunk/include/linux/sunrpc/cache.h index 78aa104250b7..6950c981882d 100644 --- a/trunk/include/linux/sunrpc/cache.h +++ b/trunk/include/linux/sunrpc/cache.h @@ -13,7 +13,6 @@ #ifndef _LINUX_SUNRPC_CACHE_H_ #define _LINUX_SUNRPC_CACHE_H_ -#include #include #include #include diff --git a/trunk/include/linux/suspend.h b/trunk/include/linux/suspend.h index 144b34be5c32..26697514c5ec 100644 --- a/trunk/include/linux/suspend.h +++ b/trunk/include/linux/suspend.h @@ -292,7 +292,7 @@ extern int unregister_pm_notifier(struct notifier_block *nb); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; -extern bool pm_wakeup_pending(void); +extern bool pm_check_wakeup_events(void); extern bool pm_get_wakeup_count(unsigned int *count); extern bool pm_save_wakeup_count(unsigned int count); #else /* !CONFIG_PM_SLEEP */ @@ -309,7 +309,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) -static inline bool pm_wakeup_pending(void) { return false; } +static inline bool pm_check_wakeup_events(void) { return true; } #endif /* !CONFIG_PM_SLEEP */ extern struct mutex pm_mutex; diff --git a/trunk/include/linux/tpm.h b/trunk/include/linux/tpm.h index fdc718abf83b..ac5d1c1285d9 100644 --- a/trunk/include/linux/tpm.h +++ b/trunk/include/linux/tpm.h @@ -31,7 +31,6 @@ extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); -extern int tpm_send(u32 chip_num, void *cmd, size_t buflen); #else static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { return -ENODEV; @@ -39,8 +38,5 @@ static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { return -ENODEV; } -static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) { - return -ENODEV; -} #endif #endif diff --git a/trunk/include/linux/tpm_command.h b/trunk/include/linux/tpm_command.h deleted file mode 100644 index 727512e249b5..000000000000 --- a/trunk/include/linux/tpm_command.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __LINUX_TPM_COMMAND_H__ -#define __LINUX_TPM_COMMAND_H__ - -/* - * TPM Command constants from specifications at - * http://www.trustedcomputinggroup.org - */ - -/* Command TAGS */ -#define TPM_TAG_RQU_COMMAND 193 -#define TPM_TAG_RQU_AUTH1_COMMAND 194 -#define TPM_TAG_RQU_AUTH2_COMMAND 195 -#define TPM_TAG_RSP_COMMAND 196 -#define TPM_TAG_RSP_AUTH1_COMMAND 197 -#define TPM_TAG_RSP_AUTH2_COMMAND 198 - -/* Command Ordinals */ -#define TPM_ORD_GETRANDOM 70 -#define TPM_ORD_OSAP 11 -#define TPM_ORD_OIAP 10 -#define TPM_ORD_SEAL 23 -#define TPM_ORD_UNSEAL 24 - -/* Other constants */ -#define SRKHANDLE 0x40000000 -#define TPM_NONCE_SIZE 20 - -#endif diff --git a/trunk/include/linux/xattr.h b/trunk/include/linux/xattr.h index e6131ef98d8f..f1e5bde4b35a 100644 --- a/trunk/include/linux/xattr.h +++ b/trunk/include/linux/xattr.h @@ -40,13 +40,9 @@ #define XATTR_SMACK_SUFFIX "SMACK64" #define XATTR_SMACK_IPIN "SMACK64IPIN" #define XATTR_SMACK_IPOUT "SMACK64IPOUT" -#define XATTR_SMACK_EXEC "SMACK64EXEC" -#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE" #define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX #define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT -#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC -#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE #define XATTR_CAPS_SUFFIX "capability" #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 33e0a39cf359..0b5ff083fa22 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -121,7 +121,7 @@ $(obj)/configs.o: $(obj)/config_data.h # config_data.h contains the same information as ikconfig.h but gzipped. # Info from config_data can be extracted from /proc/config* targets += config_data.gz -$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE +$(obj)/config_data.gz: .config FORCE $(call if_changed,gzip) quiet_cmd_ikconfiggz = IKCFG $@ diff --git a/trunk/kernel/freezer.c b/trunk/kernel/freezer.c index 66ecd2ead215..bd1d42b17cb2 100644 --- a/trunk/kernel/freezer.c +++ b/trunk/kernel/freezer.c @@ -104,13 +104,8 @@ bool freeze_task(struct task_struct *p, bool sig_only) } if (should_send_signal(p)) { - fake_signal_wake_up(p); - /* - * fake_signal_wake_up() goes through p's scheduler - * lock and guarantees that TASK_STOPPED/TRACED -> - * TASK_RUNNING transition can't race with task state - * testing in try_to_freeze_tasks(). - */ + if (!signal_pending(p)) + fake_signal_wake_up(p); } else if (sig_only) { return false; } else { diff --git a/trunk/kernel/power/Makefile b/trunk/kernel/power/Makefile index b75597235d85..f9063c6b185d 100644 --- a/trunk/kernel/power/Makefile +++ b/trunk/kernel/power/Makefile @@ -1,4 +1,7 @@ -ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG + +ifeq ($(CONFIG_PM_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o diff --git a/trunk/kernel/power/hibernate.c b/trunk/kernel/power/hibernate.c index 870f72bc72ae..048d0b514831 100644 --- a/trunk/kernel/power/hibernate.c +++ b/trunk/kernel/power/hibernate.c @@ -62,7 +62,7 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops) { if (ops && !(ops->begin && ops->end && ops->pre_snapshot && ops->prepare && ops->finish && ops->enter && ops->pre_restore - && ops->restore_cleanup && ops->leave)) { + && ops->restore_cleanup)) { WARN_ON(1); return; } @@ -278,7 +278,7 @@ static int create_image(int platform_mode) goto Enable_irqs; } - if (hibernation_test(TEST_CORE) || pm_wakeup_pending()) + if (hibernation_test(TEST_CORE) || !pm_check_wakeup_events()) goto Power_up; in_suspend = 1; @@ -516,7 +516,7 @@ int hibernation_platform_enter(void) local_irq_disable(); sysdev_suspend(PMSG_HIBERNATE); - if (pm_wakeup_pending()) { + if (!pm_check_wakeup_events()) { error = -EAGAIN; goto Power_up; } @@ -647,7 +647,6 @@ int hibernate(void) swsusp_free(); if (!error) power_down(); - in_suspend = 0; pm_restore_gfp_mask(); } else { pr_debug("PM: Image restored successfully.\n"); diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index d6d2a10320e0..e50b4c1b2a0f 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -64,12 +64,6 @@ static int try_to_freeze_tasks(bool sig_only) * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. - * - * Because freeze_task() goes through p's - * scheduler lock after setting TIF_FREEZE, it's - * guaranteed that either we see TASK_RUNNING or - * try_to_stop() after schedule() in ptrace/signal - * stop sees TIF_FREEZE. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) @@ -85,7 +79,7 @@ static int try_to_freeze_tasks(bool sig_only) if (!todo || time_after(jiffies, end_time)) break; - if (pm_wakeup_pending()) { + if (!pm_check_wakeup_events()) { wakeup = true; break; } diff --git a/trunk/kernel/power/suspend.c b/trunk/kernel/power/suspend.c index 8850df68794d..031d5e3a6197 100644 --- a/trunk/kernel/power/suspend.c +++ b/trunk/kernel/power/suspend.c @@ -164,7 +164,7 @@ static int suspend_enter(suspend_state_t state) error = sysdev_suspend(PMSG_SUSPEND); if (!error) { - if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { + if (!suspend_test(TEST_CORE) && pm_check_wakeup_events()) { error = suspend_ops->enter(state); events_check_enabled = false; } diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index f64b8997fc76..4642a5c439eb 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -273,12 +273,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) * at open time. */ if (type == SYSLOG_ACTION_OPEN || !from_file) { - if (dmesg_restrict && !capable(CAP_SYSLOG)) - goto warn; /* switch to return -EPERM after 2.6.39 */ + if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) + return -EPERM; if ((type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER) && - !capable(CAP_SYSLOG)) - goto warn; /* switch to return -EPERM after 2.6.39 */ + !capable(CAP_SYS_ADMIN)) + return -EPERM; } error = security_syslog(type); @@ -422,12 +422,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) } out: return error; -warn: - /* remove after 2.6.39 */ - if (capable(CAP_SYS_ADMIN)) - WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " - "but no CAP_SYSLOG (deprecated and denied).\n"); - return -EPERM; } SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) diff --git a/trunk/lib/hexdump.c b/trunk/lib/hexdump.c index b66b2bd67952..5d7a4802c562 100644 --- a/trunk/lib/hexdump.c +++ b/trunk/lib/hexdump.c @@ -33,22 +33,6 @@ int hex_to_bin(char ch) } EXPORT_SYMBOL(hex_to_bin); -/** - * hex2bin - convert an ascii hexadecimal string to its binary representation - * @dst: binary result - * @src: ascii hexadecimal string - * @count: result length - */ -void hex2bin(u8 *dst, const char *src, size_t count) -{ - while (count--) { - *dst = hex_to_bin(*src++) << 4; - *dst += hex_to_bin(*src++); - dst++; - } -} -EXPORT_SYMBOL(hex2bin); - /** * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory * @buf: data blob to dump diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 264037449f08..e9f92987954a 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -3653,18 +3653,11 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) EXPORT_SYMBOL(kmem_cache_alloc); #ifdef CONFIG_TRACING -void * -kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags) +void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) { - void *ret; - - ret = __cache_alloc(cachep, flags, __builtin_return_address(0)); - - trace_kmalloc(_RET_IP_, ret, - size, slab_buffer_size(cachep), flags); - return ret; + return __cache_alloc(cachep, flags, __builtin_return_address(0)); } -EXPORT_SYMBOL(kmem_cache_alloc_trace); +EXPORT_SYMBOL(kmem_cache_alloc_notrace); #endif #ifdef CONFIG_NUMA @@ -3682,32 +3675,31 @@ void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) EXPORT_SYMBOL(kmem_cache_alloc_node); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_node_trace(size_t size, - struct kmem_cache *cachep, - gfp_t flags, - int nodeid) +void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, + gfp_t flags, + int nodeid) { - void *ret; - - ret = __cache_alloc_node(cachep, flags, nodeid, + return __cache_alloc_node(cachep, flags, nodeid, __builtin_return_address(0)); - trace_kmalloc_node(_RET_IP_, ret, - size, slab_buffer_size(cachep), - flags, nodeid); - return ret; } -EXPORT_SYMBOL(kmem_cache_alloc_node_trace); +EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); #endif static __always_inline void * __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) { struct kmem_cache *cachep; + void *ret; cachep = kmem_find_general_cachep(size, flags); if (unlikely(ZERO_OR_NULL_PTR(cachep))) return cachep; - return kmem_cache_alloc_node_trace(size, cachep, flags, node); + ret = kmem_cache_alloc_node_notrace(cachep, flags, node); + + trace_kmalloc_node((unsigned long) caller, ret, + size, cachep->buffer_size, flags, node); + + return ret; } #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING) diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 008cd743a36a..a2fe1727ed85 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -28,8 +28,6 @@ #include #include -#include - /* * Lock order: * 1. slab_lock(page) @@ -1776,21 +1774,11 @@ void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) EXPORT_SYMBOL(kmem_cache_alloc); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) -{ - void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_); - trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags); - return ret; -} -EXPORT_SYMBOL(kmem_cache_alloc_trace); - -void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) +void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) { - void *ret = kmalloc_order(size, flags, order); - trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << order, flags); - return ret; + return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_); } -EXPORT_SYMBOL(kmalloc_order_trace); +EXPORT_SYMBOL(kmem_cache_alloc_notrace); #endif #ifdef CONFIG_NUMA @@ -1806,17 +1794,13 @@ void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) EXPORT_SYMBOL(kmem_cache_alloc_node); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_node_trace(struct kmem_cache *s, +void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, - int node, size_t size) + int node) { - void *ret = slab_alloc(s, gfpflags, node, _RET_IP_); - - trace_kmalloc_node(_RET_IP_, ret, - size, s->size, gfpflags, node); - return ret; + return slab_alloc(s, gfpflags, node, _RET_IP_); } -EXPORT_SYMBOL(kmem_cache_alloc_node_trace); +EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); #endif #endif diff --git a/trunk/scripts/.gitignore b/trunk/scripts/.gitignore index e2741d23bab8..c5d5db54c009 100644 --- a/trunk/scripts/.gitignore +++ b/trunk/scripts/.gitignore @@ -7,4 +7,3 @@ pnmtologo bin2c unifdef ihex2fw -recordmcount diff --git a/trunk/scripts/Makefile.lib b/trunk/scripts/Makefile.lib index 396da16aabf8..4c72c1189479 100644 --- a/trunk/scripts/Makefile.lib +++ b/trunk/scripts/Makefile.lib @@ -200,29 +200,6 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ (rm -f $@ ; false) -# DTC -# --------------------------------------------------------------------------- - -# Generate an assembly file to wrap the output of the device tree compiler -quiet_cmd_dt_S_dtb= DTB $@ -cmd_dt_S_dtb= \ -( \ - echo '\#include '; \ - echo '.section .dtb.init.rodata,"a"'; \ - echo '.balign STRUCT_ALIGNMENT'; \ - echo '.global __dtb_$(*F)_begin'; \ - echo '__dtb_$(*F)_begin:'; \ - echo '.incbin "$<" '; \ - echo '__dtb_$(*F)_end:'; \ - echo '.global __dtb_$(*F)_end'; \ - echo '.balign STRUCT_ALIGNMENT'; \ -) > $@ - -$(obj)/%.dtb.S: $(obj)/%.dtb - $(call cmd,dt_S_dtb) - -quiet_cmd_dtc = DTC $@ -cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $< # Bzip2 # --------------------------------------------------------------------------- diff --git a/trunk/scripts/basic/fixdep.c b/trunk/scripts/basic/fixdep.c index c9a16abacab4..ea26b23de082 100644 --- a/trunk/scripts/basic/fixdep.c +++ b/trunk/scripts/basic/fixdep.c @@ -138,36 +138,38 @@ static void print_cmdline(void) printf("cmd_%s := %s\n\n", target, cmdline); } -struct item { - struct item *next; - unsigned int len; - unsigned int hash; - char name[0]; -}; +char * str_config = NULL; +int size_config = 0; +int len_config = 0; -#define HASHSZ 256 -static struct item *hashtab[HASHSZ]; - -static unsigned int strhash(const char *str, unsigned int sz) +/* + * Grow the configuration string to a desired length. + * Usually the first growth is plenty. + */ +static void grow_config(int len) { - /* fnv32 hash */ - unsigned int i, hash = 2166136261U; - - for (i = 0; i < sz; i++) - hash = (hash ^ str[i]) * 0x01000193; - return hash; + while (len_config + len > size_config) { + if (size_config == 0) + size_config = 2048; + str_config = realloc(str_config, size_config *= 2); + if (str_config == NULL) + { perror("fixdep:malloc"); exit(1); } + } } + + /* * Lookup a value in the configuration string. */ -static int is_defined_config(const char *name, int len, unsigned int hash) +static int is_defined_config(const char * name, int len) { - struct item *aux; - - for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { - if (aux->hash == hash && aux->len == len && - memcmp(aux->name, name, len) == 0) + const char * pconfig; + const char * plast = str_config + len_config - len; + for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { + if (pconfig[ -1] == '\n' + && pconfig[len] == '\n' + && !memcmp(pconfig, name, len)) return 1; } return 0; @@ -176,19 +178,13 @@ static int is_defined_config(const char *name, int len, unsigned int hash) /* * Add a new value to the configuration string. */ -static void define_config(const char *name, int len, unsigned int hash) +static void define_config(const char * name, int len) { - struct item *aux = malloc(sizeof(*aux) + len); + grow_config(len + 1); - if (!aux) { - perror("fixdep:malloc"); - exit(1); - } - memcpy(aux->name, name, len); - aux->len = len; - aux->hash = hash; - aux->next = hashtab[hash % HASHSZ]; - hashtab[hash % HASHSZ] = aux; + memcpy(str_config+len_config, name, len); + len_config += len; + str_config[len_config++] = '\n'; } /* @@ -196,49 +192,40 @@ static void define_config(const char *name, int len, unsigned int hash) */ static void clear_config(void) { - struct item *aux, *next; - unsigned int i; - - for (i = 0; i < HASHSZ; i++) { - for (aux = hashtab[i]; aux; aux = next) { - next = aux->next; - free(aux); - } - hashtab[i] = NULL; - } + len_config = 0; + define_config("", 0); } /* * Record the use of a CONFIG_* word. */ -static void use_config(const char *m, int slen) +static void use_config(char *m, int slen) { - unsigned int hash = strhash(m, slen); - int c, i; + char s[PATH_MAX]; + char *p; - if (is_defined_config(m, slen, hash)) + if (is_defined_config(m, slen)) return; - define_config(m, slen, hash); + define_config(m, slen); - printf(" $(wildcard include/config/"); - for (i = 0; i < slen; i++) { - c = m[i]; - if (c == '_') - c = '/'; + memcpy(s, m, slen); s[slen] = 0; + + for (p = s; p < s + slen; p++) { + if (*p == '_') + *p = '/'; else - c = tolower(c); - putchar(c); + *p = tolower((int)*p); } - printf(".h) \\\n"); + printf(" $(wildcard include/config/%s.h) \\\n", s); } -static void parse_config_file(const char *map, size_t len) +static void parse_config_file(char *map, size_t len) { - const int *end = (const int *) (map + len); + int *end = (int *) (map + len); /* start at +1, so that p can never be < map */ - const int *m = (const int *) map + 1; - const char *p, *q; + int *m = (int *) map + 1; + char *p, *q; for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } @@ -278,7 +265,7 @@ static int strrcmp(char *s, char *sub) return memcmp(s + slen - sublen, sub, sublen); } -static void do_config_file(const char *filename) +static void do_config_file(char *filename) { struct stat st; int fd; @@ -286,7 +273,7 @@ static void do_config_file(const char *filename) fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: error opening config file: "); + fprintf(stderr, "fixdep: "); perror(filename); exit(2); } @@ -357,15 +344,11 @@ static void print_deps(void) fd = open(depfile, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: error opening depfile: "); + fprintf(stderr, "fixdep: "); perror(depfile); exit(2); } - if (fstat(fd, &st) < 0) { - fprintf(stderr, "fixdep: error fstat'ing depfile: "); - perror(depfile); - exit(2); - } + fstat(fd, &st); if (st.st_size == 0) { fprintf(stderr,"fixdep: %s is empty\n",depfile); close(fd); diff --git a/trunk/scripts/checksyscalls.sh b/trunk/scripts/checksyscalls.sh index 3ab316e52313..6bb42e72e0e5 100755 --- a/trunk/scripts/checksyscalls.sh +++ b/trunk/scripts/checksyscalls.sh @@ -6,7 +6,7 @@ # and listed below so they are ignored. # # Usage: -# checksyscalls.sh gcc gcc-options +# syscallchk gcc gcc-options # ignore_list() { @@ -204,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ \#endif/p' $1 } -(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ +(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ $* -E -x c - > /dev/null diff --git a/trunk/scripts/coccinelle/misc/doubleinit.cocci b/trunk/scripts/coccinelle/misc/doubleinit.cocci index 156b20adb351..55d7dc19dfe0 100644 --- a/trunk/scripts/coccinelle/misc/doubleinit.cocci +++ b/trunk/scripts/coccinelle/misc/doubleinit.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ -// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise +// Comments: // Options: -no_includes -include_headers virtual org @@ -19,7 +19,7 @@ position p0,p; expression E; @@ -struct I s =@p0 { ..., .fld@p = E, ...}; +struct I s =@p0 { ... .fld@p = E, ...}; @s@ identifier I, s, r.fld; @@ -27,7 +27,7 @@ position r.p0,p; expression E; @@ -struct I s =@p0 { ..., .fld@p = E, ...}; +struct I s =@p0 { ... .fld@p = E, ...}; @script:python depends on org@ p0 << r.p0; diff --git a/trunk/scripts/coccinelle/null/deref_null.cocci b/trunk/scripts/coccinelle/null/deref_null.cocci index cdac6cfcce92..9969d76d0f4b 100644 --- a/trunk/scripts/coccinelle/null/deref_null.cocci +++ b/trunk/scripts/coccinelle/null/deref_null.cocci @@ -11,10 +11,21 @@ // Options: virtual context +virtual patch virtual org virtual report -@ifm@ +@initialize:python depends on !context && patch && !org && !report@ + +import sys +print >> sys.stderr, "This semantic patch does not support the 'patch' mode." + +@depends on patch@ +@@ + +this_rule_should_never_matches(); + +@ifm depends on !patch@ expression *E; statement S1,S2; position p1; @@ -24,7 +35,7 @@ if@p1 ((E == NULL && ...) || ...) S1 else S2 // The following two rules are separate, because both can match a single // expression in different ways -@pr1 expression@ +@pr1 depends on !patch expression@ expression *ifm.E; identifier f; position p1; @@ -32,7 +43,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr2 expression@ +@pr2 depends on !patch expression@ expression *ifm.E; identifier f; position p2; @@ -48,7 +59,7 @@ position p2; // For org and report modes -@r depends on !context && (org || report) exists@ +@r depends on !context && !patch && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -88,7 +99,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !org && report@ +@script:python depends on !context && !patch && !org && report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -98,7 +109,7 @@ msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) cocci.include_match(False) -@script:python depends on !context && org && !report@ +@script:python depends on !context && !patch && org && !report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -109,7 +120,7 @@ msg_safe=msg.replace("[","@(").replace("]",")") cocci.print_main(msg_safe,p) cocci.include_match(False) -@s depends on !context && (org || report) exists@ +@s depends on !context && !patch && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -148,7 +159,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !org && report@ +@script:python depends on !context && !patch && !org && report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -157,7 +168,7 @@ x << ifm.E; msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) -@script:python depends on !context && org && !report@ +@script:python depends on !context && !patch && org && !report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -169,7 +180,7 @@ cocci.print_main(msg_safe,p) // For context mode -@depends on context && !org && !report exists@ +@depends on context && !patch && !org && !report exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -212,7 +223,7 @@ else S3 // The following three rules are duplicates of ifm, pr1 and pr2 respectively. // It is need because the previous rule as already made a "change". -@ifm1@ +@ifm1 depends on !patch@ expression *E; statement S1,S2; position p1; @@ -220,7 +231,7 @@ position p1; if@p1 ((E == NULL && ...) || ...) S1 else S2 -@pr11 expression@ +@pr11 depends on !patch expression@ expression *ifm1.E; identifier f; position p1; @@ -228,7 +239,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr12 expression@ +@pr12 depends on !patch expression@ expression *ifm1.E; identifier f; position p2; @@ -242,7 +253,7 @@ position p2; sizeof(<+...E->f@p2...+>) ) -@depends on context && !org && !report exists@ +@depends on context && !patch && !org && !report exists@ expression subE <= ifm1.E; expression *ifm1.E; expression E1,E2; diff --git a/trunk/scripts/config b/trunk/scripts/config index a7c7c4b8e957..608d7fdb13e8 100755 --- a/trunk/scripts/config +++ b/trunk/scripts/config @@ -10,10 +10,8 @@ commands: --enable|-e option Enable option --disable|-d option Disable option --module|-m option Turn option into a module - --set-str option string - Set option to "string" - --set-val option value - Set option to value + --set-str option value + Set option to "value" --state|-s option Print state of option (n,y,m,undef) --enable-after|-E beforeopt option @@ -88,7 +86,7 @@ while [ "$1" != "" ] ; do B=$ARG shift 2 ;; - -*) + --*) checkarg "$1" shift ;; @@ -111,11 +109,6 @@ while [ "$1" != "" ] ; do shift ;; - --set-val) - set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" - shift - ;; - --state|-s) if grep -q "# CONFIG_$ARG is not set" $FN ; then echo n diff --git a/trunk/scripts/dtc/Makefile b/trunk/scripts/dtc/Makefile index 04a31c17639f..01cdb36fc583 100644 --- a/trunk/scripts/dtc/Makefile +++ b/trunk/scripts/dtc/Makefile @@ -4,7 +4,7 @@ hostprogs-y := dtc always := $(hostprogs-y) dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ - srcpos.o checks.o util.o + srcpos.o checks.o dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o # Source files need to get at the userspace version of libfdt_env.h to compile @@ -19,7 +19,6 @@ HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC) -HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) diff --git a/trunk/scripts/dtc/checks.c b/trunk/scripts/dtc/checks.c index a662a0044798..95485796f253 100644 --- a/trunk/scripts/dtc/checks.c +++ b/trunk/scripts/dtc/checks.c @@ -278,112 +278,32 @@ static void check_property_name_chars(struct check *c, struct node *dt, } PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); -#define DESCLABEL_FMT "%s%s%s%s%s" -#define DESCLABEL_ARGS(node,prop,mark) \ - ((mark) ? "value of " : ""), \ - ((prop) ? "'" : ""), \ - ((prop) ? (prop)->name : ""), \ - ((prop) ? "' in " : ""), (node)->fullpath - -static void check_duplicate_label(struct check *c, struct node *dt, - const char *label, struct node *node, - struct property *prop, struct marker *mark) -{ - struct node *othernode = NULL; - struct property *otherprop = NULL; - struct marker *othermark = NULL; - - othernode = get_node_by_label(dt, label); - - if (!othernode) - otherprop = get_property_by_label(dt, label, &othernode); - if (!othernode) - othermark = get_marker_label(dt, label, &othernode, - &otherprop); - - if (!othernode) - return; - - if ((othernode != node) || (otherprop != prop) || (othermark != mark)) - FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT - " and " DESCLABEL_FMT, - label, DESCLABEL_ARGS(node, prop, mark), - DESCLABEL_ARGS(othernode, otherprop, othermark)); -} - -static void check_duplicate_label_node(struct check *c, struct node *dt, - struct node *node) -{ - struct label *l; - - for_each_label(node->labels, l) - check_duplicate_label(c, dt, l->label, node, NULL, NULL); -} -static void check_duplicate_label_prop(struct check *c, struct node *dt, - struct node *node, struct property *prop) -{ - struct marker *m = prop->val.markers; - struct label *l; - - for_each_label(prop->labels, l) - check_duplicate_label(c, dt, l->label, node, prop, NULL); - - for_each_marker_of_type(m, LABEL) - check_duplicate_label(c, dt, m->ref, node, prop, m); -} -CHECK(duplicate_label, NULL, check_duplicate_label_node, - check_duplicate_label_prop, NULL, ERROR); - static void check_explicit_phandles(struct check *c, struct node *root, - struct node *node, struct property *prop) + struct node *node) { - struct marker *m; + struct property *prop; struct node *other; cell_t phandle; - if (!streq(prop->name, "phandle") - && !streq(prop->name, "linux,phandle")) - return; + prop = get_property(node, "linux,phandle"); + if (! prop) + return; /* No phandle, that's fine */ if (prop->val.len != sizeof(cell_t)) { - FAIL(c, "%s has bad length (%d) %s property", - node->fullpath, prop->val.len, prop->name); - return; - } - - m = prop->val.markers; - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset == 0); - if (node != get_node_by_ref(root, m->ref)) - /* "Set this node's phandle equal to some - * other node's phandle". That's nonsensical - * by construction. */ { - FAIL(c, "%s in %s is a reference to another node", - prop->name, node->fullpath); - return; - } - /* But setting this node's phandle equal to its own - * phandle is allowed - that means allocate a unique - * phandle for this node, even if it's not otherwise - * referenced. The value will be filled in later, so - * no further checking for now. */ + FAIL(c, "%s has bad length (%d) linux,phandle property", + node->fullpath, prop->val.len); return; } phandle = propval_cell(prop); - if ((phandle == 0) || (phandle == -1)) { - FAIL(c, "%s has bad value (0x%x) in %s property", - node->fullpath, phandle, prop->name); + FAIL(c, "%s has invalid linux,phandle value 0x%x", + node->fullpath, phandle); return; } - if (node->phandle && (node->phandle != phandle)) - FAIL(c, "%s has %s property which replaces existing phandle information", - node->fullpath, prop->name); - other = get_node_by_phandle(root, phandle); - if (other && (other != node)) { + if (other) { FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", node->fullpath, phandle, other->fullpath); return; @@ -391,7 +311,7 @@ static void check_explicit_phandles(struct check *c, struct node *root, node->phandle = phandle; } -PROP_CHECK(explicit_phandles, NULL, ERROR); +NODE_CHECK(explicit_phandles, NULL, ERROR); static void check_name_properties(struct check *c, struct node *root, struct node *node) @@ -629,9 +549,6 @@ static struct check *check_table[] = { &duplicate_node_names, &duplicate_property_names, &node_name_chars, &node_name_format, &property_name_chars, &name_is_string, &name_properties, - - &duplicate_label, - &explicit_phandles, &phandle_references, &path_references, diff --git a/trunk/scripts/dtc/dtc-lexer.l b/trunk/scripts/dtc/dtc-lexer.l index e866ea5166ac..a627bbee91d4 100644 --- a/trunk/scripts/dtc/dtc-lexer.l +++ b/trunk/scripts/dtc/dtc-lexer.l @@ -18,7 +18,7 @@ * USA */ -%option noyywrap nounput noinput never-interactive +%option noyywrap noinput nounput yylineno %x INCLUDE %x BYTESTRING @@ -38,13 +38,6 @@ LINECOMMENT "//".*\n #include "srcpos.h" #include "dtc-parser.tab.h" -YYLTYPE yylloc; - -/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ -#define YY_USER_ACTION \ - { \ - srcpos_update(&yylloc, yytext, yyleng); \ - } /*#define LEXDEBUG 1*/ @@ -54,10 +47,15 @@ YYLTYPE yylloc; #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version = 1; +static int dts_version; /* = 0 */ -#define BEGIN_DEFAULT() DPRINT("\n"); \ +#define BEGIN_DEFAULT() if (dts_version == 0) { \ + DPRINT("\n"); \ + BEGIN(INITIAL); \ + } else { \ + DPRINT("\n"); \ BEGIN(V1); \ + } static void push_input_file(const char *filename); static int pop_input_file(void); @@ -77,13 +75,18 @@ static int pop_input_file(void); } <*>{STRING} { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, yyleng-2); + yylloc.first_line = yylineno; return DT_STRING; } <*>"/dts-v1/" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; BEGIN_DEFAULT(); @@ -91,57 +94,106 @@ static int pop_input_file(void); } <*>"/memreserve/" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; } <*>{LABEL}: { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); + yylval.labelref = strdup(yytext); yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } +[bodh]# { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + if (*yytext == 'b') + yylval.cbase = 2; + else if (*yytext == 'o') + yylval.cbase = 8; + else if (*yytext == 'd') + yylval.cbase = 10; + else + yylval.cbase = 16; + DPRINT("Base: %d\n", yylval.cbase); + return DT_BASE; + } + +[0-9a-fA-F]+ { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + yylval.literal = strdup(yytext); + DPRINT("Literal: '%s'\n", yylval.literal); + return DT_LEGACYLITERAL; + } + [0-9]+|0[xX][0-9a-fA-F]+ { - yylval.literal = xstrdup(yytext); + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } -<*>\&{LABEL} { /* label reference */ +\&{LABEL} { /* label reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); + yylval.labelref = strdup(yytext+1); return DT_REF; } -<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ +"&{/"{PATHCHAR}+\} { /* new-style path reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); + yylval.labelref = strdup(yytext+2); + return DT_REF; + } + +"&/"{PATHCHAR}+ { /* old-style path reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = strdup(yytext+1); return DT_REF; } [0-9a-fA-F]{2} { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } "]" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } {PROPNODECHAR}+ { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup(yytext); + yylval.propnodename = strdup(yytext); BEGIN_DEFAULT(); return DT_PROPNODENAME; } "/incbin/" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Binary Include\n"); return DT_INCBIN; } @@ -151,6 +203,8 @@ static int pop_input_file(void); <*>{LINECOMMENT}+ /* eat C++-style comments */ <*>. { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); if (yytext[0] == '[') { @@ -167,25 +221,100 @@ static int pop_input_file(void); %% + +/* + * Stack of nested include file contexts. + */ + +struct incl_file { + struct dtc_file *file; + YY_BUFFER_STATE yy_prev_buf; + int yy_prev_lineno; + struct incl_file *prev; +}; + +static struct incl_file *incl_file_stack; + + +/* + * Detect infinite include recursion. + */ +#define MAX_INCLUDE_DEPTH (100) + +static int incl_depth = 0; + + static void push_input_file(const char *filename) { + struct incl_file *incl_file; + struct dtc_file *newfile; + struct search_path search, *searchptr = NULL; + assert(filename); - srcfile_push(filename); + if (incl_depth++ >= MAX_INCLUDE_DEPTH) + die("Includes nested too deeply"); + + if (srcpos_file) { + search.dir = srcpos_file->dir; + search.next = NULL; + search.prev = NULL; + searchptr = &search; + } + + newfile = dtc_open_file(filename, searchptr); - yyin = current_srcfile->f; + incl_file = xmalloc(sizeof(struct incl_file)); - yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); + /* + * Save current context. + */ + incl_file->yy_prev_buf = YY_CURRENT_BUFFER; + incl_file->yy_prev_lineno = yylineno; + incl_file->file = srcpos_file; + incl_file->prev = incl_file_stack; + + incl_file_stack = incl_file; + + /* + * Establish new context. + */ + srcpos_file = newfile; + yylineno = 1; + yyin = newfile->file; + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); } static int pop_input_file(void) { - if (srcfile_pop() == 0) + struct incl_file *incl_file; + + if (incl_file_stack == 0) return 0; - yypop_buffer_state(); - yyin = current_srcfile->f; + dtc_close_file(srcpos_file); + + /* + * Pop. + */ + --incl_depth; + incl_file = incl_file_stack; + incl_file_stack = incl_file->prev; + + /* + * Recover old context. + */ + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(incl_file->yy_prev_buf); + yylineno = incl_file->yy_prev_lineno; + srcpos_file = incl_file->file; + yyin = incl_file->file ? incl_file->file->file : NULL; + + /* + * Free old state. + */ + free(incl_file); return 1; } diff --git a/trunk/scripts/dtc/dtc-lexer.lex.c_shipped b/trunk/scripts/dtc/dtc-lexer.lex.c_shipped index 50c4420b4b2c..e27cc636e326 100644 --- a/trunk/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/trunk/scripts/dtc/dtc-lexer.lex.c_shipped @@ -170,7 +170,20 @@ extern FILE *yyin, *yyout; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - #define YY_LESS_LINENO(n) + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -372,8 +385,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 20 +#define YY_END_OF_BUFFER 21 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -381,19 +394,20 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[94] = +static yyconst flex_int16_t yy_accept[104] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 16, 13, 13, 16, 16, 16, 16, 16, 16, - 16, 10, 11, 11, 6, 6, 13, 0, 2, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 5, 0, - 9, 9, 11, 11, 6, 0, 7, 0, 0, 0, - 0, 15, 0, 0, 0, 0, 6, 0, 14, 0, - 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, + 21, 19, 16, 16, 19, 19, 19, 7, 7, 19, + 7, 19, 19, 19, 19, 13, 14, 14, 19, 8, + 8, 16, 0, 2, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 7, 7, 5, 0, 6, 0, 12, + 12, 14, 14, 8, 0, 11, 9, 0, 0, 0, + 0, 18, 0, 0, 0, 0, 8, 0, 17, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 4, 0 + 0, 4, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -402,16 +416,16 @@ static yyconst flex_int32_t yy_ec[256] = 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 4, 5, 1, 1, 6, 1, 1, - 1, 7, 5, 5, 8, 5, 9, 10, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 1, 1, - 1, 1, 5, 5, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, - 1, 17, 18, 1, 15, 1, 14, 19, 20, 21, - - 22, 14, 15, 15, 23, 15, 15, 24, 25, 26, - 15, 15, 15, 27, 28, 29, 30, 31, 15, 16, - 15, 15, 32, 1, 33, 1, 1, 1, 1, 1, + 1, 7, 8, 8, 9, 8, 10, 11, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 14, 1, 1, + 1, 1, 8, 8, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, + 1, 18, 19, 1, 16, 1, 15, 20, 21, 22, + + 23, 15, 16, 24, 25, 16, 16, 26, 27, 28, + 24, 16, 16, 29, 30, 31, 32, 33, 16, 17, + 16, 16, 34, 1, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -428,114 +442,136 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[34] = +static yyconst flex_int32_t yy_meta[36] = { 0, - 1, 1, 1, 1, 2, 1, 2, 2, 3, 4, - 4, 4, 5, 6, 7, 7, 1, 1, 6, 6, - 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 8, 1 + 1, 1, 1, 1, 2, 1, 2, 2, 2, 3, + 4, 4, 4, 5, 6, 7, 7, 1, 1, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 1 } ; -static yyconst flex_int16_t yy_base[106] = +static yyconst flex_int16_t yy_base[117] = { 0, - 0, 0, 237, 236, 25, 0, 47, 0, 30, 71, - 244, 247, 82, 84, 84, 211, 95, 229, 218, 0, - 111, 247, 0, 84, 83, 95, 106, 86, 247, 237, - 0, 230, 231, 234, 207, 209, 212, 220, 247, 206, - 247, 218, 0, 106, 116, 0, 0, 0, 223, 89, - 226, 219, 199, 206, 200, 204, 0, 190, 213, 212, - 202, 91, 178, 161, 247, 172, 144, 150, 140, 130, - 140, 124, 128, 120, 138, 137, 123, 122, 247, 247, - 134, 114, 132, 86, 135, 125, 90, 136, 247, 97, - 29, 247, 247, 153, 156, 161, 165, 170, 176, 180, - - 187, 195, 200, 205, 212 + 0, 0, 30, 0, 44, 0, 67, 0, 97, 105, + 302, 303, 35, 44, 40, 94, 112, 0, 129, 152, + 296, 295, 159, 0, 176, 303, 0, 116, 95, 165, + 49, 46, 102, 303, 296, 0, 0, 288, 290, 293, + 264, 266, 270, 0, 0, 303, 0, 303, 264, 303, + 0, 0, 195, 101, 0, 0, 0, 0, 284, 125, + 277, 265, 225, 230, 216, 218, 0, 202, 224, 221, + 217, 107, 196, 188, 303, 206, 179, 186, 178, 185, + 183, 162, 161, 150, 169, 160, 145, 125, 303, 303, + 137, 109, 190, 103, 203, 167, 108, 197, 303, 123, + + 29, 303, 303, 215, 221, 226, 229, 234, 240, 246, + 250, 257, 265, 270, 275, 282 } ; -static yyconst flex_int16_t yy_def[106] = +static yyconst flex_int16_t yy_def[117] = { 0, - 93, 1, 1, 1, 1, 5, 93, 7, 1, 1, - 93, 93, 93, 93, 94, 95, 93, 96, 17, 97, - 96, 93, 98, 99, 93, 93, 93, 94, 93, 94, - 100, 93, 101, 102, 93, 93, 93, 96, 93, 93, - 93, 96, 98, 99, 93, 103, 100, 104, 101, 101, - 102, 93, 93, 93, 93, 93, 103, 104, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 105, 93, 105, 93, 105, - 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93 + 103, 1, 1, 3, 3, 5, 103, 7, 3, 3, + 103, 103, 103, 103, 104, 105, 103, 106, 103, 19, + 19, 20, 103, 107, 20, 103, 108, 109, 105, 103, + 103, 103, 104, 103, 104, 110, 111, 103, 112, 113, + 103, 103, 103, 106, 19, 103, 20, 103, 103, 103, + 20, 108, 109, 103, 114, 110, 111, 115, 112, 112, + 113, 103, 103, 103, 103, 103, 114, 115, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 116, 103, 116, 103, 116, + + 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103 } ; -static yyconst flex_int16_t yy_nxt[281] = +static yyconst flex_int16_t yy_nxt[339] = { 0, - 12, 13, 14, 15, 12, 16, 12, 12, 17, 12, - 12, 12, 12, 18, 18, 18, 12, 12, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 12, 12, 19, 20, 20, 20, 92, 21, 25, - 26, 26, 22, 21, 21, 21, 21, 12, 13, 14, - 15, 23, 16, 23, 23, 19, 23, 23, 23, 12, - 24, 24, 24, 12, 12, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 12, 12, - 25, 26, 26, 27, 27, 27, 27, 29, 43, 29, - 43, 43, 45, 45, 45, 50, 39, 59, 46, 93, - - 30, 33, 30, 34, 45, 45, 45, 27, 27, 68, - 43, 91, 43, 43, 69, 35, 87, 36, 39, 37, - 42, 42, 42, 39, 42, 45, 45, 45, 89, 42, - 42, 42, 42, 85, 85, 86, 85, 85, 86, 89, - 84, 90, 83, 82, 81, 80, 79, 78, 77, 76, - 75, 74, 90, 28, 28, 28, 28, 28, 28, 28, - 28, 31, 31, 31, 38, 38, 38, 38, 41, 73, - 41, 43, 72, 43, 71, 43, 43, 44, 33, 44, - 44, 44, 44, 47, 69, 47, 47, 49, 49, 49, - 49, 49, 49, 49, 49, 51, 51, 51, 51, 51, - - 51, 51, 51, 57, 70, 57, 58, 58, 58, 67, - 58, 58, 88, 88, 88, 88, 88, 88, 88, 88, - 34, 66, 65, 64, 63, 62, 61, 60, 52, 50, - 39, 56, 39, 55, 54, 53, 52, 50, 48, 93, - 40, 39, 32, 93, 19, 19, 11, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 + 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, + 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, + 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 12, 12, 12, 32, 32, 102, 23, + 12, 12, 12, 34, 20, 32, 32, 32, 32, 20, + 20, 20, 20, 20, 24, 24, 24, 35, 25, 54, + 54, 54, 26, 25, 25, 25, 25, 12, 13, 14, + 15, 27, 12, 27, 27, 27, 23, 27, 27, 27, + 12, 28, 28, 28, 12, 12, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + + 12, 12, 29, 36, 103, 34, 17, 30, 31, 31, + 29, 54, 54, 54, 17, 30, 31, 31, 39, 35, + 52, 40, 52, 52, 52, 103, 78, 38, 38, 46, + 101, 60, 79, 41, 69, 97, 42, 94, 43, 45, + 45, 45, 46, 45, 47, 47, 93, 92, 45, 45, + 45, 45, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 39, 47, 91, 40, 90, + 99, 47, 47, 47, 47, 54, 54, 54, 89, 88, + 41, 55, 87, 49, 100, 43, 51, 51, 51, 86, + 51, 95, 95, 96, 85, 51, 51, 51, 51, 52, + + 99, 52, 52, 52, 95, 95, 96, 84, 46, 83, + 82, 81, 39, 79, 100, 33, 33, 33, 33, 33, + 33, 33, 33, 37, 80, 77, 37, 37, 37, 44, + 40, 44, 50, 76, 50, 52, 75, 52, 74, 52, + 52, 53, 73, 53, 53, 53, 53, 56, 56, 56, + 72, 56, 56, 57, 71, 57, 57, 59, 59, 59, + 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, + 61, 61, 61, 67, 70, 67, 68, 68, 68, 62, + 68, 68, 98, 98, 98, 98, 98, 98, 98, 98, + 60, 66, 65, 64, 63, 62, 60, 58, 103, 48, + + 48, 103, 11, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103 } ; -static yyconst flex_int16_t yy_chk[281] = +static yyconst flex_int16_t yy_chk[339] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 5, 5, 5, 5, 91, 5, 9, - 9, 9, 5, 5, 5, 5, 5, 7, 7, 7, + 1, 1, 1, 1, 1, 3, 13, 13, 101, 3, + 3, 3, 3, 15, 3, 14, 14, 32, 32, 3, + 3, 3, 3, 3, 5, 5, 5, 15, 5, 31, + 31, 31, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 10, 10, 10, 13, 13, 14, 14, 15, 24, 28, - 24, 24, 25, 25, 25, 50, 24, 50, 25, 90, - - 15, 17, 28, 17, 26, 26, 26, 27, 27, 62, - 44, 87, 44, 44, 62, 17, 84, 17, 44, 17, - 21, 21, 21, 21, 21, 45, 45, 45, 86, 21, - 21, 21, 21, 83, 83, 83, 85, 85, 85, 88, - 82, 86, 81, 78, 77, 76, 75, 74, 73, 72, - 71, 70, 88, 94, 94, 94, 94, 94, 94, 94, - 94, 95, 95, 95, 96, 96, 96, 96, 97, 69, - 97, 98, 68, 98, 67, 98, 98, 99, 66, 99, - 99, 99, 99, 100, 64, 100, 100, 101, 101, 101, - 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, - - 102, 102, 102, 103, 63, 103, 104, 104, 104, 61, - 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, - 60, 59, 58, 56, 55, 54, 53, 52, 51, 49, - 42, 40, 38, 37, 36, 35, 34, 33, 32, 30, - 19, 18, 16, 11, 4, 3, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 + + 7, 7, 9, 16, 29, 33, 9, 9, 9, 9, + 10, 54, 54, 54, 10, 10, 10, 10, 17, 33, + 28, 17, 28, 28, 28, 100, 72, 16, 29, 28, + 97, 60, 72, 17, 60, 94, 17, 92, 17, 19, + 19, 19, 19, 19, 19, 19, 91, 88, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 20, 20, 20, 23, 20, 87, 23, 86, + 96, 20, 20, 20, 20, 30, 30, 30, 85, 84, + 23, 30, 83, 23, 96, 23, 25, 25, 25, 82, + 25, 93, 93, 93, 81, 25, 25, 25, 25, 53, + + 98, 53, 53, 53, 95, 95, 95, 80, 53, 79, + 78, 77, 76, 74, 98, 104, 104, 104, 104, 104, + 104, 104, 104, 105, 73, 71, 105, 105, 105, 106, + 70, 106, 107, 69, 107, 108, 68, 108, 66, 108, + 108, 109, 65, 109, 109, 109, 109, 110, 110, 110, + 64, 110, 110, 111, 63, 111, 111, 112, 112, 112, + 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, + 113, 113, 113, 114, 62, 114, 115, 115, 115, 61, + 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, + 59, 49, 43, 42, 41, 40, 39, 38, 35, 22, + + 21, 11, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103 } ; +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[21] = + { 0, +1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, }; + static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -580,13 +616,6 @@ char *yytext; #include "srcpos.h" #include "dtc-parser.tab.h" -YYLTYPE yylloc; - -/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ -#define YY_USER_ACTION \ - { \ - srcpos_update(&yylloc, yytext, yyleng); \ - } /*#define LEXDEBUG 1*/ @@ -596,14 +625,19 @@ YYLTYPE yylloc; #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version = 1; +static int dts_version; /* = 0 */ -#define BEGIN_DEFAULT() DPRINT("\n"); \ +#define BEGIN_DEFAULT() if (dts_version == 0) { \ + DPRINT("\n"); \ + BEGIN(INITIAL); \ + } else { \ + DPRINT("\n"); \ BEGIN(V1); \ + } static void push_input_file(const char *filename); static int pop_input_file(void); -#line 607 "dtc-lexer.lex.c" +#line 641 "dtc-lexer.lex.c" #define INITIAL 0 #define INCLUDE 1 @@ -792,9 +826,9 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 66 "dtc-lexer.l" +#line 64 "dtc-lexer.l" -#line 798 "dtc-lexer.lex.c" +#line 832 "dtc-lexer.lex.c" if ( !(yy_init) ) { @@ -847,21 +881,35 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 94 ) + if ( yy_current_state >= 104 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 93 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); + while ( yy_base[yy_current_state] != 303 ); yy_find_action: yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } YY_DO_BEFORE_ACTION; + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) @@ -876,7 +924,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: /* rule 1 can match eol */ YY_RULE_SETUP -#line 67 "dtc-lexer.l" +#line 65 "dtc-lexer.l" { char *name = strchr(yytext, '\"') + 1; yytext[yyleng-1] = '\0'; @@ -888,7 +936,7 @@ case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(BYTESTRING): case YY_STATE_EOF(PROPNODENAME): case YY_STATE_EOF(V1): -#line 73 "dtc-lexer.l" +#line 71 "dtc-lexer.l" { if (!pop_input_file()) { yyterminate(); @@ -898,18 +946,23 @@ case YY_STATE_EOF(V1): case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 79 "dtc-lexer.l" +#line 77 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, yyleng-2); + yylloc.first_line = yylineno; return DT_STRING; } YY_BREAK case 3: YY_RULE_SETUP -#line 86 "dtc-lexer.l" +#line 87 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; BEGIN_DEFAULT(); @@ -918,8 +971,10 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 93 "dtc-lexer.l" +#line 96 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; @@ -927,100 +982,158 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 99 "dtc-lexer.l" +#line 104 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); + yylval.labelref = strdup(yytext); yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } YY_BREAK case 6: YY_RULE_SETUP -#line 106 "dtc-lexer.l" +#line 113 "dtc-lexer.l" +{ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + if (*yytext == 'b') + yylval.cbase = 2; + else if (*yytext == 'o') + yylval.cbase = 8; + else if (*yytext == 'd') + yylval.cbase = 10; + else + yylval.cbase = 16; + DPRINT("Base: %d\n", yylval.cbase); + return DT_BASE; + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 128 "dtc-lexer.l" { - yylval.literal = xstrdup(yytext); + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + yylval.literal = strdup(yytext); + DPRINT("Literal: '%s'\n", yylval.literal); + return DT_LEGACYLITERAL; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 136 "dtc-lexer.l" +{ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } YY_BREAK -case 7: +case 9: YY_RULE_SETUP -#line 112 "dtc-lexer.l" +#line 144 "dtc-lexer.l" { /* label reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); + yylval.labelref = strdup(yytext+1); return DT_REF; } YY_BREAK -case 8: +case 10: YY_RULE_SETUP -#line 118 "dtc-lexer.l" +#line 152 "dtc-lexer.l" { /* new-style path reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); + yylval.labelref = strdup(yytext+2); return DT_REF; } YY_BREAK -case 9: +case 11: +YY_RULE_SETUP +#line 161 "dtc-lexer.l" +{ /* old-style path reference */ + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = strdup(yytext+1); + return DT_REF; + } + YY_BREAK +case 12: YY_RULE_SETUP -#line 125 "dtc-lexer.l" +#line 169 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } YY_BREAK -case 10: +case 13: YY_RULE_SETUP -#line 131 "dtc-lexer.l" +#line 177 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } YY_BREAK -case 11: +case 14: YY_RULE_SETUP -#line 137 "dtc-lexer.l" +#line 185 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup(yytext); + yylval.propnodename = strdup(yytext); BEGIN_DEFAULT(); return DT_PROPNODENAME; } YY_BREAK -case 12: +case 15: YY_RULE_SETUP -#line 144 "dtc-lexer.l" +#line 194 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Binary Include\n"); return DT_INCBIN; } YY_BREAK -case 13: -/* rule 13 can match eol */ +case 16: +/* rule 16 can match eol */ YY_RULE_SETUP -#line 149 "dtc-lexer.l" +#line 201 "dtc-lexer.l" /* eat whitespace */ YY_BREAK -case 14: -/* rule 14 can match eol */ +case 17: +/* rule 17 can match eol */ YY_RULE_SETUP -#line 150 "dtc-lexer.l" +#line 202 "dtc-lexer.l" /* eat C-style comments */ YY_BREAK -case 15: -/* rule 15 can match eol */ +case 18: +/* rule 18 can match eol */ YY_RULE_SETUP -#line 151 "dtc-lexer.l" +#line 203 "dtc-lexer.l" /* eat C++-style comments */ YY_BREAK -case 16: +case 19: YY_RULE_SETUP -#line 153 "dtc-lexer.l" +#line 205 "dtc-lexer.l" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); if (yytext[0] == '[') { @@ -1035,12 +1148,12 @@ YY_RULE_SETUP return yytext[0]; } YY_BREAK -case 17: +case 20: YY_RULE_SETUP -#line 168 "dtc-lexer.l" +#line 222 "dtc-lexer.l" ECHO; YY_BREAK -#line 1044 "dtc-lexer.lex.c" +#line 1157 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { @@ -1105,8 +1218,7 @@ ECHO; else { - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); + yy_cp = (yy_c_buf_p); goto yy_find_action; } } @@ -1331,7 +1443,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 94 ) + if ( yy_current_state >= 104 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1359,11 +1471,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 94 ) + if ( yy_current_state >= 104 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 93); + yy_is_jam = (yy_current_state == 103); return yy_is_jam ? 0 : yy_current_state; } @@ -1438,6 +1550,11 @@ static int yy_get_next_buffer (void) *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); + if ( c == '\n' ) + + yylineno++; +; + return c; } #endif /* ifndef YY_NO_INPUT */ @@ -1552,6 +1669,10 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. @@ -1575,7 +1696,7 @@ static void yy_load_buffer_state (void) b->yy_bs_column = 0; } - b->yy_is_interactive = 0; + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } @@ -1904,6 +2025,9 @@ static int yy_init_globals (void) * This function is called from yylex_destroy(), so don't allocate here. */ + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; @@ -1996,29 +2120,104 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 168 "dtc-lexer.l" +#line 222 "dtc-lexer.l" + + + + +/* + * Stack of nested include file contexts. + */ + +struct incl_file { + struct dtc_file *file; + YY_BUFFER_STATE yy_prev_buf; + int yy_prev_lineno; + struct incl_file *prev; +}; + +static struct incl_file *incl_file_stack; +/* + * Detect infinite include recursion. + */ +#define MAX_INCLUDE_DEPTH (100) + +static int incl_depth = 0; + static void push_input_file(const char *filename) { + struct incl_file *incl_file; + struct dtc_file *newfile; + struct search_path search, *searchptr = NULL; + assert(filename); - srcfile_push(filename); + if (incl_depth++ >= MAX_INCLUDE_DEPTH) + die("Includes nested too deeply"); + + if (srcpos_file) { + search.dir = srcpos_file->dir; + search.next = NULL; + search.prev = NULL; + searchptr = &search; + } + + newfile = dtc_open_file(filename, searchptr); - yyin = current_srcfile->f; + incl_file = xmalloc(sizeof(struct incl_file)); - yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); + /* + * Save current context. + */ + incl_file->yy_prev_buf = YY_CURRENT_BUFFER; + incl_file->yy_prev_lineno = yylineno; + incl_file->file = srcpos_file; + incl_file->prev = incl_file_stack; + + incl_file_stack = incl_file; + + /* + * Establish new context. + */ + srcpos_file = newfile; + yylineno = 1; + yyin = newfile->file; + yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); } static int pop_input_file(void) { - if (srcfile_pop() == 0) + struct incl_file *incl_file; + + if (incl_file_stack == 0) return 0; - yypop_buffer_state(); - yyin = current_srcfile->f; + dtc_close_file(srcpos_file); + + /* + * Pop. + */ + --incl_depth; + incl_file = incl_file_stack; + incl_file_stack = incl_file->prev; + + /* + * Recover old context. + */ + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(incl_file->yy_prev_buf); + yylineno = incl_file->yy_prev_lineno; + srcpos_file = incl_file->file; + yyin = incl_file->file ? incl_file->file->file : NULL; + + /* + * Free old state. + */ + free(incl_file); return 1; } diff --git a/trunk/scripts/dtc/dtc-parser.tab.c_shipped b/trunk/scripts/dtc/dtc-parser.tab.c_shipped index 9be2eea18a30..27129377e5d2 100644 --- a/trunk/scripts/dtc/dtc-parser.tab.c_shipped +++ b/trunk/scripts/dtc/dtc-parser.tab.c_shipped @@ -1,23 +1,24 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify + + 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 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, or (at your option) + any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -28,7 +29,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -46,7 +47,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1" +#define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -54,32 +55,55 @@ /* Pure parsers. */ #define YYPURE 0 -/* Push parsers. */ -#define YYPUSH 0 +/* Using locations. */ +#define YYLSP_NEEDED 1 -/* Pull parsers. */ -#define YYPULL 1 -/* Using locations. */ -#define YYLSP_NEEDED 0 + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DT_V1 = 258, + DT_MEMRESERVE = 259, + DT_PROPNODENAME = 260, + DT_LITERAL = 261, + DT_LEGACYLITERAL = 262, + DT_BASE = 263, + DT_BYTE = 264, + DT_STRING = 265, + DT_LABEL = 266, + DT_REF = 267, + DT_INCBIN = 268 + }; +#endif +/* Tokens. */ +#define DT_V1 258 +#define DT_MEMRESERVE 259 +#define DT_PROPNODENAME 260 +#define DT_LITERAL 261 +#define DT_LEGACYLITERAL 262 +#define DT_BASE 263 +#define DT_BYTE 264 +#define DT_STRING 265 +#define DT_LABEL 266 +#define DT_REF 267 +#define DT_INCBIN 268 -/* Copy the first part of user declarations. */ -/* Line 189 of yacc.c */ -#line 21 "dtc-parser.y" +/* Copy the first part of user declarations. */ +#line 23 "dtc-parser.y" #include #include "dtc.h" #include "srcpos.h" -YYLTYPE yylloc; - extern int yylex(void); -extern void print_error(char const *fmt, ...); -extern void yyerror(char const *s); extern struct boot_info *the_boot_info; extern int treesource_error; @@ -87,9 +111,6 @@ extern int treesource_error; static unsigned long long eval_literal(const char *s, int base, int bits); -/* Line 189 of yacc.c */ -#line 92 "dtc-parser.tab.c" - /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -108,35 +129,10 @@ static unsigned long long eval_literal(const char *s, int base, int bits); # define YYTOKEN_TABLE 0 #endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - DT_V1 = 258, - DT_MEMRESERVE = 259, - DT_PROPNODENAME = 260, - DT_LITERAL = 261, - DT_BASE = 262, - DT_BYTE = 263, - DT_STRING = 264, - DT_LABEL = 265, - DT_REF = 266, - DT_INCBIN = 267 - }; -#endif - - - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE +#line 37 "dtc-parser.y" { - -/* Line 214 of yacc.c */ -#line 39 "dtc-parser.y" - char *propnodename; char *literal; char *labelref; @@ -151,23 +147,34 @@ typedef union YYSTYPE struct node *node; struct node *nodelist; struct reserve_info *re; - - - -/* Line 214 of yacc.c */ -#line 159 "dtc-parser.tab.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 187 of yacc.c. */ +#line 153 "dtc-parser.tab.c" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ -/* Line 264 of yacc.c */ -#line 171 "dtc-parser.tab.c" +/* Line 216 of yacc.c. */ +#line 178 "dtc-parser.tab.c" #ifdef short # undef short @@ -242,14 +249,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int yyi) +YYID (int i) #else static int -YYID (yyi) - int yyi; +YYID (i) + int i; #endif { - return yyi; + return i; } #endif @@ -325,13 +332,15 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; + yytype_int16 yyss; + YYSTYPE yyvs; + YYLTYPE yyls; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -340,8 +349,8 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ @@ -366,12 +375,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +# define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -380,22 +389,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 4 +#define YYFINAL 9 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 56 +#define YYLAST 73 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 25 +#define YYNTOKENS 27 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 16 +#define YYNNTS 20 /* YYNRULES -- Number of rules. */ -#define YYNRULES 39 +#define YYNRULES 45 /* YYNRULES -- Number of states. */ -#define YYNSTATES 67 +#define YYNSTATES 76 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 267 +#define YYMAXUTOK 268 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -407,15 +416,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 22, 24, 2, 2, 23, 2, 2, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, - 18, 17, 19, 2, 2, 2, 2, 2, 2, 2, + 24, 26, 2, 2, 25, 15, 2, 16, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, + 20, 19, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 20, 2, 21, 2, 2, 2, 2, 2, 2, + 2, 22, 2, 23, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 15, 2, 16, 2, 2, 2, 2, + 2, 2, 2, 17, 2, 18, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -429,7 +438,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12 + 5, 6, 7, 8, 9, 10, 11, 12, 13 }; #if YYDEBUG @@ -437,37 +446,41 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 8, 9, 12, 17, 20, 22, 25, - 29, 33, 39, 40, 43, 48, 51, 54, 57, 62, - 67, 70, 80, 86, 89, 90, 93, 96, 97, 100, - 103, 106, 108, 109, 112, 115, 116, 119, 122, 125 + 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, + 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, + 64, 69, 74, 77, 87, 93, 96, 97, 100, 103, + 104, 107, 110, 113, 114, 116, 118, 121, 122, 125, + 128, 129, 132, 135, 139, 140 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 26, 0, -1, 3, 13, 27, 30, -1, -1, 28, - 27, -1, 4, 29, 29, 13, -1, 10, 28, -1, - 6, -1, 14, 31, -1, 30, 14, 31, -1, 30, - 11, 31, -1, 15, 32, 39, 16, 13, -1, -1, - 32, 33, -1, 5, 17, 34, 13, -1, 5, 13, - -1, 10, 33, -1, 35, 9, -1, 35, 18, 36, - 19, -1, 35, 20, 38, 21, -1, 35, 11, -1, - 35, 12, 22, 9, 23, 29, 23, 29, 24, -1, - 35, 12, 22, 9, 24, -1, 34, 10, -1, -1, - 34, 23, -1, 35, 10, -1, -1, 36, 37, -1, - 36, 11, -1, 36, 10, -1, 6, -1, -1, 38, - 8, -1, 38, 10, -1, -1, 40, 39, -1, 40, - 33, -1, 5, 31, -1, 10, 40, -1 + 28, 0, -1, 3, 14, 29, 34, -1, 31, 34, + -1, -1, 30, 29, -1, 46, 4, 33, 33, 14, + -1, -1, 32, 31, -1, 30, -1, 46, 4, 33, + 15, 33, 14, -1, 6, -1, 7, -1, 16, 35, + -1, 17, 36, 44, 18, 14, -1, -1, 36, 37, + -1, 46, 5, 19, 38, 14, -1, 46, 5, 14, + -1, 39, 10, -1, 39, 20, 40, 21, -1, 39, + 22, 43, 23, -1, 39, 12, -1, 39, 13, 24, + 10, 25, 33, 25, 33, 26, -1, 39, 13, 24, + 10, 26, -1, 38, 11, -1, -1, 38, 25, -1, + 39, 11, -1, -1, 40, 42, -1, 40, 12, -1, + 40, 11, -1, -1, 8, -1, 6, -1, 41, 7, + -1, -1, 43, 9, -1, 43, 11, -1, -1, 45, + 44, -1, 45, 37, -1, 46, 5, 35, -1, -1, + 11, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 86, 86, 95, 98, 105, 109, 117, 124, 128, - 132, 145, 153, 156, 163, 167, 171, 179, 183, 187, - 191, 195, 212, 222, 230, 233, 237, 245, 248, 252, - 257, 264, 272, 275, 279, 287, 290, 294, 302, 306 + 0, 89, 89, 93, 101, 104, 111, 119, 122, 129, + 133, 140, 144, 151, 158, 166, 169, 176, 180, 187, + 191, 195, 199, 203, 220, 231, 239, 242, 246, 254, + 257, 261, 266, 274, 277, 281, 285, 293, 296, 300, + 308, 311, 315, 323, 331, 334 }; #endif @@ -477,12 +490,13 @@ static const yytype_uint16 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", - "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", - "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", - "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile", - "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist", - "propdef", "propdata", "propdataprefix", "celllist", "cellval", - "bytestring", "subnodes", "subnode", 0 + "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", + "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'", + "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','", + "')'", "$accept", "sourcefile", "memreserves", "memreserve", + "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef", + "proplist", "propdef", "propdata", "propdataprefix", "celllist", + "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0 }; #endif @@ -492,27 +506,29 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 59, 47, 123, 125, 61, 60, 62, - 91, 93, 40, 44, 41 + 265, 266, 267, 268, 59, 45, 47, 123, 125, 61, + 60, 62, 91, 93, 40, 44, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 25, 26, 27, 27, 28, 28, 29, 30, 30, - 30, 31, 32, 32, 33, 33, 33, 34, 34, 34, - 34, 34, 34, 34, 35, 35, 35, 36, 36, 36, - 36, 37, 38, 38, 38, 39, 39, 39, 40, 40 + 0, 27, 28, 28, 29, 29, 30, 31, 31, 32, + 32, 33, 33, 34, 35, 36, 36, 37, 37, 38, + 38, 38, 38, 38, 38, 38, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 42, 42, 43, 43, 43, + 44, 44, 44, 45, 46, 46 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 4, 0, 2, 4, 2, 1, 2, 3, - 3, 5, 0, 2, 4, 2, 2, 2, 4, 4, - 2, 9, 5, 2, 0, 2, 2, 0, 2, 2, - 2, 1, 0, 2, 2, 0, 2, 2, 2, 2 + 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, + 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, + 4, 4, 2, 9, 5, 2, 0, 2, 2, 0, + 2, 2, 2, 0, 1, 1, 2, 0, 2, 2, + 0, 2, 2, 3, 0, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -520,79 +536,86 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 3, 1, 0, 0, 0, 3, 7, - 0, 6, 0, 2, 4, 0, 12, 8, 0, 0, - 5, 35, 10, 9, 0, 0, 13, 0, 35, 15, - 24, 38, 16, 39, 0, 37, 36, 0, 0, 11, - 23, 14, 25, 17, 26, 20, 0, 27, 32, 0, - 0, 0, 0, 31, 30, 29, 18, 28, 33, 34, - 19, 0, 22, 0, 0, 0, 21 + 7, 0, 45, 0, 9, 0, 7, 0, 4, 1, + 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, + 12, 0, 2, 5, 0, 40, 0, 0, 0, 16, + 0, 40, 0, 0, 6, 0, 42, 41, 0, 10, + 14, 18, 26, 43, 0, 0, 25, 17, 27, 19, + 28, 22, 0, 29, 37, 0, 33, 0, 0, 35, + 34, 32, 31, 20, 0, 30, 38, 39, 21, 0, + 24, 36, 0, 0, 0, 23 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 2, 7, 8, 10, 13, 17, 21, 26, 37, - 38, 50, 57, 51, 27, 28 + -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, + 29, 44, 45, 56, 64, 65, 57, 30, 31, 7 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -12 +#define YYPACT_NINF -14 static const yytype_int8 yypact[] = { - 10, -11, 18, -1, -12, 22, -1, 15, -1, -12, - 22, -12, 20, 1, -12, 17, -12, -12, 20, 20, - -12, 6, -12, -12, 21, 6, -12, 23, 6, -12, - -12, -12, -12, -12, 28, -12, -12, -6, 13, -12, - -12, -12, -12, -12, -12, -12, 24, -12, -12, 33, - -5, 0, -4, -12, -12, -12, -12, -12, -12, -12, - -12, 22, -12, 25, 22, 19, -12 + 30, -11, -14, 7, -14, -1, 27, 13, 27, -14, + 8, -14, -14, 40, -1, 27, 35, -14, -14, -14, + -14, 21, -14, -14, 40, 24, 40, 28, 40, -14, + 32, 24, 46, 38, -14, 39, -14, -14, 26, -14, + -14, -14, -14, -14, -9, 10, -14, -14, -14, -14, + -14, -14, 31, -14, -14, 44, -2, 3, 23, -14, + -14, -14, -14, -14, 50, -14, -14, -14, -14, 40, + -14, -14, 33, 40, 36, -14 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -12, -12, 36, 39, -10, -12, 8, -12, 12, -12, - -12, -12, -12, -12, 27, 31 + -14, -14, 48, 29, 53, -14, -13, 47, 34, -14, + 37, -14, -14, -14, -14, -14, -14, 42, -14, -7 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = +#define YYTABLE_NINF -45 +static const yytype_int8 yytable[] = { - 15, 53, 3, 5, 40, 54, 55, 41, 58, 6, - 59, 24, 18, 1, 56, 19, 25, 42, 4, 61, - 62, 60, 43, 44, 45, 46, 22, 23, 9, 12, - 20, 47, 31, 48, 29, 16, 16, 32, 30, 34, - 35, 39, 52, 66, 14, 11, 49, 0, 64, 0, - 0, 63, 0, 0, 65, 36, 33 + 21, 16, 46, 8, 59, 47, 60, 9, 16, 61, + 62, 28, 66, 33, 67, 10, 48, 13, 32, 63, + 49, 50, 51, 52, 32, 17, 68, 19, 20, -44, + 53, -44, 54, 1, -44, 2, 26, 15, 2, 24, + 41, 2, 34, 17, 15, 42, 19, 20, 69, 70, + 35, 38, 39, 40, 58, 55, 72, 71, 73, 12, + 74, 22, 75, 23, 0, 0, 0, 0, 36, 0, + 0, 0, 43, 37 }; static const yytype_int8 yycheck[] = { - 10, 6, 13, 4, 10, 10, 11, 13, 8, 10, - 10, 5, 11, 3, 19, 14, 10, 23, 0, 23, - 24, 21, 9, 10, 11, 12, 18, 19, 6, 14, - 13, 18, 24, 20, 13, 15, 15, 25, 17, 16, - 28, 13, 9, 24, 8, 6, 22, -1, 23, -1, - -1, 61, -1, -1, 64, 28, 25 + 13, 8, 11, 14, 6, 14, 8, 0, 15, 11, + 12, 24, 9, 26, 11, 16, 25, 4, 25, 21, + 10, 11, 12, 13, 31, 17, 23, 6, 7, 5, + 20, 4, 22, 3, 4, 11, 15, 8, 11, 4, + 14, 11, 14, 17, 15, 19, 6, 7, 25, 26, + 18, 5, 14, 14, 10, 24, 69, 7, 25, 6, + 73, 14, 26, 15, -1, -1, -1, -1, 31, -1, + -1, -1, 38, 31 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 26, 13, 0, 4, 10, 27, 28, 6, - 29, 28, 14, 30, 27, 29, 15, 31, 11, 14, - 13, 32, 31, 31, 5, 10, 33, 39, 40, 13, - 17, 31, 33, 40, 16, 33, 39, 34, 35, 13, - 10, 13, 23, 9, 10, 11, 12, 18, 20, 22, - 36, 38, 9, 6, 10, 11, 19, 37, 8, 10, - 21, 23, 24, 29, 23, 29, 24 + 0, 3, 11, 28, 30, 31, 32, 46, 14, 0, + 16, 34, 31, 4, 29, 30, 46, 17, 35, 6, + 7, 33, 34, 29, 4, 36, 15, 33, 33, 37, + 44, 45, 46, 33, 14, 18, 37, 44, 5, 14, + 14, 14, 19, 35, 38, 39, 11, 14, 25, 10, + 11, 12, 13, 20, 22, 24, 40, 43, 10, 6, + 8, 11, 12, 21, 41, 42, 9, 11, 23, 25, + 26, 7, 33, 25, 33, 26 }; #define yyerrok (yyerrstatus = 0) @@ -705,7 +728,7 @@ do { \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value); \ + Type, Value, Location); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) @@ -719,17 +742,19 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) #else static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; #endif { if (!yyvaluep) return; + YYUSE (yylocationp); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); @@ -751,13 +776,14 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) #else static void -yy_symbol_print (yyoutput, yytype, yyvaluep) +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; #endif { if (yytype < YYNTOKENS) @@ -765,7 +791,9 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); YYFPRINTF (yyoutput, ")"); } @@ -777,20 +805,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } @@ -808,11 +833,12 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) #else static void -yy_reduce_print (yyvsp, yyrule) +yy_reduce_print (yyvsp, yylsp, yyrule) YYSTYPE *yyvsp; + YYLTYPE *yylsp; int yyrule; #endif { @@ -824,18 +850,18 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - YYFPRINTF (stderr, " $%d = ", yyi + 1); + fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); + , &(yylsp[(yyi + 1) - (yynrhs)]) ); + fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ + yy_reduce_print (yyvsp, yylsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that @@ -1086,16 +1112,18 @@ yysyntax_error (char *yyresult, int yystate, int yychar) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) #else static void -yydestruct (yymsg, yytype, yyvaluep) +yydestruct (yymsg, yytype, yyvaluep, yylocationp) const char *yymsg; int yytype; YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; #endif { YYUSE (yyvaluep); + YYUSE (yylocationp); if (!yymsg) yymsg = "Deleting"; @@ -1108,8 +1136,10 @@ yydestruct (yymsg, yytype, yyvaluep) break; } } + /* Prevent warnings from -Wmissing-prototypes. */ + #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1125,20 +1155,23 @@ int yyparse (); #endif /* ! YYPARSE_PARAM */ -/* The lookahead symbol. */ + +/* The look-ahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; +/* Location data for the look-ahead symbol. */ +YYLTYPE yylloc; -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ +/*----------. +| yyparse. | +`----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1162,70 +1195,79 @@ yyparse () #endif #endif { + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - YYSIZE_T yystacksize; + YYSIZE_T yystacksize = YYINITDEPTH; - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + YYLTYPE yyloc; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ + yyssp = yyss; yyvsp = yyvs; + yylsp = yyls; +#if YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 0; +#endif goto yysetstate; @@ -1252,6 +1294,7 @@ yyparse () memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a @@ -1260,8 +1303,9 @@ yyparse () yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), &yystacksize); - + yyls = yyls1; yyss = yyss1; yyvs = yyvs1; } @@ -1282,8 +1326,9 @@ yyparse () (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + YYSTACK_RELOCATE (yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1293,6 +1338,7 @@ yyparse () yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -1303,9 +1349,6 @@ yyparse () YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - if (yystate == YYFINAL) - YYACCEPT; - goto yybackup; /*-----------. @@ -1314,16 +1357,16 @@ yyparse () yybackup: /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ + look-ahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1355,20 +1398,24 @@ yybackup: goto yyreduce; } + if (yyn == YYFINAL) + YYACCEPT; + /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the lookahead token. */ + /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token. */ - yychar = YYEMPTY; + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; - + *++yylsp = yylloc; goto yynewstate; @@ -1399,387 +1446,337 @@ yyreduce: GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; - + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: - -/* Line 1455 of yacc.c */ -#line 87 "dtc-parser.y" +#line 90 "dtc-parser.y" { - the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), - guess_boot_cpuid((yyvsp[(4) - (4)].node))); + the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0); ;} break; case 3: - -/* Line 1455 of yacc.c */ -#line 95 "dtc-parser.y" +#line 94 "dtc-parser.y" { - (yyval.re) = NULL; + the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0); ;} break; case 4: - -/* Line 1455 of yacc.c */ -#line 99 "dtc-parser.y" +#line 101 "dtc-parser.y" { - (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); + (yyval.re) = NULL; ;} break; case 5: - -/* Line 1455 of yacc.c */ -#line 106 "dtc-parser.y" +#line 105 "dtc-parser.y" { - (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr)); + (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ;} break; case 6: - -/* Line 1455 of yacc.c */ -#line 110 "dtc-parser.y" +#line 112 "dtc-parser.y" { - add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); - (yyval.re) = (yyvsp[(2) - (2)].re); + (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); ;} break; case 7: - -/* Line 1455 of yacc.c */ -#line 118 "dtc-parser.y" +#line 119 "dtc-parser.y" { - (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); + (yyval.re) = NULL; ;} break; case 8: - -/* Line 1455 of yacc.c */ -#line 125 "dtc-parser.y" +#line 123 "dtc-parser.y" { - (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); + (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ;} break; case 9: - -/* Line 1455 of yacc.c */ -#line 129 "dtc-parser.y" +#line 130 "dtc-parser.y" { - (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + (yyval.re) = (yyvsp[(1) - (1)].re); ;} break; case 10: - -/* Line 1455 of yacc.c */ -#line 133 "dtc-parser.y" +#line 134 "dtc-parser.y" { - struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); - - if (target) - merge_nodes(target, (yyvsp[(3) - (3)].node)); - else - print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); - (yyval.node) = (yyvsp[(1) - (3)].node); + (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); ;} break; case 11: - -/* Line 1455 of yacc.c */ -#line 146 "dtc-parser.y" +#line 141 "dtc-parser.y" { - (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); + (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); ;} break; case 12: - -/* Line 1455 of yacc.c */ -#line 153 "dtc-parser.y" +#line 145 "dtc-parser.y" { - (yyval.proplist) = NULL; + (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); ;} break; case 13: - -/* Line 1455 of yacc.c */ -#line 157 "dtc-parser.y" +#line 152 "dtc-parser.y" { - (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); + (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); ;} break; case 14: - -/* Line 1455 of yacc.c */ -#line 164 "dtc-parser.y" +#line 159 "dtc-parser.y" { - (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); + (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); ;} break; case 15: - -/* Line 1455 of yacc.c */ -#line 168 "dtc-parser.y" +#line 166 "dtc-parser.y" { - (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); + (yyval.proplist) = NULL; ;} break; case 16: - -/* Line 1455 of yacc.c */ -#line 172 "dtc-parser.y" +#line 170 "dtc-parser.y" { - add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); - (yyval.prop) = (yyvsp[(2) - (2)].prop); + (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); ;} break; case 17: - -/* Line 1455 of yacc.c */ -#line 180 "dtc-parser.y" +#line 177 "dtc-parser.y" { - (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); + (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); ;} break; case 18: - -/* Line 1455 of yacc.c */ -#line 184 "dtc-parser.y" +#line 181 "dtc-parser.y" { - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); + (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); ;} break; case 19: - -/* Line 1455 of yacc.c */ #line 188 "dtc-parser.y" { - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); + (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); ;} break; case 20: - -/* Line 1455 of yacc.c */ #line 192 "dtc-parser.y" { - (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ;} break; case 21: - -/* Line 1455 of yacc.c */ #line 196 "dtc-parser.y" { - FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); - struct data d; + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); + ;} + break; + + case 22: +#line 200 "dtc-parser.y" + { + (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); + ;} + break; + + case 23: +#line 204 "dtc-parser.y" + { + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path); + struct data d = empty_data; if ((yyvsp[(6) - (9)].addr) != 0) - if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) - print_error("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)(yyvsp[(6) - (9)].addr), - (yyvsp[(4) - (9)].data).val, - strerror(errno)); + if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) + yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)(yyvsp[(6) - (9)].addr), + (yyvsp[(4) - (9)].data).val, strerror(errno)); - d = data_copy_file(f, (yyvsp[(8) - (9)].addr)); + d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr)); (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); - fclose(f); + dtc_close_file(file); ;} break; - case 22: - -/* Line 1455 of yacc.c */ -#line 213 "dtc-parser.y" + case 24: +#line 221 "dtc-parser.y" { - FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path); struct data d = empty_data; - d = data_copy_file(f, -1); + d = data_copy_file(file->file, -1); (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); - fclose(f); + dtc_close_file(file); ;} break; - case 23: - -/* Line 1455 of yacc.c */ -#line 223 "dtc-parser.y" + case 25: +#line 232 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 24: - -/* Line 1455 of yacc.c */ -#line 230 "dtc-parser.y" + case 26: +#line 239 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 25: - -/* Line 1455 of yacc.c */ -#line 234 "dtc-parser.y" + case 27: +#line 243 "dtc-parser.y" { (yyval.data) = (yyvsp[(1) - (2)].data); ;} break; - case 26: - -/* Line 1455 of yacc.c */ -#line 238 "dtc-parser.y" + case 28: +#line 247 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 27: - -/* Line 1455 of yacc.c */ -#line 245 "dtc-parser.y" + case 29: +#line 254 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 28: - -/* Line 1455 of yacc.c */ -#line 249 "dtc-parser.y" + case 30: +#line 258 "dtc-parser.y" { (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); ;} break; - case 29: - -/* Line 1455 of yacc.c */ -#line 253 "dtc-parser.y" + case 31: +#line 262 "dtc-parser.y" { (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, (yyvsp[(2) - (2)].labelref)), -1); ;} break; - case 30: - -/* Line 1455 of yacc.c */ -#line 258 "dtc-parser.y" + case 32: +#line 267 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 31: + case 33: +#line 274 "dtc-parser.y" + { + (yyval.cbase) = 16; + ;} + break; -/* Line 1455 of yacc.c */ -#line 265 "dtc-parser.y" + case 35: +#line 282 "dtc-parser.y" { (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); ;} break; - case 32: + case 36: +#line 286 "dtc-parser.y" + { + (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32); + ;} + break; -/* Line 1455 of yacc.c */ -#line 272 "dtc-parser.y" + case 37: +#line 293 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 33: - -/* Line 1455 of yacc.c */ -#line 276 "dtc-parser.y" + case 38: +#line 297 "dtc-parser.y" { (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); ;} break; - case 34: - -/* Line 1455 of yacc.c */ -#line 280 "dtc-parser.y" + case 39: +#line 301 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 35: - -/* Line 1455 of yacc.c */ -#line 287 "dtc-parser.y" + case 40: +#line 308 "dtc-parser.y" { (yyval.nodelist) = NULL; ;} break; - case 36: - -/* Line 1455 of yacc.c */ -#line 291 "dtc-parser.y" + case 41: +#line 312 "dtc-parser.y" { (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); ;} break; - case 37: - -/* Line 1455 of yacc.c */ -#line 295 "dtc-parser.y" + case 42: +#line 316 "dtc-parser.y" { - print_error("syntax error: properties must precede subnodes"); + yyerror("syntax error: properties must precede subnodes"); YYERROR; ;} break; - case 38: - -/* Line 1455 of yacc.c */ -#line 303 "dtc-parser.y" + case 43: +#line 324 "dtc-parser.y" { - (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); + (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref)); ;} break; - case 39: - -/* Line 1455 of yacc.c */ -#line 307 "dtc-parser.y" + case 44: +#line 331 "dtc-parser.y" { - add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); - (yyval.node) = (yyvsp[(2) - (2)].node); + (yyval.labelref) = NULL; ;} break; + case 45: +#line 335 "dtc-parser.y" + { + (yyval.labelref) = (yyvsp[(1) - (1)].labelref); + ;} + break; -/* Line 1455 of yacc.c */ -#line 1783 "dtc-parser.tab.c" +/* Line 1267 of yacc.c. */ +#line 1780 "dtc-parser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1789,6 +1786,7 @@ yyreduce: YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; + *++yylsp = yyloc; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule @@ -1850,11 +1848,11 @@ yyerrlab: #endif } - + yyerror_range[0] = yylloc; if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -1866,12 +1864,12 @@ yyerrlab: else { yydestruct ("Error: discarding", - yytoken, &yylval); + yytoken, &yylval, &yylloc); yychar = YYEMPTY; } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; @@ -1887,6 +1885,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; + yyerror_range[0] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -1920,16 +1919,24 @@ yyerrlab1: if (yyssp == yyss) YYABORT; - + yyerror_range[0] = *yylsp; yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp, yylsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } + if (yyn == YYFINAL) + YYACCEPT; + *++yyvsp = yylval; + yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the look-ahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + *++yylsp = yyloc; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); @@ -1952,7 +1959,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined(yyoverflow) || YYERROR_VERBOSE +#ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -1963,9 +1970,9 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEMPTY) + if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); + yytoken, &yylval, &yylloc); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -1973,7 +1980,7 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp, yylsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -1989,24 +1996,29 @@ yyreturn: } - -/* Line 1675 of yacc.c */ -#line 313 "dtc-parser.y" +#line 340 "dtc-parser.y" -void print_error(char const *fmt, ...) +void yyerrorf(char const *s, ...) { + const char *fname = srcpos_file ? srcpos_file->name : ""; va_list va; + va_start(va, s); - va_start(va, fmt); - srcpos_verror(&yylloc, fmt, va); - va_end(va); + if (strcmp(fname, "-") == 0) + fname = "stdin"; + + fprintf(stderr, "%s:%d ", fname, yylloc.first_line); + vfprintf(stderr, s, va); + fprintf(stderr, "\n"); treesource_error = 1; + va_end(va); } -void yyerror(char const *s) { - print_error("%s", s); +void yyerror (char const *s) +{ + yyerrorf("%s", s); } static unsigned long long eval_literal(const char *s, int base, int bits) @@ -2017,12 +2029,12 @@ static unsigned long long eval_literal(const char *s, int base, int bits) errno = 0; val = strtoull(s, &e, base); if (*e) - print_error("bad characters in literal"); + yyerror("bad characters in literal"); else if ((errno == ERANGE) || ((bits < 64) && (val >= (1ULL << bits)))) - print_error("literal out of range"); + yyerror("literal out of range"); else if (errno != 0) - print_error("bad literal"); + yyerror("bad literal"); return val; } diff --git a/trunk/scripts/dtc/dtc-parser.tab.h_shipped b/trunk/scripts/dtc/dtc-parser.tab.h_shipped index 95c9547adea5..ba99100d55c9 100644 --- a/trunk/scripts/dtc/dtc-parser.tab.h_shipped +++ b/trunk/scripts/dtc/dtc-parser.tab.h_shipped @@ -1,23 +1,24 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify + + 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 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, or (at your option) + any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -28,11 +29,10 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ - /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -43,24 +43,35 @@ DT_MEMRESERVE = 259, DT_PROPNODENAME = 260, DT_LITERAL = 261, - DT_BASE = 262, - DT_BYTE = 263, - DT_STRING = 264, - DT_LABEL = 265, - DT_REF = 266, - DT_INCBIN = 267 + DT_LEGACYLITERAL = 262, + DT_BASE = 263, + DT_BYTE = 264, + DT_STRING = 265, + DT_LABEL = 266, + DT_REF = 267, + DT_INCBIN = 268 }; #endif +/* Tokens. */ +#define DT_V1 258 +#define DT_MEMRESERVE 259 +#define DT_PROPNODENAME 260 +#define DT_LITERAL 261 +#define DT_LEGACYLITERAL 262 +#define DT_BASE 263 +#define DT_BYTE 264 +#define DT_STRING 265 +#define DT_LABEL 266 +#define DT_REF 267 +#define DT_INCBIN 268 + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE +#line 37 "dtc-parser.y" { - -/* Line 1676 of yacc.c */ -#line 39 "dtc-parser.y" - char *propnodename; char *literal; char *labelref; @@ -75,17 +86,28 @@ typedef union YYSTYPE struct node *node; struct node *nodelist; struct reserve_info *re; - - - -/* Line 1676 of yacc.c */ -#line 83 "dtc-parser.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 1489 of yacc.c. */ +#line 92 "dtc-parser.tab.h" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif +extern YYLTYPE yylloc; diff --git a/trunk/scripts/dtc/dtc-parser.y b/trunk/scripts/dtc/dtc-parser.y index 5e84a67fc1d2..b2ab562420ea 100644 --- a/trunk/scripts/dtc/dtc-parser.y +++ b/trunk/scripts/dtc/dtc-parser.y @@ -18,17 +18,15 @@ * USA */ +%locations + %{ #include #include "dtc.h" #include "srcpos.h" -YYLTYPE yylloc; - extern int yylex(void); -extern void print_error(char const *fmt, ...); -extern void yyerror(char const *s); extern struct boot_info *the_boot_info; extern int treesource_error; @@ -57,6 +55,7 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %token DT_MEMRESERVE %token DT_PROPNODENAME %token DT_LITERAL +%token DT_LEGACYLITERAL %token DT_BASE %token DT_BYTE %token DT_STRING @@ -68,8 +67,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %type propdataprefix %type memreserve %type memreserves +%type v0_memreserve +%type v0_memreserves %type addr %type celllist +%type cellbase %type cellval %type bytestring %type propdef @@ -79,14 +81,18 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %type nodedef %type subnode %type subnodes +%type label %% sourcefile: DT_V1 ';' memreserves devicetree { - the_boot_info = build_boot_info($3, $4, - guess_boot_cpuid($4)); + the_boot_info = build_boot_info($3, $4, 0); + } + | v0_memreserves devicetree + { + the_boot_info = build_boot_info($1, $2, 0); } ; @@ -102,14 +108,31 @@ memreserves: ; memreserve: - DT_MEMRESERVE addr addr ';' + label DT_MEMRESERVE addr addr ';' { - $$ = build_reserve_entry($2, $3); + $$ = build_reserve_entry($3, $4, $1); } - | DT_LABEL memreserve + ; + +v0_memreserves: + /* empty */ { - add_label(&$2->labels, $1); - $$ = $2; + $$ = NULL; + } + | v0_memreserve v0_memreserves + { + $$ = chain_reserve_entry($1, $2); + }; + ; + +v0_memreserve: + memreserve + { + $$ = $1; + } + | label DT_MEMRESERVE addr '-' addr ';' + { + $$ = build_reserve_entry($3, $5 - $3 + 1, $1); } ; @@ -118,26 +141,16 @@ addr: { $$ = eval_literal($1, 0, 64); } + | DT_LEGACYLITERAL + { + $$ = eval_literal($1, 16, 64); + } ; devicetree: '/' nodedef { - $$ = name_node($2, ""); - } - | devicetree '/' nodedef - { - $$ = merge_nodes($1, $3); - } - | devicetree DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $2); - - if (target) - merge_nodes(target, $3); - else - print_error("label or path, '%s', not found", $2); - $$ = $1; + $$ = name_node($2, "", NULL); } ; @@ -160,18 +173,13 @@ proplist: ; propdef: - DT_PROPNODENAME '=' propdata ';' - { - $$ = build_property($1, $3); - } - | DT_PROPNODENAME ';' + label DT_PROPNODENAME '=' propdata ';' { - $$ = build_property($1, empty_data); + $$ = build_property($2, $4, $1); } - | DT_LABEL propdef + | label DT_PROPNODENAME ';' { - add_label(&$2->labels, $1); - $$ = $2; + $$ = build_property($2, empty_data, $1); } ; @@ -194,30 +202,31 @@ propdata: } | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' { - FILE *f = srcfile_relative_open($4.val, NULL); - struct data d; + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); + struct data d = empty_data; if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) - print_error("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, - $4.val, - strerror(errno)); + if (fseek(file->file, $6, SEEK_SET) != 0) + yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)$6, + $4.val, strerror(errno)); - d = data_copy_file(f, $8); + d = data_copy_file(file->file, $8); $$ = data_merge($1, d); - fclose(f); + dtc_close_file(file); } | propdataprefix DT_INCBIN '(' DT_STRING ')' { - FILE *f = srcfile_relative_open($4.val, NULL); + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); struct data d = empty_data; - d = data_copy_file(f, -1); + d = data_copy_file(file->file, -1); $$ = data_merge($1, d); - fclose(f); + dtc_close_file(file); } | propdata DT_LABEL { @@ -260,11 +269,23 @@ celllist: } ; +cellbase: + /* empty */ + { + $$ = 16; + } + | DT_BASE + ; + cellval: DT_LITERAL { $$ = eval_literal($1, 0, 32); } + | cellbase DT_LEGACYLITERAL + { + $$ = eval_literal($2, $1, 32); + } ; bytestring: @@ -287,44 +308,57 @@ subnodes: { $$ = NULL; } - | subnode subnodes + | subnode subnodes { $$ = chain_node($1, $2); } | subnode propdef { - print_error("syntax error: properties must precede subnodes"); + yyerror("syntax error: properties must precede subnodes"); YYERROR; } ; subnode: - DT_PROPNODENAME nodedef + label DT_PROPNODENAME nodedef { - $$ = name_node($2, $1); + $$ = name_node($3, $2, $1); } - | DT_LABEL subnode + ; + +label: + /* empty */ { - add_label(&$2->labels, $1); - $$ = $2; + $$ = NULL; + } + | DT_LABEL + { + $$ = $1; } ; %% -void print_error(char const *fmt, ...) +void yyerrorf(char const *s, ...) { + const char *fname = srcpos_file ? srcpos_file->name : ""; va_list va; + va_start(va, s); - va_start(va, fmt); - srcpos_verror(&yylloc, fmt, va); - va_end(va); + if (strcmp(fname, "-") == 0) + fname = "stdin"; + + fprintf(stderr, "%s:%d ", fname, yylloc.first_line); + vfprintf(stderr, s, va); + fprintf(stderr, "\n"); treesource_error = 1; + va_end(va); } -void yyerror(char const *s) { - print_error("%s", s); +void yyerror (char const *s) +{ + yyerrorf("%s", s); } static unsigned long long eval_literal(const char *s, int base, int bits) @@ -335,11 +369,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits) errno = 0; val = strtoull(s, &e, base); if (*e) - print_error("bad characters in literal"); + yyerror("bad characters in literal"); else if ((errno == ERANGE) || ((bits < 64) && (val >= (1ULL << bits)))) - print_error("literal out of range"); + yyerror("literal out of range"); else if (errno != 0) - print_error("bad literal"); + yyerror("bad literal"); return val; } diff --git a/trunk/scripts/dtc/dtc.c b/trunk/scripts/dtc/dtc.c index cbc0193098e4..d8fd43b4ac1a 100644 --- a/trunk/scripts/dtc/dtc.c +++ b/trunk/scripts/dtc/dtc.c @@ -30,7 +30,30 @@ int quiet; /* Level of quietness */ int reservenum; /* Number of memory reservation slots */ int minsize; /* Minimum blob size */ int padsize; /* Additional padding to blob */ -int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ + +char *join_path(const char *path, const char *name) +{ + int lenp = strlen(path); + int lenn = strlen(name); + int len; + int needslash = 1; + char *str; + + len = lenp + lenn + 2; + if ((lenp > 0) && (path[lenp-1] == '/')) { + needslash = 0; + len--; + } + + str = xmalloc(len); + memcpy(str, path, lenp); + if (needslash) { + str[lenp] = '/'; + lenp++; + } + memcpy(str+lenp, name, lenn+1); + return str; +} static void fill_fullpaths(struct node *tree, const char *prefix) { @@ -81,15 +104,8 @@ static void __attribute__ ((noreturn)) usage(void) fprintf(stderr, "\t\tSet the physical boot cpu\n"); fprintf(stderr, "\t-f\n"); fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); - fprintf(stderr, "\t-s\n"); - fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n"); fprintf(stderr, "\t-v\n"); fprintf(stderr, "\t\tPrint DTC version and exit\n"); - fprintf(stderr, "\t-H \n"); - fprintf(stderr, "\t\tphandle formats are:\n"); - fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n"); - fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n"); - fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n"); exit(3); } @@ -99,7 +115,7 @@ int main(int argc, char *argv[]) const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; - int force = 0, check = 0, sort = 0; + int force = 0, check = 0; const char *arg; int opt; FILE *outf = NULL; @@ -111,7 +127,7 @@ int main(int argc, char *argv[]) minsize = 0; padsize = 0; - while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) { + while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) { switch (opt) { case 'I': inform = optarg; @@ -149,22 +165,6 @@ int main(int argc, char *argv[]) case 'v': printf("Version: %s\n", DTC_VERSION); exit(0); - case 'H': - if (streq(optarg, "legacy")) - phandle_format = PHANDLE_LEGACY; - else if (streq(optarg, "epapr")) - phandle_format = PHANDLE_EPAPR; - else if (streq(optarg, "both")) - phandle_format = PHANDLE_BOTH; - else - die("Invalid argument \"%s\" to -H option\n", - optarg); - break; - - case 's': - sort = 1; - break; - case 'h': default: usage(); @@ -182,9 +182,6 @@ int main(int argc, char *argv[]) if (minsize && padsize) die("Can't set both -p and -S\n"); - if (minsize) - fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n"); - fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", inform, outform, arg); @@ -203,8 +200,6 @@ int main(int argc, char *argv[]) fill_fullpaths(bi->dt, ""); process_checks(force, bi); - if (sort) - sort_tree(bi); if (streq(outname, "-")) { outf = stdout; diff --git a/trunk/scripts/dtc/dtc.h b/trunk/scripts/dtc/dtc.h index f37c97eb3dfc..08d54c870086 100644 --- a/trunk/scripts/dtc/dtc.h +++ b/trunk/scripts/dtc/dtc.h @@ -34,17 +34,7 @@ #include #include -#include "util.h" - -#ifdef DEBUG -#define debug(fmt,args...) printf(fmt, ##args) -#else -#define debug(fmt,args...) -#endif - - #define DEFAULT_FDT_VERSION 17 - /* * Command line options */ @@ -52,11 +42,36 @@ extern int quiet; /* Level of quietness */ extern int reservenum; /* Number of memory reservation slots */ extern int minsize; /* Minimum blob size */ extern int padsize; /* Additional padding to blob */ -extern int phandle_format; /* Use linux,phandle or phandle properties */ -#define PHANDLE_LEGACY 0x1 -#define PHANDLE_EPAPR 0x2 -#define PHANDLE_BOTH 0x3 +static inline void __attribute__((noreturn)) die(char * str, ...) +{ + va_list ap; + + va_start(ap, str); + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, str, ap); + exit(1); +} + +static inline void *xmalloc(size_t len) +{ + void *new = malloc(len); + + if (! new) + die("malloc() failed\n"); + + return new; +} + +static inline void *xrealloc(void *p, size_t len) +{ + void *new = realloc(p, len); + + if (! new) + die("realloc() failed (len=%d)\n", len); + + return new; +} typedef uint32_t cell_t; @@ -125,18 +140,13 @@ int data_is_one_string(struct data d); #define MAX_NODENAME_LEN 31 /* Live trees */ -struct label { - char *label; - struct label *next; -}; - struct property { char *name; struct data val; struct property *next; - struct label *labels; + char *label; }; struct node { @@ -153,28 +163,22 @@ struct node { cell_t phandle; int addr_cells, size_cells; - struct label *labels; + char *label; }; -#define for_each_label(l0, l) \ - for ((l) = (l0); (l); (l) = (l)->next) - #define for_each_property(n, p) \ for ((p) = (n)->proplist; (p); (p) = (p)->next) #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) -void add_label(struct label **labels, char *label); - -struct property *build_property(char *name, struct data val); +struct property *build_property(char *name, struct data val, char *label); struct property *chain_property(struct property *first, struct property *list); struct property *reverse_properties(struct property *first); struct node *build_node(struct property *proplist, struct node *children); -struct node *name_node(struct node *node, char *name); +struct node *name_node(struct node *node, char *name, char *label); struct node *chain_node(struct node *first, struct node *list); -struct node *merge_nodes(struct node *old_node, struct node *new_node); void add_property(struct node *node, struct property *prop); void add_child(struct node *parent, struct node *child); @@ -182,10 +186,6 @@ void add_child(struct node *parent, struct node *child); const char *get_unitname(struct node *node); struct property *get_property(struct node *node, const char *propname); cell_t propval_cell(struct property *prop); -struct property *get_property_by_label(struct node *tree, const char *label, - struct node **node); -struct marker *get_marker_label(struct node *tree, const char *label, - struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); struct node *get_node_by_path(struct node *tree, const char *path); struct node *get_node_by_label(struct node *tree, const char *label); @@ -193,8 +193,6 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); -uint32_t guess_boot_cpuid(struct node *tree); - /* Boot info (tree plus memreserve information */ struct reserve_info { @@ -202,10 +200,10 @@ struct reserve_info { struct reserve_info *next; - struct label *labels; + char *label; }; -struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len); +struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label); struct reserve_info *chain_reserve_entry(struct reserve_info *first, struct reserve_info *list); struct reserve_info *add_reserve_entry(struct reserve_info *list, @@ -220,7 +218,6 @@ struct boot_info { struct boot_info *build_boot_info(struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys); -void sort_tree(struct boot_info *bi); /* Checks */ @@ -242,4 +239,8 @@ struct boot_info *dt_from_source(const char *f); struct boot_info *dt_from_fs(const char *dirname); +/* misc */ + +char *join_path(const char *path, const char *name); + #endif /* _DTC_H */ diff --git a/trunk/scripts/dtc/flattree.c b/trunk/scripts/dtc/flattree.c index ead0332c87e1..76acd28c068d 100644 --- a/trunk/scripts/dtc/flattree.c +++ b/trunk/scripts/dtc/flattree.c @@ -52,9 +52,9 @@ struct emitter { void (*string)(void *, char *, int); void (*align)(void *, int); void (*data)(void *, struct data); - void (*beginnode)(void *, struct label *labels); - void (*endnode)(void *, struct label *labels); - void (*property)(void *, struct label *labels); + void (*beginnode)(void *, const char *); + void (*endnode)(void *, const char *); + void (*property)(void *, const char *); }; static void bin_emit_cell(void *e, cell_t val) @@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d) *dtbuf = data_append_data(*dtbuf, d.val, d.len); } -static void bin_emit_beginnode(void *e, struct label *labels) +static void bin_emit_beginnode(void *e, const char *label) { bin_emit_cell(e, FDT_BEGIN_NODE); } -static void bin_emit_endnode(void *e, struct label *labels) +static void bin_emit_endnode(void *e, const char *label) { bin_emit_cell(e, FDT_END_NODE); } -static void bin_emit_property(void *e, struct label *labels) +static void bin_emit_property(void *e, const char *label) { bin_emit_cell(e, FDT_PROP); } @@ -127,21 +127,11 @@ static void emit_offset_label(FILE *f, const char *label, int offset) fprintf(f, "%s\t= . + %d\n", label, offset); } -#define ASM_EMIT_BELONG(f, fmt, ...) \ - { \ - fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \ - fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \ - fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \ - fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \ - } - static void asm_emit_cell(void *e, cell_t val) { FILE *f = e; - fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n", - (val >> 24) & 0xff, (val >> 16) & 0xff, - (val >> 8) & 0xff, val & 0xff); + fprintf(f, "\t.long\t0x%x\n", val); } static void asm_emit_string(void *e, char *str, int len) @@ -166,7 +156,7 @@ static void asm_emit_align(void *e, int a) { FILE *f = e; - fprintf(f, "\t.balign\t%d, 0\n", a); + fprintf(f, "\t.balign\t%d\n", a); } static void asm_emit_data(void *e, struct data d) @@ -179,7 +169,8 @@ static void asm_emit_data(void *e, struct data d) emit_offset_label(f, m->ref, m->offset); while ((d.len - off) >= sizeof(uint32_t)) { - asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); + fprintf(f, "\t.long\t0x%x\n", + fdt32_to_cpu(*((uint32_t *)(d.val+off)))); off += sizeof(uint32_t); } @@ -191,43 +182,37 @@ static void asm_emit_data(void *e, struct data d) assert(off == d.len); } -static void asm_emit_beginnode(void *e, struct label *labels) +static void asm_emit_beginnode(void *e, const char *label) { FILE *f = e; - struct label *l; - for_each_label(labels, l) { - fprintf(f, "\t.globl\t%s\n", l->label); - fprintf(f, "%s:\n", l->label); + if (label) { + fprintf(f, "\t.globl\t%s\n", label); + fprintf(f, "%s:\n", label); } - fprintf(f, "\t/* FDT_BEGIN_NODE */\n"); - asm_emit_cell(e, FDT_BEGIN_NODE); + fprintf(f, "\t.long\tFDT_BEGIN_NODE\n"); } -static void asm_emit_endnode(void *e, struct label *labels) +static void asm_emit_endnode(void *e, const char *label) { FILE *f = e; - struct label *l; - fprintf(f, "\t/* FDT_END_NODE */\n"); - asm_emit_cell(e, FDT_END_NODE); - for_each_label(labels, l) { - fprintf(f, "\t.globl\t%s_end\n", l->label); - fprintf(f, "%s_end:\n", l->label); + fprintf(f, "\t.long\tFDT_END_NODE\n"); + if (label) { + fprintf(f, "\t.globl\t%s_end\n", label); + fprintf(f, "%s_end:\n", label); } } -static void asm_emit_property(void *e, struct label *labels) +static void asm_emit_property(void *e, const char *label) { FILE *f = e; - struct label *l; - for_each_label(labels, l) { - fprintf(f, "\t.globl\t%s\n", l->label); - fprintf(f, "%s:\n", l->label); + if (label) { + fprintf(f, "\t.globl\t%s\n", label); + fprintf(f, "%s:\n", label); } - fprintf(f, "\t/* FDT_PROP */\n"); - asm_emit_cell(e, FDT_PROP); + fprintf(f, "\t.long\tFDT_PROP\n"); } static struct emitter asm_emitter = { @@ -263,7 +248,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, struct node *child; int seen_name_prop = 0; - emit->beginnode(etarget, tree->labels); + emit->beginnode(etarget, tree->label); if (vi->flags & FTF_FULLPATH) emit->string(etarget, tree->fullpath, 0); @@ -280,7 +265,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, nameoff = stringtable_insert(strbuf, prop->name); - emit->property(etarget, prop->labels); + emit->property(etarget, prop->label); emit->cell(etarget, prop->val.len); emit->cell(etarget, nameoff); @@ -307,7 +292,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, flatten_tree(child, emit, etarget, strbuf, vi); } - emit->endnode(etarget, tree->labels); + emit->endnode(etarget, tree->label); } static struct data flatten_reserve_list(struct reserve_info *reservelist, @@ -428,13 +413,10 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) if (padlen > 0) blob = data_append_zeroes(blob, padlen); - if (fwrite(blob.val, blob.len, 1, f) != 1) { - if (ferror(f)) - die("Error writing device tree blob: %s\n", - strerror(errno)); - else - die("Short write on device tree blob\n"); - } + fwrite(blob.val, blob.len, 1, f); + + if (ferror(f)) + die("Error writing device tree blob: %s\n", strerror(errno)); /* * data_merge() frees the right-hand element so only the blob @@ -473,44 +455,39 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) die("Unknown device tree blob version %d\n", version); fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); + fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC); + fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE); + fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE); + fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP); + fprintf(f, "#define FDT_END 0x%x\n", FDT_END); + fprintf(f, "\n"); emit_label(f, symprefix, "blob_start"); emit_label(f, symprefix, "header"); - fprintf(f, "\t/* magic */\n"); - asm_emit_cell(f, FDT_MAGIC); - fprintf(f, "\t/* totalsize */\n"); - ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start", - symprefix, symprefix); - fprintf(f, "\t/* off_dt_struct */\n"); - ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start", + fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n"); + fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n", symprefix, symprefix); - fprintf(f, "\t/* off_dt_strings */\n"); - ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start", + fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n", symprefix, symprefix); - fprintf(f, "\t/* off_mem_rsvmap */\n"); - ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start", + fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n", symprefix, symprefix); - fprintf(f, "\t/* version */\n"); - asm_emit_cell(f, vi->version); - fprintf(f, "\t/* last_comp_version */\n"); - asm_emit_cell(f, vi->last_comp_version); - - if (vi->flags & FTF_BOOTCPUID) { - fprintf(f, "\t/* boot_cpuid_phys */\n"); - asm_emit_cell(f, bi->boot_cpuid_phys); - } + fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n", + symprefix, symprefix); + fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version); + fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n", + vi->last_comp_version); - if (vi->flags & FTF_STRTABSIZE) { - fprintf(f, "\t/* size_dt_strings */\n"); - ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start", - symprefix, symprefix); - } + if (vi->flags & FTF_BOOTCPUID) + fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", + bi->boot_cpuid_phys); - if (vi->flags & FTF_STRUCTSIZE) { - fprintf(f, "\t/* size_dt_struct */\n"); - ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start", + if (vi->flags & FTF_STRTABSIZE) + fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", + symprefix, symprefix); + + if (vi->flags & FTF_STRUCTSIZE) + fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n", symprefix, symprefix); - } /* * Reserve map entries. @@ -528,17 +505,16 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) * as it appears .quad isn't available in some assemblers. */ for (re = bi->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) { - fprintf(f, "\t.globl\t%s\n", l->label); - fprintf(f, "%s:\n", l->label); + if (re->label) { + fprintf(f, "\t.globl\t%s\n", re->label); + fprintf(f, "%s:\n", re->label); } - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); - ASM_EMIT_BELONG(f, "0x%08x", - (unsigned int)(re->re.address & 0xffffffff)); - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); + fprintf(f, "\t.long\t0x%08x, 0x%08x\n", + (unsigned int)(re->re.address >> 32), + (unsigned int)(re->re.address & 0xffffffff)); + fprintf(f, "\t.long\t0x%08x, 0x%08x\n", + (unsigned int)(re->re.size >> 32), + (unsigned int)(re->re.size & 0xffffffff)); } for (i = 0; i < reservenum; i++) { fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); @@ -548,9 +524,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) emit_label(f, symprefix, "struct_start"); flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); - - fprintf(f, "\t/* FDT_END */\n"); - asm_emit_cell(f, FDT_END); + fprintf(f, "\t.long\tFDT_END\n"); emit_label(f, symprefix, "struct_end"); emit_label(f, symprefix, "strings_start"); @@ -627,7 +601,7 @@ static char *flat_read_string(struct inbuf *inb) len++; } while ((*p++) != '\0'); - str = xstrdup(inb->ptr); + str = strdup(inb->ptr); inb->ptr += len; @@ -669,7 +643,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset) p++; } - return xstrdup(inb->base + offset); + return strdup(inb->base + offset); } static struct property *flat_read_property(struct inbuf *dtbuf, @@ -689,7 +663,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf, val = flat_read_data(dtbuf, proplen); - return build_property(name, val); + return build_property(name, val, NULL); } @@ -714,7 +688,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) if (re.size == 0) break; - new = build_reserve_entry(re.address, re.size); + new = build_reserve_entry(re.address, re.size, NULL); reservelist = add_reserve_entry(reservelist, new); } @@ -736,7 +710,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) if (!streq(ppath, "/")) plen++; - return xstrdup(cpath + plen); + return strdup(cpath + plen); } static struct node *unflatten_tree(struct inbuf *dtbuf, @@ -802,7 +776,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct boot_info *dt_from_blob(const char *fname) { - FILE *f; + struct dtc_file *dtcf; uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; uint32_t off_dt, off_str, off_mem_rsvmap; int rc; @@ -817,14 +791,14 @@ struct boot_info *dt_from_blob(const char *fname) uint32_t val; int flags = 0; - f = srcfile_relative_open(fname, NULL); + dtcf = dtc_open_file(fname, NULL); - rc = fread(&magic, sizeof(magic), 1, f); - if (ferror(f)) + rc = fread(&magic, sizeof(magic), 1, dtcf->file); + if (ferror(dtcf->file)) die("Error reading DT blob magic number: %s\n", strerror(errno)); if (rc < 1) { - if (feof(f)) + if (feof(dtcf->file)) die("EOF reading DT blob magic number\n"); else die("Mysterious short read reading magic number\n"); @@ -834,11 +808,11 @@ struct boot_info *dt_from_blob(const char *fname) if (magic != FDT_MAGIC) die("Blob has incorrect magic number\n"); - rc = fread(&totalsize, sizeof(totalsize), 1, f); - if (ferror(f)) + rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); + if (ferror(dtcf->file)) die("Error reading DT blob size: %s\n", strerror(errno)); if (rc < 1) { - if (feof(f)) + if (feof(dtcf->file)) die("EOF reading DT blob size\n"); else die("Mysterious short read reading blob size\n"); @@ -858,12 +832,12 @@ struct boot_info *dt_from_blob(const char *fname) p = blob + sizeof(magic) + sizeof(totalsize); while (sizeleft) { - if (feof(f)) + if (feof(dtcf->file)) die("EOF before reading %d bytes of DT blob\n", totalsize); - rc = fread(p, 1, sizeleft, f); - if (ferror(f)) + rc = fread(p, 1, sizeleft, dtcf->file); + if (ferror(dtcf->file)) die("Error reading DT blob: %s\n", strerror(errno)); @@ -926,7 +900,7 @@ struct boot_info *dt_from_blob(const char *fname) free(blob); - fclose(f); + dtc_close_file(dtcf); return build_boot_info(reservelist, tree, boot_cpuid_phys); } diff --git a/trunk/scripts/dtc/fstree.c b/trunk/scripts/dtc/fstree.c index f3774530170a..8fe1bdf239f0 100644 --- a/trunk/scripts/dtc/fstree.c +++ b/trunk/scripts/dtc/fstree.c @@ -58,9 +58,10 @@ static struct node *read_fstree(const char *dirname) "WARNING: Cannot open %s: %s\n", tmpnam, strerror(errno)); } else { - prop = build_property(xstrdup(de->d_name), + prop = build_property(strdup(de->d_name), data_copy_file(pfile, - st.st_size)); + st.st_size), + NULL); add_property(tree, prop); fclose(pfile); } @@ -68,7 +69,8 @@ static struct node *read_fstree(const char *dirname) struct node *newchild; newchild = read_fstree(tmpnam); - newchild = name_node(newchild, xstrdup(de->d_name)); + newchild = name_node(newchild, strdup(de->d_name), + NULL); add_child(tree, newchild); } @@ -84,8 +86,8 @@ struct boot_info *dt_from_fs(const char *dirname) struct node *tree; tree = read_fstree(dirname); - tree = name_node(tree, ""); + tree = name_node(tree, "", NULL); - return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); + return build_boot_info(NULL, tree, 0); } diff --git a/trunk/scripts/dtc/livetree.c b/trunk/scripts/dtc/livetree.c index c9209d5c999e..0ca3de550b3f 100644 --- a/trunk/scripts/dtc/livetree.c +++ b/trunk/scripts/dtc/livetree.c @@ -24,30 +24,17 @@ * Tree building functions */ -void add_label(struct label **labels, char *label) -{ - struct label *new; - - /* Make sure the label isn't already there */ - for_each_label(*labels, new) - if (streq(new->label, label)) - return; - - new = xmalloc(sizeof(*new)); - new->label = label; - new->next = *labels; - *labels = new; -} - -struct property *build_property(char *name, struct data val) +struct property *build_property(char *name, struct data val, char *label) { struct property *new = xmalloc(sizeof(*new)); - memset(new, 0, sizeof(*new)); - new->name = name; new->val = val; + new->next = NULL; + + new->label = label; + return new; } @@ -91,80 +78,15 @@ struct node *build_node(struct property *proplist, struct node *children) return new; } -struct node *name_node(struct node *node, char *name) +struct node *name_node(struct node *node, char *name, char * label) { assert(node->name == NULL); node->name = name; - return node; -} + node->label = label; -struct node *merge_nodes(struct node *old_node, struct node *new_node) -{ - struct property *new_prop, *old_prop; - struct node *new_child, *old_child; - struct label *l; - - /* Add new node labels to old node */ - for_each_label(new_node->labels, l) - add_label(&old_node->labels, l->label); - - /* Move properties from the new node to the old node. If there - * is a collision, replace the old value with the new */ - while (new_node->proplist) { - /* Pop the property off the list */ - new_prop = new_node->proplist; - new_node->proplist = new_prop->next; - new_prop->next = NULL; - - /* Look for a collision, set new value if there is */ - for_each_property(old_node, old_prop) { - if (streq(old_prop->name, new_prop->name)) { - /* Add new labels to old property */ - for_each_label(new_prop->labels, l) - add_label(&old_prop->labels, l->label); - - old_prop->val = new_prop->val; - free(new_prop); - new_prop = NULL; - break; - } - } - - /* if no collision occurred, add property to the old node. */ - if (new_prop) - add_property(old_node, new_prop); - } - - /* Move the override child nodes into the primary node. If - * there is a collision, then merge the nodes. */ - while (new_node->children) { - /* Pop the child node off the list */ - new_child = new_node->children; - new_node->children = new_child->next_sibling; - new_child->parent = NULL; - new_child->next_sibling = NULL; - - /* Search for a collision. Merge if there is */ - for_each_child(old_node, old_child) { - if (streq(old_child->name, new_child->name)) { - merge_nodes(old_child, new_child); - new_child = NULL; - break; - } - } - - /* if no collision occured, add child to the old node. */ - if (new_child) - add_child(old_node, new_child); - } - - /* The new node contents are now merged into the old node. Free - * the new node. */ - free(new_node); - - return old_node; + return node; } struct node *chain_node(struct node *first, struct node *list) @@ -202,15 +124,18 @@ void add_child(struct node *parent, struct node *child) *p = child; } -struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) +struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size, + char *label) { struct reserve_info *new = xmalloc(sizeof(*new)); - memset(new, 0, sizeof(*new)); - new->re.address = address; new->re.size = size; + new->next = NULL; + + new->label = label; + return new; } @@ -283,60 +208,6 @@ cell_t propval_cell(struct property *prop) return fdt32_to_cpu(*((cell_t *)prop->val.val)); } -struct property *get_property_by_label(struct node *tree, const char *label, - struct node **node) -{ - struct property *prop; - struct node *c; - - *node = tree; - - for_each_property(tree, prop) { - struct label *l; - - for_each_label(prop->labels, l) - if (streq(l->label, label)) - return prop; - } - - for_each_child(tree, c) { - prop = get_property_by_label(c, label, node); - if (prop) - return prop; - } - - *node = NULL; - return NULL; -} - -struct marker *get_marker_label(struct node *tree, const char *label, - struct node **node, struct property **prop) -{ - struct marker *m; - struct property *p; - struct node *c; - - *node = tree; - - for_each_property(tree, p) { - *prop = p; - m = p->val.markers; - for_each_marker_of_type(m, LABEL) - if (streq(m->ref, label)) - return m; - } - - for_each_child(tree, c) { - m = get_marker_label(c, label, node, prop); - if (m) - return m; - } - - *prop = NULL; - *node = NULL; - return NULL; -} - struct node *get_subnode(struct node *node, const char *nodename) { struct node *child; @@ -374,13 +245,11 @@ struct node *get_node_by_path(struct node *tree, const char *path) struct node *get_node_by_label(struct node *tree, const char *label) { struct node *child, *node; - struct label *l; assert(label && (strlen(label) > 0)); - for_each_label(tree->labels, l) - if (streq(l->label, label)) - return tree; + if (tree->label && streq(tree->label, label)) + return tree; for_each_child(tree, child) { node = get_node_by_label(child, label); @@ -424,186 +293,16 @@ cell_t get_node_phandle(struct node *root, struct node *node) if ((node->phandle != 0) && (node->phandle != -1)) return node->phandle; + assert(! get_property(node, "linux,phandle")); + while (get_node_by_phandle(root, phandle)) phandle++; node->phandle = phandle; - - if (!get_property(node, "linux,phandle") - && (phandle_format & PHANDLE_LEGACY)) - add_property(node, - build_property("linux,phandle", - data_append_cell(empty_data, phandle))); - - if (!get_property(node, "phandle") - && (phandle_format & PHANDLE_EPAPR)) - add_property(node, - build_property("phandle", - data_append_cell(empty_data, phandle))); - - /* If the node *does* have a phandle property, we must - * be dealing with a self-referencing phandle, which will be - * fixed up momentarily in the caller */ + add_property(node, + build_property("linux,phandle", + data_append_cell(empty_data, phandle), + NULL)); return node->phandle; } - -uint32_t guess_boot_cpuid(struct node *tree) -{ - struct node *cpus, *bootcpu; - struct property *reg; - - cpus = get_node_by_path(tree, "/cpus"); - if (!cpus) - return 0; - - - bootcpu = cpus->children; - if (!bootcpu) - return 0; - - reg = get_property(bootcpu, "reg"); - if (!reg || (reg->val.len != sizeof(uint32_t))) - return 0; - - /* FIXME: Sanity check node? */ - - return propval_cell(reg); -} - -static int cmp_reserve_info(const void *ax, const void *bx) -{ - const struct reserve_info *a, *b; - - a = *((const struct reserve_info * const *)ax); - b = *((const struct reserve_info * const *)bx); - - if (a->re.address < b->re.address) - return -1; - else if (a->re.address > b->re.address) - return 1; - else if (a->re.size < b->re.size) - return -1; - else if (a->re.size > b->re.size) - return 1; - else - return 0; -} - -static void sort_reserve_entries(struct boot_info *bi) -{ - struct reserve_info *ri, **tbl; - int n = 0, i = 0; - - for (ri = bi->reservelist; - ri; - ri = ri->next) - n++; - - if (n == 0) - return; - - tbl = xmalloc(n * sizeof(*tbl)); - - for (ri = bi->reservelist; - ri; - ri = ri->next) - tbl[i++] = ri; - - qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); - - bi->reservelist = tbl[0]; - for (i = 0; i < (n-1); i++) - tbl[i]->next = tbl[i+1]; - tbl[n-1]->next = NULL; - - free(tbl); -} - -static int cmp_prop(const void *ax, const void *bx) -{ - const struct property *a, *b; - - a = *((const struct property * const *)ax); - b = *((const struct property * const *)bx); - - return strcmp(a->name, b->name); -} - -static void sort_properties(struct node *node) -{ - int n = 0, i = 0; - struct property *prop, **tbl; - - for_each_property(node, prop) - n++; - - if (n == 0) - return; - - tbl = xmalloc(n * sizeof(*tbl)); - - for_each_property(node, prop) - tbl[i++] = prop; - - qsort(tbl, n, sizeof(*tbl), cmp_prop); - - node->proplist = tbl[0]; - for (i = 0; i < (n-1); i++) - tbl[i]->next = tbl[i+1]; - tbl[n-1]->next = NULL; - - free(tbl); -} - -static int cmp_subnode(const void *ax, const void *bx) -{ - const struct node *a, *b; - - a = *((const struct node * const *)ax); - b = *((const struct node * const *)bx); - - return strcmp(a->name, b->name); -} - -static void sort_subnodes(struct node *node) -{ - int n = 0, i = 0; - struct node *subnode, **tbl; - - for_each_child(node, subnode) - n++; - - if (n == 0) - return; - - tbl = xmalloc(n * sizeof(*tbl)); - - for_each_child(node, subnode) - tbl[i++] = subnode; - - qsort(tbl, n, sizeof(*tbl), cmp_subnode); - - node->children = tbl[0]; - for (i = 0; i < (n-1); i++) - tbl[i]->next_sibling = tbl[i+1]; - tbl[n-1]->next_sibling = NULL; - - free(tbl); -} - -static void sort_node(struct node *node) -{ - struct node *c; - - sort_properties(node); - sort_subnodes(node); - for_each_child(node, c) - sort_node(c); -} - -void sort_tree(struct boot_info *bi) -{ - sort_reserve_entries(bi); - sort_node(bi->dt); -} diff --git a/trunk/scripts/dtc/srcpos.c b/trunk/scripts/dtc/srcpos.c index 2dbc874288ca..9641b7628b4d 100644 --- a/trunk/scripts/dtc/srcpos.c +++ b/trunk/scripts/dtc/srcpos.c @@ -17,232 +17,100 @@ * USA */ -#define _GNU_SOURCE - -#include - #include "dtc.h" #include "srcpos.h" +/* + * Like yylineno, this is the current open file pos. + */ -static char *dirname(const char *path) -{ - const char *slash = strrchr(path, '/'); - - if (slash) { - int len = slash - path; - char *dir = xmalloc(len + 1); - - memcpy(dir, path, len); - dir[len] = '\0'; - return dir; - } - return NULL; -} - -struct srcfile_state *current_srcfile; /* = NULL */ - -/* Detect infinite include recursion. */ -#define MAX_SRCFILE_DEPTH (100) -static int srcfile_depth; /* = 0 */ +struct dtc_file *srcpos_file; -FILE *srcfile_relative_open(const char *fname, char **fullnamep) +static int dtc_open_one(struct dtc_file *file, + const char *search, + const char *fname) { - FILE *f; char *fullname; - if (streq(fname, "-")) { - f = stdin; - fullname = xstrdup(""); + if (search) { + fullname = xmalloc(strlen(search) + strlen(fname) + 2); + + strcpy(fullname, search); + strcat(fullname, "/"); + strcat(fullname, fname); } else { - if (!current_srcfile || !current_srcfile->dir - || (fname[0] == '/')) - fullname = xstrdup(fname); - else - fullname = join_path(current_srcfile->dir, fname); - - f = fopen(fullname, "r"); - if (!f) - die("Couldn't open \"%s\": %s\n", fname, - strerror(errno)); + fullname = strdup(fname); } - if (fullnamep) - *fullnamep = fullname; - else + file->file = fopen(fullname, "r"); + if (!file->file) { free(fullname); + return 0; + } - return f; -} - -void srcfile_push(const char *fname) -{ - struct srcfile_state *srcfile; - - if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) - die("Includes nested too deeply"); - - srcfile = xmalloc(sizeof(*srcfile)); - - srcfile->f = srcfile_relative_open(fname, &srcfile->name); - srcfile->dir = dirname(srcfile->name); - srcfile->prev = current_srcfile; - - srcfile->lineno = 1; - srcfile->colno = 1; - - current_srcfile = srcfile; -} - -int srcfile_pop(void) -{ - struct srcfile_state *srcfile = current_srcfile; - - assert(srcfile); - - current_srcfile = srcfile->prev; - - if (fclose(srcfile->f)) - die("Error closing \"%s\": %s\n", srcfile->name, - strerror(errno)); - - /* FIXME: We allow the srcfile_state structure to leak, - * because it could still be referenced from a location - * variable being carried through the parser somewhere. To - * fix this we could either allocate all the files from a - * table, or use a pool allocator. */ - - return current_srcfile ? 1 : 0; + file->name = fullname; + return 1; } -/* - * The empty source position. - */ - -struct srcpos srcpos_empty = { - .first_line = 0, - .first_column = 0, - .last_line = 0, - .last_column = 0, - .file = NULL, -}; - -#define TAB_SIZE 8 -void srcpos_update(struct srcpos *pos, const char *text, int len) +struct dtc_file *dtc_open_file(const char *fname, + const struct search_path *search) { - int i; - - pos->file = current_srcfile; - - pos->first_line = current_srcfile->lineno; - pos->first_column = current_srcfile->colno; - - for (i = 0; i < len; i++) - if (text[i] == '\n') { - current_srcfile->lineno++; - current_srcfile->colno = 1; - } else if (text[i] == '\t') { - current_srcfile->colno = - ALIGN(current_srcfile->colno, TAB_SIZE); - } else { - current_srcfile->colno++; - } - - pos->last_line = current_srcfile->lineno; - pos->last_column = current_srcfile->colno; -} - -struct srcpos * -srcpos_copy(struct srcpos *pos) -{ - struct srcpos *pos_new; + static const struct search_path default_search = { NULL, NULL, NULL }; - pos_new = xmalloc(sizeof(struct srcpos)); - memcpy(pos_new, pos, sizeof(struct srcpos)); + struct dtc_file *file; + const char *slash; - return pos_new; -} + file = xmalloc(sizeof(struct dtc_file)); + slash = strrchr(fname, '/'); + if (slash) { + char *dir = xmalloc(slash - fname + 1); + memcpy(dir, fname, slash - fname); + dir[slash - fname] = 0; + file->dir = dir; + } else { + file->dir = NULL; + } -void -srcpos_dump(struct srcpos *pos) -{ - printf("file : \"%s\"\n", - pos->file ? (char *) pos->file : ""); - printf("first_line : %d\n", pos->first_line); - printf("first_column: %d\n", pos->first_column); - printf("last_line : %d\n", pos->last_line); - printf("last_column : %d\n", pos->last_column); - printf("file : %s\n", pos->file->name); -} + if (streq(fname, "-")) { + file->name = "stdin"; + file->file = stdin; + return file; + } + if (fname[0] == '/') { + file->file = fopen(fname, "r"); + if (!file->file) + goto fail; -char * -srcpos_string(struct srcpos *pos) -{ - const char *fname = ""; - char *pos_str; - int rc; - - if (pos) - fname = pos->file->name; - - - if (pos->first_line != pos->last_line) - rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, - pos->first_line, pos->first_column, - pos->last_line, pos->last_column); - else if (pos->first_column != pos->last_column) - rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, - pos->first_line, pos->first_column, - pos->last_column); - else - rc = asprintf(&pos_str, "%s:%d.%d", fname, - pos->first_line, pos->first_column); - - if (rc == -1) - die("Couldn't allocate in srcpos string"); - - return pos_str; -} + file->name = strdup(fname); + return file; + } -void -srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) -{ - const char *srcstr; + if (!search) + search = &default_search; - srcstr = srcpos_string(pos); + while (search) { + if (dtc_open_one(file, search->dir, fname)) + return file; - fprintf(stdout, "Error: %s ", srcstr); - vfprintf(stdout, fmt, va); - fprintf(stdout, "\n"); -} + if (errno != ENOENT) + goto fail; -void -srcpos_error(struct srcpos *pos, char const *fmt, ...) -{ - va_list va; + search = search->next; + } - va_start(va, fmt); - srcpos_verror(pos, fmt, va); - va_end(va); +fail: + die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); } - -void -srcpos_warn(struct srcpos *pos, char const *fmt, ...) +void dtc_close_file(struct dtc_file *file) { - const char *srcstr; - va_list va; - va_start(va, fmt); - - srcstr = srcpos_string(pos); - - fprintf(stderr, "Warning: %s ", srcstr); - vfprintf(stderr, fmt, va); - fprintf(stderr, "\n"); + if (fclose(file->file)) + die("Error closing \"%s\": %s\n", file->name, strerror(errno)); - va_end(va); + free(file->dir); + free(file); } diff --git a/trunk/scripts/dtc/srcpos.h b/trunk/scripts/dtc/srcpos.h index bd7966e56a53..e17c7c04db8e 100644 --- a/trunk/scripts/dtc/srcpos.h +++ b/trunk/scripts/dtc/srcpos.h @@ -17,70 +17,69 @@ * USA */ -#ifndef _SRCPOS_H_ -#define _SRCPOS_H_ +/* + * Augment the standard YYLTYPE with a filenum index into an + * array of all opened filenames. + */ #include -struct srcfile_state { - FILE *f; - char *name; +struct dtc_file { char *dir; - int lineno, colno; - struct srcfile_state *prev; + const char *name; + FILE *file; }; -extern struct srcfile_state *current_srcfile; /* = NULL */ - -FILE *srcfile_relative_open(const char *fname, char **fullnamep); -void srcfile_push(const char *fname); -int srcfile_pop(void); - -struct srcpos { +#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) +typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; - struct srcfile_state *file; -}; + struct dtc_file *file; +} YYLTYPE; -#define YYLTYPE struct srcpos +#define YYLTYPE_IS_DECLARED 1 +#define YYLTYPE_IS_TRIVIAL 1 +#endif -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (N) { \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - (Current).file = YYRHSLOC(Rhs, N).file; \ - } else { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC(Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC(Rhs, 0).last_column; \ - (Current).file = YYRHSLOC (Rhs, 0).file; \ - } \ - } while (0) +/* Cater to old parser templates. */ +#ifndef YYID +#define YYID(n) (n) +#endif + +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + (Current).file = YYRHSLOC (Rhs, N).file; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + (Current).file = YYRHSLOC (Rhs, 0).file; \ + } \ + while (YYID (0)) -/* - * Fictional source position used for IR nodes that are - * created without otherwise knowing a true source position. - * For example,constant definitions from the command line. - */ -extern struct srcpos srcpos_empty; -extern void srcpos_update(struct srcpos *pos, const char *text, int len); -extern struct srcpos *srcpos_copy(struct srcpos *pos); -extern char *srcpos_string(struct srcpos *pos); -extern void srcpos_dump(struct srcpos *pos); +extern void yyerror(char const *); +extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2))); -extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) - __attribute__((format(printf, 2, 0))); -extern void srcpos_error(struct srcpos *pos, char const *, ...) - __attribute__((format(printf, 2, 3))); -extern void srcpos_warn(struct srcpos *pos, char const *, ...) - __attribute__((format(printf, 2, 3))); +extern struct dtc_file *srcpos_file; + +struct search_path { + const char *dir; /* NULL for current directory */ + struct search_path *prev, *next; +}; -#endif /* _SRCPOS_H_ */ +extern struct dtc_file *dtc_open_file(const char *fname, + const struct search_path *search); +extern void dtc_close_file(struct dtc_file *file); diff --git a/trunk/scripts/dtc/treesource.c b/trunk/scripts/dtc/treesource.c index c09aafade313..1521ff11bb97 100644 --- a/trunk/scripts/dtc/treesource.c +++ b/trunk/scripts/dtc/treesource.c @@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname) the_boot_info = NULL; treesource_error = 0; - srcfile_push(fname); - yyin = current_srcfile->f; + srcpos_file = dtc_open_file(fname, NULL); + yyin = srcpos_file->file; if (yyparse() != 0) die("Unable to parse input tree\n"); @@ -63,20 +63,26 @@ static void write_propval_string(FILE *f, struct data val) { const char *str = val.val; int i; + int newchunk = 1; struct marker *m = val.markers; assert(str[val.len-1] == '\0'); - while (m && (m->offset == 0)) { - if (m->type == LABEL) - fprintf(f, "%s: ", m->ref); - m = m->next; - } - fprintf(f, "\""); - for (i = 0; i < (val.len-1); i++) { char c = str[i]; + if (newchunk) { + while (m && (m->offset <= i)) { + if (m->type == LABEL) { + assert(m->offset == i); + fprintf(f, "%s: ", m->ref); + } + m = m->next; + } + fprintf(f, "\""); + newchunk = 0; + } + switch (c) { case '\a': fprintf(f, "\\a"); @@ -107,14 +113,7 @@ static void write_propval_string(FILE *f, struct data val) break; case '\0': fprintf(f, "\", "); - while (m && (m->offset < i)) { - if (m->type == LABEL) { - assert(m->offset == (i+1)); - fprintf(f, "%s: ", m->ref); - } - m = m->next; - } - fprintf(f, "\""); + newchunk = 1; break; default: if (isprint(c)) @@ -235,11 +234,10 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) { struct property *prop; struct node *child; - struct label *l; write_prefix(f, level); - for_each_label(tree->labels, l) - fprintf(f, "%s: ", l->label); + if (tree->label) + fprintf(f, "%s: ", tree->label); if (tree->name && (*tree->name)) fprintf(f, "%s {\n", tree->name); else @@ -247,8 +245,8 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) for_each_property(tree, prop) { write_prefix(f, level+1); - for_each_label(prop->labels, l) - fprintf(f, "%s: ", l->label); + if (prop->label) + fprintf(f, "%s: ", prop->label); fprintf(f, "%s", prop->name); write_propval(f, prop); } @@ -268,10 +266,8 @@ void dt_to_source(FILE *f, struct boot_info *bi) fprintf(f, "/dts-v1/;\n\n"); for (re = bi->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) - fprintf(f, "%s: ", l->label); + if (re->label) + fprintf(f, "%s: ", re->label); fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", (unsigned long long)re->re.address, (unsigned long long)re->re.size); diff --git a/trunk/scripts/dtc/util.c b/trunk/scripts/dtc/util.c deleted file mode 100644 index d7ac27d2ae15..000000000000 --- a/trunk/scripts/dtc/util.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include -#include -#include -#include - -#include "util.h" - -char *xstrdup(const char *s) -{ - int len = strlen(s) + 1; - char *dup = xmalloc(len); - - memcpy(dup, s, len); - - return dup; -} - -char *join_path(const char *path, const char *name) -{ - int lenp = strlen(path); - int lenn = strlen(name); - int len; - int needslash = 1; - char *str; - - len = lenp + lenn + 2; - if ((lenp > 0) && (path[lenp-1] == '/')) { - needslash = 0; - len--; - } - - str = xmalloc(len); - memcpy(str, path, lenp); - if (needslash) { - str[lenp] = '/'; - lenp++; - } - memcpy(str+lenp, name, lenn+1); - return str; -} diff --git a/trunk/scripts/dtc/util.h b/trunk/scripts/dtc/util.h deleted file mode 100644 index 9cead842c11e..000000000000 --- a/trunk/scripts/dtc/util.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _UTIL_H -#define _UTIL_H - -/* - * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -static inline void __attribute__((noreturn)) die(char * str, ...) -{ - va_list ap; - - va_start(ap, str); - fprintf(stderr, "FATAL ERROR: "); - vfprintf(stderr, str, ap); - exit(1); -} - -static inline void *xmalloc(size_t len) -{ - void *new = malloc(len); - - if (!new) - die("malloc() failed\n"); - - return new; -} - -static inline void *xrealloc(void *p, size_t len) -{ - void *new = realloc(p, len); - - if (!new) - die("realloc() failed (len=%d)\n", len); - - return new; -} - -extern char *xstrdup(const char *s); -extern char *join_path(const char *path, const char *name); - -#endif /* _UTIL_H */ diff --git a/trunk/scripts/dtc/version_gen.h b/trunk/scripts/dtc/version_gen.h index 6158b867df99..658ff42429d6 100644 --- a/trunk/scripts/dtc/version_gen.h +++ b/trunk/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.2.0-g37c0b6a0" +#define DTC_VERSION "DTC 1.2.0" diff --git a/trunk/scripts/genksyms/parse.c_shipped b/trunk/scripts/genksyms/parse.c_shipped index 809b949e495b..eaee44e66a43 100644 --- a/trunk/scripts/genksyms/parse.c_shipped +++ b/trunk/scripts/genksyms/parse.c_shipped @@ -160,7 +160,7 @@ #include -#include +#include #include "genksyms.h" static int is_typedef; diff --git a/trunk/scripts/genksyms/parse.y b/trunk/scripts/genksyms/parse.y index 09a265cd7193..10d7dc724b6d 100644 --- a/trunk/scripts/genksyms/parse.y +++ b/trunk/scripts/genksyms/parse.y @@ -24,7 +24,7 @@ %{ #include -#include +#include #include "genksyms.h" static int is_typedef; diff --git a/trunk/scripts/headers.sh b/trunk/scripts/headers.sh index 978b42b3acd7..1ddcdd38d97f 100755 --- a/trunk/scripts/headers.sh +++ b/trunk/scripts/headers.sh @@ -13,7 +13,7 @@ do_command() fi } -archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)} +archs=$(ls ${srctree}/arch) for arch in ${archs}; do case ${arch} in diff --git a/trunk/scripts/headers_check.pl b/trunk/scripts/headers_check.pl index 7957e7a5166a..50d6cfd1fa77 100644 --- a/trunk/scripts/headers_check.pl +++ b/trunk/scripts/headers_check.pl @@ -64,10 +64,10 @@ sub check_include sub check_declarations { - if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { + if ($line =~m/^\s*extern\b/) { printf STDERR "$filename:$lineno: " . - "userspace cannot reference function or " . - "variable defined in the kernel\n"; + "userspace cannot call function or variable " . + "defined in the kernel\n"; } } diff --git a/trunk/scripts/headers_install.pl b/trunk/scripts/headers_install.pl index efb3be10d428..4ca3be3b2e50 100644 --- a/trunk/scripts/headers_install.pl +++ b/trunk/scripts/headers_install.pl @@ -45,13 +45,6 @@ close $in; system $unifdef . " $tmpfile > $installdir/$file"; - # unifdef will exit 0 on success, and will exit 1 when the - # file was processed successfully but no changes were made, - # so abort only when it's higher than that. - my $e = $? >> 8; - if ($e > 1) { - die "$tmpfile: $!\n"; - } unlink $tmpfile; } exit 0; diff --git a/trunk/scripts/kconfig/conf.c b/trunk/scripts/kconfig/conf.c index 659326c3e895..5459a38be866 100644 --- a/trunk/scripts/kconfig/conf.c +++ b/trunk/scripts/kconfig/conf.c @@ -529,6 +529,8 @@ int main(int ac, char **av) } break; case savedefconfig: + conf_read(NULL); + break; case silentoldconfig: case oldaskconfig: case oldconfig: diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index 61c35bf2d9cb..9df80114b47b 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -440,11 +440,12 @@ static void conf_write_string(bool headerfile, const char *name, fputs("\"\n", out); } -static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) +static void conf_write_symbol(struct symbol *sym, enum symbol_type type, + FILE *out, bool write_no) { const char *str; - switch (sym->type) { + switch (type) { case S_BOOLEAN: case S_TRISTATE: switch (sym_get_tristate_value(sym)) { @@ -531,7 +532,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; } } - conf_write_symbol(sym, out, true); + conf_write_symbol(sym, sym->type, out, true); } next_menu: if (menu->list != NULL) { @@ -560,6 +561,7 @@ int conf_write(const char *name) const char *basename; const char *str; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; + enum symbol_type type; time_t now; int use_timestamp = 1; char *env; @@ -631,8 +633,14 @@ int conf_write(const char *name) if (!(sym->flags & SYMBOL_WRITE)) goto next; sym->flags &= ~SYMBOL_WRITE; + type = sym->type; + if (type == S_TRISTATE) { + sym_calc_value(modules_sym); + if (modules_sym->curr.tri == no) + type = S_BOOLEAN; + } /* Write config symbol to file */ - conf_write_symbol(sym, out, true); + conf_write_symbol(sym, type, out, true); } next: @@ -825,7 +833,8 @@ int conf_write_autoconf(void) " * Automatically generated C config: don't edit\n" " * %s\n" " * %s" - " */\n", + " */\n" + "#define AUTOCONF_INCLUDED\n", rootmenu.prompt->text, ctime(&now)); for_all_symbols(i, sym) { @@ -834,7 +843,7 @@ int conf_write_autoconf(void) continue; /* write symbol to config file */ - conf_write_symbol(sym, out, false); + conf_write_symbol(sym, sym->type, out, false); /* update autoconf and tristate files */ switch (sym->type) { @@ -937,7 +946,7 @@ static void randomize_choice_values(struct symbol *csym) int cnt, def; /* - * If choice is mod then we may have more items selected + * If choice is mod then we may have more items slected * and if no then no-one. * In both cases stop. */ @@ -1033,10 +1042,10 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) /* * We have different type of choice blocks. - * If curr.tri equals to mod then we can select several + * If curr.tri equal to mod then we can select several * choice symbols in one block. * In this case we do nothing. - * If curr.tri equals yes then only one symbol can be + * If curr.tri equal yes then only one symbol can be * selected in a choice block and we set it to yes, * and the rest to no. */ diff --git a/trunk/scripts/kconfig/expr.c b/trunk/scripts/kconfig/expr.c index 001003452f68..330e7c0048a8 100644 --- a/trunk/scripts/kconfig/expr.c +++ b/trunk/scripts/kconfig/expr.c @@ -64,7 +64,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; } -struct expr *expr_copy(const struct expr *org) +struct expr *expr_copy(struct expr *org) { struct expr *e; @@ -1013,48 +1013,6 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #endif } -static inline struct expr * -expr_get_leftmost_symbol(const struct expr *e) -{ - - if (e == NULL) - return NULL; - - while (e->type != E_SYMBOL) - e = e->left.expr; - - return expr_copy(e); -} - -/* - * Given expression `e1' and `e2', returns the leaf of the longest - * sub-expression of `e1' not containing 'e2. - */ -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2) -{ - struct expr *ret; - - switch (e1->type) { - case E_OR: - return expr_alloc_and( - expr_simplify_unmet_dep(e1->left.expr, e2), - expr_simplify_unmet_dep(e1->right.expr, e2)); - case E_AND: { - struct expr *e; - e = expr_alloc_and(expr_copy(e1), expr_copy(e2)); - e = expr_eliminate_dups(e); - ret = (!expr_eq(e, e1)) ? e1 : NULL; - expr_free(e); - break; - } - default: - ret = e1; - break; - } - - return expr_get_leftmost_symbol(ret); -} - void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { diff --git a/trunk/scripts/kconfig/expr.h b/trunk/scripts/kconfig/expr.h index 3d238db49764..e57826ced380 100644 --- a/trunk/scripts/kconfig/expr.h +++ b/trunk/scripts/kconfig/expr.h @@ -192,7 +192,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); -struct expr *expr_copy(const struct expr *org); +struct expr *expr_copy(struct expr *org); void expr_free(struct expr *e); int expr_eq(struct expr *e1, struct expr *e2); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); @@ -207,7 +207,6 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); void expr_fprint(struct expr *e, FILE *out); struct gstr; /* forward */ diff --git a/trunk/scripts/kconfig/lkc.h b/trunk/scripts/kconfig/lkc.h index febf0c94d558..3f7240df0f3b 100644 --- a/trunk/scripts/kconfig/lkc.h +++ b/trunk/scripts/kconfig/lkc.h @@ -14,7 +14,6 @@ static inline const char *gettext(const char *txt) { return txt; } static inline void textdomain(const char *domainname) {} static inline void bindtextdomain(const char *name, const char *dir) {} -static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } #endif #ifdef __cplusplus @@ -68,12 +67,10 @@ struct kconf_id { enum symbol_type stype; }; -#ifdef YYDEBUG -extern int zconfdebug; -#endif - int zconfparse(void); void zconfdump(FILE *out); + +extern int zconfdebug; void zconf_starthelp(void); FILE *zconf_fopen(const char *name); void zconf_initscan(const char *name); diff --git a/trunk/scripts/kconfig/menu.c b/trunk/scripts/kconfig/menu.c index 5fdf10dc1d8a..5f77dcb8977e 100644 --- a/trunk/scripts/kconfig/menu.c +++ b/trunk/scripts/kconfig/menu.c @@ -203,7 +203,7 @@ void menu_add_option(int token, char *arg) } } -static int menu_validate_number(struct symbol *sym, struct symbol *sym2) +static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); @@ -221,15 +221,6 @@ static void sym_check_prop(struct symbol *sym) prop_warn(prop, "default for config symbol '%s'" " must be a single symbol", sym->name); - if (prop->expr->type != E_SYMBOL) - break; - sym2 = prop_get_symbol(prop); - if (sym->type == S_HEX || sym->type == S_INT) { - if (!menu_validate_number(sym, sym2)) - prop_warn(prop, - "'%s': number is invalid", - sym->name); - } break; case P_SELECT: sym2 = prop_get_symbol(prop); @@ -249,8 +240,8 @@ static void sym_check_prop(struct symbol *sym) if (sym->type != S_INT && sym->type != S_HEX) prop_warn(prop, "range is only allowed " "for int or hex symbols"); - if (!menu_validate_number(sym, prop->expr->left.sym) || - !menu_validate_number(sym, prop->expr->right.sym)) + if (!menu_range_valid_sym(sym, prop->expr->left.sym) || + !menu_range_valid_sym(sym, prop->expr->right.sym)) prop_warn(prop, "range is invalid"); break; default: diff --git a/trunk/scripts/kconfig/nconf.c b/trunk/scripts/kconfig/nconf.c index db56377393d7..272a987f23e0 100644 --- a/trunk/scripts/kconfig/nconf.c +++ b/trunk/scripts/kconfig/nconf.c @@ -248,7 +248,7 @@ search_help[] = N_( "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" -"Examples: USB => find all symbols containing USB\n" +"Examples: USB = > find all symbols containing USB\n" " ^USB => find all symbols starting with USB\n" " USB$ => find all symbols ending with USB\n" "\n"); @@ -1266,13 +1266,9 @@ static void conf_choice(struct menu *menu) if (child->sym == sym_get_choice_value(menu->sym)) item_make(child, ':', " %s", _(menu_get_prompt(child))); - else if (child->sym) - item_make(child, ':', " %s", - _(menu_get_prompt(child))); else - item_make(child, ':', "*** %s ***", + item_make(child, ':', " %s", _(menu_get_prompt(child))); - if (child->sym == active){ last_top_row = top_row(curses_menu); selected_index = i; @@ -1338,7 +1334,7 @@ static void conf_choice(struct menu *menu) break; child = item_data(); - if (!child || !menu_is_visible(child) || !child->sym) + if (!child || !menu_is_visible(child)) continue; switch (res) { case ' ': diff --git a/trunk/scripts/kconfig/symbol.c b/trunk/scripts/kconfig/symbol.c index a796c95fe8a0..af6e9f3de950 100644 --- a/trunk/scripts/kconfig/symbol.c +++ b/trunk/scripts/kconfig/symbol.c @@ -351,16 +351,12 @@ void sym_calc_value(struct symbol *sym) } calc_newval: if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { - struct expr *e; - e = expr_simplify_unmet_dep(sym->rev_dep.expr, - sym->dir_dep.expr); fprintf(stderr, "warning: ("); - expr_fprint(e, stderr); + expr_fprint(sym->rev_dep.expr, stderr); fprintf(stderr, ") selects %s which has unmet direct dependencies (", sym->name); expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); - expr_free(e); } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } @@ -690,7 +686,7 @@ const char *sym_get_string_default(struct symbol *sym) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - /* The visibility may limit the value from yes => mod */ + /* The visibility imay limit the value from yes => mod */ val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); break; default: diff --git a/trunk/scripts/mkuboot.sh b/trunk/scripts/mkuboot.sh index 446739c7843a..2e3d3cd916b8 100755 --- a/trunk/scripts/mkuboot.sh +++ b/trunk/scripts/mkuboot.sh @@ -11,7 +11,7 @@ if [ -z "${MKIMAGE}" ]; then if [ -z "${MKIMAGE}" ]; then # Doesn't exist echo '"mkimage" command not found - U-Boot images will not be built' >&2 - exit 1; + exit 0; fi fi diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 97d2259ae999..33122ca04e7c 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -790,7 +790,6 @@ static const char *section_white_list[] = { ".comment*", ".debug*", - ".zdebug*", /* Compressed debug sections. */ ".GCC-command-line", /* mn10300 */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ @@ -1442,7 +1441,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = shndx2secindex(sechdr->sh_info); return (void *)elf->hdr + sechdrs[section].sh_offset + - r->r_offset; + r->r_offset - sechdrs[section].sh_addr; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) diff --git a/trunk/scripts/package/builddeb b/trunk/scripts/package/builddeb index b0b2357aef42..49b74e1ee12d 100644 --- a/trunk/scripts/package/builddeb +++ b/trunk/scripts/package/builddeb @@ -25,44 +25,8 @@ create_package() { chown -R root:root "$pdir" chmod -R go-w "$pdir" - # Attempt to find the correct Debian architecture - local forcearch="" debarch="" - case "$UTS_MACHINE" in - i386|ia64|alpha) - debarch="$UTS_MACHINE" ;; - x86_64) - debarch=amd64 ;; - sparc*) - debarch=sparc ;; - s390*) - debarch=s390 ;; - ppc*) - debarch=powerpc ;; - parisc*) - debarch=hppa ;; - mips*) - debarch=mips$(grep -q CPU_LITTLE_ENDIAN=y .config && echo el) ;; - arm*) - debarch=arm$(grep -q CONFIG_AEABI=y .config && echo el) ;; - *) - echo "" >&2 - echo "** ** ** WARNING ** ** **" >&2 - echo "" >&2 - echo "Your architecture doesn't have it's equivalent" >&2 - echo "Debian userspace architecture defined!" >&2 - echo "Falling back to using your current userspace instead!" >&2 - echo "Please add support for $UTS_MACHINE to ${0} ..." >&2 - echo "" >&2 - esac - if [ -n "$KBUILD_DEBARCH" ] ; then - debarch="$KBUILD_DEBARCH" - fi - if [ -n "$debarch" ] ; then - forcearch="-DArchitecture=$debarch" - fi - # Create the package - dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir" + dpkg-gencontrol -isp -p$pname -P"$pdir" dpkg --build "$pdir" .. } @@ -76,27 +40,17 @@ else fi tmpdir="$objtree/debian/tmp" fwdir="$objtree/debian/fwtmp" -kernel_headers_dir="$objtree/debian/hdrtmp" -libc_headers_dir="$objtree/debian/headertmp" packagename=linux-image-$version fwpackagename=linux-firmware-image -kernel_headers_packagename=linux-headers-$version -libc_headers_packagename=linux-libc-dev if [ "$ARCH" = "um" ] ; then packagename=user-mode-linux-$version fi # Setup the directory structure -rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" -mkdir -m 755 -p "$tmpdir/DEBIAN" -mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" -mkdir -m 755 -p "$fwdir/DEBIAN" -mkdir -p "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" -mkdir -m 755 -p "$libc_headers_dir/DEBIAN" -mkdir -p "$libc_headers_dir/usr/share/doc/$libc_headers_packagename" -mkdir -m 755 -p "$kernel_headers_dir/DEBIAN" -mkdir -p "$kernel_headers_dir/usr/share/doc/$kernel_headers_packagename" +rm -rf "$tmpdir" "$fwdir" +mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" +mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" if [ "$ARCH" = "um" ] ; then mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" fi @@ -127,9 +81,6 @@ if grep -q '^CONFIG_MODULES=y' .config ; then fi fi -make headers_check -make headers_install INSTALL_HDR_PATH="$libc_headers_dir/usr" - # Install the maintainer scripts # Note: hook scripts under /etc/kernel are also executed by official Debian # kernel packages, as well as kernel packages built using make-kpkg @@ -237,30 +188,6 @@ EOF fi -# Build header package -find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$ -find arch/x86/include include scripts -type f >> /tmp/files$$ -(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$) -destdir=$kernel_headers_dir/usr/src/linux-headers-$version -mkdir -p "$destdir" -tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -) -(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -) -rm -f /tmp/files$$ /tmp/objfiles$$ -arch=$(dpkg --print-architecture) - -cat <> debian/control - -Package: $kernel_headers_packagename -Provides: linux-headers, linux-headers-2.6 -Architecture: $arch -Description: Linux kernel headers for $KERNELRELEASE on $arch - This package provides kernel header files for $KERNELRELEASE on $arch - . - This is useful for people who need to build external modules -EOF - -create_package "$kernel_headers_packagename" "$kernel_headers_dir" - # Do we have firmware? Move it out of the way and build it into a package. if [ -e "$tmpdir/lib/firmware" ]; then mv "$tmpdir/lib/firmware" "$fwdir/lib/" @@ -276,18 +203,6 @@ EOF create_package "$fwpackagename" "$fwdir" fi -cat <> debian/control - -Package: $libc_headers_packagename -Section: devel -Provides: linux-kernel-headers -Architecture: any -Description: Linux support headers for userspace development - This package provides userspaces headers from the Linux kernel. These headers - are used by the installed headers for GNU glibc and other system libraries. -EOF - -create_package "$libc_headers_packagename" "$libc_headers_dir" create_package "$packagename" "$tmpdir" exit 0 diff --git a/trunk/scripts/tags.sh b/trunk/scripts/tags.sh index 92fdc4546141..bbbe584d4494 100755 --- a/trunk/scripts/tags.sh +++ b/trunk/scripts/tags.sh @@ -123,7 +123,7 @@ exuberant() -I ____cacheline_internodealigned_in_smp \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ - --extra=+f --c-kinds=+px \ + --extra=+f --c-kinds=-px \ --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ diff --git a/trunk/security/Kconfig b/trunk/security/Kconfig index 95accd442d55..e80da955e687 100644 --- a/trunk/security/Kconfig +++ b/trunk/security/Kconfig @@ -21,37 +21,6 @@ config KEYS If you are unsure as to whether this is required, answer N. -config TRUSTED_KEYS - tristate "TRUSTED KEYS" - depends on KEYS && TCG_TPM - select CRYPTO - select CRYPTO_HMAC - select CRYPTO_SHA1 - help - This option provides support for creating, sealing, and unsealing - keys in the kernel. Trusted keys are random number symmetric keys, - generated and RSA-sealed by the TPM. The TPM only unseals the keys, - if the boot PCRs and other criteria match. Userspace will only ever - see encrypted blobs. - - If you are unsure as to whether this is required, answer N. - -config ENCRYPTED_KEYS - tristate "ENCRYPTED KEYS" - depends on KEYS && TRUSTED_KEYS - select CRYPTO_AES - select CRYPTO_CBC - select CRYPTO_SHA256 - select CRYPTO_RNG - help - This option provides support for create/encrypting/decrypting keys - in the kernel. Encrypted keys are kernel generated random numbers, - which are encrypted/decrypted with a 'master' symmetric key. The - 'master' key can be either a trusted-key or user-key type. - Userspace only ever sees/stores encrypted blobs. - - If you are unsure as to whether this is required, answer N. - config KEYS_DEBUG_PROC_KEYS bool "Enable the /proc/keys file by which keys may be viewed" depends on KEYS diff --git a/trunk/security/apparmor/include/file.h b/trunk/security/apparmor/include/file.h index ab8c6d87f758..be36feabb16a 100644 --- a/trunk/security/apparmor/include/file.h +++ b/trunk/security/apparmor/include/file.h @@ -15,11 +15,12 @@ #ifndef __AA_FILE_H #define __AA_FILE_H +#include + #include "domain.h" #include "match.h" struct aa_profile; -struct path; /* * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags diff --git a/trunk/security/apparmor/include/match.h b/trunk/security/apparmor/include/match.h index 19ba16e8aacd..734a6d35112c 100644 --- a/trunk/security/apparmor/include/match.h +++ b/trunk/security/apparmor/include/match.h @@ -15,7 +15,6 @@ #ifndef __AA_MATCH_H #define __AA_MATCH_H -#include #include #define DFA_NOMATCH 0 diff --git a/trunk/security/keys/Makefile b/trunk/security/keys/Makefile index 6c941050f573..74d5447d7df7 100644 --- a/trunk/security/keys/Makefile +++ b/trunk/security/keys/Makefile @@ -13,8 +13,6 @@ obj-y := \ request_key_auth.o \ user_defined.o -obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o -obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted_defined.o obj-$(CONFIG_KEYS_COMPAT) += compat.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSCTL) += sysctl.o diff --git a/trunk/security/keys/encrypted_defined.c b/trunk/security/keys/encrypted_defined.c deleted file mode 100644 index 32d27c858388..000000000000 --- a/trunk/security/keys/encrypted_defined.c +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright (C) 2010 IBM Corporation - * - * Author: - * Mimi Zohar - * - * 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 of the License. - * - * See Documentation/keys-trusted-encrypted.txt - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "encrypted_defined.h" - -static const char KEY_TRUSTED_PREFIX[] = "trusted:"; -static const char KEY_USER_PREFIX[] = "user:"; -static const char hash_alg[] = "sha256"; -static const char hmac_alg[] = "hmac(sha256)"; -static const char blkcipher_alg[] = "cbc(aes)"; -static unsigned int ivsize; -static int blksize; - -#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1) -#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1) -#define HASH_SIZE SHA256_DIGEST_SIZE -#define MAX_DATA_SIZE 4096 -#define MIN_DATA_SIZE 20 - -struct sdesc { - struct shash_desc shash; - char ctx[]; -}; - -static struct crypto_shash *hashalg; -static struct crypto_shash *hmacalg; - -enum { - Opt_err = -1, Opt_new, Opt_load, Opt_update -}; - -static const match_table_t key_tokens = { - {Opt_new, "new"}, - {Opt_load, "load"}, - {Opt_update, "update"}, - {Opt_err, NULL} -}; - -static int aes_get_sizes(void) -{ - struct crypto_blkcipher *tfm; - - tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) { - pr_err("encrypted_key: failed to alloc_cipher (%ld)\n", - PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - ivsize = crypto_blkcipher_ivsize(tfm); - blksize = crypto_blkcipher_blocksize(tfm); - crypto_free_blkcipher(tfm); - return 0; -} - -/* - * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key - * - * key-type:= "trusted:" | "encrypted:" - * desc:= master-key description - * - * Verify that 'key-type' is valid and that 'desc' exists. On key update, - * only the master key description is permitted to change, not the key-type. - * The key-type remains constant. - * - * On success returns 0, otherwise -EINVAL. - */ -static int valid_master_desc(const char *new_desc, const char *orig_desc) -{ - if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) { - if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN) - goto out; - if (orig_desc) - if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN)) - goto out; - } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) { - if (strlen(new_desc) == KEY_USER_PREFIX_LEN) - goto out; - if (orig_desc) - if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN)) - goto out; - } else - goto out; - return 0; -out: - return -EINVAL; -} - -/* - * datablob_parse - parse the keyctl data - * - * datablob format: - * new - * load - * update - * - * Tokenizes a copy of the keyctl data, returning a pointer to each token, - * which is null terminated. - * - * On success returns 0, otherwise -EINVAL. - */ -static int datablob_parse(char *datablob, char **master_desc, - char **decrypted_datalen, char **hex_encoded_iv) -{ - substring_t args[MAX_OPT_ARGS]; - int ret = -EINVAL; - int key_cmd; - char *p; - - p = strsep(&datablob, " \t"); - if (!p) - return ret; - key_cmd = match_token(p, key_tokens, args); - - *master_desc = strsep(&datablob, " \t"); - if (!*master_desc) - goto out; - - if (valid_master_desc(*master_desc, NULL) < 0) - goto out; - - if (decrypted_datalen) { - *decrypted_datalen = strsep(&datablob, " \t"); - if (!*decrypted_datalen) - goto out; - } - - switch (key_cmd) { - case Opt_new: - if (!decrypted_datalen) - break; - ret = 0; - break; - case Opt_load: - if (!decrypted_datalen) - break; - *hex_encoded_iv = strsep(&datablob, " \t"); - if (!*hex_encoded_iv) - break; - ret = 0; - break; - case Opt_update: - if (decrypted_datalen) - break; - ret = 0; - break; - case Opt_err: - break; - } -out: - return ret; -} - -/* - * datablob_format - format as an ascii string, before copying to userspace - */ -static char *datablob_format(struct encrypted_key_payload *epayload, - size_t asciiblob_len) -{ - char *ascii_buf, *bufp; - u8 *iv = epayload->iv; - int len; - int i; - - ascii_buf = kmalloc(asciiblob_len + 1, GFP_KERNEL); - if (!ascii_buf) - goto out; - - ascii_buf[asciiblob_len] = '\0'; - - /* copy datablob master_desc and datalen strings */ - len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, - epayload->datalen); - - /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ - bufp = &ascii_buf[len]; - for (i = 0; i < (asciiblob_len - len) / 2; i++) - bufp = pack_hex_byte(bufp, iv[i]); -out: - return ascii_buf; -} - -/* - * request_trusted_key - request the trusted key - * - * Trusted keys are sealed to PCRs and other metadata. Although userspace - * manages both trusted/encrypted key-types, like the encrypted key type - * data, trusted key type data is not visible decrypted from userspace. - */ -static struct key *request_trusted_key(const char *trusted_desc, - u8 **master_key, size_t *master_keylen) -{ - struct trusted_key_payload *tpayload; - struct key *tkey; - - tkey = request_key(&key_type_trusted, trusted_desc, NULL); - if (IS_ERR(tkey)) - goto error; - - down_read(&tkey->sem); - tpayload = rcu_dereference(tkey->payload.data); - *master_key = tpayload->key; - *master_keylen = tpayload->key_len; -error: - return tkey; -} - -/* - * request_user_key - request the user key - * - * Use a user provided key to encrypt/decrypt an encrypted-key. - */ -static struct key *request_user_key(const char *master_desc, u8 **master_key, - size_t *master_keylen) -{ - struct user_key_payload *upayload; - struct key *ukey; - - ukey = request_key(&key_type_user, master_desc, NULL); - if (IS_ERR(ukey)) - goto error; - - down_read(&ukey->sem); - upayload = rcu_dereference(ukey->payload.data); - *master_key = upayload->data; - *master_keylen = upayload->datalen; -error: - return ukey; -} - -static struct sdesc *alloc_sdesc(struct crypto_shash *alg) -{ - struct sdesc *sdesc; - int size; - - size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); - sdesc = kmalloc(size, GFP_KERNEL); - if (!sdesc) - return ERR_PTR(-ENOMEM); - sdesc->shash.tfm = alg; - sdesc->shash.flags = 0x0; - return sdesc; -} - -static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen, - const u8 *buf, unsigned int buflen) -{ - struct sdesc *sdesc; - int ret; - - sdesc = alloc_sdesc(hmacalg); - if (IS_ERR(sdesc)) { - pr_info("encrypted_key: can't alloc %s\n", hmac_alg); - return PTR_ERR(sdesc); - } - - ret = crypto_shash_setkey(hmacalg, key, keylen); - if (!ret) - ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest); - kfree(sdesc); - return ret; -} - -static int calc_hash(u8 *digest, const u8 *buf, unsigned int buflen) -{ - struct sdesc *sdesc; - int ret; - - sdesc = alloc_sdesc(hashalg); - if (IS_ERR(sdesc)) { - pr_info("encrypted_key: can't alloc %s\n", hash_alg); - return PTR_ERR(sdesc); - } - - ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest); - kfree(sdesc); - return ret; -} - -enum derived_key_type { ENC_KEY, AUTH_KEY }; - -/* Derive authentication/encryption key from trusted key */ -static int get_derived_key(u8 *derived_key, enum derived_key_type key_type, - const u8 *master_key, size_t master_keylen) -{ - u8 *derived_buf; - unsigned int derived_buf_len; - int ret; - - derived_buf_len = strlen("AUTH_KEY") + 1 + master_keylen; - if (derived_buf_len < HASH_SIZE) - derived_buf_len = HASH_SIZE; - - derived_buf = kzalloc(derived_buf_len, GFP_KERNEL); - if (!derived_buf) { - pr_err("encrypted_key: out of memory\n"); - return -ENOMEM; - } - if (key_type) - strcpy(derived_buf, "AUTH_KEY"); - else - strcpy(derived_buf, "ENC_KEY"); - - memcpy(derived_buf + strlen(derived_buf) + 1, master_key, - master_keylen); - ret = calc_hash(derived_key, derived_buf, derived_buf_len); - kfree(derived_buf); - return ret; -} - -static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key, - unsigned int key_len, const u8 *iv, - unsigned int ivsize) -{ - int ret; - - desc->tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(desc->tfm)) { - pr_err("encrypted_key: failed to load %s transform (%ld)\n", - blkcipher_alg, PTR_ERR(desc->tfm)); - return PTR_ERR(desc->tfm); - } - desc->flags = 0; - - ret = crypto_blkcipher_setkey(desc->tfm, key, key_len); - if (ret < 0) { - pr_err("encrypted_key: failed to setkey (%d)\n", ret); - crypto_free_blkcipher(desc->tfm); - return ret; - } - crypto_blkcipher_set_iv(desc->tfm, iv, ivsize); - return 0; -} - -static struct key *request_master_key(struct encrypted_key_payload *epayload, - u8 **master_key, size_t *master_keylen) -{ - struct key *mkey = NULL; - - if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX, - KEY_TRUSTED_PREFIX_LEN)) { - mkey = request_trusted_key(epayload->master_desc + - KEY_TRUSTED_PREFIX_LEN, - master_key, master_keylen); - } else if (!strncmp(epayload->master_desc, KEY_USER_PREFIX, - KEY_USER_PREFIX_LEN)) { - mkey = request_user_key(epayload->master_desc + - KEY_USER_PREFIX_LEN, - master_key, master_keylen); - } else - goto out; - - if (IS_ERR(mkey)) - pr_info("encrypted_key: key %s not found", - epayload->master_desc); - if (mkey) - dump_master_key(*master_key, *master_keylen); -out: - return mkey; -} - -/* Before returning data to userspace, encrypt decrypted data. */ -static int derived_key_encrypt(struct encrypted_key_payload *epayload, - const u8 *derived_key, - unsigned int derived_keylen) -{ - struct scatterlist sg_in[2]; - struct scatterlist sg_out[1]; - struct blkcipher_desc desc; - unsigned int encrypted_datalen; - unsigned int padlen; - char pad[16]; - int ret; - - encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); - padlen = encrypted_datalen - epayload->decrypted_datalen; - - ret = init_blkcipher_desc(&desc, derived_key, derived_keylen, - epayload->iv, ivsize); - if (ret < 0) - goto out; - dump_decrypted_data(epayload); - - memset(pad, 0, sizeof pad); - sg_init_table(sg_in, 2); - sg_set_buf(&sg_in[0], epayload->decrypted_data, - epayload->decrypted_datalen); - sg_set_buf(&sg_in[1], pad, padlen); - - sg_init_table(sg_out, 1); - sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); - - ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, encrypted_datalen); - crypto_free_blkcipher(desc.tfm); - if (ret < 0) - pr_err("encrypted_key: failed to encrypt (%d)\n", ret); - else - dump_encrypted_data(epayload, encrypted_datalen); -out: - return ret; -} - -static int datablob_hmac_append(struct encrypted_key_payload *epayload, - const u8 *master_key, size_t master_keylen) -{ - u8 derived_key[HASH_SIZE]; - u8 *digest; - int ret; - - ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); - if (ret < 0) - goto out; - - digest = epayload->master_desc + epayload->datablob_len; - ret = calc_hmac(digest, derived_key, sizeof derived_key, - epayload->master_desc, epayload->datablob_len); - if (!ret) - dump_hmac(NULL, digest, HASH_SIZE); -out: - return ret; -} - -/* verify HMAC before decrypting encrypted key */ -static int datablob_hmac_verify(struct encrypted_key_payload *epayload, - const u8 *master_key, size_t master_keylen) -{ - u8 derived_key[HASH_SIZE]; - u8 digest[HASH_SIZE]; - int ret; - - ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); - if (ret < 0) - goto out; - - ret = calc_hmac(digest, derived_key, sizeof derived_key, - epayload->master_desc, epayload->datablob_len); - if (ret < 0) - goto out; - ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, - sizeof digest); - if (ret) { - ret = -EINVAL; - dump_hmac("datablob", - epayload->master_desc + epayload->datablob_len, - HASH_SIZE); - dump_hmac("calc", digest, HASH_SIZE); - } -out: - return ret; -} - -static int derived_key_decrypt(struct encrypted_key_payload *epayload, - const u8 *derived_key, - unsigned int derived_keylen) -{ - struct scatterlist sg_in[1]; - struct scatterlist sg_out[2]; - struct blkcipher_desc desc; - unsigned int encrypted_datalen; - char pad[16]; - int ret; - - encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); - ret = init_blkcipher_desc(&desc, derived_key, derived_keylen, - epayload->iv, ivsize); - if (ret < 0) - goto out; - dump_encrypted_data(epayload, encrypted_datalen); - - memset(pad, 0, sizeof pad); - sg_init_table(sg_in, 1); - sg_init_table(sg_out, 2); - sg_set_buf(sg_in, epayload->encrypted_data, encrypted_datalen); - sg_set_buf(&sg_out[0], epayload->decrypted_data, - epayload->decrypted_datalen); - sg_set_buf(&sg_out[1], pad, sizeof pad); - - ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, encrypted_datalen); - crypto_free_blkcipher(desc.tfm); - if (ret < 0) - goto out; - dump_decrypted_data(epayload); -out: - return ret; -} - -/* Allocate memory for decrypted key and datablob. */ -static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, - const char *master_desc, - const char *datalen) -{ - struct encrypted_key_payload *epayload = NULL; - unsigned short datablob_len; - unsigned short decrypted_datalen; - unsigned int encrypted_datalen; - long dlen; - int ret; - - ret = strict_strtol(datalen, 10, &dlen); - if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) - return ERR_PTR(-EINVAL); - - decrypted_datalen = dlen; - encrypted_datalen = roundup(decrypted_datalen, blksize); - - datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 - + ivsize + 1 + encrypted_datalen; - - ret = key_payload_reserve(key, decrypted_datalen + datablob_len - + HASH_SIZE + 1); - if (ret < 0) - return ERR_PTR(ret); - - epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + - datablob_len + HASH_SIZE + 1, GFP_KERNEL); - if (!epayload) - return ERR_PTR(-ENOMEM); - - epayload->decrypted_datalen = decrypted_datalen; - epayload->datablob_len = datablob_len; - return epayload; -} - -static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, - const char *hex_encoded_iv) -{ - struct key *mkey; - u8 derived_key[HASH_SIZE]; - u8 *master_key; - u8 *hmac; - const char *hex_encoded_data; - unsigned int encrypted_datalen; - size_t master_keylen; - size_t asciilen; - int ret; - - encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); - asciilen = (ivsize + 1 + encrypted_datalen + HASH_SIZE) * 2; - if (strlen(hex_encoded_iv) != asciilen) - return -EINVAL; - - hex_encoded_data = hex_encoded_iv + (2 * ivsize) + 2; - hex2bin(epayload->iv, hex_encoded_iv, ivsize); - hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); - - hmac = epayload->master_desc + epayload->datablob_len; - hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); - - mkey = request_master_key(epayload, &master_key, &master_keylen); - if (IS_ERR(mkey)) - return PTR_ERR(mkey); - - ret = datablob_hmac_verify(epayload, master_key, master_keylen); - if (ret < 0) { - pr_err("encrypted_key: bad hmac (%d)\n", ret); - goto out; - } - - ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen); - if (ret < 0) - goto out; - - ret = derived_key_decrypt(epayload, derived_key, sizeof derived_key); - if (ret < 0) - pr_err("encrypted_key: failed to decrypt key (%d)\n", ret); -out: - up_read(&mkey->sem); - key_put(mkey); - return ret; -} - -static void __ekey_init(struct encrypted_key_payload *epayload, - const char *master_desc, const char *datalen) -{ - epayload->master_desc = epayload->decrypted_data - + epayload->decrypted_datalen; - epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; - epayload->iv = epayload->datalen + strlen(datalen) + 1; - epayload->encrypted_data = epayload->iv + ivsize + 1; - - memcpy(epayload->master_desc, master_desc, strlen(master_desc)); - memcpy(epayload->datalen, datalen, strlen(datalen)); -} - -/* - * encrypted_init - initialize an encrypted key - * - * For a new key, use a random number for both the iv and data - * itself. For an old key, decrypt the hex encoded data. - */ -static int encrypted_init(struct encrypted_key_payload *epayload, - const char *master_desc, const char *datalen, - const char *hex_encoded_iv) -{ - int ret = 0; - - __ekey_init(epayload, master_desc, datalen); - if (!hex_encoded_iv) { - get_random_bytes(epayload->iv, ivsize); - - get_random_bytes(epayload->decrypted_data, - epayload->decrypted_datalen); - } else - ret = encrypted_key_decrypt(epayload, hex_encoded_iv); - return ret; -} - -/* - * encrypted_instantiate - instantiate an encrypted key - * - * Decrypt an existing encrypted datablob or create a new encrypted key - * based on a kernel random number. - * - * On success, return 0. Otherwise return errno. - */ -static int encrypted_instantiate(struct key *key, const void *data, - size_t datalen) -{ - struct encrypted_key_payload *epayload = NULL; - char *datablob = NULL; - char *master_desc = NULL; - char *decrypted_datalen = NULL; - char *hex_encoded_iv = NULL; - int ret; - - if (datalen <= 0 || datalen > 32767 || !data) - return -EINVAL; - - datablob = kmalloc(datalen + 1, GFP_KERNEL); - if (!datablob) - return -ENOMEM; - datablob[datalen] = 0; - memcpy(datablob, data, datalen); - ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, - &hex_encoded_iv); - if (ret < 0) - goto out; - - epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); - if (IS_ERR(epayload)) { - ret = PTR_ERR(epayload); - goto out; - } - ret = encrypted_init(epayload, master_desc, decrypted_datalen, - hex_encoded_iv); - if (ret < 0) { - kfree(epayload); - goto out; - } - - rcu_assign_pointer(key->payload.data, epayload); -out: - kfree(datablob); - return ret; -} - -static void encrypted_rcu_free(struct rcu_head *rcu) -{ - struct encrypted_key_payload *epayload; - - epayload = container_of(rcu, struct encrypted_key_payload, rcu); - memset(epayload->decrypted_data, 0, epayload->decrypted_datalen); - kfree(epayload); -} - -/* - * encrypted_update - update the master key description - * - * Change the master key description for an existing encrypted key. - * The next read will return an encrypted datablob using the new - * master key description. - * - * On success, return 0. Otherwise return errno. - */ -static int encrypted_update(struct key *key, const void *data, size_t datalen) -{ - struct encrypted_key_payload *epayload = key->payload.data; - struct encrypted_key_payload *new_epayload; - char *buf; - char *new_master_desc = NULL; - int ret = 0; - - if (datalen <= 0 || datalen > 32767 || !data) - return -EINVAL; - - buf = kmalloc(datalen + 1, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - buf[datalen] = 0; - memcpy(buf, data, datalen); - ret = datablob_parse(buf, &new_master_desc, NULL, NULL); - if (ret < 0) - goto out; - - ret = valid_master_desc(new_master_desc, epayload->master_desc); - if (ret < 0) - goto out; - - new_epayload = encrypted_key_alloc(key, new_master_desc, - epayload->datalen); - if (IS_ERR(new_epayload)) { - ret = PTR_ERR(new_epayload); - goto out; - } - - __ekey_init(new_epayload, new_master_desc, epayload->datalen); - - memcpy(new_epayload->iv, epayload->iv, ivsize); - memcpy(new_epayload->decrypted_data, epayload->decrypted_data, - epayload->decrypted_datalen); - - rcu_assign_pointer(key->payload.data, new_epayload); - call_rcu(&epayload->rcu, encrypted_rcu_free); -out: - kfree(buf); - return ret; -} - -/* - * encrypted_read - format and copy the encrypted data to userspace - * - * The resulting datablob format is: - * - * - * On success, return to userspace the encrypted key datablob size. - */ -static long encrypted_read(const struct key *key, char __user *buffer, - size_t buflen) -{ - struct encrypted_key_payload *epayload; - struct key *mkey; - u8 *master_key; - size_t master_keylen; - char derived_key[HASH_SIZE]; - char *ascii_buf; - size_t asciiblob_len; - int ret; - - epayload = rcu_dereference_protected(key->payload.data, - rwsem_is_locked(&((struct key *)key)->sem)); - - /* returns the hex encoded iv, encrypted-data, and hmac as ascii */ - asciiblob_len = epayload->datablob_len + ivsize + 1 - + roundup(epayload->decrypted_datalen, blksize) - + (HASH_SIZE * 2); - - if (!buffer || buflen < asciiblob_len) - return asciiblob_len; - - mkey = request_master_key(epayload, &master_key, &master_keylen); - if (IS_ERR(mkey)) - return PTR_ERR(mkey); - - ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen); - if (ret < 0) - goto out; - - ret = derived_key_encrypt(epayload, derived_key, sizeof derived_key); - if (ret < 0) - goto out; - - ret = datablob_hmac_append(epayload, master_key, master_keylen); - if (ret < 0) - goto out; - - ascii_buf = datablob_format(epayload, asciiblob_len); - if (!ascii_buf) { - ret = -ENOMEM; - goto out; - } - - up_read(&mkey->sem); - key_put(mkey); - - if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0) - ret = -EFAULT; - kfree(ascii_buf); - - return asciiblob_len; -out: - up_read(&mkey->sem); - key_put(mkey); - return ret; -} - -/* - * encrypted_destroy - before freeing the key, clear the decrypted data - * - * Before freeing the key, clear the memory containing the decrypted - * key data. - */ -static void encrypted_destroy(struct key *key) -{ - struct encrypted_key_payload *epayload = key->payload.data; - - if (!epayload) - return; - - memset(epayload->decrypted_data, 0, epayload->decrypted_datalen); - kfree(key->payload.data); -} - -struct key_type key_type_encrypted = { - .name = "encrypted", - .instantiate = encrypted_instantiate, - .update = encrypted_update, - .match = user_match, - .destroy = encrypted_destroy, - .describe = user_describe, - .read = encrypted_read, -}; -EXPORT_SYMBOL_GPL(key_type_encrypted); - -static void encrypted_shash_release(void) -{ - if (hashalg) - crypto_free_shash(hashalg); - if (hmacalg) - crypto_free_shash(hmacalg); -} - -static int __init encrypted_shash_alloc(void) -{ - int ret; - - hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(hmacalg)) { - pr_info("encrypted_key: could not allocate crypto %s\n", - hmac_alg); - return PTR_ERR(hmacalg); - } - - hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(hashalg)) { - pr_info("encrypted_key: could not allocate crypto %s\n", - hash_alg); - ret = PTR_ERR(hashalg); - goto hashalg_fail; - } - - return 0; - -hashalg_fail: - crypto_free_shash(hmacalg); - return ret; -} - -static int __init init_encrypted(void) -{ - int ret; - - ret = encrypted_shash_alloc(); - if (ret < 0) - return ret; - ret = register_key_type(&key_type_encrypted); - if (ret < 0) - goto out; - return aes_get_sizes(); -out: - encrypted_shash_release(); - return ret; - -} - -static void __exit cleanup_encrypted(void) -{ - encrypted_shash_release(); - unregister_key_type(&key_type_encrypted); -} - -late_initcall(init_encrypted); -module_exit(cleanup_encrypted); - -MODULE_LICENSE("GPL"); diff --git a/trunk/security/keys/encrypted_defined.h b/trunk/security/keys/encrypted_defined.h deleted file mode 100644 index cef5e2f2b7d1..000000000000 --- a/trunk/security/keys/encrypted_defined.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __ENCRYPTED_KEY_H -#define __ENCRYPTED_KEY_H - -#define ENCRYPTED_DEBUG 0 - -#if ENCRYPTED_DEBUG -static inline void dump_master_key(const u8 *master_key, size_t master_keylen) -{ - print_hex_dump(KERN_ERR, "master key: ", DUMP_PREFIX_NONE, 32, 1, - master_key, master_keylen, 0); -} - -static inline void dump_decrypted_data(struct encrypted_key_payload *epayload) -{ - print_hex_dump(KERN_ERR, "decrypted data: ", DUMP_PREFIX_NONE, 32, 1, - epayload->decrypted_data, - epayload->decrypted_datalen, 0); -} - -static inline void dump_encrypted_data(struct encrypted_key_payload *epayload, - unsigned int encrypted_datalen) -{ - print_hex_dump(KERN_ERR, "encrypted data: ", DUMP_PREFIX_NONE, 32, 1, - epayload->encrypted_data, encrypted_datalen, 0); -} - -static inline void dump_hmac(const char *str, const u8 *digest, - unsigned int hmac_size) -{ - if (str) - pr_info("encrypted_key: %s", str); - print_hex_dump(KERN_ERR, "hmac: ", DUMP_PREFIX_NONE, 32, 1, digest, - hmac_size, 0); -} -#else -static inline void dump_master_key(const u8 *master_key, size_t master_keylen) -{ -} - -static inline void dump_decrypted_data(struct encrypted_key_payload *epayload) -{ -} - -static inline void dump_encrypted_data(struct encrypted_key_payload *epayload, - unsigned int encrypted_datalen) -{ -} - -static inline void dump_hmac(const char *str, const u8 *digest, - unsigned int hmac_size) -{ -} -#endif -#endif diff --git a/trunk/security/keys/trusted_defined.c b/trunk/security/keys/trusted_defined.c deleted file mode 100644 index 975e9f29a52c..000000000000 --- a/trunk/security/keys/trusted_defined.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * Copyright (C) 2010 IBM Corporation - * - * Author: - * David Safford - * - * 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 of the License. - * - * See Documentation/keys-trusted-encrypted.txt - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trusted_defined.h" - -static const char hmac_alg[] = "hmac(sha1)"; -static const char hash_alg[] = "sha1"; - -struct sdesc { - struct shash_desc shash; - char ctx[]; -}; - -static struct crypto_shash *hashalg; -static struct crypto_shash *hmacalg; - -static struct sdesc *init_sdesc(struct crypto_shash *alg) -{ - struct sdesc *sdesc; - int size; - - size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); - sdesc = kmalloc(size, GFP_KERNEL); - if (!sdesc) - return ERR_PTR(-ENOMEM); - sdesc->shash.tfm = alg; - sdesc->shash.flags = 0x0; - return sdesc; -} - -static int TSS_sha1(const unsigned char *data, unsigned int datalen, - unsigned char *digest) -{ - struct sdesc *sdesc; - int ret; - - sdesc = init_sdesc(hashalg); - if (IS_ERR(sdesc)) { - pr_info("trusted_key: can't alloc %s\n", hash_alg); - return PTR_ERR(sdesc); - } - - ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); - kfree(sdesc); - return ret; -} - -static int TSS_rawhmac(unsigned char *digest, const unsigned char *key, - unsigned int keylen, ...) -{ - struct sdesc *sdesc; - va_list argp; - unsigned int dlen; - unsigned char *data; - int ret; - - sdesc = init_sdesc(hmacalg); - if (IS_ERR(sdesc)) { - pr_info("trusted_key: can't alloc %s\n", hmac_alg); - return PTR_ERR(sdesc); - } - - ret = crypto_shash_setkey(hmacalg, key, keylen); - if (ret < 0) - goto out; - ret = crypto_shash_init(&sdesc->shash); - if (ret < 0) - goto out; - - va_start(argp, keylen); - for (;;) { - dlen = va_arg(argp, unsigned int); - if (dlen == 0) - break; - data = va_arg(argp, unsigned char *); - if (data == NULL) - return -EINVAL; - ret = crypto_shash_update(&sdesc->shash, data, dlen); - if (ret < 0) - goto out; - } - va_end(argp); - if (!ret) - ret = crypto_shash_final(&sdesc->shash, digest); -out: - kfree(sdesc); - return ret; -} - -/* - * calculate authorization info fields to send to TPM - */ -static int TSS_authhmac(unsigned char *digest, const unsigned char *key, - unsigned int keylen, unsigned char *h1, - unsigned char *h2, unsigned char h3, ...) -{ - unsigned char paramdigest[SHA1_DIGEST_SIZE]; - struct sdesc *sdesc; - unsigned int dlen; - unsigned char *data; - unsigned char c; - int ret; - va_list argp; - - sdesc = init_sdesc(hashalg); - if (IS_ERR(sdesc)) { - pr_info("trusted_key: can't alloc %s\n", hash_alg); - return PTR_ERR(sdesc); - } - - c = h3; - ret = crypto_shash_init(&sdesc->shash); - if (ret < 0) - goto out; - va_start(argp, h3); - for (;;) { - dlen = va_arg(argp, unsigned int); - if (dlen == 0) - break; - data = va_arg(argp, unsigned char *); - ret = crypto_shash_update(&sdesc->shash, data, dlen); - if (ret < 0) { - va_end(argp); - goto out; - } - } - va_end(argp); - ret = crypto_shash_final(&sdesc->shash, paramdigest); - if (!ret) - ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE, - paramdigest, TPM_NONCE_SIZE, h1, - TPM_NONCE_SIZE, h2, 1, &c, 0, 0); -out: - kfree(sdesc); - return ret; -} - -/* - * verify the AUTH1_COMMAND (Seal) result from TPM - */ -static int TSS_checkhmac1(unsigned char *buffer, - const uint32_t command, - const unsigned char *ononce, - const unsigned char *key, - unsigned int keylen, ...) -{ - uint32_t bufsize; - uint16_t tag; - uint32_t ordinal; - uint32_t result; - unsigned char *enonce; - unsigned char *continueflag; - unsigned char *authdata; - unsigned char testhmac[SHA1_DIGEST_SIZE]; - unsigned char paramdigest[SHA1_DIGEST_SIZE]; - struct sdesc *sdesc; - unsigned int dlen; - unsigned int dpos; - va_list argp; - int ret; - - bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); - tag = LOAD16(buffer, 0); - ordinal = command; - result = LOAD32N(buffer, TPM_RETURN_OFFSET); - if (tag == TPM_TAG_RSP_COMMAND) - return 0; - if (tag != TPM_TAG_RSP_AUTH1_COMMAND) - return -EINVAL; - authdata = buffer + bufsize - SHA1_DIGEST_SIZE; - continueflag = authdata - 1; - enonce = continueflag - TPM_NONCE_SIZE; - - sdesc = init_sdesc(hashalg); - if (IS_ERR(sdesc)) { - pr_info("trusted_key: can't alloc %s\n", hash_alg); - return PTR_ERR(sdesc); - } - ret = crypto_shash_init(&sdesc->shash); - if (ret < 0) - goto out; - ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result, - sizeof result); - if (ret < 0) - goto out; - ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal, - sizeof ordinal); - if (ret < 0) - goto out; - va_start(argp, keylen); - for (;;) { - dlen = va_arg(argp, unsigned int); - if (dlen == 0) - break; - dpos = va_arg(argp, unsigned int); - ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); - if (ret < 0) { - va_end(argp); - goto out; - } - } - va_end(argp); - ret = crypto_shash_final(&sdesc->shash, paramdigest); - if (ret < 0) - goto out; - - ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest, - TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce, - 1, continueflag, 0, 0); - if (ret < 0) - goto out; - - if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) - ret = -EINVAL; -out: - kfree(sdesc); - return ret; -} - -/* - * verify the AUTH2_COMMAND (unseal) result from TPM - */ -static int TSS_checkhmac2(unsigned char *buffer, - const uint32_t command, - const unsigned char *ononce, - const unsigned char *key1, - unsigned int keylen1, - const unsigned char *key2, - unsigned int keylen2, ...) -{ - uint32_t bufsize; - uint16_t tag; - uint32_t ordinal; - uint32_t result; - unsigned char *enonce1; - unsigned char *continueflag1; - unsigned char *authdata1; - unsigned char *enonce2; - unsigned char *continueflag2; - unsigned char *authdata2; - unsigned char testhmac1[SHA1_DIGEST_SIZE]; - unsigned char testhmac2[SHA1_DIGEST_SIZE]; - unsigned char paramdigest[SHA1_DIGEST_SIZE]; - struct sdesc *sdesc; - unsigned int dlen; - unsigned int dpos; - va_list argp; - int ret; - - bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); - tag = LOAD16(buffer, 0); - ordinal = command; - result = LOAD32N(buffer, TPM_RETURN_OFFSET); - - if (tag == TPM_TAG_RSP_COMMAND) - return 0; - if (tag != TPM_TAG_RSP_AUTH2_COMMAND) - return -EINVAL; - authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1 - + SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE); - authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE); - continueflag1 = authdata1 - 1; - continueflag2 = authdata2 - 1; - enonce1 = continueflag1 - TPM_NONCE_SIZE; - enonce2 = continueflag2 - TPM_NONCE_SIZE; - - sdesc = init_sdesc(hashalg); - if (IS_ERR(sdesc)) { - pr_info("trusted_key: can't alloc %s\n", hash_alg); - return PTR_ERR(sdesc); - } - ret = crypto_shash_init(&sdesc->shash); - if (ret < 0) - goto out; - ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result, - sizeof result); - if (ret < 0) - goto out; - ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal, - sizeof ordinal); - if (ret < 0) - goto out; - - va_start(argp, keylen2); - for (;;) { - dlen = va_arg(argp, unsigned int); - if (dlen == 0) - break; - dpos = va_arg(argp, unsigned int); - ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); - if (ret < 0) { - va_end(argp); - goto out; - } - } - va_end(argp); - ret = crypto_shash_final(&sdesc->shash, paramdigest); - if (ret < 0) - goto out; - - ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE, - paramdigest, TPM_NONCE_SIZE, enonce1, - TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0); - if (ret < 0) - goto out; - if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { - ret = -EINVAL; - goto out; - } - ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE, - paramdigest, TPM_NONCE_SIZE, enonce2, - TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0); - if (ret < 0) - goto out; - if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) - ret = -EINVAL; -out: - kfree(sdesc); - return ret; -} - -/* - * For key specific tpm requests, we will generate and send our - * own TPM command packets using the drivers send function. - */ -static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd, - size_t buflen) -{ - int rc; - - dump_tpm_buf(cmd); - rc = tpm_send(chip_num, cmd, buflen); - dump_tpm_buf(cmd); - if (rc > 0) - /* Can't return positive return codes values to keyctl */ - rc = -EPERM; - return rc; -} - -/* - * get a random value from TPM - */ -static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len) -{ - int ret; - - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_COMMAND); - store32(tb, TPM_GETRANDOM_SIZE); - store32(tb, TPM_ORD_GETRANDOM); - store32(tb, len); - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data); - if (!ret) - memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len); - return ret; -} - -static int my_get_random(unsigned char *buf, int len) -{ - struct tpm_buf *tb; - int ret; - - tb = kmalloc(sizeof *tb, GFP_KERNEL); - if (!tb) - return -ENOMEM; - ret = tpm_get_random(tb, buf, len); - - kfree(tb); - return ret; -} - -/* - * Lock a trusted key, by extending a selected PCR. - * - * Prevents a trusted key that is sealed to PCRs from being accessed. - * This uses the tpm driver's extend function. - */ -static int pcrlock(const int pcrnum) -{ - unsigned char hash[SHA1_DIGEST_SIZE]; - int ret; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - ret = my_get_random(hash, SHA1_DIGEST_SIZE); - if (ret < 0) - return ret; - return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; -} - -/* - * Create an object specific authorisation protocol (OSAP) session - */ -static int osap(struct tpm_buf *tb, struct osapsess *s, - const unsigned char *key, uint16_t type, uint32_t handle) -{ - unsigned char enonce[TPM_NONCE_SIZE]; - unsigned char ononce[TPM_NONCE_SIZE]; - int ret; - - ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE); - if (ret < 0) - return ret; - - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_COMMAND); - store32(tb, TPM_OSAP_SIZE); - store32(tb, TPM_ORD_OSAP); - store16(tb, type); - store32(tb, handle); - storebytes(tb, ononce, TPM_NONCE_SIZE); - - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); - if (ret < 0) - return ret; - - s->handle = LOAD32(tb->data, TPM_DATA_OFFSET); - memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]), - TPM_NONCE_SIZE); - memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) + - TPM_NONCE_SIZE]), TPM_NONCE_SIZE); - return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE, - enonce, TPM_NONCE_SIZE, ononce, 0, 0); -} - -/* - * Create an object independent authorisation protocol (oiap) session - */ -static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce) -{ - int ret; - - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_COMMAND); - store32(tb, TPM_OIAP_SIZE); - store32(tb, TPM_ORD_OIAP); - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); - if (ret < 0) - return ret; - - *handle = LOAD32(tb->data, TPM_DATA_OFFSET); - memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)], - TPM_NONCE_SIZE); - return 0; -} - -struct tpm_digests { - unsigned char encauth[SHA1_DIGEST_SIZE]; - unsigned char pubauth[SHA1_DIGEST_SIZE]; - unsigned char xorwork[SHA1_DIGEST_SIZE * 2]; - unsigned char xorhash[SHA1_DIGEST_SIZE]; - unsigned char nonceodd[TPM_NONCE_SIZE]; -}; - -/* - * Have the TPM seal(encrypt) the trusted key, possibly based on - * Platform Configuration Registers (PCRs). AUTH1 for sealing key. - */ -static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, - uint32_t keyhandle, const unsigned char *keyauth, - const unsigned char *data, uint32_t datalen, - unsigned char *blob, uint32_t *bloblen, - const unsigned char *blobauth, - const unsigned char *pcrinfo, uint32_t pcrinfosize) -{ - struct osapsess sess; - struct tpm_digests *td; - unsigned char cont; - uint32_t ordinal; - uint32_t pcrsize; - uint32_t datsize; - int sealinfosize; - int encdatasize; - int storedsize; - int ret; - int i; - - /* alloc some work space for all the hashes */ - td = kmalloc(sizeof *td, GFP_KERNEL); - if (!td) - return -ENOMEM; - - /* get session for sealing key */ - ret = osap(tb, &sess, keyauth, keytype, keyhandle); - if (ret < 0) - return ret; - dump_sess(&sess); - - /* calculate encrypted authorization value */ - memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE); - memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE); - ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash); - if (ret < 0) - return ret; - - ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE); - if (ret < 0) - return ret; - ordinal = htonl(TPM_ORD_SEAL); - datsize = htonl(datalen); - pcrsize = htonl(pcrinfosize); - cont = 0; - - /* encrypt data authorization key */ - for (i = 0; i < SHA1_DIGEST_SIZE; ++i) - td->encauth[i] = td->xorhash[i] ^ blobauth[i]; - - /* calculate authorization HMAC value */ - if (pcrinfosize == 0) { - /* no pcr info specified */ - ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, - sess.enonce, td->nonceodd, cont, - sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE, - td->encauth, sizeof(uint32_t), &pcrsize, - sizeof(uint32_t), &datsize, datalen, data, 0, - 0); - } else { - /* pcr info specified */ - ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, - sess.enonce, td->nonceodd, cont, - sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE, - td->encauth, sizeof(uint32_t), &pcrsize, - pcrinfosize, pcrinfo, sizeof(uint32_t), - &datsize, datalen, data, 0, 0); - } - if (ret < 0) - return ret; - - /* build and send the TPM request packet */ - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_AUTH1_COMMAND); - store32(tb, TPM_SEAL_SIZE + pcrinfosize + datalen); - store32(tb, TPM_ORD_SEAL); - store32(tb, keyhandle); - storebytes(tb, td->encauth, SHA1_DIGEST_SIZE); - store32(tb, pcrinfosize); - storebytes(tb, pcrinfo, pcrinfosize); - store32(tb, datalen); - storebytes(tb, data, datalen); - store32(tb, sess.handle); - storebytes(tb, td->nonceodd, TPM_NONCE_SIZE); - store8(tb, cont); - storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE); - - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); - if (ret < 0) - return ret; - - /* calculate the size of the returned Blob */ - sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t)); - encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) + - sizeof(uint32_t) + sealinfosize); - storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize + - sizeof(uint32_t) + encdatasize; - - /* check the HMAC in the response */ - ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret, - SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0, - 0); - - /* copy the returned blob to caller */ - if (!ret) { - memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize); - *bloblen = storedsize; - } - return ret; -} - -/* - * use the AUTH2_COMMAND form of unseal, to authorize both key and blob - */ -static int tpm_unseal(struct tpm_buf *tb, - uint32_t keyhandle, const unsigned char *keyauth, - const unsigned char *blob, int bloblen, - const unsigned char *blobauth, - unsigned char *data, unsigned int *datalen) -{ - unsigned char nonceodd[TPM_NONCE_SIZE]; - unsigned char enonce1[TPM_NONCE_SIZE]; - unsigned char enonce2[TPM_NONCE_SIZE]; - unsigned char authdata1[SHA1_DIGEST_SIZE]; - unsigned char authdata2[SHA1_DIGEST_SIZE]; - uint32_t authhandle1 = 0; - uint32_t authhandle2 = 0; - unsigned char cont = 0; - uint32_t ordinal; - uint32_t keyhndl; - int ret; - - /* sessions for unsealing key and data */ - ret = oiap(tb, &authhandle1, enonce1); - if (ret < 0) { - pr_info("trusted_key: oiap failed (%d)\n", ret); - return ret; - } - ret = oiap(tb, &authhandle2, enonce2); - if (ret < 0) { - pr_info("trusted_key: oiap failed (%d)\n", ret); - return ret; - } - - ordinal = htonl(TPM_ORD_UNSEAL); - keyhndl = htonl(SRKHANDLE); - ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE); - if (ret < 0) { - pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); - return ret; - } - ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE, - enonce1, nonceodd, cont, sizeof(uint32_t), - &ordinal, bloblen, blob, 0, 0); - if (ret < 0) - return ret; - ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE, - enonce2, nonceodd, cont, sizeof(uint32_t), - &ordinal, bloblen, blob, 0, 0); - if (ret < 0) - return ret; - - /* build and send TPM request packet */ - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_AUTH2_COMMAND); - store32(tb, TPM_UNSEAL_SIZE + bloblen); - store32(tb, TPM_ORD_UNSEAL); - store32(tb, keyhandle); - storebytes(tb, blob, bloblen); - store32(tb, authhandle1); - storebytes(tb, nonceodd, TPM_NONCE_SIZE); - store8(tb, cont); - storebytes(tb, authdata1, SHA1_DIGEST_SIZE); - store32(tb, authhandle2); - storebytes(tb, nonceodd, TPM_NONCE_SIZE); - store8(tb, cont); - storebytes(tb, authdata2, SHA1_DIGEST_SIZE); - - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); - if (ret < 0) { - pr_info("trusted_key: authhmac failed (%d)\n", ret); - return ret; - } - - *datalen = LOAD32(tb->data, TPM_DATA_OFFSET); - ret = TSS_checkhmac2(tb->data, ordinal, nonceodd, - keyauth, SHA1_DIGEST_SIZE, - blobauth, SHA1_DIGEST_SIZE, - sizeof(uint32_t), TPM_DATA_OFFSET, - *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0, - 0); - if (ret < 0) { - pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret); - return ret; - } - memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen); - return 0; -} - -/* - * Have the TPM seal(encrypt) the symmetric key - */ -static int key_seal(struct trusted_key_payload *p, - struct trusted_key_options *o) -{ - struct tpm_buf *tb; - int ret; - - tb = kzalloc(sizeof *tb, GFP_KERNEL); - if (!tb) - return -ENOMEM; - - /* include migratable flag at end of sealed key */ - p->key[p->key_len] = p->migratable; - - ret = tpm_seal(tb, o->keytype, o->keyhandle, o->keyauth, - p->key, p->key_len + 1, p->blob, &p->blob_len, - o->blobauth, o->pcrinfo, o->pcrinfo_len); - if (ret < 0) - pr_info("trusted_key: srkseal failed (%d)\n", ret); - - kfree(tb); - return ret; -} - -/* - * Have the TPM unseal(decrypt) the symmetric key - */ -static int key_unseal(struct trusted_key_payload *p, - struct trusted_key_options *o) -{ - struct tpm_buf *tb; - int ret; - - tb = kzalloc(sizeof *tb, GFP_KERNEL); - if (!tb) - return -ENOMEM; - - ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len, - o->blobauth, p->key, &p->key_len); - if (ret < 0) - pr_info("trusted_key: srkunseal failed (%d)\n", ret); - else - /* pull migratable flag out of sealed key */ - p->migratable = p->key[--p->key_len]; - - kfree(tb); - return ret; -} - -enum { - Opt_err = -1, - Opt_new, Opt_load, Opt_update, - Opt_keyhandle, Opt_keyauth, Opt_blobauth, - Opt_pcrinfo, Opt_pcrlock, Opt_migratable -}; - -static const match_table_t key_tokens = { - {Opt_new, "new"}, - {Opt_load, "load"}, - {Opt_update, "update"}, - {Opt_keyhandle, "keyhandle=%s"}, - {Opt_keyauth, "keyauth=%s"}, - {Opt_blobauth, "blobauth=%s"}, - {Opt_pcrinfo, "pcrinfo=%s"}, - {Opt_pcrlock, "pcrlock=%s"}, - {Opt_migratable, "migratable=%s"}, - {Opt_err, NULL} -}; - -/* can have zero or more token= options */ -static int getoptions(char *c, struct trusted_key_payload *pay, - struct trusted_key_options *opt) -{ - substring_t args[MAX_OPT_ARGS]; - char *p = c; - int token; - int res; - unsigned long handle; - unsigned long lock; - - while ((p = strsep(&c, " \t"))) { - if (*p == '\0' || *p == ' ' || *p == '\t') - continue; - token = match_token(p, key_tokens, args); - - switch (token) { - case Opt_pcrinfo: - opt->pcrinfo_len = strlen(args[0].from) / 2; - if (opt->pcrinfo_len > MAX_PCRINFO_SIZE) - return -EINVAL; - hex2bin(opt->pcrinfo, args[0].from, opt->pcrinfo_len); - break; - case Opt_keyhandle: - res = strict_strtoul(args[0].from, 16, &handle); - if (res < 0) - return -EINVAL; - opt->keytype = SEAL_keytype; - opt->keyhandle = handle; - break; - case Opt_keyauth: - if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) - return -EINVAL; - hex2bin(opt->keyauth, args[0].from, SHA1_DIGEST_SIZE); - break; - case Opt_blobauth: - if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) - return -EINVAL; - hex2bin(opt->blobauth, args[0].from, SHA1_DIGEST_SIZE); - break; - case Opt_migratable: - if (*args[0].from == '0') - pay->migratable = 0; - else - return -EINVAL; - break; - case Opt_pcrlock: - res = strict_strtoul(args[0].from, 10, &lock); - if (res < 0) - return -EINVAL; - opt->pcrlock = lock; - break; - default: - return -EINVAL; - } - } - return 0; -} - -/* - * datablob_parse - parse the keyctl data and fill in the - * payload and options structures - * - * On success returns 0, otherwise -EINVAL. - */ -static int datablob_parse(char *datablob, struct trusted_key_payload *p, - struct trusted_key_options *o) -{ - substring_t args[MAX_OPT_ARGS]; - long keylen; - int ret = -EINVAL; - int key_cmd; - char *c; - - /* main command */ - c = strsep(&datablob, " \t"); - if (!c) - return -EINVAL; - key_cmd = match_token(c, key_tokens, args); - switch (key_cmd) { - case Opt_new: - /* first argument is key size */ - c = strsep(&datablob, " \t"); - if (!c) - return -EINVAL; - ret = strict_strtol(c, 10, &keylen); - if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE) - return -EINVAL; - p->key_len = keylen; - ret = getoptions(datablob, p, o); - if (ret < 0) - return ret; - ret = Opt_new; - break; - case Opt_load: - /* first argument is sealed blob */ - c = strsep(&datablob, " \t"); - if (!c) - return -EINVAL; - p->blob_len = strlen(c) / 2; - if (p->blob_len > MAX_BLOB_SIZE) - return -EINVAL; - hex2bin(p->blob, c, p->blob_len); - ret = getoptions(datablob, p, o); - if (ret < 0) - return ret; - ret = Opt_load; - break; - case Opt_update: - /* all arguments are options */ - ret = getoptions(datablob, p, o); - if (ret < 0) - return ret; - ret = Opt_update; - break; - case Opt_err: - return -EINVAL; - break; - } - return ret; -} - -static struct trusted_key_options *trusted_options_alloc(void) -{ - struct trusted_key_options *options; - - options = kzalloc(sizeof *options, GFP_KERNEL); - if (options) { - /* set any non-zero defaults */ - options->keytype = SRK_keytype; - options->keyhandle = SRKHANDLE; - } - return options; -} - -static struct trusted_key_payload *trusted_payload_alloc(struct key *key) -{ - struct trusted_key_payload *p = NULL; - int ret; - - ret = key_payload_reserve(key, sizeof *p); - if (ret < 0) - return p; - p = kzalloc(sizeof *p, GFP_KERNEL); - if (p) - p->migratable = 1; /* migratable by default */ - return p; -} - -/* - * trusted_instantiate - create a new trusted key - * - * Unseal an existing trusted blob or, for a new key, get a - * random key, then seal and create a trusted key-type key, - * adding it to the specified keyring. - * - * On success, return 0. Otherwise return errno. - */ -static int trusted_instantiate(struct key *key, const void *data, - size_t datalen) -{ - struct trusted_key_payload *payload = NULL; - struct trusted_key_options *options = NULL; - char *datablob; - int ret = 0; - int key_cmd; - - if (datalen <= 0 || datalen > 32767 || !data) - return -EINVAL; - - datablob = kmalloc(datalen + 1, GFP_KERNEL); - if (!datablob) - return -ENOMEM; - memcpy(datablob, data, datalen); - datablob[datalen] = '\0'; - - options = trusted_options_alloc(); - if (!options) { - ret = -ENOMEM; - goto out; - } - payload = trusted_payload_alloc(key); - if (!payload) { - ret = -ENOMEM; - goto out; - } - - key_cmd = datablob_parse(datablob, payload, options); - if (key_cmd < 0) { - ret = key_cmd; - goto out; - } - - dump_payload(payload); - dump_options(options); - - switch (key_cmd) { - case Opt_load: - ret = key_unseal(payload, options); - dump_payload(payload); - dump_options(options); - if (ret < 0) - pr_info("trusted_key: key_unseal failed (%d)\n", ret); - break; - case Opt_new: - ret = my_get_random(payload->key, payload->key_len); - if (ret < 0) { - pr_info("trusted_key: key_create failed (%d)\n", ret); - goto out; - } - ret = key_seal(payload, options); - if (ret < 0) - pr_info("trusted_key: key_seal failed (%d)\n", ret); - break; - default: - ret = -EINVAL; - goto out; - } - if (!ret && options->pcrlock) - ret = pcrlock(options->pcrlock); -out: - kfree(datablob); - kfree(options); - if (!ret) - rcu_assign_pointer(key->payload.data, payload); - else - kfree(payload); - return ret; -} - -static void trusted_rcu_free(struct rcu_head *rcu) -{ - struct trusted_key_payload *p; - - p = container_of(rcu, struct trusted_key_payload, rcu); - memset(p->key, 0, p->key_len); - kfree(p); -} - -/* - * trusted_update - reseal an existing key with new PCR values - */ -static int trusted_update(struct key *key, const void *data, size_t datalen) -{ - struct trusted_key_payload *p = key->payload.data; - struct trusted_key_payload *new_p; - struct trusted_key_options *new_o; - char *datablob; - int ret = 0; - - if (!p->migratable) - return -EPERM; - if (datalen <= 0 || datalen > 32767 || !data) - return -EINVAL; - - datablob = kmalloc(datalen + 1, GFP_KERNEL); - if (!datablob) - return -ENOMEM; - new_o = trusted_options_alloc(); - if (!new_o) { - ret = -ENOMEM; - goto out; - } - new_p = trusted_payload_alloc(key); - if (!new_p) { - ret = -ENOMEM; - goto out; - } - - memcpy(datablob, data, datalen); - datablob[datalen] = '\0'; - ret = datablob_parse(datablob, new_p, new_o); - if (ret != Opt_update) { - ret = -EINVAL; - goto out; - } - /* copy old key values, and reseal with new pcrs */ - new_p->migratable = p->migratable; - new_p->key_len = p->key_len; - memcpy(new_p->key, p->key, p->key_len); - dump_payload(p); - dump_payload(new_p); - - ret = key_seal(new_p, new_o); - if (ret < 0) { - pr_info("trusted_key: key_seal failed (%d)\n", ret); - kfree(new_p); - goto out; - } - if (new_o->pcrlock) { - ret = pcrlock(new_o->pcrlock); - if (ret < 0) { - pr_info("trusted_key: pcrlock failed (%d)\n", ret); - kfree(new_p); - goto out; - } - } - rcu_assign_pointer(key->payload.data, new_p); - call_rcu(&p->rcu, trusted_rcu_free); -out: - kfree(datablob); - kfree(new_o); - return ret; -} - -/* - * trusted_read - copy the sealed blob data to userspace in hex. - * On success, return to userspace the trusted key datablob size. - */ -static long trusted_read(const struct key *key, char __user *buffer, - size_t buflen) -{ - struct trusted_key_payload *p; - char *ascii_buf; - char *bufp; - int i; - - p = rcu_dereference_protected(key->payload.data, - rwsem_is_locked(&((struct key *)key)->sem)); - if (!p) - return -EINVAL; - if (!buffer || buflen <= 0) - return 2 * p->blob_len; - ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL); - if (!ascii_buf) - return -ENOMEM; - - bufp = ascii_buf; - for (i = 0; i < p->blob_len; i++) - bufp = pack_hex_byte(bufp, p->blob[i]); - if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) { - kfree(ascii_buf); - return -EFAULT; - } - kfree(ascii_buf); - return 2 * p->blob_len; -} - -/* - * trusted_destroy - before freeing the key, clear the decrypted data - */ -static void trusted_destroy(struct key *key) -{ - struct trusted_key_payload *p = key->payload.data; - - if (!p) - return; - memset(p->key, 0, p->key_len); - kfree(key->payload.data); -} - -struct key_type key_type_trusted = { - .name = "trusted", - .instantiate = trusted_instantiate, - .update = trusted_update, - .match = user_match, - .destroy = trusted_destroy, - .describe = user_describe, - .read = trusted_read, -}; - -EXPORT_SYMBOL_GPL(key_type_trusted); - -static void trusted_shash_release(void) -{ - if (hashalg) - crypto_free_shash(hashalg); - if (hmacalg) - crypto_free_shash(hmacalg); -} - -static int __init trusted_shash_alloc(void) -{ - int ret; - - hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(hmacalg)) { - pr_info("trusted_key: could not allocate crypto %s\n", - hmac_alg); - return PTR_ERR(hmacalg); - } - - hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(hashalg)) { - pr_info("trusted_key: could not allocate crypto %s\n", - hash_alg); - ret = PTR_ERR(hashalg); - goto hashalg_fail; - } - - return 0; - -hashalg_fail: - crypto_free_shash(hmacalg); - return ret; -} - -static int __init init_trusted(void) -{ - int ret; - - ret = trusted_shash_alloc(); - if (ret < 0) - return ret; - ret = register_key_type(&key_type_trusted); - if (ret < 0) - trusted_shash_release(); - return ret; -} - -static void __exit cleanup_trusted(void) -{ - trusted_shash_release(); - unregister_key_type(&key_type_trusted); -} - -late_initcall(init_trusted); -module_exit(cleanup_trusted); - -MODULE_LICENSE("GPL"); diff --git a/trunk/security/keys/trusted_defined.h b/trunk/security/keys/trusted_defined.h deleted file mode 100644 index 3249fbd2b653..000000000000 --- a/trunk/security/keys/trusted_defined.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __TRUSTED_KEY_H -#define __TRUSTED_KEY_H - -/* implementation specific TPM constants */ -#define MAX_PCRINFO_SIZE 64 -#define MAX_BUF_SIZE 512 -#define TPM_GETRANDOM_SIZE 14 -#define TPM_OSAP_SIZE 36 -#define TPM_OIAP_SIZE 10 -#define TPM_SEAL_SIZE 87 -#define TPM_UNSEAL_SIZE 104 -#define TPM_SIZE_OFFSET 2 -#define TPM_RETURN_OFFSET 6 -#define TPM_DATA_OFFSET 10 - -#define LOAD32(buffer, offset) (ntohl(*(uint32_t *)&buffer[offset])) -#define LOAD32N(buffer, offset) (*(uint32_t *)&buffer[offset]) -#define LOAD16(buffer, offset) (ntohs(*(uint16_t *)&buffer[offset])) - -struct tpm_buf { - int len; - unsigned char data[MAX_BUF_SIZE]; -}; - -#define INIT_BUF(tb) (tb->len = 0) - -struct osapsess { - uint32_t handle; - unsigned char secret[SHA1_DIGEST_SIZE]; - unsigned char enonce[TPM_NONCE_SIZE]; -}; - -/* discrete values, but have to store in uint16_t for TPM use */ -enum { - SEAL_keytype = 1, - SRK_keytype = 4 -}; - -struct trusted_key_options { - uint16_t keytype; - uint32_t keyhandle; - unsigned char keyauth[SHA1_DIGEST_SIZE]; - unsigned char blobauth[SHA1_DIGEST_SIZE]; - uint32_t pcrinfo_len; - unsigned char pcrinfo[MAX_PCRINFO_SIZE]; - int pcrlock; -}; - -#define TPM_DEBUG 0 - -#if TPM_DEBUG -static inline void dump_options(struct trusted_key_options *o) -{ - pr_info("trusted_key: sealing key type %d\n", o->keytype); - pr_info("trusted_key: sealing key handle %0X\n", o->keyhandle); - pr_info("trusted_key: pcrlock %d\n", o->pcrlock); - pr_info("trusted_key: pcrinfo %d\n", o->pcrinfo_len); - print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE, - 16, 1, o->pcrinfo, o->pcrinfo_len, 0); -} - -static inline void dump_payload(struct trusted_key_payload *p) -{ - pr_info("trusted_key: key_len %d\n", p->key_len); - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE, - 16, 1, p->key, p->key_len, 0); - pr_info("trusted_key: bloblen %d\n", p->blob_len); - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE, - 16, 1, p->blob, p->blob_len, 0); - pr_info("trusted_key: migratable %d\n", p->migratable); -} - -static inline void dump_sess(struct osapsess *s) -{ - print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE, - 16, 1, &s->handle, 4, 0); - pr_info("trusted-key: secret:\n"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, - 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0); - pr_info("trusted-key: enonce:\n"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, - 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0); -} - -static inline void dump_tpm_buf(unsigned char *buf) -{ - int len; - - pr_info("\ntrusted-key: tpm buffer\n"); - len = LOAD32(buf, TPM_SIZE_OFFSET); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0); -} -#else -static inline void dump_options(struct trusted_key_options *o) -{ -} - -static inline void dump_payload(struct trusted_key_payload *p) -{ -} - -static inline void dump_sess(struct osapsess *s) -{ -} - -static inline void dump_tpm_buf(unsigned char *buf) -{ -} -#endif - -static inline void store8(struct tpm_buf *buf, const unsigned char value) -{ - buf->data[buf->len++] = value; -} - -static inline void store16(struct tpm_buf *buf, const uint16_t value) -{ - *(uint16_t *) & buf->data[buf->len] = htons(value); - buf->len += sizeof value; -} - -static inline void store32(struct tpm_buf *buf, const uint32_t value) -{ - *(uint32_t *) & buf->data[buf->len] = htonl(value); - buf->len += sizeof value; -} - -static inline void storebytes(struct tpm_buf *buf, const unsigned char *in, - const int len) -{ - memcpy(buf->data + buf->len, in, len); - buf->len += len; -} -#endif diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index e276eb468536..6f637d2678ac 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -2525,10 +2525,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, sid = tsec->sid; newsid = tsec->create_sid; - if ((sbsec->flags & SE_SBINITIALIZED) && - (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) - newsid = sbsec->mntpoint_sid; - else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { + if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { rc = security_transition_sid(sid, dsec->sid, inode_mode_to_security_class(inode->i_mode), &newsid); diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index 5615081b73ec..e94e82f73818 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "flask.h" #include "av_permissions.h" diff --git a/trunk/security/selinux/include/classmap.h b/trunk/security/selinux/include/classmap.h index 7ed3663332ec..8858d2b2d4b6 100644 --- a/trunk/security/selinux/include/classmap.h +++ b/trunk/security/selinux/include/classmap.h @@ -142,7 +142,7 @@ struct security_class_mapping secclass_map[] = { "node_bind", "name_connect", NULL } }, { "memprotect", { "mmap_zero", NULL } }, { "peer", { "recv", NULL } }, - { "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, + { "capability2", { "mac_override", "mac_admin", NULL } }, { "kernel_service", { "use_as_override", "create_files_as", NULL } }, { "tun_socket", { COMMON_SOCK_PERMS, NULL } }, diff --git a/trunk/security/selinux/nlmsgtab.c b/trunk/security/selinux/nlmsgtab.c index 8b02b2137da2..75ec0c6ebacd 100644 --- a/trunk/security/selinux/nlmsgtab.c +++ b/trunk/security/selinux/nlmsgtab.c @@ -65,8 +65,6 @@ static struct nlmsg_perm nlmsg_route_perms[] = { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, - { RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, - { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, }; static struct nlmsg_perm nlmsg_firewall_perms[] = diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index ea39cb742ae5..43deac219491 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -141,24 +141,19 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t length; int new_value; - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out; - - /* No partial writes. */ - length = EINVAL; - if (*ppos != 0) - goto out; - - length = -ENOMEM; + return -ENOMEM; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) - goto out; - + return -ENOMEM; length = -EFAULT; if (copy_from_user(page, buf, count)) goto out; @@ -273,25 +268,20 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t length; int new_value; extern int selinux_disable(void); - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out;; - - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - length = -ENOMEM; + return -ENOMEM; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) - goto out; - + return -ENOMEM; length = -EFAULT; if (copy_from_user(page, buf, count)) goto out; @@ -302,7 +292,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, if (new_value) { length = selinux_disable(); - if (length) + if (length < 0) goto out; audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, "selinux=0 auid=%u ses=%u", @@ -503,6 +493,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + int ret; ssize_t length; void *data = NULL; @@ -512,19 +503,17 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, if (length) goto out; - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - length = -EFBIG; - if (count > 64 * 1024 * 1024) + if (*ppos != 0) { + /* No partial writes. */ + length = -EINVAL; goto out; + } - length = -ENOMEM; - data = vmalloc(count); - if (!data) + if ((count > 64 * 1024 * 1024) + || (data = vmalloc(count)) == NULL) { + length = -ENOMEM; goto out; + } length = -EFAULT; if (copy_from_user(data, buf, count) != 0) @@ -534,19 +523,23 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, if (length) goto out; - length = sel_make_bools(); - if (length) - goto out1; - - length = sel_make_classes(); - if (length) + ret = sel_make_bools(); + if (ret) { + length = ret; goto out1; + } - length = sel_make_policycap(); - if (length) + ret = sel_make_classes(); + if (ret) { + length = ret; goto out1; + } - length = count; + ret = sel_make_policycap(); + if (ret) + length = ret; + else + length = count; out1: audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, @@ -566,26 +559,26 @@ static const struct file_operations sel_load_ops = { static ssize_t sel_write_context(struct file *file, char *buf, size_t size) { - char *canon = NULL; + char *canon; u32 sid, len; ssize_t length; length = task_has_security(current, SECURITY__CHECK_CONTEXT); if (length) - goto out; + return length; length = security_context_to_sid(buf, size, &sid); - if (length) - goto out; + if (length < 0) + return length; length = security_sid_to_context(sid, &canon, &len); - if (length) - goto out; + if (length < 0) + return length; - length = -ERANGE; if (len > SIMPLE_TRANSACTION_LIMIT) { printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " "payload max\n", __func__, len); + length = -ERANGE; goto out; } @@ -609,28 +602,23 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t length; unsigned int new_value; length = task_has_security(current, SECURITY__SETCHECKREQPROT); if (length) - goto out; + return length; - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out; - - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - length = -ENOMEM; + return -ENOMEM; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) - goto out; - + return -ENOMEM; length = -EFAULT; if (copy_from_user(page, buf, count)) goto out; @@ -705,7 +693,7 @@ static const struct file_operations transaction_ops = { static ssize_t sel_write_access(struct file *file, char *buf, size_t size) { - char *scon = NULL, *tcon = NULL; + char *scon, *tcon; u32 ssid, tsid; u16 tclass; struct av_decision avd; @@ -713,29 +701,27 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) length = task_has_security(current, SECURITY__COMPUTE_AV); if (length) - goto out; + return length; length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out; + return length; - length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); if (!tcon) goto out; length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) - goto out; + goto out2; length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); - if (length) - goto out; - + if (length < 0) + goto out2; length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); - if (length) - goto out; + if (length < 0) + goto out2; security_compute_av_user(ssid, tsid, tclass, &avd); @@ -744,131 +730,133 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) avd.allowed, 0xffffffff, avd.auditallow, avd.auditdeny, avd.seqno, avd.flags); -out: +out2: kfree(tcon); +out: kfree(scon); return length; } static ssize_t sel_write_create(struct file *file, char *buf, size_t size) { - char *scon = NULL, *tcon = NULL; + char *scon, *tcon; u32 ssid, tsid, newsid; u16 tclass; ssize_t length; - char *newcon = NULL; + char *newcon; u32 len; length = task_has_security(current, SECURITY__COMPUTE_CREATE); if (length) - goto out; + return length; length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out; + return length; - length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); if (!tcon) goto out; length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) - goto out; + goto out2; length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); - if (length) - goto out; - + if (length < 0) + goto out2; length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_transition_sid_user(ssid, tsid, tclass, &newsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_sid_to_context(newsid, &newcon, &len); - if (length) - goto out; + if (length < 0) + goto out2; - length = -ERANGE; if (len > SIMPLE_TRANSACTION_LIMIT) { printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " "payload max\n", __func__, len); - goto out; + length = -ERANGE; + goto out3; } memcpy(buf, newcon, len); length = len; -out: +out3: kfree(newcon); +out2: kfree(tcon); +out: kfree(scon); return length; } static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) { - char *scon = NULL, *tcon = NULL; + char *scon, *tcon; u32 ssid, tsid, newsid; u16 tclass; ssize_t length; - char *newcon = NULL; + char *newcon; u32 len; length = task_has_security(current, SECURITY__COMPUTE_RELABEL); if (length) - goto out; + return length; length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out; + return length; - length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); if (!tcon) goto out; length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) - goto out; + goto out2; length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); - if (length) - goto out; - + if (length < 0) + goto out2; length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_change_sid(ssid, tsid, tclass, &newsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_sid_to_context(newsid, &newcon, &len); - if (length) - goto out; + if (length < 0) + goto out2; - length = -ERANGE; - if (len > SIMPLE_TRANSACTION_LIMIT) - goto out; + if (len > SIMPLE_TRANSACTION_LIMIT) { + length = -ERANGE; + goto out3; + } memcpy(buf, newcon, len); length = len; -out: +out3: kfree(newcon); +out2: kfree(tcon); +out: kfree(scon); return length; } static ssize_t sel_write_user(struct file *file, char *buf, size_t size) { - char *con = NULL, *user = NULL, *ptr; - u32 sid, *sids = NULL; + char *con, *user, *ptr; + u32 sid, *sids; ssize_t length; char *newcon; int i, rc; @@ -876,29 +864,28 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) length = task_has_security(current, SECURITY__COMPUTE_USER); if (length) - goto out;; + return length; length = -ENOMEM; con = kzalloc(size + 1, GFP_KERNEL); if (!con) - goto out;; + return length; - length = -ENOMEM; user = kzalloc(size + 1, GFP_KERNEL); if (!user) goto out; length = -EINVAL; if (sscanf(buf, "%s %s", con, user) != 2) - goto out; + goto out2; length = security_context_to_sid(con, strlen(con) + 1, &sid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_get_user_sids(sid, user, &sids, &nsids); - if (length) - goto out; + if (length < 0) + goto out2; length = sprintf(buf, "%u", nsids) + 1; ptr = buf + length; @@ -906,80 +893,82 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) rc = security_sid_to_context(sids[i], &newcon, &len); if (rc) { length = rc; - goto out; + goto out3; } if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { kfree(newcon); length = -ERANGE; - goto out; + goto out3; } memcpy(ptr, newcon, len); kfree(newcon); ptr += len; length += len; } -out: +out3: kfree(sids); +out2: kfree(user); +out: kfree(con); return length; } static ssize_t sel_write_member(struct file *file, char *buf, size_t size) { - char *scon = NULL, *tcon = NULL; + char *scon, *tcon; u32 ssid, tsid, newsid; u16 tclass; ssize_t length; - char *newcon = NULL; + char *newcon; u32 len; length = task_has_security(current, SECURITY__COMPUTE_MEMBER); if (length) - goto out; + return length; length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out;; + return length; - length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); if (!tcon) goto out; length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) - goto out; + goto out2; length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); - if (length) - goto out; - + if (length < 0) + goto out2; length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_member_sid(ssid, tsid, tclass, &newsid); - if (length) - goto out; + if (length < 0) + goto out2; length = security_sid_to_context(newsid, &newcon, &len); - if (length) - goto out; + if (length < 0) + goto out2; - length = -ERANGE; if (len > SIMPLE_TRANSACTION_LIMIT) { printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " "payload max\n", __func__, len); - goto out; + length = -ERANGE; + goto out3; } memcpy(buf, newcon, len); length = len; -out: +out3: kfree(newcon); +out2: kfree(tcon); +out: kfree(scon); return length; } @@ -989,6 +978,7 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode) struct inode *ret = new_inode(sb); if (ret) { + ret->i_ino = get_next_ino(); ret->i_mode = mode; ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; } @@ -1008,14 +998,16 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, mutex_lock(&sel_mutex); - ret = -EINVAL; - if (index >= bool_num || strcmp(name, bool_pending_names[index])) + if (index >= bool_num || strcmp(name, bool_pending_names[index])) { + ret = -EINVAL; goto out; + } - ret = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) + if (!page) { + ret = -ENOMEM; goto out; + } cur_enforcing = security_get_bool_value(index); if (cur_enforcing < 0) { @@ -1027,7 +1019,8 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, ret = simple_read_from_buffer(buf, count, ppos, page, length); out: mutex_unlock(&sel_mutex); - free_page((unsigned long)page); + if (page) + free_page((unsigned long)page); return ret; } @@ -1047,23 +1040,26 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, if (length) goto out; - length = -EINVAL; - if (index >= bool_num || strcmp(name, bool_pending_names[index])) + if (index >= bool_num || strcmp(name, bool_pending_names[index])) { + length = -EINVAL; goto out; + } - length = -ENOMEM; - if (count >= PAGE_SIZE) + if (count >= PAGE_SIZE) { + length = -ENOMEM; goto out; + } - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) + if (*ppos != 0) { + /* No partial writes. */ + length = -EINVAL; goto out; - - length = -ENOMEM; + } page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) + if (!page) { + length = -ENOMEM; goto out; + } length = -EFAULT; if (copy_from_user(page, buf, count)) @@ -1081,7 +1077,8 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, out: mutex_unlock(&sel_mutex); - free_page((unsigned long) page); + if (page) + free_page((unsigned long) page); return length; } @@ -1105,19 +1102,19 @@ static ssize_t sel_commit_bools_write(struct file *filep, if (length) goto out; - length = -ENOMEM; - if (count >= PAGE_SIZE) + if (count >= PAGE_SIZE) { + length = -ENOMEM; goto out; - - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) + } + if (*ppos != 0) { + /* No partial writes. */ goto out; - - length = -ENOMEM; + } page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) + if (!page) { + length = -ENOMEM; goto out; + } length = -EFAULT; if (copy_from_user(page, buf, count)) @@ -1127,16 +1124,15 @@ static ssize_t sel_commit_bools_write(struct file *filep, if (sscanf(page, "%d", &new_value) != 1) goto out; - length = 0; if (new_value && bool_pending_values) - length = security_set_bools(bool_num, bool_pending_values); + security_set_bools(bool_num, bool_pending_values); - if (!length) - length = count; + length = count; out: mutex_unlock(&sel_mutex); - free_page((unsigned long) page); + if (page) + free_page((unsigned long) page); return length; } @@ -1177,7 +1173,7 @@ static void sel_remove_entries(struct dentry *de) static int sel_make_bools(void) { - int i, ret; + int i, ret = 0; ssize_t len; struct dentry *dentry = NULL; struct dentry *dir = bool_dir; @@ -1198,40 +1194,38 @@ static int sel_make_bools(void) sel_remove_entries(dir); - ret = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) - goto out; + return -ENOMEM; ret = security_get_bools(&num, &names, &values); - if (ret) + if (ret != 0) goto out; for (i = 0; i < num; i++) { - ret = -ENOMEM; dentry = d_alloc_name(dir, names[i]); - if (!dentry) - goto out; - - ret = -ENOMEM; + if (!dentry) { + ret = -ENOMEM; + goto err; + } inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); - if (!inode) - goto out; + if (!inode) { + ret = -ENOMEM; + goto err; + } - ret = -EINVAL; len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); - if (len < 0) - goto out; - - ret = -ENAMETOOLONG; - if (len >= PAGE_SIZE) - goto out; - + if (len < 0) { + ret = -EINVAL; + goto err; + } else if (len >= PAGE_SIZE) { + ret = -ENAMETOOLONG; + goto err; + } isec = (struct inode_security_struct *)inode->i_security; ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); if (ret) - goto out; - + goto err; isec->sid = sid; isec->initialized = 1; inode->i_fop = &sel_bool_ops; @@ -1241,12 +1235,10 @@ static int sel_make_bools(void) bool_num = num; bool_pending_names = names; bool_pending_values = values; - - free_page((unsigned long)page); - return 0; out: free_page((unsigned long)page); - + return ret; +err: if (names) { for (i = 0; i < num; i++) kfree(names[i]); @@ -1254,8 +1246,8 @@ static int sel_make_bools(void) } kfree(values); sel_remove_entries(dir); - - return ret; + ret = -ENOMEM; + goto out; } #define NULL_FILE_NAME "null" @@ -1277,41 +1269,47 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t ret; int new_value; - ret = task_has_security(current, SECURITY__SETSECPARAM); - if (ret) - goto out; - - ret = -ENOMEM; - if (count >= PAGE_SIZE) + if (count >= PAGE_SIZE) { + ret = -ENOMEM; goto out; + } - /* No partial writes. */ - ret = -EINVAL; - if (*ppos != 0) + if (*ppos != 0) { + /* No partial writes. */ + ret = -EINVAL; goto out; + } - ret = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) + if (!page) { + ret = -ENOMEM; goto out; + } - ret = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + if (copy_from_user(page, buf, count)) { + ret = -EFAULT; + goto out_free; + } - ret = -EINVAL; - if (sscanf(page, "%u", &new_value) != 1) + if (sscanf(page, "%u", &new_value) != 1) { + ret = -EINVAL; goto out; + } - avc_cache_threshold = new_value; - + if (new_value != avc_cache_threshold) { + ret = task_has_security(current, SECURITY__SETSECPARAM); + if (ret) + goto out_free; + avc_cache_threshold = new_value; + } ret = count; -out: +out_free: free_page((unsigned long)page); +out: return ret; } @@ -1319,18 +1317,19 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { char *page; - ssize_t length; + ssize_t ret = 0; page = (char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - length = avc_get_hash_stats(page); - if (length >= 0) - length = simple_read_from_buffer(buf, count, ppos, page, length); + if (!page) { + ret = -ENOMEM; + goto out; + } + ret = avc_get_hash_stats(page); + if (ret >= 0) + ret = simple_read_from_buffer(buf, count, ppos, page, ret); free_page((unsigned long)page); - - return length; +out: + return ret; } static const struct file_operations sel_avc_cache_threshold_ops = { @@ -1412,7 +1411,7 @@ static const struct file_operations sel_avc_cache_stats_ops = { static int sel_make_avc_files(struct dentry *dir) { - int i; + int i, ret = 0; static struct tree_descr files[] = { { "cache_threshold", &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, @@ -1427,19 +1426,22 @@ static int sel_make_avc_files(struct dentry *dir) struct dentry *dentry; dentry = d_alloc_name(dir, files[i].name); - if (!dentry) - return -ENOMEM; + if (!dentry) { + ret = -ENOMEM; + goto out; + } inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); - if (!inode) - return -ENOMEM; - + if (!inode) { + ret = -ENOMEM; + goto out; + } inode->i_fop = files[i].ops; inode->i_ino = ++sel_last_ino; d_add(dentry, inode); } - - return 0; +out: + return ret; } static ssize_t sel_read_initcon(struct file *file, char __user *buf, @@ -1453,7 +1455,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf, inode = file->f_path.dentry->d_inode; sid = inode->i_ino&SEL_INO_MASK; ret = security_sid_to_context(sid, &con, &len); - if (ret) + if (ret < 0) return ret; ret = simple_read_from_buffer(buf, count, ppos, con, len); @@ -1468,25 +1470,28 @@ static const struct file_operations sel_initcon_ops = { static int sel_make_initcon_files(struct dentry *dir) { - int i; + int i, ret = 0; for (i = 1; i <= SECINITSID_NUM; i++) { struct inode *inode; struct dentry *dentry; dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); - if (!dentry) - return -ENOMEM; + if (!dentry) { + ret = -ENOMEM; + goto out; + } inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); - if (!inode) - return -ENOMEM; - + if (!inode) { + ret = -ENOMEM; + goto out; + } inode->i_fop = &sel_initcon_ops; inode->i_ino = i|SEL_INITCON_INO_OFFSET; d_add(dentry, inode); } - - return 0; +out: + return ret; } static inline unsigned int sel_div(unsigned long a, unsigned long b) @@ -1522,13 +1527,15 @@ static ssize_t sel_read_class(struct file *file, char __user *buf, unsigned long ino = file->f_path.dentry->d_inode->i_ino; page = (char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; + if (!page) { + rc = -ENOMEM; + goto out; + } len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino)); rc = simple_read_from_buffer(buf, count, ppos, page, len); free_page((unsigned long)page); - +out: return rc; } @@ -1545,13 +1552,15 @@ static ssize_t sel_read_perm(struct file *file, char __user *buf, unsigned long ino = file->f_path.dentry->d_inode->i_ino; page = (char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; + if (!page) { + rc = -ENOMEM; + goto out; + } len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino)); rc = simple_read_from_buffer(buf, count, ppos, page, len); free_page((unsigned long)page); - +out: return rc; } @@ -1582,37 +1591,39 @@ static const struct file_operations sel_policycap_ops = { static int sel_make_perm_files(char *objclass, int classvalue, struct dentry *dir) { - int i, rc, nperms; + int i, rc = 0, nperms; char **perms; rc = security_get_permissions(objclass, &perms, &nperms); if (rc) - return rc; + goto out; for (i = 0; i < nperms; i++) { struct inode *inode; struct dentry *dentry; - rc = -ENOMEM; dentry = d_alloc_name(dir, perms[i]); - if (!dentry) - goto out; + if (!dentry) { + rc = -ENOMEM; + goto out1; + } - rc = -ENOMEM; inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); - if (!inode) - goto out; - + if (!inode) { + rc = -ENOMEM; + goto out1; + } inode->i_fop = &sel_perm_ops; /* i+1 since perm values are 1-indexed */ inode->i_ino = sel_perm_to_ino(classvalue, i + 1); d_add(dentry, inode); } - rc = 0; -out: + +out1: for (i = 0; i < nperms; i++) kfree(perms[i]); kfree(perms); +out: return rc; } @@ -1624,27 +1635,34 @@ static int sel_make_class_dir_entries(char *classname, int index, int rc; dentry = d_alloc_name(dir, "index"); - if (!dentry) - return -ENOMEM; + if (!dentry) { + rc = -ENOMEM; + goto out; + } inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); - if (!inode) - return -ENOMEM; + if (!inode) { + rc = -ENOMEM; + goto out; + } inode->i_fop = &sel_class_ops; inode->i_ino = sel_class_to_ino(index); d_add(dentry, inode); dentry = d_alloc_name(dir, "perms"); - if (!dentry) - return -ENOMEM; + if (!dentry) { + rc = -ENOMEM; + goto out; + } rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); if (rc) - return rc; + goto out; rc = sel_make_perm_files(classname, index, dentry); +out: return rc; } @@ -1674,15 +1692,15 @@ static void sel_remove_classes(void) static int sel_make_classes(void) { - int rc, nclasses, i; + int rc = 0, nclasses, i; char **classes; /* delete any existing entries */ sel_remove_classes(); rc = security_get_classes(&classes, &nclasses); - if (rc) - return rc; + if (rc < 0) + goto out; /* +2 since classes are 1-indexed */ last_class_ino = sel_class_to_ino(nclasses + 2); @@ -1690,27 +1708,29 @@ static int sel_make_classes(void) for (i = 0; i < nclasses; i++) { struct dentry *class_name_dir; - rc = -ENOMEM; class_name_dir = d_alloc_name(class_dir, classes[i]); - if (!class_name_dir) - goto out; + if (!class_name_dir) { + rc = -ENOMEM; + goto out1; + } rc = sel_make_dir(class_dir->d_inode, class_name_dir, &last_class_ino); if (rc) - goto out; + goto out1; /* i+1 since class values are 1-indexed */ rc = sel_make_class_dir_entries(classes[i], i + 1, class_name_dir); if (rc) - goto out; + goto out1; } - rc = 0; -out: + +out1: for (i = 0; i < nclasses; i++) kfree(classes[i]); kfree(classes); +out: return rc; } @@ -1747,12 +1767,14 @@ static int sel_make_policycap(void) static int sel_make_dir(struct inode *dir, struct dentry *dentry, unsigned long *ino) { + int ret = 0; struct inode *inode; inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); - if (!inode) - return -ENOMEM; - + if (!inode) { + ret = -ENOMEM; + goto out; + } inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; inode->i_ino = ++(*ino); @@ -1761,8 +1783,8 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry, d_add(dentry, inode); /* bump link count on parent directory, too */ inc_nlink(dir); - - return 0; +out: + return ret; } static int sel_fill_super(struct super_block *sb, void *data, int silent) @@ -1798,10 +1820,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) root_inode = sb->s_root->d_inode; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } ret = sel_make_dir(root_inode, dentry, &sel_last_ino); if (ret) @@ -1809,16 +1832,17 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) bool_dir = dentry; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } - ret = -ENOMEM; inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); - if (!inode) + if (!inode) { + ret = -ENOMEM; goto err; - + } inode->i_ino = ++sel_last_ino; isec = (struct inode_security_struct *)inode->i_security; isec->sid = SECINITSID_DEVNULL; @@ -1829,10 +1853,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) d_add(dentry, inode); selinux_null = dentry; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, "avc"); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } ret = sel_make_dir(root_inode, dentry, &sel_last_ino); if (ret) @@ -1842,10 +1867,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) if (ret) goto err; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, "initial_contexts"); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } ret = sel_make_dir(root_inode, dentry, &sel_last_ino); if (ret) @@ -1855,10 +1881,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) if (ret) goto err; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, "class"); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } ret = sel_make_dir(root_inode, dentry, &sel_last_ino); if (ret) @@ -1866,10 +1893,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) class_dir = dentry; - ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, "policy_capabilities"); - if (!dentry) + if (!dentry) { + ret = -ENOMEM; goto err; + } ret = sel_make_dir(root_inode, dentry, &sel_last_ino); if (ret) @@ -1877,11 +1905,12 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) policycap_dir = dentry; - return 0; +out: + return ret; err: printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", __func__); - return ret; + goto out; } static struct dentry *sel_mount(struct file_system_type *fs_type, @@ -1905,16 +1934,14 @@ static int __init init_sel_fs(void) if (!selinux_enabled) return 0; err = register_filesystem(&sel_fs_type); - if (err) - return err; - - selinuxfs_mount = kern_mount(&sel_fs_type); - if (IS_ERR(selinuxfs_mount)) { - printk(KERN_ERR "selinuxfs: could not mount!\n"); - err = PTR_ERR(selinuxfs_mount); - selinuxfs_mount = NULL; + if (!err) { + selinuxfs_mount = kern_mount(&sel_fs_type); + if (IS_ERR(selinuxfs_mount)) { + printk(KERN_ERR "selinuxfs: could not mount!\n"); + err = PTR_ERR(selinuxfs_mount); + selinuxfs_mount = NULL; + } } - return err; } diff --git a/trunk/security/selinux/ss/conditional.c b/trunk/security/selinux/ss/conditional.c index c3f845cbcd48..655fe1c6cc69 100644 --- a/trunk/security/selinux/ss/conditional.c +++ b/trunk/security/selinux/ss/conditional.c @@ -193,7 +193,6 @@ int cond_index_bool(void *key, void *datum, void *datap) { struct policydb *p; struct cond_bool_datum *booldatum; - struct flex_array *fa; booldatum = datum; p = datap; @@ -201,10 +200,7 @@ int cond_index_bool(void *key, void *datum, void *datap) if (!booldatum->value || booldatum->value > p->p_bools.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_BOOLS]; - if (flex_array_put_ptr(fa, booldatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_bool_val_to_name[booldatum->value - 1] = key; p->bool_val_to_struct[booldatum->value - 1] = booldatum; return 0; diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index 1ef8e4e89880..b4eff7a60c50 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context) len = 1; /* for the beginning ":" */ for (l = 0; l < 2; l++) { int index_sens = context->range.level[l].sens; - len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1)); + len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); /* categories */ head = -2; @@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context) if (i - prev > 1) { /* one or more negative bits are skipped */ if (head != prev) { - nm = sym_name(&policydb, SYM_CATS, prev); + nm = policydb.p_cat_val_to_name[prev]; len += strlen(nm) + 1; } - nm = sym_name(&policydb, SYM_CATS, i); + nm = policydb.p_cat_val_to_name[i]; len += strlen(nm) + 1; head = i; } prev = i; } if (prev != head) { - nm = sym_name(&policydb, SYM_CATS, prev); + nm = policydb.p_cat_val_to_name[prev]; len += strlen(nm) + 1; } if (l == 0) { @@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context, scontextp++; for (l = 0; l < 2; l++) { - strcpy(scontextp, sym_name(&policydb, SYM_LEVELS, - context->range.level[l].sens - 1)); + strcpy(scontextp, + policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); scontextp += strlen(scontextp); /* categories */ @@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context, *scontextp++ = '.'; else *scontextp++ = ','; - nm = sym_name(&policydb, SYM_CATS, prev); + nm = policydb.p_cat_val_to_name[prev]; strcpy(scontextp, nm); scontextp += strlen(nm); } @@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context, *scontextp++ = ':'; else *scontextp++ = ','; - nm = sym_name(&policydb, SYM_CATS, i); + nm = policydb.p_cat_val_to_name[i]; strcpy(scontextp, nm); scontextp += strlen(nm); head = i; @@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context, *scontextp++ = '.'; else *scontextp++ = ','; - nm = sym_name(&policydb, SYM_CATS, prev); + nm = policydb.p_cat_val_to_name[prev]; strcpy(scontextp, nm); scontextp += strlen(nm); } @@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) if (!l->sens || l->sens > p->p_levels.nprim) return 0; levdatum = hashtab_search(p->p_levels.table, - sym_name(p, SYM_LEVELS, l->sens - 1)); + p->p_sens_val_to_name[l->sens - 1]); if (!levdatum) return 0; @@ -482,8 +482,7 @@ int mls_convert_context(struct policydb *oldp, for (l = 0; l < 2; l++) { levdatum = hashtab_search(newp->p_levels.table, - sym_name(oldp, SYM_LEVELS, - c->range.level[l].sens - 1)); + oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); if (!levdatum) return -EINVAL; @@ -494,7 +493,7 @@ int mls_convert_context(struct policydb *oldp, int rc; catdatum = hashtab_search(newp->p_cats.table, - sym_name(oldp, SYM_CATS, i)); + oldp->p_cat_val_to_name[i]); if (!catdatum) return -EINVAL; rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index be9de3872837..94f630d93a5c 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -148,30 +148,32 @@ static int roles_init(struct policydb *p) int rc; struct role_datum *role; - rc = -ENOMEM; role = kzalloc(sizeof(*role), GFP_KERNEL); - if (!role) + if (!role) { + rc = -ENOMEM; goto out; - - rc = -EINVAL; + } role->value = ++p->p_roles.nprim; - if (role->value != OBJECT_R_VAL) - goto out; - - rc = -ENOMEM; + if (role->value != OBJECT_R_VAL) { + rc = -EINVAL; + goto out_free_role; + } key = kstrdup(OBJECT_R, GFP_KERNEL); - if (!key) - goto out; - + if (!key) { + rc = -ENOMEM; + goto out_free_role; + } rc = hashtab_insert(p->p_roles.table, key, role); if (rc) - goto out; - - return 0; + goto out_free_key; out: + return rc; + +out_free_key: kfree(key); +out_free_role: kfree(role); - return rc; + goto out; } static u32 rangetr_hash(struct hashtab *h, const void *k) @@ -211,33 +213,35 @@ static int policydb_init(struct policydb *p) for (i = 0; i < SYM_NUM; i++) { rc = symtab_init(&p->symtab[i], symtab_sizes[i]); if (rc) - goto out; + goto out_free_symtab; } rc = avtab_init(&p->te_avtab); if (rc) - goto out; + goto out_free_symtab; rc = roles_init(p); if (rc) - goto out; + goto out_free_symtab; rc = cond_policydb_init(p); if (rc) - goto out; + goto out_free_symtab; p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); if (!p->range_tr) - goto out; + goto out_free_symtab; ebitmap_init(&p->policycaps); ebitmap_init(&p->permissive_map); - return 0; out: + return rc; + +out_free_symtab: for (i = 0; i < SYM_NUM; i++) hashtab_destroy(p->symtab[i].table); - return rc; + goto out; } /* @@ -254,17 +258,12 @@ static int common_index(void *key, void *datum, void *datap) { struct policydb *p; struct common_datum *comdatum; - struct flex_array *fa; comdatum = datum; p = datap; if (!comdatum->value || comdatum->value > p->p_commons.nprim) return -EINVAL; - - fa = p->sym_val_to_name[SYM_COMMONS]; - if (flex_array_put_ptr(fa, comdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_common_val_to_name[comdatum->value - 1] = key; return 0; } @@ -272,16 +271,12 @@ static int class_index(void *key, void *datum, void *datap) { struct policydb *p; struct class_datum *cladatum; - struct flex_array *fa; cladatum = datum; p = datap; if (!cladatum->value || cladatum->value > p->p_classes.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_CLASSES]; - if (flex_array_put_ptr(fa, cladatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_class_val_to_name[cladatum->value - 1] = key; p->class_val_to_struct[cladatum->value - 1] = cladatum; return 0; } @@ -290,7 +285,6 @@ static int role_index(void *key, void *datum, void *datap) { struct policydb *p; struct role_datum *role; - struct flex_array *fa; role = datum; p = datap; @@ -298,11 +292,7 @@ static int role_index(void *key, void *datum, void *datap) || role->value > p->p_roles.nprim || role->bounds > p->p_roles.nprim) return -EINVAL; - - fa = p->sym_val_to_name[SYM_ROLES]; - if (flex_array_put_ptr(fa, role->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_role_val_to_name[role->value - 1] = key; p->role_val_to_struct[role->value - 1] = role; return 0; } @@ -311,7 +301,6 @@ static int type_index(void *key, void *datum, void *datap) { struct policydb *p; struct type_datum *typdatum; - struct flex_array *fa; typdatum = datum; p = datap; @@ -321,15 +310,8 @@ static int type_index(void *key, void *datum, void *datap) || typdatum->value > p->p_types.nprim || typdatum->bounds > p->p_types.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_TYPES]; - if (flex_array_put_ptr(fa, typdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); - - fa = p->type_val_to_struct_array; - if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_type_val_to_name[typdatum->value - 1] = key; + p->type_val_to_struct[typdatum->value - 1] = typdatum; } return 0; @@ -339,7 +321,6 @@ static int user_index(void *key, void *datum, void *datap) { struct policydb *p; struct user_datum *usrdatum; - struct flex_array *fa; usrdatum = datum; p = datap; @@ -347,11 +328,7 @@ static int user_index(void *key, void *datum, void *datap) || usrdatum->value > p->p_users.nprim || usrdatum->bounds > p->p_users.nprim) return -EINVAL; - - fa = p->sym_val_to_name[SYM_USERS]; - if (flex_array_put_ptr(fa, usrdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_user_val_to_name[usrdatum->value - 1] = key; p->user_val_to_struct[usrdatum->value - 1] = usrdatum; return 0; } @@ -360,7 +337,6 @@ static int sens_index(void *key, void *datum, void *datap) { struct policydb *p; struct level_datum *levdatum; - struct flex_array *fa; levdatum = datum; p = datap; @@ -369,10 +345,7 @@ static int sens_index(void *key, void *datum, void *datap) if (!levdatum->level->sens || levdatum->level->sens > p->p_levels.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_LEVELS]; - if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_sens_val_to_name[levdatum->level->sens - 1] = key; } return 0; @@ -382,7 +355,6 @@ static int cat_index(void *key, void *datum, void *datap) { struct policydb *p; struct cat_datum *catdatum; - struct flex_array *fa; catdatum = datum; p = datap; @@ -390,10 +362,7 @@ static int cat_index(void *key, void *datum, void *datap) if (!catdatum->isalias) { if (!catdatum->value || catdatum->value > p->p_cats.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_CATS]; - if (flex_array_put_ptr(fa, catdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->p_cat_val_to_name[catdatum->value - 1] = key; } return 0; @@ -411,6 +380,47 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) = cat_index, }; +/* + * Define the common val_to_name array and the class + * val_to_name and val_to_struct arrays in a policy + * database structure. + * + * Caller must clean up upon failure. + */ +static int policydb_index_classes(struct policydb *p) +{ + int rc; + + p->p_common_val_to_name = + kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL); + if (!p->p_common_val_to_name) { + rc = -ENOMEM; + goto out; + } + + rc = hashtab_map(p->p_commons.table, common_index, p); + if (rc) + goto out; + + p->class_val_to_struct = + kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL); + if (!p->class_val_to_struct) { + rc = -ENOMEM; + goto out; + } + + p->p_class_val_to_name = + kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL); + if (!p->p_class_val_to_name) { + rc = -ENOMEM; + goto out; + } + + rc = hashtab_map(p->p_classes.table, class_index, p); +out: + return rc; +} + #ifdef DEBUG_HASHES static void symtab_hash_eval(struct symtab *s) { @@ -448,9 +458,9 @@ static inline void rangetr_hash_eval(struct hashtab *h) * * Caller must clean up on failure. */ -static int policydb_index(struct policydb *p) +static int policydb_index_others(struct policydb *p) { - int i, rc; + int i, rc = 0; printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); @@ -467,63 +477,47 @@ static int policydb_index(struct policydb *p) symtab_hash_eval(p->symtab); #endif - rc = -ENOMEM; - p->class_val_to_struct = - kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), - GFP_KERNEL); - if (!p->class_val_to_struct) - goto out; - - rc = -ENOMEM; p->role_val_to_struct = kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), GFP_KERNEL); - if (!p->role_val_to_struct) + if (!p->role_val_to_struct) { + rc = -ENOMEM; goto out; + } - rc = -ENOMEM; p->user_val_to_struct = kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), GFP_KERNEL); - if (!p->user_val_to_struct) - goto out; - - /* Yes, I want the sizeof the pointer, not the structure */ - rc = -ENOMEM; - p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), - p->p_types.nprim, - GFP_KERNEL | __GFP_ZERO); - if (!p->type_val_to_struct_array) - goto out; - - rc = flex_array_prealloc(p->type_val_to_struct_array, 0, - p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); - if (rc) + if (!p->user_val_to_struct) { + rc = -ENOMEM; goto out; + } - rc = -ENOMEM; - if (cond_init_bool_indexes(p)) + p->type_val_to_struct = + kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), + GFP_KERNEL); + if (!p->type_val_to_struct) { + rc = -ENOMEM; goto out; + } - for (i = 0; i < SYM_NUM; i++) { + if (cond_init_bool_indexes(p)) { rc = -ENOMEM; - p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), - p->symtab[i].nprim, - GFP_KERNEL | __GFP_ZERO); - if (!p->sym_val_to_name[i]) - goto out; + goto out; + } - rc = flex_array_prealloc(p->sym_val_to_name[i], - 0, p->symtab[i].nprim - 1, - GFP_KERNEL | __GFP_ZERO); - if (rc) + for (i = SYM_ROLES; i < SYM_NUM; i++) { + p->sym_val_to_name[i] = + kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); + if (!p->sym_val_to_name[i]) { + rc = -ENOMEM; goto out; - + } rc = hashtab_map(p->symtab[i].table, index_f[i], p); if (rc) goto out; } - rc = 0; + out: return rc; } @@ -546,11 +540,9 @@ static int common_destroy(void *key, void *datum, void *p) struct common_datum *comdatum; kfree(key); - if (datum) { - comdatum = datum; - hashtab_map(comdatum->permissions.table, perm_destroy, NULL); - hashtab_destroy(comdatum->permissions.table); - } + comdatum = datum; + hashtab_map(comdatum->permissions.table, perm_destroy, NULL); + hashtab_destroy(comdatum->permissions.table); kfree(datum); return 0; } @@ -562,40 +554,38 @@ static int cls_destroy(void *key, void *datum, void *p) struct constraint_expr *e, *etmp; kfree(key); - if (datum) { - cladatum = datum; - hashtab_map(cladatum->permissions.table, perm_destroy, NULL); - hashtab_destroy(cladatum->permissions.table); - constraint = cladatum->constraints; - while (constraint) { - e = constraint->expr; - while (e) { - ebitmap_destroy(&e->names); - etmp = e; - e = e->next; - kfree(etmp); - } - ctemp = constraint; - constraint = constraint->next; - kfree(ctemp); + cladatum = datum; + hashtab_map(cladatum->permissions.table, perm_destroy, NULL); + hashtab_destroy(cladatum->permissions.table); + constraint = cladatum->constraints; + while (constraint) { + e = constraint->expr; + while (e) { + ebitmap_destroy(&e->names); + etmp = e; + e = e->next; + kfree(etmp); } - - constraint = cladatum->validatetrans; - while (constraint) { - e = constraint->expr; - while (e) { - ebitmap_destroy(&e->names); - etmp = e; - e = e->next; - kfree(etmp); - } - ctemp = constraint; - constraint = constraint->next; - kfree(ctemp); + ctemp = constraint; + constraint = constraint->next; + kfree(ctemp); + } + + constraint = cladatum->validatetrans; + while (constraint) { + e = constraint->expr; + while (e) { + ebitmap_destroy(&e->names); + etmp = e; + e = e->next; + kfree(etmp); } - - kfree(cladatum->comkey); + ctemp = constraint; + constraint = constraint->next; + kfree(ctemp); } + + kfree(cladatum->comkey); kfree(datum); return 0; } @@ -605,11 +595,9 @@ static int role_destroy(void *key, void *datum, void *p) struct role_datum *role; kfree(key); - if (datum) { - role = datum; - ebitmap_destroy(&role->dominates); - ebitmap_destroy(&role->types); - } + role = datum; + ebitmap_destroy(&role->dominates); + ebitmap_destroy(&role->types); kfree(datum); return 0; } @@ -626,13 +614,11 @@ static int user_destroy(void *key, void *datum, void *p) struct user_datum *usrdatum; kfree(key); - if (datum) { - usrdatum = datum; - ebitmap_destroy(&usrdatum->roles); - ebitmap_destroy(&usrdatum->range.level[0].cat); - ebitmap_destroy(&usrdatum->range.level[1].cat); - ebitmap_destroy(&usrdatum->dfltlevel.cat); - } + usrdatum = datum; + ebitmap_destroy(&usrdatum->roles); + ebitmap_destroy(&usrdatum->range.level[0].cat); + ebitmap_destroy(&usrdatum->range.level[1].cat); + ebitmap_destroy(&usrdatum->dfltlevel.cat); kfree(datum); return 0; } @@ -642,11 +628,9 @@ static int sens_destroy(void *key, void *datum, void *p) struct level_datum *levdatum; kfree(key); - if (datum) { - levdatum = datum; - ebitmap_destroy(&levdatum->level->cat); - kfree(levdatum->level); - } + levdatum = datum; + ebitmap_destroy(&levdatum->level->cat); + kfree(levdatum->level); kfree(datum); return 0; } @@ -711,16 +695,13 @@ void policydb_destroy(struct policydb *p) hashtab_destroy(p->symtab[i].table); } - for (i = 0; i < SYM_NUM; i++) { - if (p->sym_val_to_name[i]) - flex_array_free(p->sym_val_to_name[i]); - } + for (i = 0; i < SYM_NUM; i++) + kfree(p->sym_val_to_name[i]); kfree(p->class_val_to_struct); kfree(p->role_val_to_struct); kfree(p->user_val_to_struct); - if (p->type_val_to_struct_array) - flex_array_free(p->type_val_to_struct_array); + kfree(p->type_val_to_struct); avtab_destroy(&p->te_avtab); @@ -804,21 +785,19 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) head = p->ocontexts[OCON_ISID]; for (c = head; c; c = c->next) { - rc = -EINVAL; if (!c->context[0].user) { - printk(KERN_ERR "SELinux: SID %s was never defined.\n", - c->u.name); + printk(KERN_ERR "SELinux: SID %s was never " + "defined.\n", c->u.name); + rc = -EINVAL; goto out; } - - rc = sidtab_insert(s, c->sid[0], &c->context[0]); - if (rc) { - printk(KERN_ERR "SELinux: unable to load initial SID %s.\n", - c->u.name); + if (sidtab_insert(s, c->sid[0], &c->context[0])) { + printk(KERN_ERR "SELinux: unable to load initial " + "SID %s.\n", c->u.name); + rc = -EINVAL; goto out; } } - rc = 0; out: return rc; } @@ -867,7 +846,8 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) * Role must be authorized for the type. */ role = p->role_val_to_struct[c->role - 1]; - if (!ebitmap_get_bit(&role->types, c->type - 1)) + if (!ebitmap_get_bit(&role->types, + c->type - 1)) /* role may not be associated with type */ return 0; @@ -878,7 +858,8 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) if (!usrdatum) return 0; - if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1)) + if (!ebitmap_get_bit(&usrdatum->roles, + c->role - 1)) /* user may not be associated with role */ return 0; } @@ -900,22 +881,20 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) int rc; rc = next_entry(buf, fp, sizeof(u32)); - if (rc) + if (rc < 0) goto out; - rc = -EINVAL; items = le32_to_cpu(buf[0]); if (items > ARRAY_SIZE(buf)) { printk(KERN_ERR "SELinux: mls: range overflow\n"); + rc = -EINVAL; goto out; } - rc = next_entry(buf, fp, sizeof(u32) * items); - if (rc) { + if (rc < 0) { printk(KERN_ERR "SELinux: mls: truncated range\n"); goto out; } - r->level[0].sens = le32_to_cpu(buf[0]); if (items > 1) r->level[1].sens = le32_to_cpu(buf[1]); @@ -924,13 +903,15 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) rc = ebitmap_read(&r->level[0].cat, fp); if (rc) { - printk(KERN_ERR "SELinux: mls: error reading low categories\n"); + printk(KERN_ERR "SELinux: mls: error reading low " + "categories\n"); goto out; } if (items > 1) { rc = ebitmap_read(&r->level[1].cat, fp); if (rc) { - printk(KERN_ERR "SELinux: mls: error reading high categories\n"); + printk(KERN_ERR "SELinux: mls: error reading high " + "categories\n"); goto bad_high; } } else { @@ -941,11 +922,12 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) } } - return 0; -bad_high: - ebitmap_destroy(&r->level[0].cat); + rc = 0; out: return rc; +bad_high: + ebitmap_destroy(&r->level[0].cat); + goto out; } /* @@ -960,7 +942,7 @@ static int context_read_and_validate(struct context *c, int rc; rc = next_entry(buf, fp, sizeof buf); - if (rc) { + if (rc < 0) { printk(KERN_ERR "SELinux: context truncated\n"); goto out; } @@ -968,20 +950,19 @@ static int context_read_and_validate(struct context *c, c->role = le32_to_cpu(buf[1]); c->type = le32_to_cpu(buf[2]); if (p->policyvers >= POLICYDB_VERSION_MLS) { - rc = mls_read_range_helper(&c->range, fp); - if (rc) { - printk(KERN_ERR "SELinux: error reading MLS range of context\n"); + if (mls_read_range_helper(&c->range, fp)) { + printk(KERN_ERR "SELinux: error reading MLS range of " + "context\n"); + rc = -EINVAL; goto out; } } - rc = -EINVAL; if (!policydb_context_isvalid(p, c)) { printk(KERN_ERR "SELinux: invalid security context\n"); context_destroy(c); - goto out; + rc = -EINVAL; } - rc = 0; out: return rc; } @@ -1000,36 +981,37 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - rc = -ENOMEM; perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); - if (!perdatum) - goto bad; + if (!perdatum) { + rc = -ENOMEM; + goto out; + } rc = next_entry(buf, fp, sizeof buf); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); perdatum->value = le32_to_cpu(buf[1]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; - + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; rc = hashtab_insert(h, key, perdatum); if (rc) goto bad; - - return 0; +out: + return rc; bad: perm_destroy(key, perdatum, NULL); - return rc; + goto out; } static int common_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1040,13 +1022,14 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) u32 len, nel; int i, rc; - rc = -ENOMEM; comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); - if (!comdatum) - goto bad; + if (!comdatum) { + rc = -ENOMEM; + goto out; + } rc = next_entry(buf, fp, sizeof buf); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); @@ -1058,13 +1041,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) comdatum->permissions.nprim = le32_to_cpu(buf[2]); nel = le32_to_cpu(buf[3]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; - + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; @@ -1077,10 +1060,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) rc = hashtab_insert(h, key, comdatum); if (rc) goto bad; - return 0; +out: + return rc; bad: common_destroy(key, comdatum, NULL); - return rc; + goto out; } static int read_cons_helper(struct constraint_node **nodep, int ncons, @@ -1104,7 +1088,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, *nodep = c; rc = next_entry(buf, fp, (sizeof(u32) * 2)); - if (rc) + if (rc < 0) return rc; c->permissions = le32_to_cpu(buf[0]); nexpr = le32_to_cpu(buf[1]); @@ -1121,7 +1105,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, c->expr = e; rc = next_entry(buf, fp, (sizeof(u32) * 3)); - if (rc) + if (rc < 0) return rc; e->expr_type = le32_to_cpu(buf[0]); e->attr = le32_to_cpu(buf[1]); @@ -1149,9 +1133,8 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, if (depth == (CEXPR_MAXDEPTH - 1)) return -EINVAL; depth++; - rc = ebitmap_read(&e->names, fp); - if (rc) - return rc; + if (ebitmap_read(&e->names, fp)) + return -EINVAL; break; default: return -EINVAL; @@ -1174,13 +1157,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) u32 len, len2, ncons, nel; int i, rc; - rc = -ENOMEM; cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); - if (!cladatum) - goto bad; + if (!cladatum) { + rc = -ENOMEM; + goto out; + } rc = next_entry(buf, fp, sizeof(u32)*6); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); @@ -1195,30 +1179,33 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ncons = le32_to_cpu(buf[5]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; - + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; if (len2) { - rc = -ENOMEM; cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); - if (!cladatum->comkey) + if (!cladatum->comkey) { + rc = -ENOMEM; goto bad; + } rc = next_entry(cladatum->comkey, fp, len2); - if (rc) + if (rc < 0) goto bad; cladatum->comkey[len2] = '\0'; - rc = -EINVAL; - cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); + cladatum->comdatum = hashtab_search(p->p_commons.table, + cladatum->comkey); if (!cladatum->comdatum) { - printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey); + printk(KERN_ERR "SELinux: unknown common %s\n", + cladatum->comkey); + rc = -EINVAL; goto bad; } } @@ -1235,7 +1222,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { /* grab the validatetrans rules */ rc = next_entry(buf, fp, sizeof(u32)); - if (rc) + if (rc < 0) goto bad; ncons = le32_to_cpu(buf[0]); rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); @@ -1247,10 +1234,12 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) if (rc) goto bad; - return 0; + rc = 0; +out: + return rc; bad: cls_destroy(key, cladatum, NULL); - return rc; + goto out; } static int role_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1261,16 +1250,17 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - rc = -ENOMEM; role = kzalloc(sizeof(*role), GFP_KERNEL); - if (!role) - goto bad; + if (!role) { + rc = -ENOMEM; + goto out; + } if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) to_read = 3; rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); @@ -1278,13 +1268,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) role->bounds = le32_to_cpu(buf[2]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; - + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; @@ -1297,10 +1287,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) goto bad; if (strcmp(key, OBJECT_R) == 0) { - rc = -EINVAL; if (role->value != OBJECT_R_VAL) { printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", OBJECT_R, role->value); + rc = -EINVAL; goto bad; } rc = 0; @@ -1310,10 +1300,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) rc = hashtab_insert(h, key, role); if (rc) goto bad; - return 0; +out: + return rc; bad: role_destroy(key, role, NULL); - return rc; + goto out; } static int type_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1324,16 +1315,17 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[4]; u32 len; - rc = -ENOMEM; typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); - if (!typdatum) - goto bad; + if (!typdatum) { + rc = -ENOMEM; + return rc; + } if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) to_read = 4; rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); @@ -1351,22 +1343,24 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) typdatum->primary = le32_to_cpu(buf[2]); } - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; rc = hashtab_insert(h, key, typdatum); if (rc) goto bad; - return 0; +out: + return rc; bad: type_destroy(key, typdatum, NULL); - return rc; + goto out; } @@ -1382,18 +1376,22 @@ static int mls_read_level(struct mls_level *lp, void *fp) memset(lp, 0, sizeof(*lp)); rc = next_entry(buf, fp, sizeof buf); - if (rc) { + if (rc < 0) { printk(KERN_ERR "SELinux: mls: truncated level\n"); - return rc; + goto bad; } lp->sens = le32_to_cpu(buf[0]); - rc = ebitmap_read(&lp->cat, fp); - if (rc) { - printk(KERN_ERR "SELinux: mls: error reading level categories\n"); - return rc; + if (ebitmap_read(&lp->cat, fp)) { + printk(KERN_ERR "SELinux: mls: error reading level " + "categories\n"); + goto bad; } + return 0; + +bad: + return -EINVAL; } static int user_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1404,16 +1402,17 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - rc = -ENOMEM; usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); - if (!usrdatum) - goto bad; + if (!usrdatum) { + rc = -ENOMEM; + goto out; + } if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) to_read = 3; rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); @@ -1421,12 +1420,13 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) usrdatum->bounds = le32_to_cpu(buf[2]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_KERNEL); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; @@ -1446,10 +1446,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) rc = hashtab_insert(h, key, usrdatum); if (rc) goto bad; - return 0; +out: + return rc; bad: user_destroy(key, usrdatum, NULL); - return rc; + goto out; } static int sens_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1460,43 +1461,47 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - rc = -ENOMEM; levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); - if (!levdatum) - goto bad; + if (!levdatum) { + rc = -ENOMEM; + goto out; + } rc = next_entry(buf, fp, sizeof buf); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); levdatum->isalias = le32_to_cpu(buf[1]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_ATOMIC); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; - rc = -ENOMEM; levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); - if (!levdatum->level) + if (!levdatum->level) { + rc = -ENOMEM; goto bad; - - rc = mls_read_level(levdatum->level, fp); - if (rc) + } + if (mls_read_level(levdatum->level, fp)) { + rc = -EINVAL; goto bad; + } rc = hashtab_insert(h, key, levdatum); if (rc) goto bad; - return 0; +out: + return rc; bad: sens_destroy(key, levdatum, NULL); - return rc; + goto out; } static int cat_read(struct policydb *p, struct hashtab *h, void *fp) @@ -1507,35 +1512,39 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - rc = -ENOMEM; catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); - if (!catdatum) - goto bad; + if (!catdatum) { + rc = -ENOMEM; + goto out; + } rc = next_entry(buf, fp, sizeof buf); - if (rc) + if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); catdatum->value = le32_to_cpu(buf[1]); catdatum->isalias = le32_to_cpu(buf[2]); - rc = -ENOMEM; key = kmalloc(len + 1, GFP_ATOMIC); - if (!key) + if (!key) { + rc = -ENOMEM; goto bad; + } rc = next_entry(key, fp, len); - if (rc) + if (rc < 0) goto bad; key[len] = '\0'; rc = hashtab_insert(h, key, catdatum); if (rc) goto bad; - return 0; +out: + return rc; + bad: cat_destroy(key, catdatum, NULL); - return rc; + goto out; } static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = @@ -1576,9 +1585,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap) printk(KERN_ERR "SELinux: boundary violated policy: " "user=%s role=%s bounds=%s\n", - sym_name(p, SYM_USERS, user->value - 1), - sym_name(p, SYM_ROLES, bit), - sym_name(p, SYM_USERS, upper->value - 1)); + p->p_user_val_to_name[user->value - 1], + p->p_role_val_to_name[bit], + p->p_user_val_to_name[upper->value - 1]); return -EINVAL; } @@ -1613,9 +1622,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap) printk(KERN_ERR "SELinux: boundary violated policy: " "role=%s type=%s bounds=%s\n", - sym_name(p, SYM_ROLES, role->value - 1), - sym_name(p, SYM_TYPES, bit), - sym_name(p, SYM_ROLES, upper->value - 1)); + p->p_role_val_to_name[role->value - 1], + p->p_type_val_to_name[bit], + p->p_role_val_to_name[upper->value - 1]); return -EINVAL; } @@ -1639,15 +1648,12 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap) return -EINVAL; } - upper = flex_array_get_ptr(p->type_val_to_struct_array, - upper->bounds - 1); - BUG_ON(!upper); - + upper = p->type_val_to_struct[upper->bounds - 1]; if (upper->attribute) { printk(KERN_ERR "SELinux: type %s: " "bounded by attribute %s", (char *) key, - sym_name(p, SYM_TYPES, upper->value - 1)); + p->p_type_val_to_name[upper->value - 1]); return -EINVAL; } } @@ -2060,14 +2066,13 @@ int policydb_read(struct policydb *p, void *fp) rc = policydb_init(p); if (rc) - return rc; + goto out; /* Read the magic number and string length. */ rc = next_entry(buf, fp, sizeof(u32) * 2); - if (rc) + if (rc < 0) goto bad; - rc = -EINVAL; if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { printk(KERN_ERR "SELinux: policydb magic number 0x%x does " "not match expected magic number 0x%x\n", @@ -2075,7 +2080,6 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - rc = -EINVAL; len = le32_to_cpu(buf[1]); if (len != strlen(POLICYDB_STRING)) { printk(KERN_ERR "SELinux: policydb string length %d does not " @@ -2083,23 +2087,19 @@ int policydb_read(struct policydb *p, void *fp) len, strlen(POLICYDB_STRING)); goto bad; } - - rc = -ENOMEM; policydb_str = kmalloc(len + 1, GFP_KERNEL); if (!policydb_str) { printk(KERN_ERR "SELinux: unable to allocate memory for policydb " "string of length %d\n", len); + rc = -ENOMEM; goto bad; } - rc = next_entry(policydb_str, fp, len); - if (rc) { + if (rc < 0) { printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); kfree(policydb_str); goto bad; } - - rc = -EINVAL; policydb_str[len] = '\0'; if (strcmp(policydb_str, POLICYDB_STRING)) { printk(KERN_ERR "SELinux: policydb string %s does not match " @@ -2113,10 +2113,9 @@ int policydb_read(struct policydb *p, void *fp) /* Read the version and table sizes. */ rc = next_entry(buf, fp, sizeof(u32)*4); - if (rc) + if (rc < 0) goto bad; - rc = -EINVAL; p->policyvers = le32_to_cpu(buf[0]); if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX) { @@ -2129,7 +2128,6 @@ int policydb_read(struct policydb *p, void *fp) if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { p->mls_enabled = 1; - rc = -EINVAL; if (p->policyvers < POLICYDB_VERSION_MLS) { printk(KERN_ERR "SELinux: security policydb version %d " "(MLS) not backwards compatible\n", @@ -2140,19 +2138,14 @@ int policydb_read(struct policydb *p, void *fp) p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); - if (p->policyvers >= POLICYDB_VERSION_POLCAP) { - rc = ebitmap_read(&p->policycaps, fp); - if (rc) - goto bad; - } + if (p->policyvers >= POLICYDB_VERSION_POLCAP && + ebitmap_read(&p->policycaps, fp) != 0) + goto bad; - if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) { - rc = ebitmap_read(&p->permissive_map, fp); - if (rc) - goto bad; - } + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + ebitmap_read(&p->permissive_map, fp) != 0) + goto bad; - rc = -EINVAL; info = policydb_lookup_compat(p->policyvers); if (!info) { printk(KERN_ERR "SELinux: unable to find policy compat info " @@ -2160,7 +2153,6 @@ int policydb_read(struct policydb *p, void *fp) goto bad; } - rc = -EINVAL; if (le32_to_cpu(buf[2]) != info->sym_num || le32_to_cpu(buf[3]) != info->ocon_num) { printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " @@ -2172,7 +2164,7 @@ int policydb_read(struct policydb *p, void *fp) for (i = 0; i < info->sym_num; i++) { rc = next_entry(buf, fp, sizeof(u32)*2); - if (rc) + if (rc < 0) goto bad; nprim = le32_to_cpu(buf[0]); nel = le32_to_cpu(buf[1]); @@ -2196,73 +2188,78 @@ int policydb_read(struct policydb *p, void *fp) } rc = next_entry(buf, fp, sizeof(u32)); - if (rc) + if (rc < 0) goto bad; nel = le32_to_cpu(buf[0]); ltr = NULL; for (i = 0; i < nel; i++) { - rc = -ENOMEM; tr = kzalloc(sizeof(*tr), GFP_KERNEL); - if (!tr) + if (!tr) { + rc = -ENOMEM; goto bad; + } if (ltr) ltr->next = tr; else p->role_tr = tr; rc = next_entry(buf, fp, sizeof(u32)*3); - if (rc) + if (rc < 0) goto bad; - - rc = -EINVAL; tr->role = le32_to_cpu(buf[0]); tr->type = le32_to_cpu(buf[1]); tr->new_role = le32_to_cpu(buf[2]); if (!policydb_role_isvalid(p, tr->role) || !policydb_type_isvalid(p, tr->type) || - !policydb_role_isvalid(p, tr->new_role)) + !policydb_role_isvalid(p, tr->new_role)) { + rc = -EINVAL; goto bad; + } ltr = tr; } rc = next_entry(buf, fp, sizeof(u32)); - if (rc) + if (rc < 0) goto bad; nel = le32_to_cpu(buf[0]); lra = NULL; for (i = 0; i < nel; i++) { - rc = -ENOMEM; ra = kzalloc(sizeof(*ra), GFP_KERNEL); - if (!ra) + if (!ra) { + rc = -ENOMEM; goto bad; + } if (lra) lra->next = ra; else p->role_allow = ra; rc = next_entry(buf, fp, sizeof(u32)*2); - if (rc) + if (rc < 0) goto bad; - - rc = -EINVAL; ra->role = le32_to_cpu(buf[0]); ra->new_role = le32_to_cpu(buf[1]); if (!policydb_role_isvalid(p, ra->role) || - !policydb_role_isvalid(p, ra->new_role)) + !policydb_role_isvalid(p, ra->new_role)) { + rc = -EINVAL; goto bad; + } lra = ra; } - rc = policydb_index(p); + rc = policydb_index_classes(p); + if (rc) + goto bad; + + rc = policydb_index_others(p); if (rc) goto bad; - rc = -EINVAL; p->process_class = string_to_security_class(p, "process"); if (!p->process_class) goto bad; - - rc = -EINVAL; - p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); - p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); + p->process_trans_perms = string_to_av_perm(p, p->process_class, + "transition"); + p->process_trans_perms |= string_to_av_perm(p, p->process_class, + "dyntransition"); if (!p->process_trans_perms) goto bad; @@ -2315,6 +2312,8 @@ int policydb_read(struct policydb *p, void *fp) out: return rc; bad: + if (!rc) + rc = -EINVAL; policydb_destroy(p); goto out; } @@ -3077,7 +3076,7 @@ int policydb_write(struct policydb *p, void *fp) if (!info) { printk(KERN_ERR "SELinux: compatibility lookup failed for policy " "version %d", p->policyvers); - return -EINVAL; + return rc; } buf[0] = cpu_to_le32(p->policyvers); diff --git a/trunk/security/selinux/ss/policydb.h b/trunk/security/selinux/ss/policydb.h index 4e3ab9d0b315..95d3d7de361e 100644 --- a/trunk/security/selinux/ss/policydb.h +++ b/trunk/security/selinux/ss/policydb.h @@ -203,13 +203,21 @@ struct policydb { #define p_cats symtab[SYM_CATS] /* symbol names indexed by (value - 1) */ - struct flex_array *sym_val_to_name[SYM_NUM]; + char **sym_val_to_name[SYM_NUM]; +#define p_common_val_to_name sym_val_to_name[SYM_COMMONS] +#define p_class_val_to_name sym_val_to_name[SYM_CLASSES] +#define p_role_val_to_name sym_val_to_name[SYM_ROLES] +#define p_type_val_to_name sym_val_to_name[SYM_TYPES] +#define p_user_val_to_name sym_val_to_name[SYM_USERS] +#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS] +#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS] +#define p_cat_val_to_name sym_val_to_name[SYM_CATS] /* class, role, and user attributes indexed by (value - 1) */ struct class_datum **class_val_to_struct; struct role_datum **role_val_to_struct; struct user_datum **user_val_to_struct; - struct flex_array *type_val_to_struct_array; + struct type_datum **type_val_to_struct; /* type enforcement access vectors and transitions */ struct avtab te_avtab; @@ -313,13 +321,6 @@ static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file return 0; } -static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr) -{ - struct flex_array *fa = p->sym_val_to_name[sym_num]; - - return flex_array_get_ptr(fa, element_nr); -} - extern u16 string_to_security_class(struct policydb *p, const char *name); extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index a03cfaf0ee07..223c1ff6ef23 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -464,7 +464,7 @@ static void security_dump_masked_av(struct context *scontext, if (!permissions) return; - tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1); + tclass_name = policydb.p_class_val_to_name[tclass - 1]; tclass_dat = policydb.class_val_to_struct[tclass - 1]; common_dat = tclass_dat->comdatum; @@ -530,18 +530,12 @@ static void type_attribute_bounds_av(struct context *scontext, struct context lo_scontext; struct context lo_tcontext; struct av_decision lo_avd; - struct type_datum *source; - struct type_datum *target; + struct type_datum *source + = policydb.type_val_to_struct[scontext->type - 1]; + struct type_datum *target + = policydb.type_val_to_struct[tcontext->type - 1]; u32 masked = 0; - source = flex_array_get_ptr(policydb.type_val_to_struct_array, - scontext->type - 1); - BUG_ON(!source); - - target = flex_array_get_ptr(policydb.type_val_to_struct_array, - tcontext->type - 1); - BUG_ON(!target); - if (source->bounds) { memset(&lo_avd, 0, sizeof(lo_avd)); @@ -707,16 +701,16 @@ static int security_validtrans_handle_fail(struct context *ocontext, char *o = NULL, *n = NULL, *t = NULL; u32 olen, nlen, tlen; - if (context_struct_to_string(ocontext, &o, &olen)) + if (context_struct_to_string(ocontext, &o, &olen) < 0) goto out; - if (context_struct_to_string(ncontext, &n, &nlen)) + if (context_struct_to_string(ncontext, &n, &nlen) < 0) goto out; - if (context_struct_to_string(tcontext, &t, &tlen)) + if (context_struct_to_string(tcontext, &t, &tlen) < 0) goto out; audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, "security_validate_transition: denied for" " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", - o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1)); + o, n, t, policydb.p_class_val_to_name[tclass-1]); out: kfree(o); kfree(n); @@ -807,11 +801,10 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) struct context *old_context, *new_context; struct type_datum *type; int index; - int rc; + int rc = -EINVAL; read_lock(&policy_rwlock); - rc = -EINVAL; old_context = sidtab_search(&sidtab, old_sid); if (!old_context) { printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", @@ -819,7 +812,6 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) goto out; } - rc = -EINVAL; new_context = sidtab_search(&sidtab, new_sid); if (!new_context) { printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", @@ -827,27 +819,28 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) goto out; } - rc = 0; /* type/domain unchanged */ - if (old_context->type == new_context->type) + if (old_context->type == new_context->type) { + rc = 0; goto out; + } index = new_context->type; while (true) { - type = flex_array_get_ptr(policydb.type_val_to_struct_array, - index - 1); + type = policydb.type_val_to_struct[index - 1]; BUG_ON(!type); /* not bounded anymore */ - rc = -EPERM; - if (!type->bounds) + if (!type->bounds) { + rc = -EPERM; break; + } /* @newsid is bounded by @oldsid */ - rc = 0; - if (type->bounds == old_context->type) + if (type->bounds == old_context->type) { + rc = 0; break; - + } index = type->bounds; } @@ -1012,9 +1005,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 } /* Compute the size of the context. */ - *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1; - *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1; - *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1; + *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; + *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; + *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; *scontext_len += mls_compute_context_len(context); if (!scontext) @@ -1030,12 +1023,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 * Copy the user name, role name and type name into the context. */ sprintf(scontextp, "%s:%s:%s", - sym_name(&policydb, SYM_USERS, context->user - 1), - sym_name(&policydb, SYM_ROLES, context->role - 1), - sym_name(&policydb, SYM_TYPES, context->type - 1)); - scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + - 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + - 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)); + policydb.p_user_val_to_name[context->user - 1], + policydb.p_role_val_to_name[context->role - 1], + policydb.p_type_val_to_name[context->type - 1]); + scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + + 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + + 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); mls_sid_to_context(context, &scontextp); @@ -1194,13 +1187,16 @@ static int string_to_context_struct(struct policydb *pol, if (rc) goto out; - rc = -EINVAL; - if ((p - scontext) < scontext_len) + if ((p - scontext) < scontext_len) { + rc = -EINVAL; goto out; + } /* Check the validity of the new context. */ - if (!policydb_context_isvalid(pol, ctx)) + if (!policydb_context_isvalid(pol, ctx)) { + rc = -EINVAL; goto out; + } rc = 0; out: if (rc) @@ -1239,26 +1235,27 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, if (force) { /* Save another copy for storing in uninterpreted form */ - rc = -ENOMEM; str = kstrdup(scontext2, gfp_flags); - if (!str) - goto out; + if (!str) { + kfree(scontext2); + return -ENOMEM; + } } read_lock(&policy_rwlock); - rc = string_to_context_struct(&policydb, &sidtab, scontext2, - scontext_len, &context, def_sid); + rc = string_to_context_struct(&policydb, &sidtab, + scontext2, scontext_len, + &context, def_sid); if (rc == -EINVAL && force) { context.str = str; context.len = scontext_len; str = NULL; } else if (rc) - goto out_unlock; + goto out; rc = sidtab_context_to_sid(&sidtab, &context, sid); context_destroy(&context); -out_unlock: - read_unlock(&policy_rwlock); out: + read_unlock(&policy_rwlock); kfree(scontext2); kfree(str); return rc; @@ -1322,18 +1319,18 @@ static int compute_sid_handle_invalid_context( char *s = NULL, *t = NULL, *n = NULL; u32 slen, tlen, nlen; - if (context_struct_to_string(scontext, &s, &slen)) + if (context_struct_to_string(scontext, &s, &slen) < 0) goto out; - if (context_struct_to_string(tcontext, &t, &tlen)) + if (context_struct_to_string(tcontext, &t, &tlen) < 0) goto out; - if (context_struct_to_string(newcontext, &n, &nlen)) + if (context_struct_to_string(newcontext, &n, &nlen) < 0) goto out; audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, "security_compute_sid: invalid context %s" " for scontext=%s" " tcontext=%s" " tclass=%s", - n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1)); + n, s, t, policydb.p_class_val_to_name[tclass-1]); out: kfree(s); kfree(t); @@ -1572,17 +1569,22 @@ static int clone_sid(u32 sid, static inline int convert_context_handle_invalid_context(struct context *context) { - char *s; - u32 len; - - if (selinux_enforcing) - return -EINVAL; + int rc = 0; - if (!context_struct_to_string(context, &s, &len)) { - printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s); - kfree(s); + if (selinux_enforcing) { + rc = -EINVAL; + } else { + char *s; + u32 len; + + if (!context_struct_to_string(context, &s, &len)) { + printk(KERN_WARNING + "SELinux: Context %s would be invalid if enforcing\n", + s); + kfree(s); + } } - return 0; + return rc; } struct convert_context_args { @@ -1619,17 +1621,17 @@ static int convert_context(u32 key, if (c->str) { struct context ctx; - - rc = -ENOMEM; s = kstrdup(c->str, GFP_KERNEL); - if (!s) + if (!s) { + rc = -ENOMEM; goto out; - + } rc = string_to_context_struct(args->newp, NULL, s, c->len, &ctx, SECSID_NULL); kfree(s); if (!rc) { - printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n", + printk(KERN_INFO + "SELinux: Context %s became valid (mapped).\n", c->str); /* Replace string with mapped representation. */ kfree(c->str); @@ -1641,7 +1643,8 @@ static int convert_context(u32 key, goto out; } else { /* Other error condition, e.g. ENOMEM. */ - printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n", + printk(KERN_ERR + "SELinux: Unable to map context %s, rc = %d.\n", c->str, -rc); goto out; } @@ -1651,26 +1654,25 @@ static int convert_context(u32 key, if (rc) goto out; - /* Convert the user. */ rc = -EINVAL; + + /* Convert the user. */ usrdatum = hashtab_search(args->newp->p_users.table, - sym_name(args->oldp, SYM_USERS, c->user - 1)); + args->oldp->p_user_val_to_name[c->user - 1]); if (!usrdatum) goto bad; c->user = usrdatum->value; /* Convert the role. */ - rc = -EINVAL; role = hashtab_search(args->newp->p_roles.table, - sym_name(args->oldp, SYM_ROLES, c->role - 1)); + args->oldp->p_role_val_to_name[c->role - 1]); if (!role) goto bad; c->role = role->value; /* Convert the type. */ - rc = -EINVAL; typdatum = hashtab_search(args->newp->p_types.table, - sym_name(args->oldp, SYM_TYPES, c->type - 1)); + args->oldp->p_type_val_to_name[c->type - 1]); if (!typdatum) goto bad; c->type = typdatum->value; @@ -1698,7 +1700,6 @@ static int convert_context(u32 key, oc = args->newp->ocontexts[OCON_ISID]; while (oc && oc->sid[0] != SECINITSID_UNLABELED) oc = oc->next; - rc = -EINVAL; if (!oc) { printk(KERN_ERR "SELinux: unable to look up" " the initial SIDs list\n"); @@ -1718,20 +1719,19 @@ static int convert_context(u32 key, } context_destroy(&oldc); - rc = 0; out: return rc; bad: /* Map old representation to string and save it. */ - rc = context_struct_to_string(&oldc, &s, &len); - if (rc) - return rc; + if (context_struct_to_string(&oldc, &s, &len)) + return -ENOMEM; context_destroy(&oldc); context_destroy(c); c->str = s; c->len = len; - printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n", + printk(KERN_INFO + "SELinux: Context %s became invalid (unmapped).\n", c->str); rc = 0; goto out; @@ -2012,7 +2012,7 @@ int security_node_sid(u16 domain, u32 addrlen, u32 *out_sid) { - int rc; + int rc = 0; struct ocontext *c; read_lock(&policy_rwlock); @@ -2021,9 +2021,10 @@ int security_node_sid(u16 domain, case AF_INET: { u32 addr; - rc = -EINVAL; - if (addrlen != sizeof(u32)) + if (addrlen != sizeof(u32)) { + rc = -EINVAL; goto out; + } addr = *((u32 *)addrp); @@ -2037,9 +2038,10 @@ int security_node_sid(u16 domain, } case AF_INET6: - rc = -EINVAL; - if (addrlen != sizeof(u64) * 2) + if (addrlen != sizeof(u64) * 2) { + rc = -EINVAL; goto out; + } c = policydb.ocontexts[OCON_NODE6]; while (c) { if (match_ipv6_addrmask(addrp, c->u.node6.addr, @@ -2050,7 +2052,6 @@ int security_node_sid(u16 domain, break; default: - rc = 0; *out_sid = SECINITSID_NODE; goto out; } @@ -2068,7 +2069,6 @@ int security_node_sid(u16 domain, *out_sid = SECINITSID_NODE; } - rc = 0; out: read_unlock(&policy_rwlock); return rc; @@ -2113,22 +2113,24 @@ int security_get_user_sids(u32 fromsid, context_init(&usercon); - rc = -EINVAL; fromcon = sidtab_search(&sidtab, fromsid); - if (!fromcon) + if (!fromcon) { + rc = -EINVAL; goto out_unlock; + } - rc = -EINVAL; user = hashtab_search(policydb.p_users.table, username); - if (!user) + if (!user) { + rc = -EINVAL; goto out_unlock; - + } usercon.user = user->value; - rc = -ENOMEM; mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); - if (!mysids) + if (!mysids) { + rc = -ENOMEM; goto out_unlock; + } ebitmap_for_each_positive_bit(&user->roles, rnode, i) { role = policydb.role_val_to_struct[i]; @@ -2145,11 +2147,12 @@ int security_get_user_sids(u32 fromsid, if (mynel < maxnel) { mysids[mynel++] = sid; } else { - rc = -ENOMEM; maxnel += SIDS_NEL; mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); - if (!mysids2) + if (!mysids2) { + rc = -ENOMEM; goto out_unlock; + } memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); kfree(mysids); mysids = mysids2; @@ -2157,7 +2160,7 @@ int security_get_user_sids(u32 fromsid, } } } - rc = 0; + out_unlock: read_unlock(&policy_rwlock); if (rc || !mynel) { @@ -2165,9 +2168,9 @@ int security_get_user_sids(u32 fromsid, goto out; } - rc = -ENOMEM; mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); if (!mysids2) { + rc = -ENOMEM; kfree(mysids); goto out; } @@ -2208,7 +2211,7 @@ int security_genfs_sid(const char *fstype, u16 sclass; struct genfs *genfs; struct ocontext *c; - int rc, cmp = 0; + int rc = 0, cmp = 0; while (path[0] == '/' && path[1] == '/') path++; @@ -2216,7 +2219,6 @@ int security_genfs_sid(const char *fstype, read_lock(&policy_rwlock); sclass = unmap_class(orig_sclass); - *sid = SECINITSID_UNLABELED; for (genfs = policydb.genfs; genfs; genfs = genfs->next) { cmp = strcmp(fstype, genfs->fstype); @@ -2224,9 +2226,11 @@ int security_genfs_sid(const char *fstype, break; } - rc = -ENOENT; - if (!genfs || cmp) + if (!genfs || cmp) { + *sid = SECINITSID_UNLABELED; + rc = -ENOENT; goto out; + } for (c = genfs->head; c; c = c->next) { len = strlen(c->u.name); @@ -2235,18 +2239,21 @@ int security_genfs_sid(const char *fstype, break; } - rc = -ENOENT; - if (!c) + if (!c) { + *sid = SECINITSID_UNLABELED; + rc = -ENOENT; goto out; + } if (!c->sid[0]) { - rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); + rc = sidtab_context_to_sid(&sidtab, + &c->context[0], + &c->sid[0]); if (rc) goto out; } *sid = c->sid[0]; - rc = 0; out: read_unlock(&policy_rwlock); return rc; @@ -2278,7 +2285,8 @@ int security_fs_use( if (c) { *behavior = c->v.behavior; if (!c->sid[0]) { - rc = sidtab_context_to_sid(&sidtab, &c->context[0], + rc = sidtab_context_to_sid(&sidtab, + &c->context[0], &c->sid[0]); if (rc) goto out; @@ -2301,39 +2309,34 @@ int security_fs_use( int security_get_bools(int *len, char ***names, int **values) { - int i, rc; + int i, rc = -ENOMEM; read_lock(&policy_rwlock); *names = NULL; *values = NULL; - rc = 0; *len = policydb.p_bools.nprim; - if (!*len) + if (!*len) { + rc = 0; goto out; + } - rc = -ENOMEM; - *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); + *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); if (!*names) goto err; - rc = -ENOMEM; - *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); + *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); if (!*values) goto err; for (i = 0; i < *len; i++) { size_t name_len; - (*values)[i] = policydb.bool_val_to_struct[i]->state; - name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1; - - rc = -ENOMEM; - (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); + name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; + (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); if (!(*names)[i]) goto err; - - strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len); + strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); (*names)[i][name_len - 1] = 0; } rc = 0; @@ -2352,23 +2355,24 @@ int security_get_bools(int *len, char ***names, int **values) int security_set_bools(int len, int *values) { - int i, rc; + int i, rc = 0; int lenp, seqno = 0; struct cond_node *cur; write_lock_irq(&policy_rwlock); - rc = -EFAULT; lenp = policydb.p_bools.nprim; - if (len != lenp) + if (len != lenp) { + rc = -EFAULT; goto out; + } for (i = 0; i < len; i++) { if (!!values[i] != policydb.bool_val_to_struct[i]->state) { audit_log(current->audit_context, GFP_ATOMIC, AUDIT_MAC_CONFIG_CHANGE, "bool=%s val=%d old_val=%d auid=%u ses=%u", - sym_name(&policydb, SYM_BOOLS, i), + policydb.p_bool_val_to_name[i], !!values[i], policydb.bool_val_to_struct[i]->state, audit_get_loginuid(current), @@ -2387,7 +2391,7 @@ int security_set_bools(int len, int *values) } seqno = ++latest_granting; - rc = 0; + out: write_unlock_irq(&policy_rwlock); if (!rc) { @@ -2401,15 +2405,16 @@ int security_set_bools(int len, int *values) int security_get_bool_value(int bool) { - int rc; + int rc = 0; int len; read_lock(&policy_rwlock); - rc = -EFAULT; len = policydb.p_bools.nprim; - if (bool >= len) + if (bool >= len) { + rc = -EFAULT; goto out; + } rc = policydb.bool_val_to_struct[bool]->state; out: @@ -2459,9 +2464,8 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) struct context newcon; char *s; u32 len; - int rc; + int rc = 0; - rc = 0; if (!ss_initialized || !policydb.mls_enabled) { *new_sid = sid; goto out; @@ -2470,20 +2474,19 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) context_init(&newcon); read_lock(&policy_rwlock); - - rc = -EINVAL; context1 = sidtab_search(&sidtab, sid); if (!context1) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", __func__, sid); + rc = -EINVAL; goto out_unlock; } - rc = -EINVAL; context2 = sidtab_search(&sidtab, mls_sid); if (!context2) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", __func__, mls_sid); + rc = -EINVAL; goto out_unlock; } @@ -2497,17 +2500,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) /* Check the validity of the new context. */ if (!policydb_context_isvalid(&policydb, &newcon)) { rc = convert_context_handle_invalid_context(&newcon); - if (rc) { - if (!context_struct_to_string(&newcon, &s, &len)) { - audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "security_sid_mls_copy: invalid context %s", s); - kfree(s); - } - goto out_unlock; - } + if (rc) + goto bad; } rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); + goto out_unlock; + +bad: + if (!context_struct_to_string(&newcon, &s, &len)) { + audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, + "security_sid_mls_copy: invalid context %s", s); + kfree(s); + } + out_unlock: read_unlock(&policy_rwlock); context_destroy(&newcon); @@ -2543,8 +2549,6 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, struct context *nlbl_ctx; struct context *xfrm_ctx; - *peer_sid = SECSID_NULL; - /* handle the common (which also happens to be the set of easy) cases * right away, these two if statements catch everything involving a * single or absent peer SID/label */ @@ -2563,37 +2567,40 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, /* we don't need to check ss_initialized here since the only way both * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the * security server was initialized and ss_initialized was true */ - if (!policydb.mls_enabled) + if (!policydb.mls_enabled) { + *peer_sid = SECSID_NULL; return 0; + } read_lock(&policy_rwlock); - rc = -EINVAL; nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); if (!nlbl_ctx) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", __func__, nlbl_sid); - goto out; + rc = -EINVAL; + goto out_slowpath; } - rc = -EINVAL; xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); if (!xfrm_ctx) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", __func__, xfrm_sid); - goto out; + rc = -EINVAL; + goto out_slowpath; } rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); - if (rc) - goto out; - /* at present NetLabel SIDs/labels really only carry MLS - * information so if the MLS portion of the NetLabel SID - * matches the MLS portion of the labeled XFRM SID/label - * then pass along the XFRM SID as it is the most - * expressive */ - *peer_sid = xfrm_sid; -out: +out_slowpath: read_unlock(&policy_rwlock); + if (rc == 0) + /* at present NetLabel SIDs/labels really only carry MLS + * information so if the MLS portion of the NetLabel SID + * matches the MLS portion of the labeled XFRM SID/label + * then pass along the XFRM SID as it is the most + * expressive */ + *peer_sid = xfrm_sid; + else + *peer_sid = SECSID_NULL; return rc; } @@ -2612,11 +2619,10 @@ static int get_classes_callback(void *k, void *d, void *args) int security_get_classes(char ***classes, int *nclasses) { - int rc; + int rc = -ENOMEM; read_lock(&policy_rwlock); - rc = -ENOMEM; *nclasses = policydb.p_classes.nprim; *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); if (!*classes) @@ -2624,7 +2630,7 @@ int security_get_classes(char ***classes, int *nclasses) rc = hashtab_map(policydb.p_classes.table, get_classes_callback, *classes); - if (rc) { + if (rc < 0) { int i; for (i = 0; i < *nclasses; i++) kfree((*classes)[i]); @@ -2651,20 +2657,19 @@ static int get_permissions_callback(void *k, void *d, void *args) int security_get_permissions(char *class, char ***perms, int *nperms) { - int rc, i; + int rc = -ENOMEM, i; struct class_datum *match; read_lock(&policy_rwlock); - rc = -EINVAL; match = hashtab_search(policydb.p_classes.table, class); if (!match) { printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", __func__, class); + rc = -EINVAL; goto out; } - rc = -ENOMEM; *nperms = match->permissions.nprim; *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); if (!*perms) @@ -2673,13 +2678,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms) if (match->comdatum) { rc = hashtab_map(match->comdatum->permissions.table, get_permissions_callback, *perms); - if (rc) + if (rc < 0) goto err; } rc = hashtab_map(match->permissions.table, get_permissions_callback, *perms); - if (rc) + if (rc < 0) goto err; out: @@ -2791,39 +2796,36 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) switch (field) { case AUDIT_SUBJ_USER: case AUDIT_OBJ_USER: - rc = -EINVAL; userdatum = hashtab_search(policydb.p_users.table, rulestr); if (!userdatum) - goto out; - tmprule->au_ctxt.user = userdatum->value; + rc = -EINVAL; + else + tmprule->au_ctxt.user = userdatum->value; break; case AUDIT_SUBJ_ROLE: case AUDIT_OBJ_ROLE: - rc = -EINVAL; roledatum = hashtab_search(policydb.p_roles.table, rulestr); if (!roledatum) - goto out; - tmprule->au_ctxt.role = roledatum->value; + rc = -EINVAL; + else + tmprule->au_ctxt.role = roledatum->value; break; case AUDIT_SUBJ_TYPE: case AUDIT_OBJ_TYPE: - rc = -EINVAL; typedatum = hashtab_search(policydb.p_types.table, rulestr); if (!typedatum) - goto out; - tmprule->au_ctxt.type = typedatum->value; + rc = -EINVAL; + else + tmprule->au_ctxt.type = typedatum->value; break; case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); - if (rc) - goto out; break; } - rc = 0; -out: + read_unlock(&policy_rwlock); if (rc) { @@ -3048,7 +3050,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, u32 *sid) { - int rc; + int rc = -EIDRM; struct context *ctx; struct context ctx_new; @@ -3059,15 +3061,16 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, read_lock(&policy_rwlock); - if (secattr->flags & NETLBL_SECATTR_CACHE) + if (secattr->flags & NETLBL_SECATTR_CACHE) { *sid = *(u32 *)secattr->cache->data; - else if (secattr->flags & NETLBL_SECATTR_SECID) + rc = 0; + } else if (secattr->flags & NETLBL_SECATTR_SECID) { *sid = secattr->attr.secid; - else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { - rc = -EIDRM; + rc = 0; + } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); if (ctx == NULL) - goto out; + goto netlbl_secattr_to_sid_return; context_init(&ctx_new); ctx_new.user = ctx->user; @@ -3075,35 +3078,34 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, ctx_new.type = ctx->type; mls_import_netlbl_lvl(&ctx_new, secattr); if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { - rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat, - secattr->attr.mls.cat); - if (rc) - goto out; + if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, + secattr->attr.mls.cat) != 0) + goto netlbl_secattr_to_sid_return; memcpy(&ctx_new.range.level[1].cat, &ctx_new.range.level[0].cat, sizeof(ctx_new.range.level[0].cat)); } - rc = -EIDRM; - if (!mls_context_isvalid(&policydb, &ctx_new)) - goto out_free; + if (mls_context_isvalid(&policydb, &ctx_new) != 1) + goto netlbl_secattr_to_sid_return_cleanup; rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); - if (rc) - goto out_free; + if (rc != 0) + goto netlbl_secattr_to_sid_return_cleanup; security_netlbl_cache_add(secattr, *sid); ebitmap_destroy(&ctx_new.range.level[0].cat); - } else + } else { *sid = SECSID_NULL; + rc = 0; + } - read_unlock(&policy_rwlock); - return 0; -out_free: - ebitmap_destroy(&ctx_new.range.level[0].cat); -out: +netlbl_secattr_to_sid_return: read_unlock(&policy_rwlock); return rc; +netlbl_secattr_to_sid_return_cleanup: + ebitmap_destroy(&ctx_new.range.level[0].cat); + goto netlbl_secattr_to_sid_return; } /** @@ -3125,23 +3127,28 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) return 0; read_lock(&policy_rwlock); - - rc = -ENOENT; ctx = sidtab_search(&sidtab, sid); - if (ctx == NULL) - goto out; - - rc = -ENOMEM; - secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1), + if (ctx == NULL) { + rc = -ENOENT; + goto netlbl_sid_to_secattr_failure; + } + secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], GFP_ATOMIC); - if (secattr->domain == NULL) - goto out; - + if (secattr->domain == NULL) { + rc = -ENOMEM; + goto netlbl_sid_to_secattr_failure; + } secattr->attr.secid = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(ctx, secattr); rc = mls_export_netlbl_cat(ctx, secattr); -out: + if (rc != 0) + goto netlbl_sid_to_secattr_failure; + read_unlock(&policy_rwlock); + + return 0; + +netlbl_sid_to_secattr_failure: read_unlock(&policy_rwlock); return rc; } diff --git a/trunk/security/selinux/ss/sidtab.c b/trunk/security/selinux/ss/sidtab.c index 5840a35155fc..e817989764cd 100644 --- a/trunk/security/selinux/ss/sidtab.c +++ b/trunk/security/selinux/ss/sidtab.c @@ -147,17 +147,6 @@ int sidtab_map(struct sidtab *s, return rc; } -static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc) -{ - BUG_ON(loc >= SIDTAB_CACHE_LEN); - - while (loc > 0) { - s->cache[loc] = s->cache[loc - 1]; - loc--; - } - s->cache[0] = n; -} - static inline u32 sidtab_search_context(struct sidtab *s, struct context *context) { @@ -167,33 +156,14 @@ static inline u32 sidtab_search_context(struct sidtab *s, for (i = 0; i < SIDTAB_SIZE; i++) { cur = s->htable[i]; while (cur) { - if (context_cmp(&cur->context, context)) { - sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1); + if (context_cmp(&cur->context, context)) return cur->sid; - } cur = cur->next; } } return 0; } -static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context) -{ - int i; - struct sidtab_node *node; - - for (i = 0; i < SIDTAB_CACHE_LEN; i++) { - node = s->cache[i]; - if (unlikely(!node)) - return 0; - if (context_cmp(&node->context, context)) { - sidtab_update_cache(s, node, i); - return node->sid; - } - } - return 0; -} - int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *out_sid) @@ -204,9 +174,7 @@ int sidtab_context_to_sid(struct sidtab *s, *out_sid = SECSID_NULL; - sid = sidtab_search_cache(s, context); - if (!sid) - sid = sidtab_search_context(s, context); + sid = sidtab_search_context(s, context); if (!sid) { spin_lock_irqsave(&s->lock, flags); /* Rescan now that we hold the lock. */ @@ -291,15 +259,12 @@ void sidtab_destroy(struct sidtab *s) void sidtab_set(struct sidtab *dst, struct sidtab *src) { unsigned long flags; - int i; spin_lock_irqsave(&src->lock, flags); dst->htable = src->htable; dst->nel = src->nel; dst->next_sid = src->next_sid; dst->shutdown = 0; - for (i = 0; i < SIDTAB_CACHE_LEN; i++) - dst->cache[i] = NULL; spin_unlock_irqrestore(&src->lock, flags); } diff --git a/trunk/security/selinux/ss/sidtab.h b/trunk/security/selinux/ss/sidtab.h index 84dc154d9389..64ea5b1cdea4 100644 --- a/trunk/security/selinux/ss/sidtab.h +++ b/trunk/security/selinux/ss/sidtab.h @@ -26,8 +26,6 @@ struct sidtab { unsigned int nel; /* number of elements */ unsigned int next_sid; /* next SID to allocate */ unsigned char shutdown; -#define SIDTAB_CACHE_LEN 3 - struct sidtab_node *cache[SIDTAB_CACHE_LEN]; spinlock_t lock; }; diff --git a/trunk/security/smack/smack.h b/trunk/security/smack/smack.h index 129c4eb8ffb1..43ae747a5aa4 100644 --- a/trunk/security/smack/smack.h +++ b/trunk/security/smack/smack.h @@ -51,18 +51,11 @@ struct socket_smack { */ struct inode_smack { char *smk_inode; /* label of the fso */ - char *smk_task; /* label of the task */ struct mutex smk_lock; /* initialization lock */ int smk_flags; /* smack inode flags */ }; -struct task_smack { - char *smk_task; /* label used for access control */ - char *smk_forked; /* label when forked */ -}; - #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ -#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ /* * A label access rule. @@ -167,10 +160,6 @@ struct smack_known { #define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ #define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ -/* - * Flag for transmute access - */ -#define MAY_TRANSMUTE 64 /* * Just to make the common cases easier to deal with */ @@ -202,7 +191,6 @@ struct inode_smack *new_inode_smack(char *); /* * These functions are in smack_access.c */ -int smk_access_entry(char *, char *); int smk_access(char *, char *, int, struct smk_audit_info *); int smk_curacc(char *, u32, struct smk_audit_info *); int smack_to_cipso(const char *, struct smack_cipso *); @@ -245,15 +233,6 @@ static inline void smack_catset_bit(int cat, char *catsetp) catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8); } -/* - * Is the directory transmuting? - */ -static inline int smk_inode_transmutable(const struct inode *isp) -{ - struct inode_smack *sip = isp->i_security; - return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0; -} - /* * Present a pointer to the smack label in an inode blob. */ @@ -263,30 +242,6 @@ static inline char *smk_of_inode(const struct inode *isp) return sip->smk_inode; } -/* - * Present a pointer to the smack label in an task blob. - */ -static inline char *smk_of_task(const struct task_smack *tsp) -{ - return tsp->smk_task; -} - -/* - * Present a pointer to the forked smack label in an task blob. - */ -static inline char *smk_of_forked(const struct task_smack *tsp) -{ - return tsp->smk_forked; -} - -/* - * Present a pointer to the smack label in the current task blob. - */ -static inline char *smk_of_current(void) -{ - return smk_of_task(current_security()); -} - /* * logging functions */ diff --git a/trunk/security/smack/smack_access.c b/trunk/security/smack/smack_access.c index 7ba8478f599e..f4fac64c4da8 100644 --- a/trunk/security/smack/smack_access.c +++ b/trunk/security/smack/smack_access.c @@ -66,46 +66,6 @@ static u32 smack_next_secid = 10; */ int log_policy = SMACK_AUDIT_DENIED; -/** - * smk_access_entry - look up matching access rule - * @subject_label: a pointer to the subject's Smack label - * @object_label: a pointer to the object's Smack label - * - * This function looks up the subject/object pair in the - * access rule list and returns pointer to the matching rule if found, - * NULL otherwise. - * - * NOTE: - * Even though Smack labels are usually shared on smack_list - * labels that come in off the network can't be imported - * and added to the list for locking reasons. - * - * Therefore, it is necessary to check the contents of the labels, - * not just the pointer values. Of course, in most cases the labels - * will be on the list, so checking the pointers may be a worthwhile - * optimization. - */ -int smk_access_entry(char *subject_label, char *object_label) -{ - u32 may = MAY_NOT; - struct smack_rule *srp; - - rcu_read_lock(); - list_for_each_entry_rcu(srp, &smack_rule_list, list) { - if (srp->smk_subject == subject_label || - strcmp(srp->smk_subject, subject_label) == 0) { - if (srp->smk_object == object_label || - strcmp(srp->smk_object, object_label) == 0) { - may = srp->smk_access; - break; - } - } - } - rcu_read_unlock(); - - return may; -} - /** * smk_access - determine if a subject has a specific access to an object * @subject_label: a pointer to the subject's Smack label @@ -130,6 +90,7 @@ int smk_access(char *subject_label, char *object_label, int request, struct smk_audit_info *a) { u32 may = MAY_NOT; + struct smack_rule *srp; int rc = 0; /* @@ -183,7 +144,18 @@ int smk_access(char *subject_label, char *object_label, int request, * access (e.g. read is included in readwrite) it's * good. */ - may = smk_access_entry(subject_label, object_label); + rcu_read_lock(); + list_for_each_entry_rcu(srp, &smack_rule_list, list) { + if (srp->smk_subject == subject_label || + strcmp(srp->smk_subject, subject_label) == 0) { + if (srp->smk_object == object_label || + strcmp(srp->smk_object, object_label) == 0) { + may = srp->smk_access; + break; + } + } + } + rcu_read_unlock(); /* * This is a bit map operation. */ @@ -213,7 +185,7 @@ int smk_access(char *subject_label, char *object_label, int request, int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) { int rc; - char *sp = smk_of_current(); + char *sp = current_security(); rc = smk_access(sp, obj_label, mode, NULL); if (rc == 0) @@ -224,7 +196,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) * only one that gets privilege and current does not * have that label. */ - if (smack_onlycap != NULL && smack_onlycap != sp) + if (smack_onlycap != NULL && smack_onlycap != current->cred->security) goto out_audit; if (capable(CAP_MAC_OVERRIDE)) diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 533bf3255d7f..ccb71a044a1a 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -3,14 +3,12 @@ * * This file contains the smack hook function implementations. * - * Authors: + * Author: * Casey Schaufler - * Jarkko Sakkinen * * Copyright (C) 2007 Casey Schaufler * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. * Paul Moore - * Copyright (C) 2010 Nokia Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -37,9 +35,6 @@ #define task_security(task) (task_cred_xxx((task), security)) -#define TRANS_TRUE "TRUE" -#define TRANS_TRUE_SIZE 4 - /** * smk_fetch - Fetch the smack label from a file. * @ip: a pointer to the inode @@ -48,7 +43,7 @@ * Returns a pointer to the master list entry for the Smack label * or NULL if there was no label to fetch. */ -static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) +static char *smk_fetch(struct inode *ip, struct dentry *dp) { int rc; char in[SMK_LABELLEN]; @@ -56,7 +51,7 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) if (ip->i_op->getxattr == NULL) return NULL; - rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN); + rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); if (rc < 0) return NULL; @@ -108,8 +103,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) if (rc != 0) return rc; - sp = smk_of_current(); - tsp = smk_of_task(task_security(ctp)); + sp = current_security(); + tsp = task_security(ctp); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, ctp); @@ -143,8 +138,8 @@ static int smack_ptrace_traceme(struct task_struct *ptp) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, ptp); - sp = smk_of_current(); - tsp = smk_of_task(task_security(ptp)); + sp = current_security(); + tsp = task_security(ptp); /* we won't log here, because rc can be overriden */ rc = smk_access(tsp, sp, MAY_READWRITE, NULL); if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) @@ -165,7 +160,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp) static int smack_syslog(int typefrom_file) { int rc = 0; - char *sp = smk_of_current(); + char *sp = current_security(); if (capable(CAP_MAC_OVERRIDE)) return 0; @@ -395,40 +390,6 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); } -/* - * BPRM hooks - */ - -static int smack_bprm_set_creds(struct linux_binprm *bprm) -{ - struct task_smack *tsp = bprm->cred->security; - struct inode_smack *isp; - struct dentry *dp; - int rc; - - rc = cap_bprm_set_creds(bprm); - if (rc != 0) - return rc; - - if (bprm->cred_prepared) - return 0; - - if (bprm->file == NULL || bprm->file->f_dentry == NULL) - return 0; - - dp = bprm->file->f_dentry; - - if (dp->d_inode == NULL) - return 0; - - isp = dp->d_inode->i_security; - - if (isp->smk_task != NULL) - tsp->smk_task = isp->smk_task; - - return 0; -} - /* * Inode hooks */ @@ -441,7 +402,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) */ static int smack_inode_alloc_security(struct inode *inode) { - inode->i_security = new_inode_smack(smk_of_current()); + inode->i_security = new_inode_smack(current_security()); if (inode->i_security == NULL) return -ENOMEM; return 0; @@ -473,8 +434,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, char **name, void **value, size_t *len) { char *isp = smk_of_inode(inode); - char *dsp = smk_of_inode(dir); - u32 may; if (name) { *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); @@ -483,16 +442,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, } if (value) { - may = smk_access_entry(smk_of_current(), dsp); - - /* - * If the access rule allows transmutation and - * the directory requests transmutation then - * by all means transmute. - */ - if (((may & MAY_TRANSMUTE) != 0) && smk_inode_transmutable(dir)) - isp = dsp; - *value = kstrdup(isp, GFP_KERNEL); if (*value == NULL) return -ENOMEM; @@ -715,8 +664,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, if (strcmp(name, XATTR_NAME_SMACK) == 0 || strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || - strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || - strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; /* @@ -726,12 +674,6 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, if (size == 0 || size >= SMK_LABELLEN || smk_import(value, size) == NULL) rc = -EINVAL; - } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { - if (!capable(CAP_MAC_ADMIN)) - rc = -EPERM; - if (size != TRANS_TRUE_SIZE || - strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) - rc = -EINVAL; } else rc = cap_inode_setxattr(dentry, name, value, size, flags); @@ -758,23 +700,26 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + struct inode_smack *isp; char *nsp; - struct inode_smack *isp = dentry->d_inode->i_security; - if (strcmp(name, XATTR_NAME_SMACK) == 0) { - nsp = smk_import(value, size); - if (nsp != NULL) - isp->smk_inode = nsp; - else - isp->smk_inode = smack_known_invalid.smk_known; - } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { - nsp = smk_import(value, size); - if (nsp != NULL) - isp->smk_task = nsp; - else - isp->smk_task = smack_known_invalid.smk_known; - } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) - isp->smk_flags |= SMK_INODE_TRANSMUTE; + /* + * Not SMACK + */ + if (strcmp(name, XATTR_NAME_SMACK)) + return; + + isp = dentry->d_inode->i_security; + + /* + * No locking is done here. This is a pointer + * assignment. + */ + nsp = smk_import(value, size); + if (nsp != NULL) + isp->smk_inode = nsp; + else + isp->smk_inode = smack_known_invalid.smk_known; return; } @@ -807,15 +752,12 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) */ static int smack_inode_removexattr(struct dentry *dentry, const char *name) { - struct inode_smack *isp; struct smk_audit_info ad; int rc = 0; if (strcmp(name, XATTR_NAME_SMACK) == 0 || strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || - strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || - strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || - strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else @@ -826,11 +768,6 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); - if (rc == 0) { - isp = dentry->d_inode->i_security; - isp->smk_task = NULL; - } - return rc; } @@ -958,7 +895,7 @@ static int smack_file_permission(struct file *file, int mask) */ static int smack_file_alloc_security(struct file *file) { - file->f_security = smk_of_current(); + file->f_security = current_security(); return 0; } @@ -1068,7 +1005,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, */ static int smack_file_set_fowner(struct file *file) { - file->f_security = smk_of_current(); + file->f_security = current_security(); return 0; } @@ -1088,7 +1025,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, { struct file *file; int rc; - char *tsp = smk_of_task(tsk->cred->security); + char *tsp = tsk->cred->security; struct smk_audit_info ad; /* @@ -1145,9 +1082,7 @@ static int smack_file_receive(struct file *file) */ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) { - cred->security = kzalloc(sizeof(struct task_smack), gfp); - if (cred->security == NULL) - return -ENOMEM; + cred->security = NULL; return 0; } @@ -1162,7 +1097,7 @@ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) */ static void smack_cred_free(struct cred *cred) { - kfree(cred->security); + cred->security = NULL; } /** @@ -1176,16 +1111,7 @@ static void smack_cred_free(struct cred *cred) static int smack_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) { - struct task_smack *old_tsp = old->security; - struct task_smack *new_tsp; - - new_tsp = kzalloc(sizeof(struct task_smack), gfp); - if (new_tsp == NULL) - return -ENOMEM; - - new_tsp->smk_task = old_tsp->smk_task; - new_tsp->smk_forked = old_tsp->smk_task; - new->security = new_tsp; + new->security = old->security; return 0; } @@ -1198,11 +1124,7 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old, */ static void smack_cred_transfer(struct cred *new, const struct cred *old) { - struct task_smack *old_tsp = old->security; - struct task_smack *new_tsp = new->security; - - new_tsp->smk_task = old_tsp->smk_task; - new_tsp->smk_forked = old_tsp->smk_task; + new->security = old->security; } /** @@ -1214,13 +1136,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old) */ static int smack_kernel_act_as(struct cred *new, u32 secid) { - struct task_smack *new_tsp = new->security; char *smack = smack_from_secid(secid); if (smack == NULL) return -EINVAL; - new_tsp->smk_task = smack; + new->security = smack; return 0; } @@ -1236,10 +1157,8 @@ static int smack_kernel_create_files_as(struct cred *new, struct inode *inode) { struct inode_smack *isp = inode->i_security; - struct task_smack *tsp = new->security; - tsp->smk_forked = isp->smk_inode; - tsp->smk_task = isp->smk_inode; + new->security = isp->smk_inode; return 0; } @@ -1256,7 +1175,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, p); - return smk_curacc(smk_of_task(task_security(p)), access, &ad); + return smk_curacc(task_security(p), access, &ad); } /** @@ -1302,7 +1221,7 @@ static int smack_task_getsid(struct task_struct *p) */ static void smack_task_getsecid(struct task_struct *p, u32 *secid) { - *secid = smack_to_secid(smk_of_task(task_security(p))); + *secid = smack_to_secid(task_security(p)); } /** @@ -1414,15 +1333,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, * can write the receiver. */ if (secid == 0) - return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, - &ad); + return smk_curacc(task_security(p), MAY_WRITE, &ad); /* * If the secid isn't 0 we're dealing with some USB IO * specific behavior. This is not clean. For one thing * we can't take privilege into account. */ - return smk_access(smack_from_secid(secid), - smk_of_task(task_security(p)), MAY_WRITE, &ad); + return smk_access(smack_from_secid(secid), task_security(p), + MAY_WRITE, &ad); } /** @@ -1434,12 +1352,12 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, static int smack_task_wait(struct task_struct *p) { struct smk_audit_info ad; - char *sp = smk_of_current(); - char *tsp = smk_of_forked(task_security(p)); + char *sp = current_security(); + char *tsp = task_security(p); int rc; /* we don't log here, we can be overriden */ - rc = smk_access(tsp, sp, MAY_WRITE, NULL); + rc = smk_access(sp, tsp, MAY_WRITE, NULL); if (rc == 0) goto out_log; @@ -1460,7 +1378,7 @@ static int smack_task_wait(struct task_struct *p) out_log: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, p); - smack_log(tsp, sp, MAY_WRITE, rc, &ad); + smack_log(sp, tsp, MAY_WRITE, rc, &ad); return rc; } @@ -1474,7 +1392,7 @@ static int smack_task_wait(struct task_struct *p) static void smack_task_to_inode(struct task_struct *p, struct inode *inode) { struct inode_smack *isp = inode->i_security; - isp->smk_inode = smk_of_task(task_security(p)); + isp->smk_inode = task_security(p); } /* @@ -1493,7 +1411,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) */ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) { - char *csp = smk_of_current(); + char *csp = current_security(); struct socket_smack *ssp; ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); @@ -1749,13 +1667,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, ssp->smk_in = sp; else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { ssp->smk_out = sp; - if (sock->sk->sk_family != PF_UNIX) { - rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); - if (rc != 0) - printk(KERN_WARNING - "Smack: \"%s\" netlbl error %d.\n", - __func__, -rc); - } + rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); + if (rc != 0) + printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", + __func__, -rc); } else return -EOPNOTSUPP; @@ -1834,7 +1749,7 @@ static int smack_flags_to_may(int flags) */ static int smack_msg_msg_alloc_security(struct msg_msg *msg) { - msg->security = smk_of_current(); + msg->security = current_security(); return 0; } @@ -1870,7 +1785,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) { struct kern_ipc_perm *isp = &shp->shm_perm; - isp->security = smk_of_current(); + isp->security = current_security(); return 0; } @@ -1993,7 +1908,7 @@ static int smack_sem_alloc_security(struct sem_array *sma) { struct kern_ipc_perm *isp = &sma->sem_perm; - isp->security = smk_of_current(); + isp->security = current_security(); return 0; } @@ -2111,7 +2026,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq) { struct kern_ipc_perm *kisp = &msq->q_perm; - kisp->security = smk_of_current(); + kisp->security = current_security(); return 0; } @@ -2283,11 +2198,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) struct super_block *sbp; struct superblock_smack *sbsp; struct inode_smack *isp; - char *csp = smk_of_current(); + char *csp = current_security(); char *fetched; char *final; - char trattr[TRANS_TRUE_SIZE]; - int transflag = 0; struct dentry *dp; if (inode == NULL) @@ -2354,10 +2267,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) break; case SOCKFS_MAGIC: /* - * Socket access is controlled by the socket - * structures associated with the task involved. + * Casey says sockets get the smack of the task. */ - final = smack_known_star.smk_known; + final = csp; break; case PROC_SUPER_MAGIC: /* @@ -2384,16 +2296,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) /* * This isn't an understood special case. * Get the value from the xattr. - */ - - /* - * UNIX domain sockets use lower level socket data. - */ - if (S_ISSOCK(inode->i_mode)) { - final = smack_known_star.smk_known; - break; - } - /* + * * No xattr support means, alas, no SMACK label. * Use the aforeapplied default. * It would be curious if the label of the task @@ -2405,21 +2308,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * Get the dentry for xattr. */ dp = dget(opt_dentry); - fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); - if (fetched != NULL) { + fetched = smk_fetch(inode, dp); + if (fetched != NULL) final = fetched; - if (S_ISDIR(inode->i_mode)) { - trattr[0] = '\0'; - inode->i_op->getxattr(dp, - XATTR_NAME_SMACKTRANSMUTE, - trattr, TRANS_TRUE_SIZE); - if (strncmp(trattr, TRANS_TRUE, - TRANS_TRUE_SIZE) == 0) - transflag = SMK_INODE_TRANSMUTE; - } - } - isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); - dput(dp); break; } @@ -2429,7 +2320,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) else isp->smk_inode = final; - isp->smk_flags |= (SMK_INODE_INSTANT | transflag); + isp->smk_flags |= SMK_INODE_INSTANT; unlockandout: mutex_unlock(&isp->smk_lock); @@ -2454,7 +2345,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) if (strcmp(name, "current") != 0) return -EINVAL; - cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); + cp = kstrdup(task_security(p), GFP_KERNEL); if (cp == NULL) return -ENOMEM; @@ -2478,8 +2369,6 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) static int smack_setprocattr(struct task_struct *p, char *name, void *value, size_t size) { - struct task_smack *tsp; - struct task_smack *oldtsp; struct cred *new; char *newsmack; @@ -2509,18 +2398,10 @@ static int smack_setprocattr(struct task_struct *p, char *name, if (newsmack == smack_known_web.smk_known) return -EPERM; - oldtsp = p->cred->security; new = prepare_creds(); if (new == NULL) return -ENOMEM; - tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); - if (tsp == NULL) { - kfree(new); - return -ENOMEM; - } - tsp->smk_task = newsmack; - tsp->smk_forked = oldtsp->smk_forked; - new->security = tsp; + new->security = newsmack; commit_creds(new); return size; } @@ -2537,18 +2418,14 @@ static int smack_setprocattr(struct task_struct *p, char *name, static int smack_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { - struct socket_smack *ssp = sock->sk_security; - struct socket_smack *osp = other->sk_security; + struct inode *sp = SOCK_INODE(sock->sk_socket); + struct inode *op = SOCK_INODE(other->sk_socket); struct smk_audit_info ad; - int rc = 0; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_setfield_u_net_sk(&ad, other); - - if (!capable(CAP_MAC_OVERRIDE)) - rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); - - return rc; + return smk_access(smk_of_inode(sp), smk_of_inode(op), + MAY_READWRITE, &ad); } /** @@ -2561,18 +2438,13 @@ static int smack_unix_stream_connect(struct sock *sock, */ static int smack_unix_may_send(struct socket *sock, struct socket *other) { - struct socket_smack *ssp = sock->sk->sk_security; - struct socket_smack *osp = other->sk->sk_security; + struct inode *sp = SOCK_INODE(sock); + struct inode *op = SOCK_INODE(other); struct smk_audit_info ad; - int rc = 0; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_setfield_u_net_sk(&ad, other->sk); - - if (!capable(CAP_MAC_OVERRIDE)) - rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); - - return rc; + return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); } /** @@ -2757,7 +2629,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, /** * smack_socket_getpeersec_dgram - pull in packet label - * @sock: the peer socket + * @sock: the socket * @skb: packet data * @secid: pointer to where to put the secid of the packet * @@ -2768,39 +2640,41 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, { struct netlbl_lsm_secattr secattr; - struct socket_smack *sp; + struct sock *sk; char smack[SMK_LABELLEN]; - int family = PF_UNSPEC; - u32 s = 0; /* 0 is the invalid secid */ + int family = PF_INET; + u32 s; int rc; - if (skb != NULL) { - if (skb->protocol == htons(ETH_P_IP)) - family = PF_INET; - else if (skb->protocol == htons(ETH_P_IPV6)) - family = PF_INET6; + /* + * Only works for families with packets. + */ + if (sock != NULL) { + sk = sock->sk; + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) + return 0; + family = sk->sk_family; } - if (family == PF_UNSPEC && sock != NULL) - family = sock->sk->sk_family; + /* + * Translate what netlabel gave us. + */ + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); + if (rc == 0) + smack_from_secattr(&secattr, smack); + netlbl_secattr_destroy(&secattr); - if (family == PF_UNIX) { - sp = sock->sk->sk_security; - s = smack_to_secid(sp->smk_out); - } else if (family == PF_INET || family == PF_INET6) { - /* - * Translate what netlabel gave us. - */ - netlbl_secattr_init(&secattr); - rc = netlbl_skbuff_getattr(skb, family, &secattr); - if (rc == 0) { - smack_from_secattr(&secattr, smack); - s = smack_to_secid(smack); - } - netlbl_secattr_destroy(&secattr); - } - *secid = s; + /* + * Give up if we couldn't get anything + */ + if (rc != 0) + return rc; + + s = smack_to_secid(smack); if (s == 0) return -EINVAL; + + *secid = s; return 0; } @@ -2821,7 +2695,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) return; ssp = sk->sk_security; - ssp->smk_in = ssp->smk_out = smk_of_current(); + ssp->smk_in = ssp->smk_out = current_security(); /* cssp->smk_packet is already set in smack_inet_csk_clone() */ } @@ -2942,7 +2816,7 @@ static void smack_inet_csk_clone(struct sock *sk, static int smack_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { - key->security = smk_of_task(cred->security); + key->security = cred->security; return 0; } @@ -2971,7 +2845,6 @@ static int smack_key_permission(key_ref_t key_ref, { struct key *keyp; struct smk_audit_info ad; - char *tsp = smk_of_task(cred->security); keyp = key_ref_to_ptr(key_ref); if (keyp == NULL) @@ -2985,14 +2858,14 @@ static int smack_key_permission(key_ref_t key_ref, /* * This should not occur */ - if (tsp == NULL) + if (cred->security == NULL) return -EACCES; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); ad.a.u.key_struct.key = keyp->serial; ad.a.u.key_struct.key_desc = keyp->description; #endif - return smk_access(tsp, keyp->security, + return smk_access(cred->security, keyp->security, MAY_READWRITE, &ad); } #endif /* CONFIG_KEYS */ @@ -3194,8 +3067,6 @@ struct security_operations smack_ops = { .sb_mount = smack_sb_mount, .sb_umount = smack_sb_umount, - .bprm_set_creds = smack_bprm_set_creds, - .inode_alloc_security = smack_inode_alloc_security, .inode_free_security = smack_inode_free_security, .inode_init_security = smack_inode_init_security, @@ -3332,16 +3203,9 @@ static __init void init_smack_know_list(void) static __init int smack_init(void) { struct cred *cred; - struct task_smack *tsp; - tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); - if (tsp == NULL) - return -ENOMEM; - - if (!security_module_enable(&smack_ops)) { - kfree(tsp); + if (!security_module_enable(&smack_ops)) return 0; - } printk(KERN_INFO "Smack: Initializing.\n"); @@ -3349,9 +3213,7 @@ static __init int smack_init(void) * Set the security state for the initial task. */ cred = (struct cred *) current->cred; - tsp->smk_forked = smack_known_floor.smk_known; - tsp->smk_task = smack_known_floor.smk_known; - cred->security = tsp; + cred->security = &smack_known_floor.smk_known; /* initialize the smack_know_list */ init_smack_know_list(); diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 362d5eda948b..dc1fd6239f24 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -109,12 +109,9 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION; * SMK_ACCESSLEN: Maximum length for a rule access field * SMK_LOADLEN: Smack rule length */ -#define SMK_OACCESS "rwxa" -#define SMK_ACCESS "rwxat" -#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1) -#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) -#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) -#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) +#define SMK_ACCESS "rwxa" +#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) +#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) /** * smk_netlabel_audit_set - fill a netlbl_audit struct @@ -124,7 +121,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) { nap->loginuid = audit_get_loginuid(current); nap->sessionid = audit_get_sessionid(current); - nap->secid = smack_to_secid(smk_of_current()); + nap->secid = smack_to_secid(current_security()); } /* @@ -178,8 +175,6 @@ static int load_seq_show(struct seq_file *s, void *v) seq_putc(s, 'x'); if (srp->smk_access & MAY_APPEND) seq_putc(s, 'a'); - if (srp->smk_access & MAY_TRANSMUTE) - seq_putc(s, 't'); if (srp->smk_access == 0) seq_putc(s, '-'); @@ -278,15 +273,10 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, if (!capable(CAP_MAC_ADMIN)) return -EPERM; - if (*ppos != 0) - return -EINVAL; - /* - * Minor hack for backward compatability - */ - if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN) + if (*ppos != 0 || count != SMK_LOADLEN) return -EINVAL; - data = kzalloc(SMK_LOADLEN, GFP_KERNEL); + data = kzalloc(count, GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -295,12 +285,6 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, goto out; } - /* - * More on the minor hack for backward compatability - */ - if (count == (SMK_OLOADLEN)) - data[SMK_OLOADLEN] = '-'; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); if (rule == NULL) { rc = -ENOMEM; @@ -361,17 +345,6 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, goto out_free_rule; } - switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { - case '-': - break; - case 't': - case 'T': - rule->smk_access |= MAY_TRANSMUTE; - break; - default: - goto out_free_rule; - } - rc = smk_set_access(rule); if (!rc) @@ -1187,7 +1160,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char in[SMK_LABELLEN]; - char *sp = smk_of_task(current->cred->security); + char *sp = current->cred->security; if (!capable(CAP_MAC_ADMIN)) return -EPERM; diff --git a/trunk/usr/gen_init_cpio.c b/trunk/usr/gen_init_cpio.c index 7f06884ecd41..b2b3c2d1cf8b 100644 --- a/trunk/usr/gen_init_cpio.c +++ b/trunk/usr/gen_init_cpio.c @@ -104,8 +104,6 @@ static int cpio_mkslink(const char *name, const char *target, char s[256]; time_t mtime = time(NULL); - if (name[0] == '/') - name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -154,8 +152,6 @@ static int cpio_mkgeneric(const char *name, unsigned int mode, char s[256]; time_t mtime = time(NULL); - if (name[0] == '/') - name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -249,8 +245,6 @@ static int cpio_mknod(const char *name, unsigned int mode, else mode |= S_IFCHR; - if (name[0] == '/') - name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -309,15 +303,15 @@ static int cpio_mkfile(const char *name, const char *location, mode |= S_IFREG; - file = open (location, O_RDONLY); - if (file < 0) { - fprintf (stderr, "File %s could not be opened for reading\n", location); + retval = stat (location, &buf); + if (retval) { + fprintf (stderr, "File %s could not be located\n", location); goto error; } - retval = fstat(file, &buf); - if (retval) { - fprintf(stderr, "File %s could not be stat()'ed\n", location); + file = open (location, O_RDONLY); + if (file < 0) { + fprintf (stderr, "File %s could not be opened for reading\n", location); goto error; } @@ -338,8 +332,6 @@ static int cpio_mkfile(const char *name, const char *location, /* data goes on last link */ if (i == nlinks) size = buf.st_size; - if (name[0] == '/') - name++; namesize = strlen(name) + 1; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08lX%08X%08X%08X%08X%08X%08X",